summaryrefslogtreecommitdiff
path: root/lib/label
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2021-11-12 16:46:39 -0600
committerDavid Teigland <teigland@redhat.com>2021-11-15 11:07:11 -0600
commit89c54db16cfca284d78dd3be5316dc9bca67e8ef (patch)
treeb92957e073e19455892fd5400bd2ebc554e30a00 /lib/label
parentc5f998aec4b5e42f7f1b6ddeec6c4544dceaa1b5 (diff)
downloadlvm2-89c54db16cfca284d78dd3be5316dc9bca67e8ef.tar.gz
vgchange autoactivation: error path cleanup
If the optimized label scan fails (using online files), then clear the device state prior to falling back to the standard label_scan. This avoids printing output about unexpected state.
Diffstat (limited to 'lib/label')
-rw-r--r--lib/label/label.c63
1 files changed, 60 insertions, 3 deletions
diff --git a/lib/label/label.c b/lib/label/label.c
index d506b81e3..5c77a6923 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1022,6 +1022,35 @@ int label_scan_for_pvid(struct cmd_context *cmd, char *pvid, struct device **dev
}
/*
+ * Clear state that label_scan_vg_online() created so it will not
+ * confuse the standard label_scan() that the caller falls back to.
+ * the results of filtering (call filter->wipe)
+ * the results of matching device_id (reset dev and du)
+ * the results of scanning in lvmcache
+ */
+static void _clear_scan_state(struct cmd_context *cmd, struct dm_list *devs)
+{
+ struct device_list *devl;
+ struct device *dev;
+ struct dev_use *du;
+
+ dm_list_iterate_items(devl, devs) {
+ dev = devl->dev;
+
+ cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
+ dev->flags &= ~DEV_MATCHED_USE_ID;
+ dev->id = NULL;
+
+ if ((du = get_du_for_dev(cmd, dev)))
+ du->dev = NULL;
+
+ lvmcache_del_dev(dev);
+
+ memset(dev->pvid, 0, ID_LEN);
+ }
+}
+
+/*
* Use files under /run/lvm/, created by pvscan --cache autoactivation,
* to optimize device setup/scanning. autoactivation happens during
* system startup when the hints file is not useful, but he pvs_online
@@ -1033,6 +1062,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
{
struct dm_list pvs_online;
struct dm_list devs;
+ struct dm_list devs_drop;
struct pv_online *po;
struct device_list *devl, *devl2;
int relax_deviceid_filter = 0;
@@ -1041,6 +1071,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
dm_list_init(&pvs_online);
dm_list_init(&devs);
+ dm_list_init(&devs_drop);
log_debug_devs("Finding online devices to scan");
@@ -1116,6 +1147,15 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
* factor code common to pvscan_cache_args
*/
+ /*
+ * Match devs with the devices file because special/optimized
+ * device setup was used which does not check the devices file.
+ * If a match fails here do not exclude it, that will be done below by
+ * passes_filter() which runs filter-deviceid. The
+ * relax_deviceid_filter case needs to be able to work around
+ * unmatching devs.
+ */
+
if (cmd->enable_devices_file) {
dm_list_iterate_items(devl, &devs)
device_ids_match_dev(cmd, devl->dev);
@@ -1127,6 +1167,8 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
if (cmd->enable_devices_file && device_ids_use_devname(cmd)) {
relax_deviceid_filter = 1;
cmd->filter_deviceid_skip = 1;
+ /* PVIDs read from devs matched to devices file below instead. */
+ log_debug("Skipping device_id filtering due to devname ids.");
}
cmd->filter_nodata_only = 1;
@@ -1136,6 +1178,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
log_print("%s excluded by filters: %s.",
dev_name(devl->dev), dev_filtered_reason(devl->dev));
dm_list_del(&devl->list);
+ dm_list_add(&devs_drop, &devl->list);
}
}
@@ -1160,11 +1203,13 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
label_scan_setup_bcache();
dm_list_iterate_items_safe(devl, devl2, &devs) {
+ struct dev_use *du;
int has_pvid;
if (!label_read_pvid(devl->dev, &has_pvid)) {
log_print("%s cannot read label.", dev_name(devl->dev));
dm_list_del(&devl->list);
+ dm_list_add(&devs_drop, &devl->list);
continue;
}
@@ -1172,6 +1217,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
/* Not an lvm device */
log_print("%s not an lvm device.", dev_name(devl->dev));
dm_list_del(&devl->list);
+ dm_list_add(&devs_drop, &devl->list);
continue;
}
@@ -1180,11 +1226,16 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
* so in place of that check if the pvid is in the devices file.
*/
if (relax_deviceid_filter) {
- if (!get_du_for_pvid(cmd, devl->dev->pvid)) {
+ if (!(du = get_du_for_pvid(cmd, devl->dev->pvid))) {
log_print("%s excluded by devices file (checking PVID).",
dev_name(devl->dev));
dm_list_del(&devl->list);
+ dm_list_add(&devs_drop, &devl->list);
continue;
+ } else {
+ /* Special case matching for devname entries based on pvid. */
+ log_debug("Match device_id %s %s to %s: matching PVID",
+ idtype_to_str(du->idtype), du->idname, dev_name(devl->dev));
}
}
@@ -1193,6 +1244,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
log_print("%s excluded by filters: %s.",
dev_name(devl->dev), dev_filtered_reason(devl->dev));
dm_list_del(&devl->list);
+ dm_list_add(&devs_drop, &devl->list);
}
}
@@ -1202,6 +1254,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
free_po_list(&pvs_online);
if (dm_list_empty(&devs)) {
+ _clear_scan_state(cmd, &devs_drop);
*found_none = 1;
return 1;
}
@@ -1227,6 +1280,8 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
if (metadata_pv_count > dm_list_size(&devs)) {
log_debug("Incomplete PV list from online files %d metadata %d.",
dm_list_size(&devs), metadata_pv_count);
+ _clear_scan_state(cmd, &devs_drop);
+ _clear_scan_state(cmd, &devs);
*found_incomplete = 1;
return 1;
}
@@ -1235,6 +1290,8 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
*found_all = 1;
return 1;
bad:
+ _clear_scan_state(cmd, &devs_drop);
+ _clear_scan_state(cmd, &devs);
free_po_list(&pvs_online);
return 0;
}
@@ -1527,7 +1584,7 @@ int label_read_pvid(struct device *dev, int *has_pvid)
lh = (struct label_header *)(buf + 512);
if (memcmp(lh->id, LABEL_ID, sizeof(lh->id))) {
- /* Not an lvm deice */
+ /* Not an lvm device */
label_scan_invalidate(dev);
return 1;
}
@@ -1537,7 +1594,7 @@ int label_read_pvid(struct device *dev, int *has_pvid)
* rest of the label_header intact.
*/
if (memcmp(lh->type, LVM2_LABEL, sizeof(lh->type))) {
- /* Not an lvm deice */
+ /* Not an lvm device */
label_scan_invalidate(dev);
return 1;
}