mirror of
git://sourceware.org/git/lvm2.git
synced 2025-10-01 21:44:22 +03:00
Compare commits
3 Commits
v2_03_31
...
dev-dct-pv
Author | SHA1 | Date | |
---|---|---|---|
|
1068c5c15e | ||
|
a2392655a9 | ||
|
f4d285a3cb |
@@ -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 */
|
||||
@@ -207,6 +208,7 @@ struct cmd_context {
|
||||
unsigned udevoutput:1;
|
||||
unsigned online_vg_file_removed:1;
|
||||
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.
|
||||
|
@@ -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) {
|
||||
@@ -179,7 +182,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;
|
||||
@@ -250,3 +253,48 @@ 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;
|
||||
if (strstr(fname, "pci-"))
|
||||
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)) {
|
||||
|
103
tools/pvscan.c
103
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;
|
||||
@@ -910,30 +867,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 */
|
||||
@@ -1550,6 +1483,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 &&
|
||||
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);
|
||||
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: %s.",
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user