libmount: correctly propagate ambivalent blkid probing results

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>
This commit is contained in:
Karel Zak 2013-02-13 12:36:10 +01:00
parent 8c24b6aa2c
commit 82a2c1600d
4 changed files with 44 additions and 15 deletions

View 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;
char *data = NULL;
if (mnt_cache_read_tags(cache, devname) != 0)
return 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);

View 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");

View 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 */

View 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, "