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);
// If mount failed, try
// helper program <mnt_type>
// helper program mount.<mnt_type>
if (ENABLE_FEATURE_MOUNT_HELPERS && rc) {
char *args[6];
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";
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 *fstype = NULL;
char *storage_path = NULL;
char *storage_path;
char *opt_o;
const char *fstabname;
FILE *fstab;
@ -1744,39 +1744,31 @@ int mount_main(int argc, char **argv)
// Parse long options, like --bind and --move. Note that -o option
// and --option are synonymous. Yes, this means --remount,rw works.
for (i = j = 0; i < argc; i++) {
if (argv[i][0] == '-' && argv[i][1] == '-') {
for (i = j = 1; argv[i]; i++) {
if (argv[i][0] == '-' && argv[i][1] == '-')
append_mount_options(&cmdopts, argv[i] + 2);
} else argv[j++] = argv[i];
else
argv[j++] = argv[i];
}
argv[j] = NULL;
argc = j;
// Parse remaining options
#if ENABLE_FEATURE_MOUNT_VERBOSE
opt_complementary = "vv"; // -v is a counter
#endif
// Max 2 params; -v is a counter
opt_complementary = "?2" USE_FEATURE_MOUNT_VERBOSE(":vv");
opt = getopt32(argv, OPTION_STR, &opt_o, &fstype
USE_FEATURE_MOUNT_VERBOSE(, &verbose));
if (opt & OPT_o) append_mount_options(&cmdopts, opt_o); // -o
if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r
if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w
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 (!argc) {
if (!argv[0]) {
if (!(opt & OPT_a)) {
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,
GETMNTENT_BUFSIZE))
@ -1790,16 +1782,16 @@ int mount_main(int argc, char **argv)
mtpair->mnt_dir, mtpair->mnt_type,
mtpair->mnt_opts);
}
if (ENABLE_FEATURE_CLEAN_UP) endmntent(mountTable);
if (ENABLE_FEATURE_CLEAN_UP)
endmntent(mountTable);
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
// skip looking at fstab entirely. We can always abspath() the directory
// argument when we get it.
if (argc == 2) {
if (argv[1]) {
if (nonroot)
bb_error_msg_and_die(must_be_root);
mtpair->mnt_fsname = argv[0];
@ -1810,132 +1802,128 @@ int mount_main(int argc, char **argv)
resolve_mount_spec(&mtpair->mnt_fsname);
}
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"
if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags
bb_error_msg_and_die(must_be_root);
// If we have a shared subtree flag, don't worry about fstab or mtab.
if (ENABLE_FEATURE_MOUNT_FLAGS
&& (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
) {
rc = verbose_mount("", argv[0], "", i, "");
if (rc) bb_simple_perror_msg_and_die(argv[0]);
goto clean_up;
rc = verbose_mount(/*source:*/ "", /*target:*/ argv[0],
/*type:*/ "", /*flags:*/ i, /*data:*/ "");
if (rc)
bb_simple_perror_msg_and_die(argv[0]);
return rc;
}
// Open either fstab or mtab
fstabname = "/etc/fstab";
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;
}
fstab = setmntent(fstabname, "r");
if (!fstab)
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));
for (;;) {
struct mntent *mtnext = (mtcur==mtpair ? mtpair+1 : mtpair);
struct mntent *mtother = (mtcur==mtpair ? mtpair+1 : mtpair);
// Get next fstab entry
if (!getmntent_r(fstab, mtcur, getmntent_buf
+ (mtcur==mtpair ? GETMNTENT_BUFSIZE/2 : 0),
GETMNTENT_BUFSIZE/2))
{
// Were we looking for something specific?
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);
GETMNTENT_BUFSIZE/2)
) { // End of fstab/mtab is reached
mtcur = mtother; // the thing we found last time
break;
}
// 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);
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) {
// 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
// "proc") or a full path from root
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;
// Remember this entry. Something later may have overmounted
// it, and we want the _last_ match.
mtcur = mtnext;
// If we're mounting all.
// Remember this entry. Something later may have
// overmounted it, and we want the _last_ match.
mtcur = mtother;
// If we're mounting all
} else {
// Do we need to match a filesystem type?
if (fstype && match_fstype(mtcur, fstype))
continue;
// Skip noauto and swap anyway.
if (parse_mount_options(mtcur->mnt_opts, 0) & (MOUNT_NOAUTO | MOUNT_SWAP))
continue;
// No, mount -a won't mount anything,
// even user mounts, for mere humans.
// even user mounts, for mere humans
if (nonroot)
bb_error_msg_and_die(must_be_root);
// Mount this thing.
// Mount this thing
if (ENABLE_FEATURE_MOUNT_LABEL)
resolve_mount_spec(&mtpair->mnt_fsname);
// NFS mounts want this to be xrealloc-able
mtcur->mnt_opts = xstrdup(mtcur->mnt_opts);
if (singlemount(mtcur, 1)) {
/* Count number of failed mounts */
// Count number of failed mounts
rc++;
}
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) {
free(storage_path);
free(cmdopts);
}
return rc;
}