summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2009-12-05 04:25:19 +0100
committerDenys Vlasenko2009-12-05 04:25:19 +0100
commita7329667b4c19fbe8ba077062f14a96038c094db (patch)
treed9a7b98355e92523c444345e397d97670d83dfd4
parent14b0f4feb3648378acb5eba12c8fcd8fa291b231 (diff)
downloadbusybox-a7329667b4c19fbe8ba077062f14a96038c094db.zip
busybox-a7329667b4c19fbe8ba077062f14a96038c094db.tar.gz
mount: prevent second mount -a from mounting everything again
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--coreutils/df.c3
-rw-r--r--util-linux/mount.c77
2 files changed, 59 insertions, 21 deletions
diff --git a/coreutils/df.c b/coreutils/df.c
index 11a7398..83794ad 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -167,10 +167,9 @@ int df_main(int argc UNUSED_PARAM, char **argv)
continue;
#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) {
/* 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("/");
if (!device) {
goto set_error;
diff --git a/util-linux/mount.c b/util-linux/mount.c
index d7ca7da..c2b508e 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -1829,7 +1829,8 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
llist_t *lst_o = NULL;
const char *fstabname;
FILE *fstab;
- int i, j, rc = 0;
+ int i, j;
+ int rc = EXIT_SUCCESS;
unsigned opt;
struct mntent mtpair[2], *mtcur = mtpair;
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_opts = cmdopts;
resolve_mount_spec(&mtpair->mnt_fsname);
- rc = singlemount(mtpair, 0);
+ rc = singlemount(mtpair, /*ignore_busy:*/ 0);
return rc;
}
storage_path = bb_simplify_path(argv[0]); // malloced
@@ -1949,10 +1950,13 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
if (argv[0]) {
// Is this what we're looking for?
- if (strcmp(argv[0], mtcur->mnt_fsname) &&
- strcmp(storage_path, mtcur->mnt_fsname) &&
- strcmp(argv[0], mtcur->mnt_dir) &&
- strcmp(storage_path, mtcur->mnt_dir)) continue;
+ if (strcmp(argv[0], mtcur->mnt_fsname) != 0
+ && strcmp(storage_path, mtcur->mnt_fsname) != 0
+ && strcmp(argv[0], mtcur->mnt_dir) != 0
+ && strcmp(storage_path, mtcur->mnt_dir) != 0
+ ) {
+ continue; // no
+ }
// Remember this entry. Something later may have
// 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
} else {
+ struct mntent *mp;
// No, mount -a won't mount anything,
// even user mounts, for mere humans
if (nonroot)
@@ -1969,7 +1974,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
if (!match_fstype(mtcur, fstype))
continue;
- // Skip noauto and swap anyway.
+ // Skip noauto and swap anyway
if ((parse_mount_options(mtcur->mnt_opts, NULL) & (MOUNT_NOAUTO | MOUNT_SWAP))
// swap is bogus "fstype", parse_mount_options can't check fstypes
|| 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
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
- // Mount this thing
- if (singlemount(mtcur, 1)) {
- // Count number of failed mounts
- rc++;
+ // If nothing is mounted on this directory...
+ // (otherwise repeated "mount -a" mounts everything again)
+ mp = find_mount_point(mtcur->mnt_dir, /*subdir_too:*/ 0);
+ // 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);
}
@@ -1998,7 +2016,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
// End of fstab/mtab is reached.
// Were we looking for something specific?
- if (argv[0]) {
+ if (argv[0]) { // yes
long l;
// 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);
}
- // 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, 0);
- if (ENABLE_FEATURE_CLEAN_UP)
- free(mtcur->mnt_opts);
+ //util-linux-2.12 does not do this check.
+ //// If nothing is mounted on this directory...
+ //// (otherwise repeated "mount FOO" mounts FOO again)
+ //mp = find_mount_point(mtcur->mnt_dir, /*subdir_too:*/ 0);
+ //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 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:
@@ -2047,5 +2076,15 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
free(storage_path);
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;
}