]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: correctly propagate ambivalent blkid probing results
authorKarel Zak <kzak@redhat.com>
Wed, 13 Feb 2013 11:36:10 +0000 (12:36 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 13 Feb 2013 11:36:10 +0000 (12:36 +0100)
libmount ignores "ambivalent probing result" from libblkid and tries
filesystems /etc/filesystems. This is incorrect behavior.

Reported-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/cache.c
libmount/src/context.c
libmount/src/mountP.h
sys-utils/mount.c

index 2a8077c3a530e1371ce338414dea039f8e553e67..b718fd5d4189ced3d1b22c80015f21994e13e3a6 100644 (file)
@@ -258,6 +258,7 @@ int mnt_cache_read_tags(struct libmnt_cache *cache, const char *devname)
 {
        blkid_probe pr;
        size_t i, ntags = 0;
+       int rc;
        const char *tags[] = { "LABEL", "UUID", "TYPE", "PARTUUID", "PARTLABEL" };
        const char *blktags[] = { "LABEL", "UUID", "TYPE", "PART_ENTRY_UUID", "PART_ENTRY_NAME" };
 
@@ -291,7 +292,8 @@ int mnt_cache_read_tags(struct libmnt_cache *cache, const char *devname)
        blkid_probe_enable_partitions(pr, 1);
        blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
 
-       if (blkid_do_safeprobe(pr))
+       rc = blkid_do_safeprobe(pr);
+       if (rc)
                goto error;
 
        DBG(CACHE, mnt_debug_h(cache, "reading tags for: %s", devname));
@@ -323,7 +325,7 @@ int mnt_cache_read_tags(struct libmnt_cache *cache, const char *devname)
        return ntags ? 0 : 1;
 error:
        blkid_free_probe(pr);
-       return -1;
+       return rc < 0 ? rc : -1;
 }
 
 /**
@@ -347,6 +349,22 @@ int mnt_cache_device_has_tag(struct libmnt_cache *cache, const char *devname,
        return 0;
 }
 
+static int __mnt_cache_find_tag_value(struct libmnt_cache *cache,
+               const char *devname, const char *token, char **data)
+{
+       int rc = 0;
+
+       if (!cache || !devname || !token || !data)
+               return -EINVAL;
+
+       rc = mnt_cache_read_tags(cache, devname);
+       if (rc)
+               return rc;
+
+       *data = cache_find_tag_value(cache, devname, token);
+       return data ? 0 : -1;
+}
+
 /**
  * mnt_cache_find_tag_value:
  * @cache: cache for results
@@ -358,13 +376,11 @@ int mnt_cache_device_has_tag(struct libmnt_cache *cache, const char *devname,
 char *mnt_cache_find_tag_value(struct libmnt_cache *cache,
                const char *devname, const char *token)
 {
-       if (!cache || !devname || !token)
-               return NULL;
-
-       if (mnt_cache_read_tags(cache, devname) != 0)
-               return NULL;
+       char *data = NULL;
 
-       return cache_find_tag_value(cache, devname, token);
+       if (__mnt_cache_find_tag_value(cache, devname, token, &data) == 0)
+               return data;
+       return NULL;
 }
 
 /**
@@ -385,8 +401,13 @@ char *mnt_get_fstype(const char *devname, int *ambi, struct libmnt_cache *cache)
 
        DBG(CACHE, mnt_debug_h(cache, "get %s FS type", devname));
 
-       if (cache)
-               return mnt_cache_find_tag_value(cache, devname, "TYPE");
+       if (cache) {
+               char *val = NULL;
+               rc = __mnt_cache_find_tag_value(cache, devname, "TYPE", &val);
+               if (ambi)
+                       *ambi = rc == -2 ? TRUE : FALSE;
+               return rc ? NULL : val;
+       }
 
        /*
         * no cache, probe directly
@@ -396,11 +417,12 @@ char *mnt_get_fstype(const char *devname, int *ambi, struct libmnt_cache *cache)
                return NULL;
 
        blkid_probe_enable_superblocks(pr, 1);
-
        blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE);
 
        rc = blkid_do_safeprobe(pr);
 
+       DBG(CACHE, mnt_debug_h(cache, "liblkid rc=%d", rc));
+
        if (!rc && !blkid_probe_lookup_value(pr, "TYPE", &data, NULL))
                type = strdup(data);
 
index 6d57038349aad589598a0e0e307146d59fce0c48..2e2a161dd009e225dca852d2daccf40b598d7644 100644 (file)
@@ -146,7 +146,6 @@ int mnt_reset_context(struct libmnt_context *cxt)
 
        cxt->fs = NULL;
        cxt->mtab = NULL;
-       cxt->ambi = 0;
        cxt->helper = NULL;
        cxt->orig_user = NULL;
        cxt->mountflags = 0;
@@ -1514,13 +1513,16 @@ int mnt_context_guess_fstype(struct libmnt_context *cxt)
 
        if (access(dev, F_OK) == 0) {
                struct libmnt_cache *cache = mnt_context_get_cache(cxt);
+               int ambi = 0;
 
-               type = mnt_get_fstype(dev, &cxt->ambi, cache);
+               type = mnt_get_fstype(dev, &ambi, cache);
                if (type) {
                        rc = mnt_fs_set_fstype(cxt->fs, type);
                        if (!cache)
                                free(type);     /* type is not cached */
                }
+               if (ambi)
+                       rc = -MNT_ERR_AMBIFS;
        } else {
                if (strchr(dev, ':') != NULL)
                        rc = mnt_fs_set_fstype(cxt->fs, "nfs");
@@ -1529,7 +1531,8 @@ int mnt_context_guess_fstype(struct libmnt_context *cxt)
        }
 
 done:
-       DBG(CXT, mnt_debug_h(cxt, "FS type: %s", mnt_fs_get_fstype(cxt->fs)));
+       DBG(CXT, mnt_debug_h(cxt, "FS type: %s [rc=%d]",
+                               mnt_fs_get_fstype(cxt->fs), rc));
        return rc;
 none:
        return mnt_fs_set_fstype(cxt->fs, "none");
index 0fe5b1d86f960bd6564d805ac9dafaf15a6c85bc..8eb677cdce8d71d6f8ed3e9a5417f11c9aafd2c0 100644 (file)
@@ -338,7 +338,6 @@ struct libmnt_context
        int             utab_writable; /* is utab writable */
 
        int     flags;          /* private context flags */
-       int     ambi;           /* libblkid returns ambivalent result */
 
        char    *helper;        /* name of the used /sbin/[u]mount.<type> helper */
        int     helper_status;  /* helper wait(2) status */
index 0c74ed9006d3b231d1c083ff62e68f9c2f2c6016..ebdfe885d66660d0df2b029573dd2edee72a5b0c 100644 (file)
@@ -385,6 +385,11 @@ try_readonly:
                                warnx(_("can't find mount source %s in %s"),
                                                src, mnt_get_fstab_path());
                        return MOUNT_EX_USAGE;
+               case -MNT_ERR_AMBIFS:
+                       warnx(_("%s: more filesystems detected. This should not happen,\n"
+                         "       use -t <type> to explicitly specify the filesystem type or\n"
+                         "       use wipefs(8) to clean up the device."), src);
+                       return MOUNT_EX_USAGE;
                case -MNT_ERR_NOFSTYPE:
                        if (restricted)
                                warnx(_("I could not determine the filesystem type, "