for a single device.
Add a new function to the blkid library, blkid_probe_all_new().
Optimize blkid_find_dev_with_tag() so that extraneous device validation are
skipped. (Makes a difference for system with a large number of disks).
2005-05-07 Theodore Ts'o <tytso@mit.edu>
+ * tag.c (blkid_find_dev_with_tag): If a device can't be found with
+ the specified search arguments, probe all new devices
+ before trying to verify existing devices, as a speed
+ optimization.
+
+ * devname.c (blkid_probe_all_new): New function which only probes
+ devices are not known in the blkid cache. This takes
+ much less time than a full probe of all devices.
+
* cache.c, dev.c, devno.c, probe.c, probe.h: Fix gcc -Wall nits.
* blkidP.h, cache.c, dev.c, read.c, tag.c: Clean up the debugging
/* devname.c */
extern int blkid_probe_all(blkid_cache cache);
+extern int blkid_probe_all_new(blkid_cache cache);
extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname,
int flags);
* 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;
blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
bid_devs);
if (tmp->bid_devno == devno) {
+ if (only_if_new)
+ return;
dev = blkid_verify(cache, tmp);
break;
}
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;
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);
+ probe_one(cache, lvm_device, dev, BLKID_PRI_LVM,
+ only_if_new);
free(lvm_device);
}
closedir(lv_list);
#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;
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);
/*
* 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];
return 0;
blkid_read_cache(cache);
- evms_probe_all(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");
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,
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);
+ 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;
- blkid_flush_cache(cache);
- 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)
{
* 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.
*/
extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
const char *type,
blkid_dev dev;
int pri;
struct list_head *p;
+ int probe_new = 0;
if (!cache || !type || !value)
return NULL;
goto try_again;
}
+ if (!dev && !probe_new) {
+ if (blkid_probe_all_new(cache) < 0)
+ return NULL;
+ probe_new++;
+ goto try_again;
+ }
+
if (!dev && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) {
if (blkid_probe_all(cache) < 0)
return NULL;
blkid_dev_has_tag(). Remove compare_search_type() since
it has been obseleted by blkid_dev_has_tag().
+ * blkid.c (main): Add a new flag, -l, which will use a more
+ efficient method to find the device that matches a
+ particular tag specifier.
+
2005-05-06 Theodore Ts'o <tytso@mit.edu>
* blkid.c (main): Use an int instead of an char to store the
.SH SYNOPSIS
.B blkid
[
-.B \-hv
+.B \-hlv
]
[
[
.B \-h
Display a usage message and exit.
.TP
+.B \-l
+Lookup the device that matches the search parameter specified using
+the
+.B \-t
+option, assuming that there is only one matching the search parameter.
+For a system with a large number of disks, this will be more
+efficient by avoiding the need to revalidate devices unless absolutely
+necessary. If this option is not specified,
+.B blkid
+will use a less efficient approach, which allows
+.B blkid
+to print all of the devices that match the search parameter.
+.IP
+This option is best used for tag searches such as
+.I LABEL=data_vol
+or
+.IR UUID=e280469a-d06f-4c0b-b068-44f3b576029e .
+If you want
+.B blkid
+to print all of the ext3 filesystems using a search parameter
+such as
+.IR TYPE=ext3 ,
+then this option should
+.I not
+be used.
+.TP
.B \-o
Display
.BR blkid 's
If you don't want to save the cache to the default file, specify
.IR /dev/null.
If not specified it will be the same file as that given by the
-.B -c
+.B \-c
option.
.TP
.I <device>
print_version(out);
fprintf(out,
- "usage:\t%s [-c <file>] [-h] [-o format] "
+ "usage:\t%s [-c <file>] [-hl] [-o format] "
"[-s <tag>] [-t <token>]\n [-v] [-w <file>] [dev ...]\n"
"\t-c\tcache file (default: /etc/blkid.tab, /dev/null = none)\n"
"\t-h\tprint this usage message and exit\n"
"\t-s\tshow specified tag(s) (default show all tags)\n"
"\t-t\tfind device with a specific token (NAME=value pair)\n"
+ "\t-l\tlookup the the first device with arguments specified by -t\n"
"\t-v\tprint version and exit\n"
"\t-w\twrite cache to different file (/dev/null = no write)\n"
"\tdev\tspecify device(s) to probe (default: all devices)\n",
int err = 4;
unsigned int i;
int output_format = 0;
+ int lookup = 0;
int c;
- while ((c = getopt (argc, argv, "c:f:ho:s:t:w:v")) != EOF)
+ while ((c = getopt (argc, argv, "c:f:hlo:s:t:w:v")) != EOF)
switch (c) {
case 'c':
if (optarg && !*optarg)
if (!write)
write = read;
break;
+ case 'l':
+ lookup++;
+ break;
case 'o':
if (!strcmp(optarg, "value"))
output_format = OUTPUT_VALUE_ONLY;
goto exit;
err = 2;
+ if (lookup) {
+ blkid_dev dev;
+
+ if (!search_type) {
+ fprintf(stderr, "The lookup option requires a "
+ "search type specified using -t\n");
+ exit(1);
+ }
+ /* Load any additional devices not in the cache */
+ for (i = 0; i < numdev; i++)
+ blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);
+
+ if ((dev = blkid_find_dev_with_tag(cache, search_type,
+ search_value))) {
+ print_tags(dev, show, numtag, output_format);
+ err = 0;
+ }
/* If we didn't specify a single device, show all available devices */
- if (!numdev) {
+ } else if (!numdev) {
blkid_dev_iterate iter;
blkid_dev dev;