From 49361dc4dca0a9079ee57a2a0d8833aabd93277b Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 1 Feb 2010 14:23:55 +0100 Subject: [PATCH] libblkid: add blkid_probe_all_removable() The libblkid probing is based on devices from /proc/partitions by default. This file usually does not contain removable devices (e.g. CDROMs) and this kind of devices are invisible for libblkid. The blkid_probe_all_removable() function adds removable block devices to blkid cache. The probing is based on information from the /sys directory. The devices which were detected by this function won't be written to blkid.tab cache file. Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=533874 Signed-off-by: Karel Zak --- include/pathnames.h | 2 + shlibs/blkid/src/blkid.h.in | 1 + shlibs/blkid/src/blkid.sym | 8 +++ shlibs/blkid/src/blkidP.h | 1 + shlibs/blkid/src/devname.c | 110 +++++++++++++++++++++++++++++++++--- shlibs/blkid/src/save.c | 2 +- 6 files changed, 116 insertions(+), 8 deletions(-) diff --git a/include/pathnames.h b/include/pathnames.h index efe5c3bc..9c4eb009 100644 --- a/include/pathnames.h +++ b/include/pathnames.h @@ -76,6 +76,8 @@ #define _PATH_PROC_PARTITIONS "/proc/partitions" #define _PATH_PROC_DEVICES "/proc/devices" +#define _PATH_SYS_BLOCK "/sys/block" + #ifndef _PATH_MOUNTED # ifdef MOUNTED /* deprecated */ # define _PATH_MOUNTED MOUNTED diff --git a/shlibs/blkid/src/blkid.h.in b/shlibs/blkid/src/blkid.h.in index febb4372..4e53b39f 100644 --- a/shlibs/blkid/src/blkid.h.in +++ b/shlibs/blkid/src/blkid.h.in @@ -142,6 +142,7 @@ extern int blkid_devno_to_wholedisk(dev_t dev, char *diskname, /* devname.c */ extern int blkid_probe_all(blkid_cache cache); extern int blkid_probe_all_new(blkid_cache cache); +extern int blkid_probe_all_removable(blkid_cache cache); extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags); diff --git a/shlibs/blkid/src/blkid.sym b/shlibs/blkid/src/blkid.sym index 97255526..4d01aa20 100644 --- a/shlibs/blkid/src/blkid.sym +++ b/shlibs/blkid/src/blkid.sym @@ -114,3 +114,11 @@ global: blkid_topology_get_optimal_io_size; blkid_topology_get_physical_sector_size; } BLKID_2.15; + +/* + * version(s) since util-linux-ng 2.18 + */ +BLKID_2.18 { +global: + blkid_probe_all_removable; +} BLKID_2.17; diff --git a/shlibs/blkid/src/blkidP.h b/shlibs/blkid/src/blkidP.h index 4d21304e..d15b5305 100644 --- a/shlibs/blkid/src/blkidP.h +++ b/shlibs/blkid/src/blkidP.h @@ -51,6 +51,7 @@ struct blkid_struct_dev #define BLKID_BID_FL_VERIFIED 0x0001 /* Device data validated from disk */ #define BLKID_BID_FL_INVALID 0x0004 /* Device is invalid */ +#define BLKID_BID_FL_REMOVABLE 0x0008 /* Device added by blkid_probe_all_removable() */ /* * Each tag defines a NAME=value pair for a particular device. The tags diff --git a/shlibs/blkid/src/devname.c b/shlibs/blkid/src/devname.c index d048c722..5d6da891 100644 --- a/shlibs/blkid/src/devname.c +++ b/shlibs/blkid/src/devname.c @@ -22,6 +22,7 @@ #include #include #include +#include #if HAVE_SYS_TYPES_H #include #endif @@ -38,7 +39,9 @@ #include #include "blkidP.h" + #include "canonicalize.h" /* $(top_srcdir)/include */ +#include "pathnames.h" /* * Find a dev struct in the cache by device name, if available. @@ -157,7 +160,7 @@ static int is_dm_leaf(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, int only_if_new) + dev_t devno, int pri, int only_if_new, int removable) { blkid_dev dev = NULL; struct list_head *p, *pnext; @@ -237,6 +240,8 @@ set_pri: dev->bid_pri += 5; } else if (!strncmp(ptname, "md", 2)) dev->bid_pri = BLKID_PRI_MD; + if (removable) + dev->bid_flags |= BLKID_BID_FL_REMOVABLE; } return; } @@ -328,7 +333,7 @@ static void lvm_probe_all(blkid_cache cache, int only_if_new) lvm_device, (unsigned int) dev)); probe_one(cache, lvm_device, dev, BLKID_PRI_LVM, - only_if_new); + only_if_new, 0); free(lvm_device); } closedir(lv_list); @@ -360,7 +365,7 @@ evms_probe_all(blkid_cache cache, int only_if_new) device, ma, mi)); probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS, - only_if_new); + only_if_new, 0); num++; } fclose(procpt); @@ -408,7 +413,7 @@ ubi_probe_all(blkid_cache cache, int only_if_new) continue; DBG(DEBUG_DEVNAME, printf("UBI vol %s/%s: devno 0x%04X\n", *dirname, name, (int) dev)); - probe_one(cache, name, dev, BLKID_PRI_UBI, only_if_new); + probe_one(cache, name, dev, BLKID_PRI_UBI, only_if_new, 0); } closedir(dir); } @@ -485,7 +490,7 @@ static int probe_all(blkid_cache cache, int only_if_new) if (sz > 1) probe_one(cache, ptname, devs[which], 0, - only_if_new); + only_if_new, 0); lens[which] = 0; /* mark as checked */ } @@ -522,20 +527,81 @@ static int probe_all(blkid_cache cache, int only_if_new) 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); + only_if_new, 0); lens[last] = 0; } } /* Handle the last device if it wasn't partitioned */ if (lens[which]) - probe_one(cache, ptname, devs[which], 0, only_if_new); + probe_one(cache, ptname, devs[which], 0, only_if_new, 0); fclose(proc); blkid_flush_cache(cache); return 0; } +/* Don't use it by default -- it's pretty slow (because cdroms, floppy, ...) + */ +static int probe_all_removable(blkid_cache cache) +{ + DIR *dir; + struct dirent *d; + char buf[PATH_MAX]; + + if (!cache) + return -BLKID_ERR_PARAM; + + dir = opendir(_PATH_SYS_BLOCK); + if (!dir) + return -BLKID_ERR_PROC; + + while((d = readdir(dir))) { + int fd, rc, ma, mi; + +#ifdef _DIRENT_HAVE_D_TYPE + if (d->d_type != DT_UNKNOWN && d->d_type != DT_LNK) + continue; +#endif + if (d->d_name[0] == '.' && + ((d->d_name[1] == 0) || + ((d->d_name[1] == '.') && (d->d_name[2] == 0)))) + continue; + + snprintf(buf, sizeof(buf), "%s/removable", d->d_name); + fd = blkid_openat(dir, _PATH_SYS_BLOCK, buf, O_RDONLY); + if (fd < 0) + continue; + + rc = read(fd, buf, 1); + close(fd); + + if (rc != 1 || *buf != '1') + continue; /* not removable device */ + + /* get devno */ + snprintf(buf, sizeof(buf), "%s/dev", d->d_name); + fd = blkid_openat(dir, _PATH_SYS_BLOCK, buf, O_RDONLY); + if (fd < 0) + continue; + + rc = read(fd, buf, sizeof(buf)); + close(fd); + + if (rc < 3) + continue; /* M:N */ + buf[rc] = '\0'; + if (sscanf(buf, "%d:%d", &ma, &mi) != 2) + continue; + + probe_one(cache, d->d_name, makedev(ma, mi), 0, 0, 1); + } + + closedir(dir); + return 0; +} + + /** * blkid_probe_all: * @cache: cache handler @@ -574,6 +640,33 @@ int blkid_probe_all_new(blkid_cache cache) return ret; } +/** + * blkid_probe_all_removable: + * @cache: cache handler + * + * The libblkid probing is based on devices from /proc/partitions by default. + * This file usually does not contain removable devices (e.g. CDROMs) and this kind + * of devices are invisible for libblkid. + * + * This function adds removable block devices to @cache (probing is based on + * information from the /sys directory). Don't forget that removable devices + * (floppies, CDROMs, ...) could be pretty slow. It's very bad idea to call + * this function by default. + * + * Note that devices which were detected by this function won't be written to + * blkid.tab cache file. + * + * Returns: 0 on success, or number less than zero in case of error. + */ +int blkid_probe_all_removable(blkid_cache cache) +{ + int ret; + + DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_removable()\n")); + ret = probe_all_removable(cache); + DBG(DEBUG_PROBE, printf("End blkid_probe_all_removable()\n")); + return ret; +} #ifdef TEST_PROGRAM int main(int argc, char **argv) @@ -595,6 +688,9 @@ int main(int argc, char **argv) if (blkid_probe_all(cache) < 0) printf("%s: error probing devices\n", argv[0]); + if (blkid_probe_all_removable(cache) < 0) + printf("%s: error probing removable devices\n", argv[0]); + blkid_put_cache(cache); return (0); } diff --git a/shlibs/blkid/src/save.c b/shlibs/blkid/src/save.c index c61373d5..a1583ecc 100644 --- a/shlibs/blkid/src/save.c +++ b/shlibs/blkid/src/save.c @@ -119,7 +119,7 @@ int blkid_flush_cache(blkid_cache cache) list_for_each(p, &cache->bic_devs) { blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs); - if (!dev->bid_type) + if (!dev->bid_type || (dev->bid_flags & BLKID_BID_FL_REMOVABLE)) continue; if ((ret = save_dev(dev, file)) < 0) break; -- 2.39.5