A few minor updates. ;-)
Seriously though, read the Changelog for busybox 0.42, which this is about to become... -Erik
This commit is contained in:
@@ -37,11 +37,24 @@ static const char umount_usage[] =
|
||||
#else
|
||||
"\n"
|
||||
#endif
|
||||
#ifdef BB_FEATURE_REMOUNT
|
||||
"\t-r:\tTry to remount devices as read-only if mount is busy\n"
|
||||
#endif
|
||||
;
|
||||
|
||||
struct _mtab_entry_t {
|
||||
char *device;
|
||||
char *mountpt;
|
||||
struct _mtab_entry_t *next;
|
||||
};
|
||||
|
||||
static struct _mtab_entry_t *mtab_cache = NULL;
|
||||
|
||||
|
||||
|
||||
static int useMtab = TRUE;
|
||||
static int umountAll = FALSE;
|
||||
static int doRemount = FALSE;
|
||||
extern const char mtab_file[]; /* Defined in utility.c */
|
||||
|
||||
#define MIN(x,y) (x > y ? x : y)
|
||||
@@ -50,21 +63,10 @@ static int
|
||||
do_umount(const char* name, int useMtab)
|
||||
{
|
||||
int status;
|
||||
struct mntent *m;
|
||||
FILE *mountTable;
|
||||
const char *blockDevice = NULL;
|
||||
char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE);
|
||||
|
||||
if ((mountTable = setmntent (mtab_file, "r"))) {
|
||||
while ((m = getmntent (mountTable)) != 0) {
|
||||
if (strncmp(m->mnt_dir, name,
|
||||
MIN(strlen(m->mnt_dir),strlen(name))) == 0)
|
||||
blockDevice = m->mnt_fsname;
|
||||
else if (strcmp(m->mnt_fsname, name) == 0) {
|
||||
blockDevice = name;
|
||||
name = m->mnt_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (blockDevice && strcmp(blockDevice, name) == 0)
|
||||
name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT);
|
||||
|
||||
status = umount(name);
|
||||
|
||||
@@ -73,57 +75,53 @@ do_umount(const char* name, int useMtab)
|
||||
/* this was a loop device, delete it */
|
||||
del_loop(blockDevice);
|
||||
#endif
|
||||
#if defined BB_MTAB
|
||||
#if defined BB_FEATURE_REMOUNT
|
||||
if ( status != 0 && doRemount == TRUE && errno == EBUSY ) {
|
||||
status = mount(blockDevice, name, NULL,
|
||||
MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
|
||||
if (status == 0) {
|
||||
fprintf(stderr, "umount: %s busy - remounted read-only\n",
|
||||
blockDevice);
|
||||
/* TODO: update mtab if BB_MTAB is defined */
|
||||
} else {
|
||||
fprintf(stderr, "umount: Cannot remount %s read-only\n",
|
||||
blockDevice);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if ( status == 0 ) {
|
||||
#if defined BB_MTAB
|
||||
if ( useMtab==TRUE )
|
||||
erase_mtab(name);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return(status);
|
||||
return( TRUE);
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
umount_all(int useMtab)
|
||||
{
|
||||
int status;
|
||||
struct mntent *m;
|
||||
FILE *mountTable;
|
||||
int status = TRUE;
|
||||
char *mountpt;
|
||||
void *iter;
|
||||
|
||||
if ((mountTable = setmntent (mtab_file, "r"))) {
|
||||
while ((m = getmntent (mountTable)) != 0) {
|
||||
char *blockDevice = m->mnt_fsname;
|
||||
#if ! defined BB_MTAB
|
||||
if (strcmp (blockDevice, "/dev/root") == 0) {
|
||||
struct fstab* fstabItem;
|
||||
fstabItem = getfsfile ("/");
|
||||
if (fstabItem != NULL) {
|
||||
blockDevice = fstabItem->fs_spec;
|
||||
}
|
||||
for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
|
||||
status=do_umount (mountpt, useMtab);
|
||||
if (status != 0) {
|
||||
/* Don't bother retrying the umount on busy devices */
|
||||
if (errno == EBUSY) {
|
||||
perror(mountpt);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* Don't umount /proc when doing umount -a */
|
||||
if (strcmp (blockDevice, "proc") == 0)
|
||||
continue;
|
||||
|
||||
status=do_umount (m->mnt_dir, useMtab);
|
||||
if (status!=0) {
|
||||
/* Don't bother retrying the umount on busy devices */
|
||||
if (errno==EBUSY) {
|
||||
perror(m->mnt_dir);
|
||||
continue;
|
||||
}
|
||||
status=do_umount (blockDevice, useMtab);
|
||||
if (status!=0) {
|
||||
printf ("Couldn't umount %s on %s (type %s): %s\n",
|
||||
blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
|
||||
}
|
||||
status = do_umount (mountpt, useMtab);
|
||||
if (status != 0) {
|
||||
printf ("Couldn't umount %s on %s: %s\n",
|
||||
mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), strerror(errno));
|
||||
}
|
||||
}
|
||||
endmntent (mountTable);
|
||||
}
|
||||
return( TRUE);
|
||||
return (status);
|
||||
}
|
||||
|
||||
extern int
|
||||
@@ -143,14 +141,19 @@ umount_main(int argc, char** argv)
|
||||
case 'n':
|
||||
useMtab = FALSE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef BB_FEATURE_REMOUNT
|
||||
case 'r':
|
||||
doRemount = TRUE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
usage( umount_usage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(umountAll==TRUE) {
|
||||
mtab_read();
|
||||
if (umountAll==TRUE) {
|
||||
exit(umount_all(useMtab));
|
||||
}
|
||||
if ( do_umount(*argv,useMtab) == 0 )
|
||||
@@ -161,3 +164,87 @@ umount_main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* These functions are here because the getmntent functions do not appear
|
||||
* to be re-entrant, which leads to all sorts of problems when we try to
|
||||
* use them recursively - randolph
|
||||
*/
|
||||
void mtab_read(void)
|
||||
{
|
||||
struct _mtab_entry_t *entry = NULL;
|
||||
struct mntent *e;
|
||||
FILE *fp;
|
||||
|
||||
if (mtab_cache != NULL) return;
|
||||
|
||||
if ((fp = setmntent(mtab_file, "r")) == NULL) {
|
||||
fprintf(stderr, "Cannot open %s\n", mtab_file);
|
||||
return;
|
||||
}
|
||||
while ((e = getmntent(fp))) {
|
||||
entry = malloc(sizeof(struct _mtab_entry_t));
|
||||
entry->device = strdup(e->mnt_fsname);
|
||||
entry->mountpt = strdup(e->mnt_dir);
|
||||
entry->next = mtab_cache;
|
||||
mtab_cache = entry;
|
||||
}
|
||||
endmntent(fp);
|
||||
}
|
||||
|
||||
char *mtab_getinfo(const char *match, const char which)
|
||||
{
|
||||
struct _mtab_entry_t *cur = mtab_cache;
|
||||
while (cur) {
|
||||
if (strcmp(cur->mountpt, match) == 0 ||
|
||||
strcmp(cur->device, match) == 0) {
|
||||
if (which == MTAB_GETMOUNTPT) {
|
||||
return cur->mountpt;
|
||||
} else {
|
||||
#if !defined BB_MTAB
|
||||
if (strcmp(cur->device, "/dev/root") == 0) {
|
||||
struct fstab* fstabItem;
|
||||
fstabItem = getfsfile ("/");
|
||||
if (fstabItem != NULL) return fstabItem->fs_spec;
|
||||
}
|
||||
#endif
|
||||
return cur->device;
|
||||
}
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *mtab_first(void **iter)
|
||||
{
|
||||
struct _mtab_entry_t *mtab_iter;
|
||||
if (!iter) return NULL;
|
||||
mtab_iter = mtab_cache;
|
||||
*iter = (void *)mtab_iter;
|
||||
return mtab_next(iter);
|
||||
}
|
||||
|
||||
char *mtab_next(void **iter)
|
||||
{
|
||||
char *mp;
|
||||
if (iter == NULL || *iter == NULL) return NULL;
|
||||
mp = ((struct _mtab_entry_t *)(*iter))->mountpt;
|
||||
*iter = (void *)((struct _mtab_entry_t *)(*iter))->next;
|
||||
return mp;
|
||||
}
|
||||
|
||||
void mtab_free(void)
|
||||
{
|
||||
struct _mtab_entry_t *this, *next;
|
||||
|
||||
this = mtab_cache;
|
||||
while (this) {
|
||||
next = this->next;
|
||||
if (this->device) free(this->device);
|
||||
if (this->mountpt) free(this->mountpt);
|
||||
free(this);
|
||||
this = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user