From 1da1caabbef6d178a6d6a85cf80bed89f489f6be Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Sat, 13 Dec 2008 02:47:42 +0100 Subject: [PATCH] mount: clean up SPEC canonicalization The SPEC (fsname) field in fstab/mtab could be: - devname - NAME=value (e.g LABEL, UUID) - directory (MS_MOVE, MS_BIND, ..) - pseudo-fs keyword (tmpfs, proc, sysfs, ...) the pseudo-fs keywords shouldn't be canonicalized to absolute path. It means we have to differ between SPEC and mountpoint (fs_dir). Unfortunately, the keywords was checked on wrong place. This patch move this check to the new function canonicalize_spec(). The fsname in mtab entry is canonicalized when the FS type is not pseudo filesystem. Signed-off-by: Karel Zak --- mount/fsprobe.c | 5 +++++ mount/fstab.c | 13 +++++++------ mount/mount.c | 18 ++++++++++++------ mount/realpath.c | 22 ++++++++++++++++------ mount/realpath.h | 3 ++- 5 files changed, 42 insertions(+), 19 deletions(-) diff --git a/mount/fsprobe.c b/mount/fsprobe.c index 96548647..07ffbd9a 100644 --- a/mount/fsprobe.c +++ b/mount/fsprobe.c @@ -170,6 +170,9 @@ fsprobe_get_devname_for_mounting(const char *spec) if (!spec) return NULL; + if (is_pseudo_fs(spec)) + return xstrdup(spec); + if (parse_spec(spec, &name, &value) != 0) return NULL; /* parse error */ @@ -203,6 +206,8 @@ fsprobe_get_devname(const char *spec) if (!spec) return NULL; + if (is_pseudo_fs(spec)) + return xstrdup(spec); if (parse_spec(spec, &name, &value) != 0) return NULL; /* parse error */ diff --git a/mount/fstab.c b/mount/fstab.c index 8c62a9e2..306e7bec 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -326,7 +326,7 @@ getfs_by_specdir (const char *spec, const char *dir) { for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) { /* dir */ if (!streq(mc->m.mnt_dir, dir)) { - char *dr = canonicalize_mountpoint(mc->m.mnt_dir); + char *dr = canonicalize(mc->m.mnt_dir); int ok = 0; if (streq(dr, dir)) @@ -338,7 +338,7 @@ getfs_by_specdir (const char *spec, const char *dir) { /* spec */ if (!streq(mc->m.mnt_fsname, spec)) { - char *fs = canonicalize(mc->m.mnt_fsname); + char *fs = canonicalize_spec(mc->m.mnt_fsname); int ok = 0; if (streq(fs, spec)) @@ -372,7 +372,7 @@ getfs_by_dir (const char *dir) { if (streq(mc->m.mnt_dir, dir)) return mc; - cdir = canonicalize_mountpoint(dir); + cdir = canonicalize(dir); for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) { if (streq(mc->m.mnt_dir, cdir)) { free(cdir); @@ -405,7 +405,7 @@ getfs_by_spec (const char *spec) { return mc; } - cspec = canonicalize(spec); + cspec = canonicalize_spec(spec); mc = getfs_by_devname(cspec); free(cspec); @@ -436,7 +436,7 @@ getfs_by_devname (const char *devname) { strncmp(mc->m.mnt_fsname, "UUID=", 5) == 0) continue; - fs = canonicalize(mc->m.mnt_fsname); + fs = canonicalize_spec(mc->m.mnt_fsname); if (streq(fs, devname)) { free(fs); return mc; @@ -922,7 +922,8 @@ void my_endmntent (mntFILE *mfp) { } int my_addmntent (mntFILE *mfp, struct my_mntent *mnt) { return 0; } char *canonicalize (const char *path) { return NULL; } -char *canonicalize_mountpoint (const char *path) { return NULL; } +char *canonicalize_spec (const char *path) { return NULL; } +int is_pseudo_fs(const char *type) { return 0; }; int main(int argc, char **argv) diff --git a/mount/mount.c b/mount/mount.c index ace4b146..947c94a8 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -242,7 +242,7 @@ print_one (const struct my_mntent *me) { printf (" type %s", me->mnt_type); if (me->mnt_opts != NULL) printf (" (%s)", me->mnt_opts); - if (list_with_volumelabel) { + if (list_with_volumelabel && is_pseudo_fs(me->mnt_type) == 0) { const char *devname = fsprobe_get_devname(me->mnt_fsname); if (devname) { @@ -500,9 +500,11 @@ fix_opts_string (int flags, const char *extra_opts, const char *user) { } static int -already (const char *spec, const char *node) { +already (const char *spec0, const char *node0) { struct mntentchn *mc; int ret = 1; + char *spec = canonicalize_spec(spec0); + char *node = canonicalize(node0); if ((mc = getmntfile(node)) != NULL) error (_("mount: according to mtab, " @@ -514,6 +516,10 @@ already (const char *spec, const char *node) { spec, mc->m.mnt_dir); else ret = 0; + + free(spec); + free(node); + return ret; } @@ -841,7 +847,7 @@ is_mounted_same_loopfile(const char *node0, const char *loopfile, unsigned long char *node; int res = 0; - node = canonicalize_mountpoint(node0); + node = canonicalize(node0); /* Search for mountpoint node in mtab, * procceed if any of these has the loop option set or @@ -981,8 +987,8 @@ update_mtab_entry(const char *spec, const char *node, const char *type, const char *opts, int flags, int freq, int pass) { struct my_mntent mnt; - mnt.mnt_fsname = canonicalize (spec); - mnt.mnt_dir = canonicalize_mountpoint (node); + mnt.mnt_fsname = is_pseudo_fs(type) ? xstrdup(spec) : canonicalize(spec); + mnt.mnt_dir = canonicalize (node); mnt.mnt_type = type; mnt.mnt_opts = opts; mnt.mnt_freq = freq; @@ -1511,7 +1517,7 @@ mounted (const char *spec0, const char *node0) { if (!spec) return ret; - node = canonicalize_mountpoint(node0); + node = canonicalize(node0); mc0 = mtab_head(); for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) diff --git a/mount/realpath.c b/mount/realpath.c index dbcd42ab..9b46951b 100644 --- a/mount/realpath.c +++ b/mount/realpath.c @@ -29,6 +29,19 @@ # define MAXSYMLINKS 256 #endif +int +is_pseudo_fs(const char *type) +{ + if (type == NULL || *type == '/') + return 0; + if (streq(type, "none") || + streq(type, "proc") || + streq(type, "tmpfs") || + streq(type, "sysfs") || + streq(type, "devpts")) + return 1; + return 0; +} /* Make a canonical pathname from PATH. Returns a freshly malloced string. It is up the *caller* to ensure that the PATH is sensible. i.e. @@ -36,15 +49,12 @@ is not a legal pathname for ``/dev/fd0''. Anything we cannot parse we return unmodified. */ char * -canonicalize_mountpoint (const char *path) { +canonicalize_spec (const char *path) +{ if (path == NULL) return NULL; - - if (streq(path, "none") || - streq(path, "proc") || - streq(path, "devpts")) + if (is_pseudo_fs(path)) return xstrdup(path); - return canonicalize(path); } diff --git a/mount/realpath.h b/mount/realpath.h index a8fad639..15450c1d 100644 --- a/mount/realpath.h +++ b/mount/realpath.h @@ -8,6 +8,7 @@ extern char *myrealpath(const char *path, char *resolved_path, int m); extern char *canonicalize (const char *path); -extern char *canonicalize_mountpoint (const char *path); +extern char *canonicalize_spec (const char *path); +extern int is_pseudo_fs(const char *type); #endif /* REALPATH_H */ -- 2.39.5