summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2023-01-27 15:56:06 -0600
committerDavid Teigland <teigland@redhat.com>2023-01-31 15:30:35 -0600
commitc9fdc828ff0504bc2e57f65862bc382f7663a8a2 (patch)
treebe061567e92602421b7e1cd0ccbcb72bfba1c681 /lib
parent17a3585cbb55d9a15ced9775a18b50c53a50ee8e (diff)
downloadlvm2-c9fdc828ff0504bc2e57f65862bc382f7663a8a2.tar.gz
vgchange autoactivation: skip regex filter containing symlinks
"vgchange -aay --autoactivation event" is called by our udev rule. When the udev rule runs, symlinks for devices may not all be created yet. If the regex filter contains symlinks, it won't work correctly. This command uses devices that already passed through pvscan. Since pvscan applies the regex filter correctly, this command inherits the filtering from pvscan and can skip the regex filter itself. See the previous commit "pvscan: use alternate device names from DEVLINKS to check filter"
Diffstat (limited to 'lib')
-rw-r--r--lib/commands/toolcontext.h1
-rw-r--r--lib/filters/filter-regex.c46
-rw-r--r--lib/filters/filter.h2
-rw-r--r--lib/label/label.c17
4 files changed, 66 insertions, 0 deletions
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 4069b6116..b5c1d8a90 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -194,6 +194,7 @@ struct cmd_context {
unsigned create_edit_devices_file:1; /* command expects to create and/or edit devices file */
unsigned edit_devices_file:1; /* command expects to edit devices file */
unsigned filter_deviceid_skip:1; /* don't use filter-deviceid */
+ unsigned filter_regex_skip:1; /* don't use filter-regex */
unsigned filter_regex_with_devices_file:1; /* use filter-regex even when devices file is enabled */
unsigned filter_nodata_only:1; /* only use filters that do not require data from the dev */
unsigned run_by_dmeventd:1; /* command is being run by dmeventd */
diff --git a/lib/filters/filter-regex.c b/lib/filters/filter-regex.c
index d9ed0104c..40dc8aa1b 100644
--- a/lib/filters/filter-regex.c
+++ b/lib/filters/filter-regex.c
@@ -161,6 +161,9 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
if (cmd->enable_devices_list)
return 1;
+ if (cmd->filter_regex_skip)
+ return 1;
+
if (cmd->enable_devices_file && !cmd->filter_regex_with_devices_file) {
/* can't warn in create_filter because enable_devices_file is set later */
if (rf->config_filter && !rf->warned_filter) {
@@ -250,3 +253,46 @@ struct dev_filter *regex_filter_create(const struct dm_config_value *patterns, i
dm_pool_destroy(mem);
return NULL;
}
+
+static int _filter_contains_symlink(struct cmd_context *cmd, int filter_cfg)
+{
+ const struct dm_config_node *cn;
+ const struct dm_config_value *cv;
+ const char *fname;
+
+ if ((cn = find_config_tree_array(cmd, filter_cfg, NULL))) {
+ for (cv = cn->v; cv; cv = cv->next) {
+ if (cv->type != DM_CFG_STRING)
+ continue;
+ if (!cv->v.str)
+ continue;
+
+ fname = cv->v.str;
+
+ if (fname[0] != 'a')
+ continue;
+
+ if (strstr(fname, "/dev/disk/"))
+ return 1;
+ if (strstr(fname, "/dev/mapper/"))
+ return 1;
+
+ /* In case /dev/disk/by was omitted */
+ if (strstr(fname, "lvm-pv-uuid"))
+ return 1;
+ if (strstr(fname, "dm-uuid"))
+ return 1;
+ if (strstr(fname, "wwn-"))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int regex_filter_contains_symlink(struct cmd_context *cmd)
+{
+ return _filter_contains_symlink(cmd, devices_filter_CFG) ||
+ _filter_contains_symlink(cmd, devices_global_filter_CFG);
+}
+
diff --git a/lib/filters/filter.h b/lib/filters/filter.h
index 4cdfa2c9b..0678e5e11 100644
--- a/lib/filters/filter.h
+++ b/lib/filters/filter.h
@@ -64,4 +64,6 @@ struct dev_filter *usable_filter_create(struct cmd_context *cmd, struct dev_type
#define DEV_FILTERED_DEVICES_LIST 0x00001000
#define DEV_FILTERED_IS_LV 0x00002000
+int regex_filter_contains_symlink(struct cmd_context *cmd);
+
#endif /* _LVM_FILTER_H */
diff --git a/lib/label/label.c b/lib/label/label.c
index f845abb96..42d7b6709 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -27,6 +27,7 @@
#include "lib/format_text/layout.h"
#include "lib/device/device_id.h"
#include "lib/device/online.h"
+#include "lib/filters/filter.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -1099,6 +1100,20 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
log_debug("Skipping device_id filtering due to devname ids.");
}
+ /*
+ * See corresponding code in pvscan. This function is used during
+ * startup autoactivation when udev has not created all symlinks, so
+ * regex filter containing symlinks doesn't work. pvscan has code
+ * to properly check devs against the filter using DEVLINKS. The
+ * pvscan will only create pvs_online files for devs that pass the
+ * filter. We get devs from the pvs_online files, so we inherit the
+ * regex filtering from pvscan and don't have to do it ourself.
+ */
+ if (!cmd->enable_devices_file &&
+ !cmd->enable_devices_list &&
+ regex_filter_contains_symlink(cmd))
+ cmd->filter_regex_skip = 1;
+
cmd->filter_nodata_only = 1;
dm_list_iterate_items_safe(devl, devl2, &devs) {
@@ -1179,6 +1194,8 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
if (relax_deviceid_filter)
cmd->filter_deviceid_skip = 0;
+ cmd->filter_regex_skip = 0;
+
free_po_list(&pvs_online);
if (dm_list_empty(&devs)) {