summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/pathnames.h2
-rw-r--r--shlibs/blkid/src/blkid.h.in1
-rw-r--r--shlibs/blkid/src/blkid.sym8
-rw-r--r--shlibs/blkid/src/blkidP.h1
-rw-r--r--shlibs/blkid/src/devname.c110
-rw-r--r--shlibs/blkid/src/save.c2
6 files changed, 116 insertions, 8 deletions
diff --git a/include/pathnames.h b/include/pathnames.h
index efe5c3bc8..9c4eb009b 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 febb43728..4e53b39fe 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 972555266..4d01aa201 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 4d21304e3..d15b53058 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 d048c7222..5d6da8918 100644
--- a/shlibs/blkid/src/devname.c
+++ b/shlibs/blkid/src/devname.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <fcntl.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -38,7 +39,9 @@
#include <time.h>
#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 c61373d50..a1583ecca 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;