diff options
Diffstat (limited to 'tools/toollib.c')
-rw-r--r-- | tools/toollib.c | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/tools/toollib.c b/tools/toollib.c index 9640f003e..f6a4ebda1 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -16,6 +16,7 @@ #include "tools.h" #include "lib/format_text/format-text.h" #include "lib/label/hints.h" +#include "lib/device/device_id.h" #include <sys/stat.h> #include <signal.h> @@ -5101,15 +5102,57 @@ int pvcreate_each_device(struct cmd_context *cmd, /* * Translate arg names into struct device's. */ + + /* + * We allow pvcreate to look outside devices file here to find + * the target device, in case the user has not added the device + * being pvcreated to the devices file. + * + * First, wipe the filter to remove the previous result of filtering + * the target device that was done during label_scan. The persistent + * filter is storing the result of filtering the device when we + * were not skipping filter-deviceid. + * Then look up the device in dev-cache which will rerun the filters + * against the target device, skipping filter-deviceid. The target + * device could be excluded by a filter other than deviceid. + * + * TODO: do we want to add a config setting that would disable this + * ability of pvcreate to use devs outside of the devices_file? + * i.e. disable the ability to skip filter-deviceid. + * If devices_file is to be more strict in allowing access to devs, + * e.g. applied to pvcreate, then a user would need to add the new + * device to devices_file prior to running pvcreate on it. + */ + cmd->filter_deviceid_skip = 1; + dm_list_iterate_items_safe(pd, pd2, &pp->arg_devices) { - pd->dev = dev_cache_get(cmd, pd->name, cmd->filter); - if (!pd->dev) { - log_print("No device found for %s", pd->name); + struct device *new_dev; + + /* + * No filter applied here because we first need to wipe the + * previous result that was based on using filter-deviceid. + */ + if (!(new_dev = dev_cache_get(cmd, pd->name, NULL))) { + log_error("No device found for %s", pd->name); dm_list_del(&pd->list); dm_list_add(&pp->arg_fail, &pd->list); + continue; } + + cmd->filter->wipe(cmd, cmd->filter, new_dev, NULL); + + if (!cmd->filter->passes_filter(cmd, cmd->filter, new_dev, NULL)) { + log_error("Device %s is excluded by filter.", pd->name); + dm_list_del(&pd->list); + dm_list_add(&pp->arg_fail, &pd->list); + continue; + } + + pd->dev = new_dev; } + cmd->filter_deviceid_skip = 0; + /* * Can the command continue if some specified devices were not found? */ @@ -5411,6 +5454,10 @@ do_command: log_debug("Using existing orphan PV %s.", pv_dev_name(vgpvl->pv)); pvl->pv = vgpvl->pv; dm_list_add(&pp->pvs, &pvl->list); + + device_id_add(cmd, pd->dev, (const char *)&pvl->pv->id.uuid, + arg_str_value(cmd, deviceidtype_ARG, NULL), + arg_str_value(cmd, deviceid_ARG, NULL)); } else { log_error("Failed to find PV %s", pd->name); dm_list_move(&pp->arg_fail, &pd->list); @@ -5449,6 +5496,10 @@ do_command: continue; } + device_id_add(cmd, pd->dev, (const char *)&pv->id.uuid, + arg_str_value(cmd, deviceidtype_ARG, NULL), + arg_str_value(cmd, deviceid_ARG, NULL)); + log_verbose("Set up physical volume for \"%s\" with %" PRIu64 " available sectors.", pv_name, pv_size(pv)); @@ -5494,6 +5545,8 @@ do_command: continue; } + device_id_pvremove(cmd, pd->dev); + log_print_unless_silent("Labels on physical volume \"%s\" successfully wiped.", pd->name); } @@ -5510,10 +5563,15 @@ do_command: lvmcache_del_dev_from_duplicates(pd->dev); + device_id_pvremove(cmd, pd->dev); + log_print_unless_silent("Labels on physical volume \"%s\" successfully wiped.", pd->name); } + /* TODO: when vgcreate uses only existing PVs this doesn't change and can be skipped */ + device_ids_write(cmd); + /* * Don't keep devs open excl in bcache because the excl will prevent * using that dev elsewhere. |