diff options
author | Theodore Ts'o <tytso@mit.edu> | 2003-02-14 01:31:45 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2003-02-14 01:31:45 -0500 |
commit | ce72b862c59da24ba16b354d687549276a24f908 (patch) | |
tree | 1a7e26be58937f4dbcdc99e7c4832ffe7bede4ab | |
parent | 50b380b4d4ab668bad45033e3a8aaf93c7f42844 (diff) | |
download | e2fsprogs-ce72b862c59da24ba16b354d687549276a24f908.tar.gz |
Add a priority label to the device structure, so we can give
preference to EVMS and LVM devices when searching for a device
matching a particular LABEL or UUID in the blkid library.
-rw-r--r-- | lib/blkid/ChangeLog | 33 | ||||
-rw-r--r-- | lib/blkid/Makefile.in | 4 | ||||
-rw-r--r-- | lib/blkid/blkidP.h | 14 | ||||
-rw-r--r-- | lib/blkid/devname.c | 138 | ||||
-rw-r--r-- | lib/blkid/probe.c | 6 | ||||
-rw-r--r-- | lib/blkid/read.c | 2 | ||||
-rw-r--r-- | lib/blkid/resolve.c | 14 | ||||
-rw-r--r-- | lib/blkid/save.c | 2 | ||||
-rw-r--r-- | lib/blkid/tag.c | 30 |
9 files changed, 143 insertions, 100 deletions
diff --git a/lib/blkid/ChangeLog b/lib/blkid/ChangeLog index b73e5aa3..79bdb2a3 100644 --- a/lib/blkid/ChangeLog +++ b/lib/blkid/ChangeLog @@ -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, diff --git a/lib/blkid/Makefile.in b/lib/blkid/Makefile.in index 42528357..17e772e3 100644 --- a/lib/blkid/Makefile.in +++ b/lib/blkid/Makefile.in @@ -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 diff --git a/lib/blkid/blkidP.h b/lib/blkid/blkidP.h index 5a998029..423e7dea 100644 --- a/lib/blkid/blkidP.h +++ b/lib/blkid/blkidP.h @@ -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) { diff --git a/lib/blkid/devname.c b/lib/blkid/devname.c index 6cb3a8e8..ef001d13 100644 --- a/lib/blkid/devname.c +++ b/lib/blkid/devname.c @@ -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; } diff --git a/lib/blkid/probe.c b/lib/blkid/probe.c index eeb544c6..f703052a 100644 --- a/lib/blkid/probe.c +++ b/lib/blkid/probe.c @@ -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) diff --git a/lib/blkid/read.c b/lib/blkid/read.c index 7c9c4d42..ce52d832 100644 --- a/lib/blkid/read.c +++ b/lib/blkid/read.c @@ -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); diff --git a/lib/blkid/resolve.c b/lib/blkid/resolve.c index 19478ed3..fca1e168 100644 --- a/lib/blkid/resolve.c +++ b/lib/blkid/resolve.c @@ -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 diff --git a/lib/blkid/save.c b/lib/blkid/save.c index 5a8771e7..5de07190 100644 --- a/lib/blkid/save.c +++ b/lib/blkid/save.c @@ -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")) diff --git a/lib/blkid/tag.c b/lib/blkid/tag.c index 9bb99e14..3948a1e6 100644 --- a/lib/blkid/tag.c +++ b/lib/blkid/tag.c @@ -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; } |