summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2010-03-15 13:46:43 +0100
committerKarel Zak <kzak@redhat.com>2010-03-15 13:46:43 +0100
commitc6c98f93f5e4b3fb9a8b51ed2ef9967793df7b1c (patch)
tree2e7a565f33234947bf90343851f252142c61f4fa
parentf5b1bab190e86bd6a52942047d2c767ec82508d1 (diff)
downloadutil-linux-old-c6c98f93f5e4b3fb9a8b51ed2ef9967793df7b1c.tar.gz
mount: report ambivalent FS detection, improve brute force detection
The ambivalent probing result should be properly reported and user should be informed that the problem is possible to bypass by "-t <type>" or resolved by wipefs(8). The mount(8) command uses a brute force stage (calls mount(2) for all /{proc,etc}/fylesystems) if there is not any other way how to detect the filesystem type. The brute force stage should not be restricted by libblkid. It's possible that libblkid is not able to detect slightly corrupted filesystem, but kernel is able to mount such filesystem. Note that the brute force stage should not be used if libblkid returns ambivalent probing result. In this case user's intervention is required (e.g. mount -t <type>). Reported-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--include/fsprobe.h1
-rw-r--r--lib/fsprobe.c33
-rw-r--r--mount/mount.c14
3 files changed, 34 insertions, 14 deletions
diff --git a/include/fsprobe.h b/include/fsprobe.h
index 307eb64a..9e2bf50f 100644
--- a/include/fsprobe.h
+++ b/include/fsprobe.h
@@ -17,6 +17,7 @@ extern char *fsprobe_get_devname_by_spec(const char *spec);
extern char *fsprobe_get_label_by_devname(const char *devname);
extern char *fsprobe_get_uuid_by_devname(const char *devname);
extern char *fsprobe_get_fstype_by_devname(const char *devname);
+extern char *fsprobe_get_fstype_by_devname_ambi(const char *devname, int *ambi);
extern int fsprobe_known_fstype(const char *fstype);
diff --git a/lib/fsprobe.c b/lib/fsprobe.c
index 77211806..8eb08fac 100644
--- a/lib/fsprobe.c
+++ b/lib/fsprobe.c
@@ -117,9 +117,9 @@ fsprobe_exit(void)
* probing interface
*/
static char *
-fsprobe_get_value(const char *name, const char *devname)
+fsprobe_get_value(const char *name, const char *devname, int *ambi)
{
- int fd;
+ int fd, rc;
const char *data = NULL;
if (!devname || !name)
@@ -139,10 +139,11 @@ fsprobe_get_value(const char *name, const char *devname)
blkid_probe_set_superblocks_flags(blprobe,
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | BLKID_SUBLKS_TYPE);
- if (blkid_do_safeprobe(blprobe))
- goto done;
- if (blkid_probe_lookup_value(blprobe, name, &data, NULL))
- goto done;
+ rc = blkid_do_safeprobe(blprobe);
+ if (ambi)
+ *ambi = rc == -2 ? 1 : 0; /* ambivalent probing result */
+ if (!rc)
+ blkid_probe_lookup_value(blprobe, name, &data, NULL);
done:
close(fd);
return data ? strdup((char *) data) : NULL;
@@ -151,19 +152,25 @@ done:
char *
fsprobe_get_label_by_devname(const char *devname)
{
- return fsprobe_get_value("LABEL", devname);
+ return fsprobe_get_value("LABEL", devname, NULL);
}
char *
fsprobe_get_uuid_by_devname(const char *devname)
{
- return fsprobe_get_value("UUID", devname);
+ return fsprobe_get_value("UUID", devname, NULL);
}
char *
fsprobe_get_fstype_by_devname(const char *devname)
{
- return fsprobe_get_value("TYPE", devname);
+ return fsprobe_get_value("TYPE", devname, NULL);
+}
+
+char *
+fsprobe_get_fstype_by_devname_ambi(const char *devname, int *ambi)
+{
+ return fsprobe_get_value("TYPE", devname, ambi);
}
char *
@@ -232,6 +239,14 @@ fsprobe_get_fstype_by_devname(const char *devname)
}
char *
+fsprobe_get_fstype_by_devname_ambi(const char *devname, int *ambi)
+{
+ if (ambi)
+ *ambi = 0;
+ return fsprobe_get_fstype_by_devname(devname);
+}
+
+char *
fsprobe_get_label_by_devname(const char *devname)
{
if (!blcache)
diff --git a/mount/mount.c b/mount/mount.c
index 0f986df3..a73b606c 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -744,8 +744,6 @@ static int
was_tested(const char *fstype) {
struct tried *t;
- if (fsprobe_known_fstype(fstype))
- return 1;
for (t = tried; t; t = t->next) {
if (!strcmp(t->type, fstype))
return 1;
@@ -886,9 +884,9 @@ procfsloop_mount(int (*mount_fn)(struct mountargs *, int *, int *),
}
static const char *
-guess_fstype_by_devname(const char *devname)
+guess_fstype_by_devname(const char *devname, int *ambivalent)
{
- const char *type = fsprobe_get_fstype_by_devname(devname);
+ const char *type = fsprobe_get_fstype_by_devname_ambi(devname, ambivalent);
if (verbose) {
printf (_("mount: you didn't specify a filesystem type for %s\n"), devname);
@@ -915,12 +913,13 @@ static int
guess_fstype_and_mount(const char *spec, const char *node, const char **types,
int flags, char *mount_opts, int *special, int *status) {
struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts };
+ int ambivalent = 0;
if (*types && strcasecmp (*types, "auto") == 0)
*types = NULL;
if (!*types && !(flags & MS_REMOUNT)) {
- *types = guess_fstype_by_devname(spec);
+ *types = guess_fstype_by_devname(spec, &ambivalent);
if (*types) {
if (!strcmp(*types, MNTTYPE_SWAP)) {
error(_("%s looks like swapspace - not mounted"), spec);
@@ -930,6 +929,11 @@ guess_fstype_and_mount(const char *spec, const char *node, const char **types,
args.type = *types;
return do_mount (&args, special, status);
}
+ } else if (ambivalent) {
+ error(_("mount: %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.\n"), spec);
+ return 1;
}
}