mount: code shrink without logic changes. Added a comment

on possible mismatch with util-linux in -o remount handling.

function                                             old     new   delta
mount_main                                           995     953     -42
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-42)             Total: -42 bytes
This commit is contained in:
Denis Vlasenko 2008-06-24 18:59:59 +00:00
parent fe733a9744
commit d0cc3f4ade

View File

@ -407,7 +407,7 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
vfsflags, filteropts); vfsflags, filteropts);
// If mount failed, try // If mount failed, try
// helper program <mnt_type> // helper program mount.<mnt_type>
if (ENABLE_FEATURE_MOUNT_HELPERS && rc) { if (ENABLE_FEATURE_MOUNT_HELPERS && rc) {
char *args[6]; char *args[6];
int errno_save = errno; int errno_save = errno;
@ -1727,11 +1727,11 @@ static int singlemount(struct mntent *mp, int ignore_busy)
static const char must_be_root[] ALIGN1 = "you must be root"; static const char must_be_root[] ALIGN1 = "you must be root";
int mount_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int mount_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int mount_main(int argc, char **argv) int mount_main(int argc ATTRIBUTE_UNUSED, char **argv)
{ {
char *cmdopts = xstrdup(""); char *cmdopts = xstrdup("");
char *fstype = NULL; char *fstype = NULL;
char *storage_path = NULL; char *storage_path;
char *opt_o; char *opt_o;
const char *fstabname; const char *fstabname;
FILE *fstab; FILE *fstab;
@ -1740,43 +1740,35 @@ int mount_main(int argc, char **argv)
struct mntent mtpair[2], *mtcur = mtpair; struct mntent mtpair[2], *mtcur = mtpair;
SKIP_DESKTOP(const int nonroot = 0;) SKIP_DESKTOP(const int nonroot = 0;)
USE_DESKTOP( int nonroot = ) sanitize_env_if_suid(); USE_DESKTOP(int nonroot = ) sanitize_env_if_suid();
// Parse long options, like --bind and --move. Note that -o option // Parse long options, like --bind and --move. Note that -o option
// and --option are synonymous. Yes, this means --remount,rw works. // and --option are synonymous. Yes, this means --remount,rw works.
for (i = j = 1; argv[i]; i++) {
for (i = j = 0; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] == '-')
if (argv[i][0] == '-' && argv[i][1] == '-') { append_mount_options(&cmdopts, argv[i] + 2);
append_mount_options(&cmdopts, argv[i]+2); else
} else argv[j++] = argv[i]; argv[j++] = argv[i];
} }
argv[j] = NULL; argv[j] = NULL;
argc = j;
// Parse remaining options // Parse remaining options
// Max 2 params; -v is a counter
#if ENABLE_FEATURE_MOUNT_VERBOSE opt_complementary = "?2" USE_FEATURE_MOUNT_VERBOSE(":vv");
opt_complementary = "vv"; // -v is a counter
#endif
opt = getopt32(argv, OPTION_STR, &opt_o, &fstype opt = getopt32(argv, OPTION_STR, &opt_o, &fstype
USE_FEATURE_MOUNT_VERBOSE(, &verbose)); USE_FEATURE_MOUNT_VERBOSE(, &verbose));
if (opt & OPT_o) append_mount_options(&cmdopts, opt_o); // -o if (opt & OPT_o) append_mount_options(&cmdopts, opt_o); // -o
if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r
if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w
argv += optind; argv += optind;
argc -= optind;
// Three or more non-option arguments? Die with a usage message.
if (argc > 2) bb_show_usage();
// If we have no arguments, show currently mounted filesystems // If we have no arguments, show currently mounted filesystems
if (!argv[0]) {
if (!argc) {
if (!(opt & OPT_a)) { if (!(opt & OPT_a)) {
FILE *mountTable = setmntent(bb_path_mtab_file, "r"); FILE *mountTable = setmntent(bb_path_mtab_file, "r");
if (!mountTable) bb_error_msg_and_die("no %s", bb_path_mtab_file); if (!mountTable)
bb_error_msg_and_die("no %s", bb_path_mtab_file);
while (getmntent_r(mountTable, &mtpair[0], getmntent_buf, while (getmntent_r(mountTable, &mtpair[0], getmntent_buf,
GETMNTENT_BUFSIZE)) GETMNTENT_BUFSIZE))
@ -1790,16 +1782,16 @@ int mount_main(int argc, char **argv)
mtpair->mnt_dir, mtpair->mnt_type, mtpair->mnt_dir, mtpair->mnt_type,
mtpair->mnt_opts); mtpair->mnt_opts);
} }
if (ENABLE_FEATURE_CLEAN_UP) endmntent(mountTable); if (ENABLE_FEATURE_CLEAN_UP)
endmntent(mountTable);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
} else storage_path = bb_simplify_path(argv[0]); storage_path = NULL;
} else {
// When we have two arguments, the second is the directory and we can // When we have two arguments, the second is the directory and we can
// skip looking at fstab entirely. We can always abspath() the directory // skip looking at fstab entirely. We can always abspath() the directory
// argument when we get it. // argument when we get it.
if (argv[1]) {
if (argc == 2) {
if (nonroot) if (nonroot)
bb_error_msg_and_die(must_be_root); bb_error_msg_and_die(must_be_root);
mtpair->mnt_fsname = argv[0]; mtpair->mnt_fsname = argv[0];
@ -1810,132 +1802,128 @@ int mount_main(int argc, char **argv)
resolve_mount_spec(&mtpair->mnt_fsname); resolve_mount_spec(&mtpair->mnt_fsname);
} }
rc = singlemount(mtpair, 0); rc = singlemount(mtpair, 0);
goto clean_up; return rc;
} }
storage_path = bb_simplify_path(argv[0]); // malloced
}
// Past this point, we are handling either "mount -a [opts]"
// or "mount [opts] single_param"
i = parse_mount_options(cmdopts, 0); // FIXME: should be "long", not "int" i = parse_mount_options(cmdopts, 0); // FIXME: should be "long", not "int"
if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags
bb_error_msg_and_die(must_be_root); bb_error_msg_and_die(must_be_root);
// If we have a shared subtree flag, don't worry about fstab or mtab. // If we have a shared subtree flag, don't worry about fstab or mtab.
if (ENABLE_FEATURE_MOUNT_FLAGS if (ENABLE_FEATURE_MOUNT_FLAGS
&& (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) && (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
) { ) {
rc = verbose_mount("", argv[0], "", i, ""); rc = verbose_mount(/*source:*/ "", /*target:*/ argv[0],
if (rc) bb_simple_perror_msg_and_die(argv[0]); /*type:*/ "", /*flags:*/ i, /*data:*/ "");
goto clean_up; if (rc)
bb_simple_perror_msg_and_die(argv[0]);
return rc;
} }
// Open either fstab or mtab // Open either fstab or mtab
fstabname = "/etc/fstab"; fstabname = "/etc/fstab";
if (i & MS_REMOUNT) { if (i & MS_REMOUNT) {
// WARNING. I am not sure this matches util-linux's
// behavior. It's possible util-linux does not
// take -o opts from mtab (takes only mount source).
fstabname = bb_path_mtab_file; fstabname = bb_path_mtab_file;
} }
fstab = setmntent(fstabname, "r"); fstab = setmntent(fstabname, "r");
if (!fstab) if (!fstab)
bb_perror_msg_and_die("cannot read %s", fstabname); bb_perror_msg_and_die("cannot read %s", fstabname);
// Loop through entries until we find what we're looking for. // Loop through entries until we find what we're looking for
memset(mtpair, 0, sizeof(mtpair)); memset(mtpair, 0, sizeof(mtpair));
for (;;) { for (;;) {
struct mntent *mtnext = (mtcur==mtpair ? mtpair+1 : mtpair); struct mntent *mtother = (mtcur==mtpair ? mtpair+1 : mtpair);
// Get next fstab entry // Get next fstab entry
if (!getmntent_r(fstab, mtcur, getmntent_buf if (!getmntent_r(fstab, mtcur, getmntent_buf
+ (mtcur==mtpair ? GETMNTENT_BUFSIZE/2 : 0), + (mtcur==mtpair ? GETMNTENT_BUFSIZE/2 : 0),
GETMNTENT_BUFSIZE/2)) GETMNTENT_BUFSIZE/2)
{ ) { // End of fstab/mtab is reached
// Were we looking for something specific? mtcur = mtother; // the thing we found last time
break;
if (argc) {
// If we didn't find anything, complain.
if (!mtnext->mnt_fsname)
bb_error_msg_and_die("can't find %s in %s",
argv[0], fstabname);
mtcur = mtnext;
if (nonroot) {
// fstab must have "users" or "user"
if (!(parse_mount_options(mtcur->mnt_opts, 0) & MOUNT_USERS))
bb_error_msg_and_die(must_be_root);
} }
// Mount the last thing we found. // If we're trying to mount something specific and this isn't it,
// skip it. Note we must match the exact text in fstab (ala
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); // "proc") or a full path from root
append_mount_options(&(mtcur->mnt_opts), cmdopts); if (argv[0]) {
if (ENABLE_FEATURE_MOUNT_LABEL) {
resolve_mount_spec(&mtpair->mnt_fsname);
}
rc = singlemount(mtcur, 0);
free(mtcur->mnt_opts);
}
goto clean_up;
}
/* If we're trying to mount something specific and this isn't it,
* skip it. Note we must match both the exact text in fstab (ala
* "proc") or a full path from root */
if (argc) {
// 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) &&
strcmp(storage_path, mtcur->mnt_fsname) && strcmp(storage_path, mtcur->mnt_fsname) &&
strcmp(argv[0], mtcur->mnt_dir) && strcmp(argv[0], mtcur->mnt_dir) &&
strcmp(storage_path, mtcur->mnt_dir)) continue; strcmp(storage_path, mtcur->mnt_dir)) continue;
// Remember this entry. Something later may have overmounted // Remember this entry. Something later may have
// it, and we want the _last_ match. // overmounted it, and we want the _last_ match.
mtcur = mtother;
mtcur = mtnext;
// If we're mounting all.
// If we're mounting all
} else { } else {
// Do we need to match a filesystem type? // Do we need to match a filesystem type?
if (fstype && match_fstype(mtcur, fstype)) if (fstype && match_fstype(mtcur, fstype))
continue; continue;
// Skip noauto and swap anyway. // Skip noauto and swap anyway.
if (parse_mount_options(mtcur->mnt_opts, 0) & (MOUNT_NOAUTO | MOUNT_SWAP)) if (parse_mount_options(mtcur->mnt_opts, 0) & (MOUNT_NOAUTO | MOUNT_SWAP))
continue; continue;
// 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)
bb_error_msg_and_die(must_be_root); bb_error_msg_and_die(must_be_root);
// Mount this thing. // Mount this thing
if (ENABLE_FEATURE_MOUNT_LABEL) if (ENABLE_FEATURE_MOUNT_LABEL)
resolve_mount_spec(&mtpair->mnt_fsname); resolve_mount_spec(&mtpair->mnt_fsname);
// 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);
if (singlemount(mtcur, 1)) { if (singlemount(mtcur, 1)) {
/* Count number of failed mounts */ // Count number of failed mounts
rc++; rc++;
} }
free(mtcur->mnt_opts); free(mtcur->mnt_opts);
} }
} }
if (ENABLE_FEATURE_CLEAN_UP) endmntent(fstab);
clean_up: // End of fstab/mtab is reached.
// Were we looking for something specific?
if (argv[0]) {
// If we didn't find anything, complain
if (!mtcur->mnt_fsname)
bb_error_msg_and_die("can't find %s in %s",
argv[0], fstabname);
if (nonroot) {
// fstab must have "users" or "user"
if (!(parse_mount_options(mtcur->mnt_opts, 0) & MOUNT_USERS))
bb_error_msg_and_die(must_be_root);
}
// Mount the last thing we found
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
append_mount_options(&(mtcur->mnt_opts), cmdopts);
if (ENABLE_FEATURE_MOUNT_LABEL) {
resolve_mount_spec(&mtpair->mnt_fsname);
}
rc = singlemount(mtcur, 0);
if (ENABLE_FEATURE_CLEAN_UP)
free(mtcur->mnt_opts);
}
if (ENABLE_FEATURE_CLEAN_UP)
endmntent(fstab);
if (ENABLE_FEATURE_CLEAN_UP) { if (ENABLE_FEATURE_CLEAN_UP) {
free(storage_path); free(storage_path);
free(cmdopts); free(cmdopts);
} }
return rc; return rc;
} }