1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

metadata: Fix metadata repair paths when lvmetad is used.

This commit is contained in:
Petr Rockai 2013-10-09 14:04:47 +02:00
parent fbb6de845e
commit 0decd7553a
3 changed files with 50 additions and 31 deletions

2
lib/cache/lvmetad.c vendored
View File

@ -392,8 +392,6 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
pvl->pv->dev = lvmcache_device(info); pvl->pv->dev = lvmcache_device(info);
if (!pvl->pv->dev) if (!pvl->pv->dev)
pvl->pv->status |= MISSING_PV; pvl->pv->status |= MISSING_PV;
else
check_reappeared_pv(vg, pvl->pv);
if (!lvmcache_fid_add_mdas_pv(info, fid)) { if (!lvmcache_fid_add_mdas_pv(info, fid)) {
vg = NULL; vg = NULL;
goto_out; /* FIXME error path */ goto_out; /* FIXME error path */

View File

@ -2883,10 +2883,11 @@ int vg_missing_pv_count(const struct volume_group *vg)
return ret; return ret;
} }
void check_reappeared_pv(struct volume_group *correct_vg, static int _check_reappeared_pv(struct volume_group *correct_vg,
struct physical_volume *pv) struct physical_volume *pv, int act)
{ {
struct pv_list *pvl; struct pv_list *pvl;
int rv = 0;
/* /*
* Skip these checks in case the tool is going to deal with missing * Skip these checks in case the tool is going to deal with missing
@ -2894,21 +2895,47 @@ void check_reappeared_pv(struct volume_group *correct_vg,
* confusing. * confusing.
*/ */
if (correct_vg->cmd->handles_missing_pvs) if (correct_vg->cmd->handles_missing_pvs)
return; return rv;
dm_list_iterate_items(pvl, &correct_vg->pvs) dm_list_iterate_items(pvl, &correct_vg->pvs)
if (pv->dev == pvl->pv->dev && is_missing_pv(pvl->pv)) { if (pv->dev == pvl->pv->dev && is_missing_pv(pvl->pv)) {
log_warn("Missing device %s reappeared, updating " if (act)
"metadata for VG %s to version %u.", log_warn("Missing device %s reappeared, updating "
pv_dev_name(pvl->pv), pv_vg_name(pvl->pv), "metadata for VG %s to version %u.",
correct_vg->seqno); pv_dev_name(pvl->pv), pv_vg_name(pvl->pv),
correct_vg->seqno);
if (pvl->pv->pe_alloc_count == 0) { if (pvl->pv->pe_alloc_count == 0) {
pv->status &= ~MISSING_PV; if (act) {
pvl->pv->status &= ~MISSING_PV; pv->status &= ~MISSING_PV;
} else pvl->pv->status &= ~MISSING_PV;
}
++ rv;
} else if (act)
log_warn("Device still marked missing because of allocated data " log_warn("Device still marked missing because of allocated data "
"on it, remove volumes and consider vgreduce --removemissing."); "on it, remove volumes and consider vgreduce --removemissing.");
} }
return rv;
}
static int _repair_inconsistent_vg(struct volume_group *vg)
{
unsigned saved_handles_missing_pvs = vg->cmd->handles_missing_pvs;
vg->cmd->handles_missing_pvs = 1;
if (!vg_write(vg)) {
log_error("Automatic metadata correction failed");
vg->cmd->handles_missing_pvs = saved_handles_missing_pvs;
return 0;
}
vg->cmd->handles_missing_pvs = saved_handles_missing_pvs;
if (!vg_commit(vg)) {
log_error("Automatic metadata correction commit failed");
return 0;
}
return 1;
} }
static int _check_mda_in_use(struct metadata_area *mda, void *_in_use) static int _check_mda_in_use(struct metadata_area *mda, void *_in_use)
@ -2951,12 +2978,12 @@ 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;
unsigned use_precommitted = precommitted; unsigned use_precommitted = precommitted;
unsigned saved_handles_missing_pvs = cmd->handles_missing_pvs;
struct dm_list *pvids; struct dm_list *pvids;
struct pv_list *pvl, *pvl2; struct pv_list *pvl, *pvl2;
struct dm_list all_pvs; struct dm_list all_pvs;
char uuid[64] __attribute__((aligned(8))); char uuid[64] __attribute__((aligned(8)));
unsigned seqno = 0; unsigned seqno = 0;
int reappeared = 0;
if (is_orphan_vg(vgname)) { if (is_orphan_vg(vgname)) {
if (use_precommitted) { if (use_precommitted) {
@ -2969,8 +2996,16 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
} }
if (lvmetad_active() && !use_precommitted) { if (lvmetad_active() && !use_precommitted) {
*consistent = 1; if ((correct_vg = lvmcache_get_vg(cmd, vgname, vgid, precommitted))) {
return lvmcache_get_vg(cmd, vgname, vgid, precommitted); dm_list_iterate_items(pvl, &correct_vg->pvs)
if (pvl->pv->dev)
reappeared += _check_reappeared_pv(correct_vg, pvl->pv, *consistent);
if (reappeared && *consistent)
*consistent = _repair_inconsistent_vg(correct_vg);
else
*consistent = !reappeared;
}
return correct_vg;
} }
/* /*
@ -3339,22 +3374,11 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
* update metadata and remove MISSING flag * update metadata and remove MISSING flag
*/ */
dm_list_iterate_items(pvl, &all_pvs) dm_list_iterate_items(pvl, &all_pvs)
check_reappeared_pv(correct_vg, pvl->pv); _check_reappeared_pv(correct_vg, pvl->pv, 1);
cmd->handles_missing_pvs = 1; if (!_repair_inconsistent_vg(correct_vg)) {
if (!vg_write(correct_vg)) {
log_error("Automatic metadata correction failed");
_free_pv_list(&all_pvs); _free_pv_list(&all_pvs);
release_vg(correct_vg); release_vg(correct_vg);
cmd->handles_missing_pvs = saved_handles_missing_pvs;
return NULL;
}
cmd->handles_missing_pvs = saved_handles_missing_pvs;
if (!vg_commit(correct_vg)) {
log_error("Automatic metadata correction commit "
"failed");
release_vg(correct_vg);
return NULL; return NULL;
} }

View File

@ -486,7 +486,4 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
uint64_t find_min_mda_size(struct dm_list *mdas); uint64_t find_min_mda_size(struct dm_list *mdas);
char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tags); char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tags);
void check_reappeared_pv(struct volume_group *correct_vg,
struct physical_volume *pv);
#endif #endif