mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
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"
This commit is contained in:
parent
17a3585cbb
commit
c9fdc828ff
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user