summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--tools/pvscan.c49
-rw-r--r--tools/vgchange.c1
6 files changed, 70 insertions, 46 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)) {
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 71485610b..8f60b2522 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -803,49 +803,6 @@ out:
return ret;
}
-/*
- * The optimization in which only the pvscan arg devname is added to dev-cache
- * does not work if there's an lvm.conf filter containing symlinks to the dev
- * like /dev/disk/by-id/lvm-pv-uuid-xyz entries. A full dev_cache_scan will
- * associate the symlinks with the system dev name passed to pvscan, which lets
- * filter-regex match the devname with the symlink name in the filter.
- */
-static int _filter_uses_symlinks(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;
-}
-
struct pvscan_arg {
struct dm_list list;
const char *devname;
@@ -1544,9 +1501,9 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
* 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))) {
+ !cmd->enable_devices_file &&
+ !cmd->enable_devices_list &&
+ regex_filter_contains_symlink(cmd)) {
char *env_str;
struct dm_list *env_aliases;
devl = dm_list_item(dm_list_first(&pvscan_devs), struct device_list);
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 09ade96a6..7d1bbd70a 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -16,6 +16,7 @@
#include "tools.h"
#include "lib/device/device_id.h"
#include "lib/label/hints.h"
+#include "lib/filters/filter.h"
struct vgchange_params {
int lock_start_count;