1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-30 17:18:21 +03:00

dev-cache: iterate devices in sysfs for VGID/LVID index if obtain_device_list_from_udev=0

If obtain_device_list_from_udev=0, LVM can make use of persistent .cache
file. This cache file contains only devices which underwent filters in
previous LVM command run. But we need to iterate over all block devices
to create the VGID/LVID index completely for the device mismatch check
to be complete as well.

This patch iterates over block devices found in sysfs to generate the
VGID/LVID index in dev cache if obtain_device_list_from_udev=0
(if obtain_device_list_from_udev=1, we always read complete list of
block devices from udev and we ignore .cache file so we don't need
to look in sysfs for the complete list).
This commit is contained in:
Peter Rajnoha 2016-04-01 11:34:09 +02:00
parent 7ed5a65ee5
commit 15d1824fac

View File

@ -684,14 +684,15 @@ static int _insert_dev(const char *path, dev_t d)
}
/* is this device already registered ? */
if (!(dev = (struct device *) btree_lookup(_cache.devices,
(uint32_t) d))) {
/* create new device */
if (loopfile) {
if (!(dev = dev_create_file(path, NULL, NULL, 0)))
if (!(dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) d))) {
if (!(dev = (struct device *) btree_lookup(_cache.sysfs_only_devices, (uint32_t) d))) {
/* create new device */
if (loopfile) {
if (!(dev = dev_create_file(path, NULL, NULL, 0)))
return_0;
} else if (!(dev = _dev_create(d)))
return_0;
} else if (!(dev = _dev_create(d)))
return_0;
}
if (!(btree_insert(_cache.devices, (uint32_t) d, dev))) {
log_error("Couldn't insert device into binary tree.");
@ -799,7 +800,7 @@ static int _insert_file(const char *path)
return 1;
}
int dev_cache_index_devs(void)
static int _dev_cache_iterate_devs_for_index(void)
{
struct btree_iter *iter = btree_first(_cache.devices);
struct device *dev;
@ -817,6 +818,71 @@ int dev_cache_index_devs(void)
return r;
}
static int _dev_cache_iterate_sysfs_for_index(void)
{
char path[PATH_MAX];
char devname[PATH_MAX];
DIR *d;
struct dirent *dirent;
int major, minor;
dev_t devno;
struct device *dev;
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;
}
while ((dirent = readdir(d))) {
if (!strcmp(".", dirent->d_name) ||
!strcmp("..", dirent->d_name))
continue;
if (sscanf(dirent->d_name, "%d:%d", &major, &minor) != 2) {
log_error("_dev_cache_iterate_sysfs_for_index: %s: failed "
"to get major and minor number", dirent->d_name);
partial_failure = 1;
continue;
}
devno = MKDEV(major, minor);
if (!(dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devno)) &&
!(dev = (struct device *) btree_lookup(_cache.sysfs_only_devices, (uint32_t) devno))) {
if (!dm_device_get_name(major, minor, 1, devname, sizeof(devname)) ||
!(dev = _insert_sysfs_dev(devno, devname))) {
partial_failure = 1;
continue;
}
}
if (!_index_dev_by_vgid_and_lvid(dev))
partial_failure = 1;
}
r = !partial_failure;
if (closedir(d))
log_sys_error("closedir", path);
return r;
}
int dev_cache_index_devs(void)
{
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();
}
#ifdef UDEV_SYNC_SUPPORT
static int _device_in_udev_db(const dev_t d)