Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:Update
lvm2-clvm.16468
bug-1173503_lvmetad-fix-pvs-for-many-devices.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bug-1173503_lvmetad-fix-pvs-for-many-devices.patch of Package lvm2-clvm.16468
From 5502f72e41dceb85d11ec562819ad6c5db6758ae Mon Sep 17 00:00:00 2001 From: David Teigland <teigland@redhat.com> Date: Mon, 27 Aug 2018 11:42:25 -0500 Subject: [PATCH] lvmetad: fix pvs for many devices When using lvmetad, 'pvs' still evaluates full filters on all devices (lvmetad only provides info about PVs, but pvs needs to report info about all devices, at least sometimes.) Because some filters read the devices, pvs still reads every device, even with lvmetad (i.e. lvmetad is no help for the pvs command.) Because the device reads are not being managed by the standard label scan layer, but only happen incidentally through the filters, there is nothing to control and limit the bcache content and the open file descriptors for the devices. When there are a lot of devs on the system, the number of open fd's excedes the limit and all opens begin failing. The proper solution for this would be for pvs to really use lvmetad and not scan devs, or for pvs to do a proper label scan even when lvmetad is enabled. To avoid any major changes to the way this has worked, just work around this problem by dropping bcache and closing the fd after pvs evaluates the filter on each device. --- tools/toollib.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/tools/toollib.c b/tools/toollib.c index 6ae78bd..3221e5f 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -3931,7 +3931,7 @@ static int _get_arg_devices(struct cmd_context *cmd, return ret_max; } -static int _get_all_devices(struct cmd_context *cmd, struct dm_list *all_devices) +static int _get_all_devices_lvmetad(struct cmd_context *cmd, struct dm_list *all_devices) { struct dev_iter *iter; struct device *dev; @@ -3947,6 +3947,56 @@ static int _get_all_devices(struct cmd_context *cmd, struct dm_list *all_devices return ECMD_FAILED; } + /* + * The dev_iter_get applies the filter, which means it reads the device + * (since some filters read devices). The read is called from the + * filter, and done without label_scan_open, so the dev_read_bytes does + * the open. Since the open and read are not done from the label scan + * layer, there's nothing to do label_scan_invalidate and close devs + * that are not lvms. Hack around this by doing label_scan_invalidate + * here. It's dumb that we are reading all disks here when we're meant + * to be using lvmetad. process_each_pv with lvmetad should either + * just do a proper label_scan or find a way to not need to read devs + * at all. If we didn't close each dev here, all devs would remain + * open and lvm will have too many open fds. It's all because we're + * not using the label scan layer to do the scanning, but pretending a + * label scan isn't needed (because of lvmetad) and then secretly doing + * a scan anyway hidden down in the filters. + */ + + while ((dev = dev_iter_get(iter))) { + if (!(dil = dm_pool_alloc(cmd->mem, sizeof(*dil)))) { + log_error("device_id_list alloc failed."); + goto out; + } + + strncpy(dil->pvid, dev->pvid, ID_LEN); + dil->dev = dev; + dm_list_add(all_devices, &dil->list); + + label_scan_invalidate(dev); + } + + r = ECMD_PROCESSED; +out: + dev_iter_destroy(iter); + return r; +} + +static int _get_all_devices_normal(struct cmd_context *cmd, struct dm_list *all_devices) +{ + struct dev_iter *iter; + struct device *dev; + struct device_id_list *dil; + int r = ECMD_FAILED; + + log_debug("Getting list of all devices"); + + if (!(iter = dev_iter_create(cmd->full_filter, 1))) { + log_error("dev_iter creation failed."); + return ECMD_FAILED; + } + while ((dev = dev_iter_get(iter))) { if (!(dil = dm_pool_alloc(cmd->mem, sizeof(*dil)))) { log_error("device_id_list alloc failed."); @@ -3964,6 +4014,14 @@ out: return r; } +static int _get_all_devices(struct cmd_context *cmd, struct dm_list *all_devices) +{ + if (lvmetad_used()) + return _get_all_devices_lvmetad(cmd, all_devices); + else + return _get_all_devices_normal(cmd, all_devices); +} + static int _device_list_remove(struct dm_list *devices, struct device *dev) { struct device_id_list *dil; -- 1.8.3.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor