Whamcloud - gitweb
Improve VFAT detection to support filesystems w/o a magic string in the superblock
[tools/e2fsprogs.git] / lib / blkid / devname.c
index ef001d1..3b1ad89 100644 (file)
 
 #include "blkidP.h"
 
-/* #define DEBUG_DEVNAME */
-#ifdef DEBUG_DEVNAME
-#define DBG(x) x
-#else
-#define DBG(x)
-#endif
-
 /*
  * Find a dev struct in the cache by device name, if available.
  *
  * If there is no entry with the specified device name, and the create
  * flag is set, then create an empty device entry.
  */
-blkid_dev blkid_get_devname(blkid_cache cache, const char *devname,
-                            int flags)
+blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags)
 {
        blkid_dev dev = NULL, tmp;
        struct list_head *p;
@@ -62,7 +54,8 @@ blkid_dev blkid_get_devname(blkid_cache cache, const char *devname,
                if (strcmp(tmp->bid_name, devname))
                        continue;
 
-               DBG(printf("found devname %s in cache\n", tmp->bid_name));
+               DBG(DEBUG_DEVNAME, 
+                   printf("found devname %s in cache\n", tmp->bid_name));
                dev = tmp;
                break;
        }
@@ -73,13 +66,12 @@ blkid_dev blkid_get_devname(blkid_cache cache, const char *devname,
                        return NULL;
                dev->bid_name = blkid_strdup(devname);
                dev->bid_cache = cache;
-               dev->bid_id = ++(cache->bic_idmax);
                list_add_tail(&dev->bid_devs, &cache->bic_devs);
                cache->bic_flags |= BLKID_BIC_FL_CHANGED;
        }
 
        if (flags & BLKID_DEV_VERIFY)
-               dev = blkid_verify_devname(cache, dev);
+               dev = blkid_verify(cache, dev);
        return dev;
 }
 
@@ -87,7 +79,7 @@ blkid_dev blkid_get_devname(blkid_cache cache, const char *devname,
  * Probe a single block device to add to the device cache.
  */
 static void probe_one(blkid_cache cache, const char *ptname,
-                     dev_t devno, int pri)
+                     dev_t devno, int pri, int only_if_new)
 {
        blkid_dev dev = NULL;
        struct list_head *p;
@@ -99,7 +91,9 @@ static void probe_one(blkid_cache cache, const char *ptname,
                blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
                                           bid_devs);
                if (tmp->bid_devno == devno) {
-                       dev = blkid_verify_devname(cache, tmp);
+                       if (only_if_new)
+                               return;
+                       dev = blkid_verify(cache, tmp);
                        break;
                }
        }
@@ -117,11 +111,12 @@ static void probe_one(blkid_cache cache, const char *ptname,
                char device[256];
 
                sprintf(device, "%s/%s", *dir, ptname);
-               if ((dev = blkid_get_devname(cache, device, BLKID_DEV_FIND)) &&
+               if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) &&
                    dev->bid_devno == devno)
                        goto set_pri;
 
-               if (stat(device, &st) == 0 && st.st_rdev == devno) {
+               if (stat(device, &st) == 0 && S_ISBLK(st.st_mode) && 
+                   st.st_rdev == devno) {
                        devname = blkid_strdup(device);
                        break;
                }
@@ -131,13 +126,14 @@ static void probe_one(blkid_cache cache, const char *ptname,
                if (!devname)
                        return;
        }
-       dev = blkid_get_devname(cache, devname, BLKID_DEV_NORMAL);
+       dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL);
        free(devname);
 
 set_pri:
        if (!pri && !strncmp(ptname, "md", 2))
                pri = BLKID_PRI_MD;
-       dev->bid_pri = pri;
+       if (dev)
+               dev->bid_pri = pri;
        return;
 }
 
@@ -159,10 +155,10 @@ static dev_t lvm_get_devno(const char *lvm_device)
        int ma, mi;
        dev_t ret = 0;
 
-       DBG(printf("opening %s\n", lvm_device));
+       DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device));
        if ((lvf = fopen(lvm_device, "r")) == NULL) {
-               DBG(printf("%s: (%d) %s\n", lvm_device, errno,
-                          strerror(errno)));
+               DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno,
+                                         strerror(errno)));
                return 0;
        }
 
@@ -177,7 +173,7 @@ static dev_t lvm_get_devno(const char *lvm_device)
        return ret;
 }
 
-static void lvm_probe_all(blkid_cache cache)
+static void lvm_probe_all(blkid_cache cache, int only_if_new)
 {
        DIR             *vg_list;
        struct dirent   *vg_iter;
@@ -187,7 +183,7 @@ static void lvm_probe_all(blkid_cache cache)
        if ((vg_list = opendir(VG_DIR)) == NULL)
                return;
 
-       DBG(printf("probing LVM devices under %s\n", VG_DIR));
+       DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR));
 
        while ((vg_iter = readdir(vg_list)) != NULL) {
                DIR             *lv_list;
@@ -225,9 +221,11 @@ static void lvm_probe_all(blkid_cache cache)
                                lv_name);
                        dev = lvm_get_devno(lvm_device);
                        sprintf(lvm_device, "%s/%s", vg_name, lv_name);
-                       DBG(printf("LVM dev %s: devno 0x%04X\n",
-                                  lvm_device, dev));
-                       probe_one(cache, lvm_device, dev, BLKID_PRI_LVM);
+                       DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n",
+                                                 lvm_device,
+                                                 (unsigned int) dev));
+                       probe_one(cache, lvm_device, dev, BLKID_PRI_LVM, 
+                                 only_if_new);
                        free(lvm_device);
                }
                closedir(lv_list);
@@ -240,7 +238,7 @@ exit:
 #define PROC_EVMS_VOLUMES "/proc/evms/volumes"
 
 static int
-evms_probe_all(blkid_cache cache)
+evms_probe_all(blkid_cache cache, int only_if_new)
 {
        char line[100];
        int ma, mi, sz, num = 0;
@@ -255,10 +253,11 @@ evms_probe_all(blkid_cache cache)
                            &ma, &mi, &sz, device) != 4)
                        continue;
 
-               DBG(printf("Checking partition %s (%d, %d)\n",
-                          device, ma, mi));
+               DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n",
+                                         device, ma, mi));
 
-               probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS);
+               probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS,
+                         only_if_new);
                num++;
        }
        fclose(procpt);
@@ -268,18 +267,21 @@ evms_probe_all(blkid_cache cache)
 /*
  * Read the device data for all available block devices in the system.
  */
-int blkid_probe_all(blkid_cache cache)
+static int probe_all(blkid_cache cache, int only_if_new)
 {
        FILE *proc;
        char line[1024];
        char ptname0[128], ptname1[128], *ptname = 0;
-       char *ptnames[2] = { ptname0, ptname1 };
+       char *ptnames[2];
        dev_t devs[2];
        int ma, mi;
        unsigned long long sz;
        int lens[2] = { 0, 0 };
        int which = 0, last = 0;
 
+       ptnames[0] = ptname0;
+       ptnames[1] = ptname1;
+
        if (!cache)
                return -BLKID_ERR_PARAM;
 
@@ -287,9 +289,10 @@ int blkid_probe_all(blkid_cache cache)
            time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
                return 0;
 
-       evms_probe_all(cache);
+       blkid_read_cache(cache);
+       evms_probe_all(cache, only_if_new);
 #ifdef VG_DIR
-       lvm_probe_all(cache);
+       lvm_probe_all(cache, only_if_new);
 #endif
 
        proc = fopen(PROC_PARTITIONS, "r");
@@ -301,12 +304,12 @@ int blkid_probe_all(blkid_cache cache)
                which ^= 1;
                ptname = ptnames[which];
 
-               if (sscanf(line, " %d %d %lld %128[^\n ]",
+               if (sscanf(line, " %d %d %llu %128[^\n ]",
                           &ma, &mi, &sz, ptname) != 4)
                        continue;
                devs[which] = makedev(ma, mi);
 
-               DBG(printf("read partition name %s\n", ptname));
+               DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname));
 
                /* Skip whole disk devs unless they have no partitions
                 * If we don't have a partition on this dev, also
@@ -321,45 +324,73 @@ int blkid_probe_all(blkid_cache cache)
 
                lens[which] = strlen(ptname);
                if (isdigit(ptname[lens[which] - 1])) {
-                       DBG(printf("partition dev %s, devno 0x%04X\n",
-                                  ptname, devs[which]));
+                       DBG(DEBUG_DEVNAME,
+                           printf("partition dev %s, devno 0x%04X\n",
+                                  ptname, (unsigned int) devs[which]));
 
                        if (sz > 1)
-                               probe_one(cache, ptname, devs[which], 0);
+                               probe_one(cache, ptname, devs[which], 0, 
+                                         only_if_new);
                        lens[which] = 0;
                        lens[last] = 0;
                } else if (lens[last] && strncmp(ptnames[last], ptname,
                                                 lens[last])) {
-                       DBG(printf("whole dev %s, devno 0x%04X\n",
-                                  ptnames[last], devs[last]));
-                       probe_one(cache, ptnames[last], devs[last], 0);
+                       DBG(DEBUG_DEVNAME,
+                           printf("whole dev %s, devno 0x%04X\n",
+                                  ptnames[last], (unsigned int) devs[last]));
+                       probe_one(cache, ptnames[last], devs[last], 0,
+                                 only_if_new);
                        lens[last] = 0;
                }
        }
 
        /* Handle the last device if it wasn't partitioned */
        if (lens[which])
-               probe_one(cache, ptname, devs[which], 0);
+               probe_one(cache, ptname, devs[which], 0, only_if_new);
 
        fclose(proc);
+       blkid_flush_cache(cache);
+       return 0;
+}
+
+int blkid_probe_all(blkid_cache cache)
+{
+       int ret;
 
+       DBG(DEBUG_PROBE, printf("Begin blkid_probe_all()\n"));
+       ret = probe_all(cache, 0);
        cache->bic_time = time(0);
        cache->bic_flags |= BLKID_BIC_FL_PROBED;
-       return 0;
+       DBG(DEBUG_PROBE, printf("End blkid_probe_all()\n"));
+       return ret;
+}
+
+int blkid_probe_all_new(blkid_cache cache)
+{
+       int ret;
+
+       DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_new()\n"));
+       ret = probe_all(cache, 1);
+       DBG(DEBUG_PROBE, printf("End blkid_probe_all_new()\n"));
+       return ret;
 }
 
+
 #ifdef TEST_PROGRAM
 int main(int argc, char **argv)
 {
        blkid_cache cache = NULL;
+       int ret;
 
+       blkid_debug_mask = DEBUG_ALL;
        if (argc != 1) {
                fprintf(stderr, "Usage: %s\n"
                        "Probe all devices and exit\n", argv[0]);
                exit(1);
        }
-       if ((cache = blkid_new_cache()) == NULL) {
-               fprintf(stderr, "%s: error creating cache\n", argv[0]);
+       if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
+               fprintf(stderr, "%s: error creating cache (%d)\n",
+                       argv[0], ret);
                exit(1);
        }
        if (blkid_probe_all(cache) < 0)