]> err.no Git - util-linux/commitdiff
mount: clean up SPEC canonicalization
authorKarel Zak <kzak@redhat.com>
Sat, 13 Dec 2008 01:47:42 +0000 (02:47 +0100)
committerKarel Zak <kzak@redhat.com>
Fri, 19 Dec 2008 11:45:20 +0000 (12:45 +0100)
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 <kzak@redhat.com>
mount/fsprobe.c
mount/fstab.c
mount/mount.c
mount/realpath.c
mount/realpath.h

index 96548647cbf61427de5a5cde20c54c2cffcdbb4c..07ffbd9ab172d1765800ac58596c6d94aac357a0 100644 (file)
@@ -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 */
index 8c62a9e25aabffdfc626c9f6423db966cb6fbcd8..306e7bec76852acc210fb2478b28eeea0629a8e9 100644 (file)
@@ -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)
index 773335ebb180e6017e87dc187e676f7c45b4041a..e70121cccf9513ba69311fdc31c3ef308caad7ba 100644 (file)
@@ -241,7 +241,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) {
@@ -499,9 +499,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, "
@@ -513,6 +515,10 @@ already (const char *spec, const char *node) {
                       spec, mc->m.mnt_dir);
        else
                ret = 0;
+
+       free(spec);
+       free(node);
+
        return ret;
 }
 
@@ -840,7 +846,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
@@ -980,8 +986,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;
@@ -1510,7 +1516,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)
index dbcd42aba6216cb8d94f39abbd4c6ccf2258bf62..9b46951b53202bfd05c090f89032af62ea9b9560 100644 (file)
 # 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.
    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);
 }
 
index a8fad639acfb54d9998930d6892689d4497d0ac4..15450c1d79c9e3d8ad4f7b02bdc0a82db62d2037 100644 (file)
@@ -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 */