mount: prevent second mount -a from mounting everything again

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2009-12-05 04:25:19 +01:00
parent 14b0f4feb3
commit a7329667b4
2 changed files with 59 additions and 21 deletions

View File

@ -167,10 +167,9 @@ int df_main(int argc UNUSED_PARAM, char **argv)
continue; continue;
#ifdef WHY_WE_DO_IT_FOR_DEV_ROOT_ONLY #ifdef WHY_WE_DO_IT_FOR_DEV_ROOT_ONLY
/* ... and also this is the only user of find_block_device */
if (strcmp(device, "/dev/root") == 0) { if (strcmp(device, "/dev/root") == 0) {
/* Adjusts device to be the real root device, /* Adjusts device to be the real root device,
* or leaves device alone if it can't find it */ * or leaves device alone if it can't find it */
device = find_block_device("/"); device = find_block_device("/");
if (!device) { if (!device) {
goto set_error; goto set_error;

View File

@ -1829,7 +1829,8 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
llist_t *lst_o = NULL; llist_t *lst_o = NULL;
const char *fstabname; const char *fstabname;
FILE *fstab; FILE *fstab;
int i, j, rc = 0; int i, j;
int rc = EXIT_SUCCESS;
unsigned opt; unsigned opt;
struct mntent mtpair[2], *mtcur = mtpair; struct mntent mtpair[2], *mtcur = mtpair;
IF_NOT_DESKTOP(const int nonroot = 0;) IF_NOT_DESKTOP(const int nonroot = 0;)
@ -1893,7 +1894,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
mtpair->mnt_type = fstype; mtpair->mnt_type = fstype;
mtpair->mnt_opts = cmdopts; mtpair->mnt_opts = cmdopts;
resolve_mount_spec(&mtpair->mnt_fsname); resolve_mount_spec(&mtpair->mnt_fsname);
rc = singlemount(mtpair, 0); rc = singlemount(mtpair, /*ignore_busy:*/ 0);
return rc; return rc;
} }
storage_path = bb_simplify_path(argv[0]); // malloced storage_path = bb_simplify_path(argv[0]); // malloced
@ -1949,10 +1950,13 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
if (argv[0]) { if (argv[0]) {
// Is this what we're looking for? // Is this what we're looking for?
if (strcmp(argv[0], mtcur->mnt_fsname) && if (strcmp(argv[0], mtcur->mnt_fsname) != 0
strcmp(storage_path, mtcur->mnt_fsname) && && strcmp(storage_path, mtcur->mnt_fsname) != 0
strcmp(argv[0], mtcur->mnt_dir) && && strcmp(argv[0], mtcur->mnt_dir) != 0
strcmp(storage_path, mtcur->mnt_dir)) continue; && strcmp(storage_path, mtcur->mnt_dir) != 0
) {
continue; // no
}
// Remember this entry. Something later may have // Remember this entry. Something later may have
// overmounted it, and we want the _last_ match. // overmounted it, and we want the _last_ match.
@ -1960,6 +1964,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
// If we're mounting all // If we're mounting all
} else { } else {
struct mntent *mp;
// No, mount -a won't mount anything, // No, mount -a won't mount anything,
// even user mounts, for mere humans // even user mounts, for mere humans
if (nonroot) if (nonroot)
@ -1969,7 +1974,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
if (!match_fstype(mtcur, fstype)) if (!match_fstype(mtcur, fstype))
continue; continue;
// Skip noauto and swap anyway. // Skip noauto and swap anyway
if ((parse_mount_options(mtcur->mnt_opts, NULL) & (MOUNT_NOAUTO | MOUNT_SWAP)) if ((parse_mount_options(mtcur->mnt_opts, NULL) & (MOUNT_NOAUTO | MOUNT_SWAP))
// swap is bogus "fstype", parse_mount_options can't check fstypes // swap is bogus "fstype", parse_mount_options can't check fstypes
|| strcasecmp(mtcur->mnt_type, "swap") == 0 || strcasecmp(mtcur->mnt_type, "swap") == 0
@ -1987,10 +1992,23 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
// NFS mounts want this to be xrealloc-able // NFS mounts want this to be xrealloc-able
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
// Mount this thing // If nothing is mounted on this directory...
if (singlemount(mtcur, 1)) { // (otherwise repeated "mount -a" mounts everything again)
// Count number of failed mounts mp = find_mount_point(mtcur->mnt_dir, /*subdir_too:*/ 0);
rc++; // We do not check fsname match of found mount point -
// "/" may have fsname of "/dev/root" while fstab
// says "/dev/something_else".
if (mp) {
bb_error_msg("according to %s, "
"%s is already mounted on %s",
bb_path_mtab_file,
mp->mnt_fsname, mp->mnt_dir);
} else {
// ...mount this thing
if (singlemount(mtcur, /*ignore_busy:*/ 1)) {
// Count number of failed mounts
rc++;
}
} }
free(mtcur->mnt_opts); free(mtcur->mnt_opts);
} }
@ -1998,7 +2016,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
// End of fstab/mtab is reached. // End of fstab/mtab is reached.
// Were we looking for something specific? // Were we looking for something specific?
if (argv[0]) { if (argv[0]) { // yes
long l; long l;
// If we didn't find anything, complain // If we didn't find anything, complain
@ -2031,13 +2049,24 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
bb_error_msg_and_die(bb_msg_you_must_be_root); bb_error_msg_and_die(bb_msg_you_must_be_root);
} }
// Mount the last thing we found //util-linux-2.12 does not do this check.
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); //// If nothing is mounted on this directory...
append_mount_options(&(mtcur->mnt_opts), cmdopts); //// (otherwise repeated "mount FOO" mounts FOO again)
resolve_mount_spec(&mtpair->mnt_fsname); //mp = find_mount_point(mtcur->mnt_dir, /*subdir_too:*/ 0);
rc = singlemount(mtcur, 0); //if (mp) {
if (ENABLE_FEATURE_CLEAN_UP) // bb_error_msg("according to %s, "
free(mtcur->mnt_opts); // "%s is already mounted on %s",
// bb_path_mtab_file,
// mp->mnt_fsname, mp->mnt_dir);
//} else {
// ...mount the last thing we found
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
append_mount_options(&(mtcur->mnt_opts), cmdopts);
resolve_mount_spec(&mtpair->mnt_fsname);
rc = singlemount(mtcur, /*ignore_busy:*/ 0);
if (ENABLE_FEATURE_CLEAN_UP)
free(mtcur->mnt_opts);
//}
} }
//ret: //ret:
@ -2047,5 +2076,15 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
free(storage_path); free(storage_path);
free(cmdopts); free(cmdopts);
} }
//TODO: exitcode should be ORed mask of (from "man mount"):
// 0 success
// 1 incorrect invocation or permissions
// 2 system error (out of memory, cannot fork, no more loop devices)
// 4 internal mount bug or missing nfs support in mount
// 8 user interrupt
//16 problems writing or locking /etc/mtab
//32 mount failure
//64 some mount succeeded
return rc; return rc;
} }