Add a new option to the blkid program, -l, which will more efficiently search

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).
bitmap-optimize
Theodore Ts'o 2005-05-07 17:06:27 -04:00
parent 12b3c8ec1d
commit ed6acfa337
7 changed files with 115 additions and 22 deletions

View File

@ -1,5 +1,14 @@
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

View File

@ -65,6 +65,7 @@ extern char *blkid_devno_to_devname(dev_t devno);
/* 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);

View File

@ -79,7 +79,7 @@ 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;
@ -91,6 +91,8 @@ 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) {
if (only_if_new)
return;
dev = blkid_verify(cache, tmp);
break;
}
@ -171,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;
@ -222,7 +224,8 @@ static void lvm_probe_all(blkid_cache cache)
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);
@ -235,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;
@ -253,7 +256,8 @@ evms_probe_all(blkid_cache cache)
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);
@ -263,7 +267,7 @@ 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];
@ -286,9 +290,9 @@ int blkid_probe_all(blkid_cache cache)
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");
@ -325,7 +329,8 @@ int blkid_probe_all(blkid_cache cache)
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,
@ -333,23 +338,44 @@ int blkid_probe_all(blkid_cache cache)
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);
cache->bic_time = time(0);
cache->bic_flags |= BLKID_BIC_FL_PROBED;
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;
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)
{

View File

@ -316,9 +316,6 @@ extern void blkid_tag_iterate_end(blkid_tag_iterate iter)
* 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,
@ -328,6 +325,7 @@ extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
blkid_dev dev;
int pri;
struct list_head *p;
int probe_new = 0;
if (!cache || !type || !value)
return NULL;
@ -359,6 +357,13 @@ try_again:
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;

View File

@ -4,6 +4,10 @@
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

View File

@ -11,7 +11,7 @@ blkid \- command\-line utility to locate/print block device attributes
.SH SYNOPSIS
.B blkid
[
.B \-hv
.B \-hlv
]
[
[
@ -63,6 +63,32 @@ scanned but not necessarily available at this time), specify
.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
@ -117,7 +143,7 @@ instead of writing it to the default cache file
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>

View File

@ -37,12 +37,13 @@ static void usage(int error)
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",
@ -101,9 +102,10 @@ int main(int argc, char **argv)
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)
@ -113,6 +115,9 @@ int main(int argc, char **argv)
if (!write)
write = read;
break;
case 'l':
lookup++;
break;
case 'o':
if (!strcmp(optarg, "value"))
output_format = OUTPUT_VALUE_ONLY;
@ -172,8 +177,25 @@ int main(int argc, char **argv)
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;