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

metadata: fix automatic updates of PV extension headers to newest version

Before, the automatic update from older to newer version of PV extension
header happened within vg_write call. This may have caused problems under
some circumnstances where there's a code in between vg_write and vg_commit
which may have failed. In such situation, we reverted precommitted metadata
and put back the state to working version of VG metadata.

However, we don't have revert for PV write operation at the moment. So
if we updated PV headers already and we reverted vg_write due to failure
in subsequent code (before vg_commit), we ended up with lost VG metadata
(because old metadata pointers got reset by the PV write operation).

To minimize problematic situations here, we should put vg_write and
vg_commit that is done after PV header rewrites as close to each
other as possible.

This patch moves the automatic PV header rewrite for new extension
header part from vg_write to _vg_read where it's done the same way
as we do any other VG repairs if detected during VG read operation
(under VG write lock).
This commit is contained in:
Peter Rajnoha 2016-07-26 15:46:36 +02:00
parent f9697ea006
commit 070c0d31ab
2 changed files with 34 additions and 10 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.162 - Version 2.02.162 -
================================= =================================
Fix automatic updates of PV extension headers to newest version.
Improve lvconvert --trackchanges validation to require --splitmirrors 1. Improve lvconvert --trackchanges validation to require --splitmirrors 1.
Add note about lastlog built-in command to lvm man page. Add note about lastlog built-in command to lvm man page.
Fix unrecognised segtype flag message. Fix unrecognised segtype flag message.

View File

@ -3297,7 +3297,7 @@ static int _pv_in_pv_list(struct physical_volume *pv, struct dm_list *head)
* Check if any of the PVs in VG still contain old PV headers * Check if any of the PVs in VG still contain old PV headers
* and if yes, schedule them for PV header update. * and if yes, schedule them for PV header update.
*/ */
static int _check_old_pv_ext_for_vg(struct volume_group *vg) static int _vg_update_old_pv_ext_if_needed(struct volume_group *vg)
{ {
struct pv_list *pvl, *new_pvl; struct pv_list *pvl, *new_pvl;
int pv_needs_rewrite; int pv_needs_rewrite;
@ -3330,9 +3330,17 @@ static int _check_old_pv_ext_for_vg(struct volume_group *vg)
} }
new_pvl->pv = pvl->pv; new_pvl->pv = pvl->pv;
dm_list_add(&vg->pv_write_list, &new_pvl->list); dm_list_add(&vg->pv_write_list, &new_pvl->list);
log_debug("PV %s has old extension header, updating to newest version.",
pv_dev_name(pvl->pv));
} }
} }
if (!dm_list_empty(&vg->pv_write_list) &&
(!vg_write(vg) || !vg_commit(vg))) {
log_error("Failed to update old PV extension headers in VG %s.", vg->name);
return 0;
}
return 1; return 1;
} }
@ -3463,11 +3471,6 @@ int vg_write(struct volume_group *vg)
return 0; return 0;
} }
if (!(_check_old_pv_ext_for_vg(vg))) {
log_error("Failed to schedule physical volume header update.");
return 0;
}
if (!drop_cached_metadata(vg)) { if (!drop_cached_metadata(vg)) {
log_error("Unable to drop cached metadata for VG %s.", vg->name); log_error("Unable to drop cached metadata for VG %s.", vg->name);
return 0; return 0;
@ -4139,6 +4142,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
int inconsistent_mdas = 0; int inconsistent_mdas = 0;
int inconsistent_mda_count = 0; int inconsistent_mda_count = 0;
int strip_historical_lvs = *consistent; int strip_historical_lvs = *consistent;
int update_old_pv_ext = *consistent;
unsigned use_precommitted = precommitted; unsigned use_precommitted = precommitted;
struct dm_list *pvids; struct dm_list *pvids;
struct pv_list *pvl; struct pv_list *pvl;
@ -4175,8 +4179,18 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
} }
} }
if (correct_vg && strip_historical_lvs && !vg_strip_outdated_historical_lvs(correct_vg))
if (correct_vg) {
if (update_old_pv_ext && !_vg_update_old_pv_ext_if_needed(correct_vg)) {
release_vg(correct_vg);
return_NULL; return_NULL;
}
if (strip_historical_lvs && !vg_strip_outdated_historical_lvs(correct_vg)) {
release_vg(correct_vg);
return_NULL;
}
}
return correct_vg; return correct_vg;
} }
@ -4616,8 +4630,17 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
*consistent = !inconsistent_pvs; *consistent = !inconsistent_pvs;
if (*consistent && correct_vg && strip_historical_lvs && !vg_strip_outdated_historical_lvs(correct_vg)) if (correct_vg && *consistent) {
if (update_old_pv_ext && !_vg_update_old_pv_ext_if_needed(correct_vg)) {
release_vg(correct_vg);
return_NULL; return_NULL;
}
if (strip_historical_lvs && !vg_strip_outdated_historical_lvs(correct_vg)) {
release_vg(correct_vg);
return_NULL;
}
}
return correct_vg; return correct_vg;
} }