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:
parent
c5f998aec4
commit
89c54db16c
@ -1021,6 +1021,35 @@ int label_scan_for_pvid(struct cmd_context *cmd, char *pvid, struct device **dev
|
|||||||
return ret;
|
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,
|
* Use files under /run/lvm/, created by pvscan --cache autoactivation,
|
||||||
* to optimize device setup/scanning. autoactivation happens during
|
* 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 pvs_online;
|
||||||
struct dm_list devs;
|
struct dm_list devs;
|
||||||
|
struct dm_list devs_drop;
|
||||||
struct pv_online *po;
|
struct pv_online *po;
|
||||||
struct device_list *devl, *devl2;
|
struct device_list *devl, *devl2;
|
||||||
int relax_deviceid_filter = 0;
|
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(&pvs_online);
|
||||||
dm_list_init(&devs);
|
dm_list_init(&devs);
|
||||||
|
dm_list_init(&devs_drop);
|
||||||
|
|
||||||
log_debug_devs("Finding online devices to scan");
|
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
|
* 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) {
|
if (cmd->enable_devices_file) {
|
||||||
dm_list_iterate_items(devl, &devs)
|
dm_list_iterate_items(devl, &devs)
|
||||||
device_ids_match_dev(cmd, devl->dev);
|
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)) {
|
if (cmd->enable_devices_file && device_ids_use_devname(cmd)) {
|
||||||
relax_deviceid_filter = 1;
|
relax_deviceid_filter = 1;
|
||||||
cmd->filter_deviceid_skip = 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;
|
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.",
|
log_print("%s excluded by filters: %s.",
|
||||||
dev_name(devl->dev), dev_filtered_reason(devl->dev));
|
dev_name(devl->dev), dev_filtered_reason(devl->dev));
|
||||||
dm_list_del(&devl->list);
|
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();
|
label_scan_setup_bcache();
|
||||||
|
|
||||||
dm_list_iterate_items_safe(devl, devl2, &devs) {
|
dm_list_iterate_items_safe(devl, devl2, &devs) {
|
||||||
|
struct dev_use *du;
|
||||||
int has_pvid;
|
int has_pvid;
|
||||||
|
|
||||||
if (!label_read_pvid(devl->dev, &has_pvid)) {
|
if (!label_read_pvid(devl->dev, &has_pvid)) {
|
||||||
log_print("%s cannot read label.", dev_name(devl->dev));
|
log_print("%s cannot read label.", dev_name(devl->dev));
|
||||||
dm_list_del(&devl->list);
|
dm_list_del(&devl->list);
|
||||||
|
dm_list_add(&devs_drop, &devl->list);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1172,6 +1217,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
|
|||||||
/* Not an lvm device */
|
/* Not an lvm device */
|
||||||
log_print("%s not an lvm device.", dev_name(devl->dev));
|
log_print("%s not an lvm device.", dev_name(devl->dev));
|
||||||
dm_list_del(&devl->list);
|
dm_list_del(&devl->list);
|
||||||
|
dm_list_add(&devs_drop, &devl->list);
|
||||||
continue;
|
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.
|
* so in place of that check if the pvid is in the devices file.
|
||||||
*/
|
*/
|
||||||
if (relax_deviceid_filter) {
|
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).",
|
log_print("%s excluded by devices file (checking PVID).",
|
||||||
dev_name(devl->dev));
|
dev_name(devl->dev));
|
||||||
dm_list_del(&devl->list);
|
dm_list_del(&devl->list);
|
||||||
|
dm_list_add(&devs_drop, &devl->list);
|
||||||
continue;
|
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.",
|
log_print("%s excluded by filters: %s.",
|
||||||
dev_name(devl->dev), dev_filtered_reason(devl->dev));
|
dev_name(devl->dev), dev_filtered_reason(devl->dev));
|
||||||
dm_list_del(&devl->list);
|
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);
|
free_po_list(&pvs_online);
|
||||||
|
|
||||||
if (dm_list_empty(&devs)) {
|
if (dm_list_empty(&devs)) {
|
||||||
|
_clear_scan_state(cmd, &devs_drop);
|
||||||
*found_none = 1;
|
*found_none = 1;
|
||||||
return 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)) {
|
if (metadata_pv_count > dm_list_size(&devs)) {
|
||||||
log_debug("Incomplete PV list from online files %d metadata %d.",
|
log_debug("Incomplete PV list from online files %d metadata %d.",
|
||||||
dm_list_size(&devs), metadata_pv_count);
|
dm_list_size(&devs), metadata_pv_count);
|
||||||
|
_clear_scan_state(cmd, &devs_drop);
|
||||||
|
_clear_scan_state(cmd, &devs);
|
||||||
*found_incomplete = 1;
|
*found_incomplete = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1235,6 +1290,8 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
|
|||||||
*found_all = 1;
|
*found_all = 1;
|
||||||
return 1;
|
return 1;
|
||||||
bad:
|
bad:
|
||||||
|
_clear_scan_state(cmd, &devs_drop);
|
||||||
|
_clear_scan_state(cmd, &devs);
|
||||||
free_po_list(&pvs_online);
|
free_po_list(&pvs_online);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1527,7 +1584,7 @@ int label_read_pvid(struct device *dev, int *has_pvid)
|
|||||||
|
|
||||||
lh = (struct label_header *)(buf + 512);
|
lh = (struct label_header *)(buf + 512);
|
||||||
if (memcmp(lh->id, LABEL_ID, sizeof(lh->id))) {
|
if (memcmp(lh->id, LABEL_ID, sizeof(lh->id))) {
|
||||||
/* Not an lvm deice */
|
/* Not an lvm device */
|
||||||
label_scan_invalidate(dev);
|
label_scan_invalidate(dev);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1537,7 +1594,7 @@ int label_read_pvid(struct device *dev, int *has_pvid)
|
|||||||
* rest of the label_header intact.
|
* rest of the label_header intact.
|
||||||
*/
|
*/
|
||||||
if (memcmp(lh->type, LVM2_LABEL, sizeof(lh->type))) {
|
if (memcmp(lh->type, LVM2_LABEL, sizeof(lh->type))) {
|
||||||
/* Not an lvm deice */
|
/* Not an lvm device */
|
||||||
label_scan_invalidate(dev);
|
label_scan_invalidate(dev);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
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 ?: "");
|
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
|
* The expected and optimal usage, which is the purpose of
|
||||||
* vgchange -aay --autoactivation event vgname when all PVs
|
* this function. We expect online files to be found for
|
||||||
* for vgname are found online. Only online pvs are used.
|
* all PVs because the udev rule calls
|
||||||
|
* vgchange -aay --autoactivation event <vgname>
|
||||||
|
* only after all PVs for vgname are found online.
|
||||||
*/
|
*/
|
||||||
if (found_all) {
|
if (found_all) {
|
||||||
*flags |= PROCESS_SKIP_SCAN;
|
*flags |= PROCESS_SKIP_SCAN;
|
||||||
@ -825,16 +827,6 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
|
|||||||
return 1;
|
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
|
* 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
|
* 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) {
|
if (found_none) {
|
||||||
log_print("PVs online not found for VG %s, using all devices.", vgname);
|
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) {
|
if (found_incomplete) {
|
||||||
log_print("PVs online incomplete for VG %s, using all devicess.", vgname);
|
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.)
|
* process_each. (No optimization used.)
|
||||||
*/
|
*/
|
||||||
log_print("PVs online unknown for VG %s, using all devices.", vgname);
|
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;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int vgchange(struct cmd_context *cmd, int argc, char **argv)
|
int vgchange(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
Loading…
Reference in New Issue
Block a user