OSDN Git Service

Add a priority label to the device structure, so we can give
authorTheodore Ts'o <tytso@mit.edu>
Fri, 14 Feb 2003 06:31:45 +0000 (01:31 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 14 Feb 2003 06:31:45 +0000 (01:31 -0500)
preference to EVMS and LVM devices when searching for a device
matching a particular LABEL or UUID in the blkid library.

lib/blkid/ChangeLog
lib/blkid/Makefile.in
lib/blkid/blkidP.h
lib/blkid/devname.c
lib/blkid/probe.c
lib/blkid/read.c
lib/blkid/resolve.c
lib/blkid/save.c
lib/blkid/tag.c

index b73e5aa..79bdb2a 100644 (file)
@@ -1,3 +1,36 @@
+2003-02-14  Theodore Ts'o  <tytso@mit.edu>
+
+       * Makefile.in (blkid): When building the blkid, don't link against
+               the shared blkid library; link only against the static
+               blkid library.
+
+       * blkidP.h (struct blkid_struct_dev): Remove bid_size and
+               bid_devsize (since they aren't used any more) and add
+               bid_pri to the device structure.
+
+       * devname.c (probe_one, lvm_probe_all, evms_probe_all,
+               blkid_probe_all): Set the bid_pri filed in the device
+               structure depending on type of device so that EVMS, LVM,
+               and MD devices get priority over normal devices.
+
+       * tag.c (blkid_find_dev_with_tag): When looking for a device that
+               matches the search criteria, return the one with the
+               largest priority (bid_pri).
+
+       * save.c (save_dev): Write out the PRI tag from bid_pri.
+
+       * read.c (parse_tag): Parse the PRI tag and store its value in
+               bid_pri.
+
+       * probe.c (blkid_verify_devname): If the device does not exist
+               (open returns ENOENT), treat this as a fatal error and
+               release the device.  After verifying the device, set the
+               cache as being modified so the changes are written out.
+
+       * resolve.c (main): Change the test driver to get a blkid cache
+               and pass it to blkid_get_tagname_devname and
+               blkid_get_token, as the cache is no longer optional.
+
 2003-02-12  Theodore Ts'o  <tytso@mit.edu>
 
        * blkid.h, blkidP.h, cache.c, dev.c, devname.c, devno.c, probe.c,
index 4252835..17e772e 100644 (file)
@@ -101,8 +101,8 @@ tst_save: $(srcdir)/save.c $(DEPLIBS_BLKID)
        $(CC) -Wall $(ALL_CFLAGS) -c $(top_srcdir)/misc/blkid.c \
                -o ../../misc/blkid.o
 
-blkid: ../../misc/blkid.o libblkid.a $(LIBBLKID) $(LIBUUID)
-       $(CC) -Wall -o blkid ../../misc/blkid.o libblkid.a $(LIBBLKID) $(LIBUUID)
+blkid: ../../misc/blkid.o libblkid.a $(LIBUUID)
+       $(CC) -Wall -o blkid ../../misc/blkid.o libblkid.a $(LIBUUID)
 
 check:: tst_cache tst_devname tst_devno tst_getsize tst_probe \
  tst_read tst_resolve tst_save
index 5a99802..423e7de 100644 (file)
@@ -33,8 +33,7 @@ struct blkid_struct_dev
        blkid_cache             bid_cache;      /* Dev belongs to this cache */
        char                    *bid_name;      /* Device inode pathname */
        char                    *bid_type;      /* Preferred device TYPE */
-       blkid_loff_t            bid_size;       /* Filesystem size in bytes */
-       blkid_loff_t            bid_devsize;    /* Device size in bytes */
+       int                     bid_pri;        /* Device priority */
        dev_t                   bid_devno;      /* Device major/minor number */
        time_t                  bid_time;       /* Last update time of device */
        unsigned int            bid_id;         /* Unique cache id for device */
@@ -89,7 +88,7 @@ struct blkid_struct_cache
        struct list_head        bic_devs;       /* List head of all devices */
        struct list_head        bic_tags;       /* List head of all tag types */
        time_t                  bic_time;       /* Last probe time */
-       unsigned int            bic_idmax;      /* Highest ID assigned */
+p      unsigned int            bic_idmax;      /* Highest ID assigned */
        unsigned int            bic_flags;      /* Status flags of the cache */
        char                    *bic_filename;  /* filename of cache */
 };
@@ -112,6 +111,13 @@ extern const char *blkid_devdirs[];
 #define BLKID_ERR_PARAM        22
 #define BLKID_ERR_BIG  27
 
+/*
+ * Priority settings for different types of devices
+ */
+#define BLKID_PRI_EVMS 30
+#define BLKID_PRI_LVM  20
+#define BLKID_PRI_MD   10
+
 #if defined(TEST_PROGRAM)
 #define DEBUG
 #endif
@@ -158,7 +164,7 @@ static inline void DEB_DUMP_DEV(blkid_dev dev)
        printf("  dev: DEVNO=\"0x%0Lx\"\n", dev->bid_devno);
        printf("  dev: ID=\"%u\"\n", dev->bid_id);
        printf("  dev: TIME=\"%lu\"\n", dev->bid_time);
-       printf("  dev: size = %Lu\n", dev->bid_size);
+       printf("  dev: PRI=\"%d\"\n", dev->bid_pri);
        printf("  dev: flags = 0x%08X\n", dev->bid_flags);
 
        list_for_each(p, &dev->bid_tags) {
index 6cb3a8e..ef001d1 100644 (file)
@@ -86,8 +86,8 @@ blkid_dev blkid_get_devname(blkid_cache cache, const char *devname,
 /*
  * Probe a single block device to add to the device cache.
  */
-static blkid_dev probe_one(blkid_cache cache, const char *ptname,
-                           dev_t devno)
+static void probe_one(blkid_cache cache, const char *ptname,
+                     dev_t devno, int pri)
 {
        blkid_dev dev = NULL;
        struct list_head *p;
@@ -104,7 +104,7 @@ static blkid_dev probe_one(blkid_cache cache, const char *ptname,
                }
        }
        if (dev && dev->bid_devno == devno)
-               return dev;
+               goto set_pri;
 
        /*
         * Take a quick look at /dev/ptname for the device number.  We check
@@ -119,7 +119,7 @@ static blkid_dev probe_one(blkid_cache cache, const char *ptname,
                sprintf(device, "%s/%s", *dir, ptname);
                if ((dev = blkid_get_devname(cache, device, BLKID_DEV_FIND)) &&
                    dev->bid_devno == devno)
-                       return dev;
+                       goto set_pri;
 
                if (stat(device, &st) == 0 && st.st_rdev == devno) {
                        devname = blkid_strdup(device);
@@ -129,12 +129,16 @@ static blkid_dev probe_one(blkid_cache cache, const char *ptname,
        if (!devname) {
                devname = blkid_devno_to_devname(devno);
                if (!devname)
-                       return NULL;
+                       return;
        }
        dev = blkid_get_devname(cache, devname, BLKID_DEV_NORMAL);
        free(devname);
 
-       return dev;
+set_pri:
+       if (!pri && !strncmp(ptname, "md", 2))
+               pri = BLKID_PRI_MD;
+       dev->bid_pri = pri;
+       return;
 }
 
 #define PROC_PARTITIONS "/proc/partitions"
@@ -223,7 +227,7 @@ static void lvm_probe_all(blkid_cache cache)
                        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);
+                       probe_one(cache, lvm_device, dev, BLKID_PRI_LVM);
                        free(lvm_device);
                }
                closedir(lv_list);
@@ -254,7 +258,7 @@ evms_probe_all(blkid_cache cache)
                DBG(printf("Checking partition %s (%d, %d)\n",
                           device, ma, mi));
 
-               probe_one(cache, device, makedev(ma, mi));
+               probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS);
                num++;
        }
        fclose(procpt);
@@ -267,7 +271,14 @@ evms_probe_all(blkid_cache cache)
 int blkid_probe_all(blkid_cache cache)
 {
        FILE *proc;
-       int firstPass;
+       char line[1024];
+       char ptname0[128], ptname1[128], *ptname = 0;
+       char *ptnames[2] = { ptname0, ptname1 };
+       dev_t devs[2];
+       int ma, mi;
+       unsigned long long sz;
+       int lens[2] = { 0, 0 };
+       int which = 0, last = 0;
 
        if (!cache)
                return -BLKID_ERR_PARAM;
@@ -276,9 +287,7 @@ int blkid_probe_all(blkid_cache cache)
            time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
                return 0;
 
-       if (evms_probe_all(cache))
-               goto finish;
-
+       evms_probe_all(cache);
 #ifdef VG_DIR
        lvm_probe_all(cache);
 #endif
@@ -287,76 +296,55 @@ int blkid_probe_all(blkid_cache cache)
        if (!proc)
                return -BLKID_ERR_PROC;
 
-       for (firstPass = 1; firstPass >= 0; firstPass--) {
-               char line[1024];
-               char ptname0[128], ptname1[128], *ptname = 0;
-               char *ptnames[2] = { ptname0, ptname1 };
-               dev_t devs[2];
-               int ma, mi;
-               unsigned long long sz;
-               int lens[2] = { 0, 0 };
-               int handleOnFirst;
-               int which = 0, last = 0;
-
-               fseek(proc, 0, SEEK_SET);
-
-               while (fgets(line, sizeof(line), proc)) {
-                       last = which;
-                       which ^= 1;
-                       ptname = ptnames[which];
-
-                       if (sscanf(line, " %d %d %lld %128[^\n ]",
-                                  &ma, &mi, &sz, ptname) != 4)
-                               continue;
-                       devs[which] = makedev(ma, mi);
-
-                       DBG(printf("read partition name %s\n", ptname));
-
-                       /* look only at md devices on first pass */
-                       handleOnFirst = !strncmp(ptname, "md", 2);
-                       if (firstPass != handleOnFirst)
-                               continue;
+       while (fgets(line, sizeof(line), proc)) {
+               last = which;
+               which ^= 1;
+               ptname = ptnames[which];
 
-                       /* Skip whole disk devs unless they have no partitions
-                        * If we don't have a partition on this dev, also
-                        * check previous dev to see if it didn't have a partn.
-                        * heuristic: partition name ends in a digit.
-                        *
-                        * Skip extended partitions.
-                        * heuristic: size is 1
-                        *
-                        * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
-                        */
-
-                       lens[which] = strlen(ptname);
-                       if (isdigit(ptname[lens[which] - 1])) {
-                               DBG(printf("partition dev %s, devno 0x%04X\n",
-                                          ptname, devs[which]));
-
-                               if (sz > 1)
-                                       probe_one(cache, ptname, devs[which]);
-                               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",
-                                          ptname, devs[last]));
-                               probe_one(cache, ptname, devs[last]);
-                               lens[last] = 0;
-                       }
+               if (sscanf(line, " %d %d %lld %128[^\n ]",
+                          &ma, &mi, &sz, ptname) != 4)
+                       continue;
+               devs[which] = makedev(ma, mi);
+
+               DBG(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
+                * check previous dev to see if it didn't have a partn.
+                * heuristic: partition name ends in a digit.
+                *
+                * Skip extended partitions.
+                * heuristic: size is 1
+                *
+                * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
+                */
+
+               lens[which] = strlen(ptname);
+               if (isdigit(ptname[lens[which] - 1])) {
+                       DBG(printf("partition dev %s, devno 0x%04X\n",
+                                  ptname, devs[which]));
+
+                       if (sz > 1)
+                               probe_one(cache, ptname, devs[which], 0);
+                       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);
+                       lens[last] = 0;
                }
-
-               /* Handle the last device if it wasn't partitioned */
-               if (lens[which])
-                       probe_one(cache, ptname, devs[which]);
        }
+
+       /* Handle the last device if it wasn't partitioned */
+       if (lens[which])
+               probe_one(cache, ptname, devs[which], 0);
+
        fclose(proc);
 
-finish:
        cache->bic_time = time(0);
        cache->bic_flags |= BLKID_BIC_FL_PROBED;
-
        return 0;
 }
 
index eeb544c..f703052 100644 (file)
@@ -344,11 +344,12 @@ blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev)
                                       diff < BLKID_PROBE_INTERVAL))
                return dev;
 
-       DBG(printf("need to revalidate %s\n", dev->bid_name));
+       DBG(printf("need to revalidate %s (time since last check %lu)\n", 
+                  dev->bid_name, diff));
 
        if (((fd = open(dev->bid_name, O_RDONLY)) < 0) ||
            (fstat(fd, &st) < 0) || !S_ISBLK(st.st_mode)) {
-               if (errno == ENXIO || errno == ENODEV) {
+               if (errno == ENXIO || errno == ENODEV || errno == ENOENT) {
                        blkid_free_dev(dev);
                        return NULL;
                }
@@ -429,6 +430,7 @@ found_type:
                dev->bid_devno = st.st_rdev;
                dev->bid_time = time(0);
                dev->bid_flags |= BLKID_BID_FL_VERIFIED;
+               cache->bic_flags |= BLKID_BIC_FL_CHANGED;
 
                blkid_set_tag(dev, "TYPE", type, 0, 1);
                if (sec_type)
index 7c9c4d4..ce52d83 100644 (file)
@@ -313,6 +313,8 @@ static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp)
                        cache->bic_idmax = dev->bid_id;
        } else if (!strcmp(name, "DEVNO"))
                dev->bid_devno = STRTOULL(value, 0, 0);
+       else if (!strcmp(name, "PRI"))
+               dev->bid_pri = strtol(value, 0, 0);
        else if (!strcmp(name, "TIME"))
                /* FIXME: need to parse a long long eventually */
                dev->bid_time = strtol(value, 0, 0);
index 19478ed..fca1e16 100644 (file)
@@ -44,9 +44,6 @@ char *blkid_get_tagname_devname(blkid_cache cache, const char *tagname,
        if (!devname)
                return NULL;
 
-       if (!cache)
-               DBG(printf("no cache given, direct device probe\n"));
-
        if ((dev = blkid_get_devname(cache, devname, BLKID_DEV_NORMAL)) &&
            (found = blkid_find_tag_dev(dev, tagname)))
                ret = blkid_strdup(found->bit_val);
@@ -113,6 +110,7 @@ errout:
 int main(int argc, char **argv)
 {
        char *value;
+       blkid_cache cache;
 
        if (argc != 2 && argc != 3) {
                fprintf(stderr, "Usage:\t%s tagname=value\n"
@@ -122,14 +120,20 @@ int main(int argc, char **argv)
                        argv[0], argv[0]);
                exit(1);
        }
+       if (blkid_get_cache(&cache, 0) < 0) {
+               fprintf(stderr, "Couldn't get blkid cache\n");
+               exit(1);
+       }
+       
        if (argv[2]) {
-               value = blkid_get_tagname_devname(NULL, argv[1], argv[2]);
+               value = blkid_get_tagname_devname(cache, argv[1], argv[2]);
                printf("%s has tag %s=%s\n", argv[2], argv[1],
                       value ? value : "<missing>");
        } else {
-               value = blkid_get_token(NULL, argv[1], NULL);
+               value = blkid_get_token(cache, argv[1], NULL);
                printf("%s has tag %s\n", value ? value : "<none>", argv[1]);
        }
+       blkid_put_cache(cache);
        return value ? 0 : 1;
 }
 #endif
index 5a8771e..5de0719 100644 (file)
@@ -45,6 +45,8 @@ static int save_dev(blkid_dev dev, FILE *file)
                "<device TYPE=\"%s\" DEVNO=\"0x%04lx\" ID=\"%d\" TIME=\"%lu\"",
                dev->bid_type, (unsigned long) dev->bid_devno,
                dev->bid_id, dev->bid_time);
+       if (dev->bid_pri)
+               fprintf(file, " PRI=\"%d\"", dev->bid_pri);
        list_for_each(p, &dev->bid_tags) {
                blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
                if (strcmp(tag->bit_name, "TYPE"))
index 9bb99e1..3948a1e 100644 (file)
@@ -306,11 +306,9 @@ extern void blkid_tag_iterate_end(blkid_tag_iterate iter)
 
 /*
  * This function returns a device which matches a particular
- * type/value pair.  Its behaviour is currently undefined if there is
- * more than one device which matches the search specification.
- * In the future we may have some kind of preference scheme so that if
- * there is more than one match for a given label/uuid (for example in
- * the case of snapshots) we return the preferred device.
+ * type/value pair.  If there is more than one device that matches the
+ * search specification, it returns the one with the highest priority
+ * value.  This allows us to give preference to EVMS or LVM devices.
  *
  * XXX there should also be an interface which uses an iterator so we
  * can get all of the devices which match a type/value search parameter.
@@ -319,7 +317,9 @@ extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
                                         const char *type,
                                         const char *value)
 {
-       blkid_tag head = 0, found = 0;
+       blkid_tag       head, found;
+       blkid_dev       dev;
+       int             pri;
        struct list_head *p;
 
        if (!cache || !type || !value)
@@ -328,24 +328,30 @@ extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
        DBG(printf("looking for %s=%s in cache\n", type, value));
        
 try_again:
-       if (!head)
-               head = blkid_find_head_cache(cache, type);
+       pri = -1;
+       found = 0;
+       head = blkid_find_head_cache(cache, type);
 
        if (head) {
                list_for_each(p, &head->bit_names) {
                        blkid_tag tmp = list_entry(p, struct blkid_struct_tag, 
                                                   bit_names);
 
-                       if (!strcmp(tmp->bit_val, value)) {
+                       if (!strcmp(tmp->bit_val, value) &&
+                           tmp->bit_dev->bid_pri > pri) {
                                found = tmp;
-                               break;
+                               dev = found->bit_dev;
+                               pri = dev->bid_pri;
                        }
                }
        }
+       dev = blkid_verify_devname(cache, dev);
+       if (dev && strcmp(found->bit_val, value))
+               dev = 0;
 
-       if ((!head || !found) && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) {
+       if ((!head || !dev) && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) {
                blkid_probe_all(cache);
                goto try_again;
        }
-       return (found ? found->bit_dev : NULL);
+       return dev;
 }