mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
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>.
This commit is contained in:
parent
d9f8acb65a
commit
17a3585cbb
@ -207,6 +207,7 @@ struct cmd_context {
|
|||||||
unsigned udevoutput:1;
|
unsigned udevoutput:1;
|
||||||
unsigned online_vg_file_removed:1;
|
unsigned online_vg_file_removed:1;
|
||||||
unsigned disable_dm_devs:1; /* temporarily disable use of dm devs cache */
|
unsigned disable_dm_devs:1; /* temporarily disable use of dm devs cache */
|
||||||
|
unsigned filter_regex_set_preferred_name_disable:1; /* prevent dev_set_preferred_name */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Devices and filtering.
|
* Devices and filtering.
|
||||||
|
@ -179,7 +179,7 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
|
|||||||
|
|
||||||
if (m >= 0) {
|
if (m >= 0) {
|
||||||
if (dm_bit(rf->accept, m)) {
|
if (dm_bit(rf->accept, m)) {
|
||||||
if (!first)
|
if (!first && !cmd->filter_regex_set_preferred_name_disable)
|
||||||
dev_set_preferred_name(sl, dev);
|
dev_set_preferred_name(sl, dev);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -184,6 +184,19 @@ system from booting. A custom systemd service could be written to run
|
|||||||
autoactivation during system startup, in which case disabling event
|
autoactivation during system startup, in which case disabling event
|
||||||
autoactivation may be useful.
|
autoactivation may be useful.
|
||||||
.
|
.
|
||||||
|
.SS lvm.conf filter
|
||||||
|
.P
|
||||||
|
Device symlinks from /dev/disk/ can be used in the lvm.conf filter to
|
||||||
|
guard against changes in kernel device names. The /dev/disk/by-path/ or
|
||||||
|
/dev/disk/by-id/ prefixes should be included in the filter names; these
|
||||||
|
prefixes help lvm detect that symlink names are used. Filters containing
|
||||||
|
symlinks require special matching by commands run in the lvm udev rule.
|
||||||
|
.P
|
||||||
|
Common symlinks, e.g. beginning with wwn-, scsi-, pci-, or lvm-pv-uuid-,
|
||||||
|
are recommended. Uncommon or custom symlinks created by custom udev rules
|
||||||
|
may be less reliable. If a custom udev rule creates symlinks used in the
|
||||||
|
lvm filter, then the udev rule should be started prior to the lvm rule.
|
||||||
|
.
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.P
|
.P
|
||||||
VG "vg" contains two PVs:
|
VG "vg" contains two PVs:
|
||||||
|
@ -910,30 +910,6 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args,
|
|||||||
struct pvscan_arg *arg;
|
struct pvscan_arg *arg;
|
||||||
struct device_list *devl;
|
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 */
|
/* pass NULL filter when getting devs from dev-cache, filtering is done separately */
|
||||||
|
|
||||||
/* in common usage, no dev will be found for a devno */
|
/* in common usage, no dev will be found for a devno */
|
||||||
@ -1550,6 +1526,42 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
|
|||||||
|
|
||||||
cmd->filter_nodata_only = 1;
|
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) {
|
dm_list_iterate_items_safe(devl, devl2, &pvscan_devs) {
|
||||||
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
|
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
|
||||||
log_print_pvscan(cmd, "%s excluded: %s.",
|
log_print_pvscan(cmd, "%s excluded: %s.",
|
||||||
|
Loading…
Reference in New Issue
Block a user