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:
parent
fe733a9744
commit
d0cc3f4ade
@ -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;
|
||||
@ -1740,43 +1740,35 @@ int mount_main(int argc, char **argv)
|
||||
struct mntent mtpair[2], *mtcur = mtpair;
|
||||
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
|
||||
// and --option are synonymous. Yes, this means --remount,rw works.
|
||||
|
||||
for (i = j = 0; i < argc; i++) {
|
||||
if (argv[i][0] == '-' && argv[i][1] == '-') {
|
||||
append_mount_options(&cmdopts, argv[i]+2);
|
||||
} else argv[j++] = argv[i];
|
||||
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];
|
||||
}
|
||||
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,152 +1782,148 @@ 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]);
|
||||
|
||||
// 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 (nonroot)
|
||||
bb_error_msg_and_die(must_be_root);
|
||||
mtpair->mnt_fsname = argv[0];
|
||||
mtpair->mnt_dir = argv[1];
|
||||
mtpair->mnt_type = fstype;
|
||||
mtpair->mnt_opts = cmdopts;
|
||||
if (ENABLE_FEATURE_MOUNT_LABEL) {
|
||||
resolve_mount_spec(&mtpair->mnt_fsname);
|
||||
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 (argv[1]) {
|
||||
if (nonroot)
|
||||
bb_error_msg_and_die(must_be_root);
|
||||
mtpair->mnt_fsname = argv[0];
|
||||
mtpair->mnt_dir = argv[1];
|
||||
mtpair->mnt_type = fstype;
|
||||
mtpair->mnt_opts = cmdopts;
|
||||
if (ENABLE_FEATURE_MOUNT_LABEL) {
|
||||
resolve_mount_spec(&mtpair->mnt_fsname);
|
||||
}
|
||||
rc = singlemount(mtpair, 0);
|
||||
return rc;
|
||||
}
|
||||
rc = singlemount(mtpair, 0);
|
||||
goto clean_up;
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
GETMNTENT_BUFSIZE/2)
|
||||
) { // End of fstab/mtab is reached
|
||||
mtcur = mtother; // the thing we found last time
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user