summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2016-04-01 17:04:11 +0200
committerPeter Rajnoha <prajnoha@redhat.com>2016-04-01 17:09:15 +0200
commit42f04a0f77ee94b01d652d6c11d10e85aa46a897 (patch)
treedb9bd956ef02cf68acc6011017b5d5fa088e1755
parent9f28eb4c20ecb772f1b8a912c43f243d63a7e5f3 (diff)
downloadlvm2-42f04a0f77ee94b01d652d6c11d10e85aa46a897.tar.gz
dev-cache: skip VGID/LVID indexing if /sys/dev/block is not present
/sys/dev/block is available since kernel version 2.2.26 (~ 2008): https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-dev The VGID/LVID indexing code relies on this feature so skip indexing if it's not available to avoid error messages about inability to open /sys/dev/block directory. We're not going to provide fallback code to read the /sys/block/ instead in this case as that's not that efficient - it needs extra reads for getting major:minor and reading partitions would also pose further reads and that's not worth it.
-rw-r--r--lib/device/dev-cache.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 84bd85b12..8461f40a2 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -818,9 +818,8 @@ static int _dev_cache_iterate_devs_for_index(void)
return r;
}
-static int _dev_cache_iterate_sysfs_for_index(void)
+static int _dev_cache_iterate_sysfs_for_index(const char *path)
{
- char path[PATH_MAX];
char devname[PATH_MAX];
DIR *d;
struct dirent *dirent;
@@ -830,11 +829,6 @@ static int _dev_cache_iterate_sysfs_for_index(void)
int partial_failure = 0;
int r = 0;
- if (dm_snprintf(path, sizeof(path), "%sdev/block", dm_sysfs_dir()) < 0) {
- log_error("_dev_cache_iterate_sysfs_for_index: dm_snprintf failed.");
- return 0;
- }
-
if (!(d = opendir(path))) {
log_sys_error("opendir", path);
return 0;
@@ -876,11 +870,36 @@ static int _dev_cache_iterate_sysfs_for_index(void)
int dev_cache_index_devs(void)
{
+ static int sysfs_has_dev_block = -1;
+ char path[PATH_MAX];
+
+ if (dm_snprintf(path, sizeof(path), "%sdev/block", dm_sysfs_dir()) < 0) {
+ log_error("dev_cache_index_devs: dm_snprintf failed.");
+ return 0;
+ }
+
+ /* Skip indexing if /sys/dev/block is not available.*/
+ if (sysfs_has_dev_block == -1) {
+ struct stat info;
+ if (stat(path, &info) == 0)
+ sysfs_has_dev_block = 1;
+ else {
+ if (errno == ENOENT) {
+ sysfs_has_dev_block = 0;
+ return 1;
+ } else {
+ log_sys_error("stat", path);
+ return 0;
+ }
+ }
+ } else if (!sysfs_has_dev_block)
+ return 1;
+
int with_udev = obtain_device_list_from_udev() &&
udev_get_library_context();
return with_udev ? _dev_cache_iterate_devs_for_index()
- : _dev_cache_iterate_sysfs_for_index();
+ : _dev_cache_iterate_sysfs_for_index(path);
}
#ifdef UDEV_SYNC_SUPPORT