]> err.no Git - util-linux/commitdiff
mount: report ambivalent FS detection, improve brute force detection
authorKarel Zak <kzak@redhat.com>
Mon, 15 Mar 2010 12:46:43 +0000 (13:46 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 15 Mar 2010 12:46:43 +0000 (13:46 +0100)
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>
include/fsprobe.h
lib/fsprobe.c
mount/mount.c

index 307eb64a17df5a7499437b0f38be88b1ea863d7c..9e2bf50f74d30bc7ffabfa20d24313058eea2374 100644 (file)
@@ -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);
index 77211806d38b5a897709d4fd8cbe9be4e11995e2..8eb08fac837f71b8dc20c9832edce1ff31d6e317 100644 (file)
@@ -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 *
@@ -231,6 +238,14 @@ fsprobe_get_fstype_by_devname(const char *devname)
        return tp;
 }
 
+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)
 {
index 0f986df3b920d04926d2c2f7e5f23b94e2c6f0a1..a73b606cde8337744bdb1093508a9c0f4800c3dc 100644 (file)
@@ -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;
       }
    }