Signed-off-by: wangzhiqiang <wangzhiqiang95@huawei.com> (cherry picked from commit 639fa142c7524c62f00d5cc76beff769212d969c)
128 lines
5.7 KiB
Diff
128 lines
5.7 KiB
Diff
From 542390047f9e38d139a68088ffdc9acad74ab8fa Mon Sep 17 00:00:00 2001
|
|
From: David Teigland <teigland@redhat.com>
|
|
Date: Thu, 19 Jan 2023 17:37:31 -0600
|
|
Subject: [PATCH] pvscan: use alternate device names from DEVLINKS to check
|
|
filter
|
|
|
|
pvscan --cache <dev> is called by our udev rule at a time when all
|
|
the symlinks for <dev> may not be created yet (by other udev rules.)
|
|
The regex filter in lvm.conf may refer to <dev> using a symlink name
|
|
that hasn't yet been created, which would cause <dev> to not match
|
|
the filter regex. The DEVLINKS env var, set by udev, contains all
|
|
the symlink names for <dev> that have been or will be created.
|
|
So, we add all these symlink names to dev->aliases, as if we had
|
|
found them in /dev. This allows <dev> to be recognized by a regex
|
|
filter containing a symlink for <dev>.
|
|
---
|
|
lib/commands/toolcontext.h | 1 +
|
|
lib/filters/filter-regex.c | 2 +-
|
|
tools/pvscan.c | 60 +++++++++++++++++++++++---------------
|
|
3 files changed, 38 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
|
|
index 957ab7f..2840fb5 100644
|
|
--- a/lib/commands/toolcontext.h
|
|
+++ b/lib/commands/toolcontext.h
|
|
@@ -202,6 +202,7 @@ struct cmd_context {
|
|
unsigned ignore_device_name_mismatch:1; /* skip updating devices file names */
|
|
unsigned backup_disabled:1; /* skip repeated debug message */
|
|
unsigned event_activation:1; /* whether event_activation is set */
|
|
+ unsigned filter_regex_set_preferred_name_disable:1; /* prevent dev_set_preferred_name */
|
|
|
|
/*
|
|
* Devices and filtering.
|
|
diff --git a/lib/filters/filter-regex.c b/lib/filters/filter-regex.c
|
|
index 05c5b3f..d9ed010 100644
|
|
--- a/lib/filters/filter-regex.c
|
|
+++ b/lib/filters/filter-regex.c
|
|
@@ -179,7 +179,7 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
|
|
|
|
if (m >= 0) {
|
|
if (dm_bit(rf->accept, m)) {
|
|
- if (!first)
|
|
+ if (!first && !cmd->filter_regex_set_preferred_name_disable)
|
|
dev_set_preferred_name(sl, dev);
|
|
|
|
return 1;
|
|
diff --git a/tools/pvscan.c b/tools/pvscan.c
|
|
index 35258c5..710ffcd 100644
|
|
--- a/tools/pvscan.c
|
|
+++ b/tools/pvscan.c
|
|
@@ -1234,30 +1234,6 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args,
|
|
struct pvscan_arg *arg;
|
|
struct device_list *devl;
|
|
|
|
- /*
|
|
- * If no devices file is used, and lvm.conf filter is set to
|
|
- * accept /dev/disk/by-id/lvm-pv-uuid-xyz or another symlink,
|
|
- * but pvscan --cache is passed devname or major:minor, so
|
|
- * pvscan needs to match its arg device to the filter symlink.
|
|
- * setup_dev_in_dev_cache() adds /dev/sda2 to dev-cache which
|
|
- * does not match a symlink to /dev/sda2, so we need a full
|
|
- * dev_cache_scan that will associate all symlinks to sda2,
|
|
- * which allows filter-regex to work. This case could be
|
|
- * optimized if needed by adding dev-cache entries for each
|
|
- * filter "a" entry (filter symlink patterns would still need
|
|
- * a full dev_cache_scan.)
|
|
- * (When no devices file is used and 69-dm-lvm.rules is
|
|
- * used which calls pvscan directly, symlinks may not
|
|
- * have been created by other rules when pvscan runs, so
|
|
- * the full dev_cache_scan may still not find them.)
|
|
- */
|
|
- if (!cmd->enable_devices_file && !cmd->enable_devices_list &&
|
|
- (_filter_uses_symlinks(cmd, devices_filter_CFG) ||
|
|
- _filter_uses_symlinks(cmd, devices_global_filter_CFG))) {
|
|
- log_print_pvscan(cmd, "finding all devices for filter symlinks.");
|
|
- dev_cache_scan(cmd);
|
|
- }
|
|
-
|
|
/* pass NULL filter when getting devs from dev-cache, filtering is done separately */
|
|
|
|
/* in common usage, no dev will be found for a devno */
|
|
@@ -1835,6 +1811,42 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
|
|
|
|
cmd->filter_nodata_only = 1;
|
|
|
|
+ /*
|
|
+ * Hack to handle regex filter that contains a symlink name for dev arg.
|
|
+ * pvscan --cache <dev> is called by our udev rule at a time when the
|
|
+ * symlinks for <dev> may not all be created yet (by other udev rules.)
|
|
+ * The regex filter in lvm.conf may refer to <dev> using a symlink name,
|
|
+ * so we need to know all the symlinks for <dev> in order for the filter
|
|
+ * to work correctly. Scanning /dev with dev_cache_scan() would usually
|
|
+ * find all the symlink names for <dev>, adding them to dev->aliases,
|
|
+ * which would let the filter work, but all symlinks aren't created yet.
|
|
+ * But, the DEVLINKS env var, set by udev, contains all the symlink
|
|
+ * names for <dev> that have been or *will be* created. So, we add all
|
|
+ * these symlink names to dev->aliases, as if we had found them in /dev.
|
|
+ * This allows <dev> to be recognized by a regex filter containing a
|
|
+ * symlink for <dev>. We have to tell filter-regex to not set the
|
|
+ * preferred name for <dev> to a symlink name since the <dev> may not
|
|
+ * be usable by that symlink name yet.
|
|
+ */
|
|
+ if ((dm_list_size(&pvscan_devs) == 1) &&
|
|
+ !cmd->enable_devices_file && !cmd->enable_devices_list &&
|
|
+ (_filter_uses_symlinks(cmd, devices_filter_CFG) ||
|
|
+ _filter_uses_symlinks(cmd, devices_global_filter_CFG))) {
|
|
+ char *env_str;
|
|
+ struct dm_list *env_aliases;
|
|
+ devl = dm_list_item(dm_list_first(&pvscan_devs), struct device_list);
|
|
+ if ((env_str = getenv("DEVLINKS"))) {
|
|
+ log_debug("Finding symlink names from DEVLINKS for filter regex.");
|
|
+ log_debug("DEVLINKS %s", env_str);
|
|
+ env_aliases = str_to_str_list(cmd->mem, env_str, " ", 0);
|
|
+ dm_list_splice(&devl->dev->aliases, env_aliases);
|
|
+ } else {
|
|
+ log_debug("Finding symlink names from /dev for filter regex.");
|
|
+ dev_cache_scan(cmd);
|
|
+ }
|
|
+ cmd->filter_regex_set_preferred_name_disable = 1;
|
|
+ }
|
|
+
|
|
dm_list_iterate_items_safe(devl, devl2, &pvscan_devs) {
|
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
|
|
log_print_pvscan(cmd, "%s excluded by filters: %s.",
|
|
--
|
|
2.33.0
|
|
|