1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

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.
This commit is contained in:
David Teigland 2021-11-12 16:46:39 -06:00
parent c5f998aec4
commit 89c54db16c
2 changed files with 80 additions and 19 deletions

View File

@ -1021,6 +1021,35 @@ int label_scan_for_pvid(struct cmd_context *cmd, char *pvid, struct device **dev
return ret;
}
/*
* 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
@ -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;
}

View File

@ -802,7 +802,7 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
*/
if (!label_scan_vg_online(cmd, vgname, &found_none, &found_all, &found_incomplete)) {
log_print("PVs online error%s%s, using all devices.", vgname ? " for VG " : "", vgname ?: "");
return 1;
goto bad;
}
/*
@ -815,9 +815,11 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
}
/*
* The expected and optimal usage, because the udev rule calls
* vgchange -aay --autoactivation event vgname when all PVs
* for vgname are found online. Only online pvs are used.
* The expected and optimal usage, which is the purpose of
* this function. We expect online files to be found for
* all PVs because the udev rule calls
* vgchange -aay --autoactivation event <vgname>
* only after all PVs for vgname are found online.
*/
if (found_all) {
*flags |= PROCESS_SKIP_SCAN;
@ -825,16 +827,6 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
return 1;
}
/*
* The online scanning optimiziation didn't work, so undo the vg
* locking optimization before falling back to normal processing.
*/
if (vg_locked) {
unlock_vg(cmd, NULL, vgname);
*flags &= ~READ_WITHOUT_LOCK;
cmd->can_use_one_scan = 0;
}
/*
* Not expected usage, no online pvs for the vgname were found. The
* caller will fall back to process_each doing a full label_scan to
@ -842,7 +834,7 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
*/
if (found_none) {
log_print("PVs online not found for VG %s, using all devices.", vgname);
return 1;
goto bad;
}
/*
@ -852,7 +844,7 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
*/
if (found_incomplete) {
log_print("PVs online incomplete for VG %s, using all devicess.", vgname);
return 1;
goto bad;
}
/*
@ -860,7 +852,19 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
* process_each. (No optimization used.)
*/
log_print("PVs online unknown for VG %s, using all devices.", vgname);
bad:
/*
* The online scanning optimization didn't work, so undo the vg
* locking optimization before falling back to normal processing.
*/
if (vg_locked) {
unlock_vg(cmd, NULL, vgname);
*flags &= ~READ_WITHOUT_LOCK;
cmd->can_use_one_scan = 0;
}
return 1;
}
int vgchange(struct cmd_context *cmd, int argc, char **argv)