diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c index c9948744d..600fc19fa 100644 --- a/lib/cache/lvmetad.c +++ b/lib/cache/lvmetad.c @@ -468,7 +468,6 @@ int lvmetad_vg_update(struct volume_group *vg) struct pv_list *pvl; struct lvmcache_info *info; struct _fixup_baton baton; - struct dm_config_tree *vgmeta; if (!vg) return 0; @@ -476,13 +475,14 @@ int lvmetad_vg_update(struct volume_group *vg) if (!lvmetad_active() || test_mode()) return 1; /* fake it */ - if (!(vgmeta = export_vg_to_config_tree(vg))) - return_0; + if (!vg->cft_precommitted) { + log_error(INTERNAL_ERROR "VG update without precommited"); + return 0; + } log_debug_lvmetad("Sending lvmetad updated metadata for VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno); reply = _lvmetad_send("vg_update", "vgname = %s", vg->name, - "metadata = %t", vgmeta, NULL); - dm_config_destroy(vgmeta); + "metadata = %t", vg->cft_precommitted, NULL); if (!_lvmetad_handle_reply(reply, "update VG", vg->name, NULL)) { daemon_reply_destroy(reply); diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index 8643b756d..278b519ff 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -864,20 +864,24 @@ int vgcreate_params_validate(struct cmd_context *cmd, */ static int _vg_update_vg_precommitted(struct volume_group *vg) { - struct dm_config_tree *cft; - release_vg(vg->vg_precommitted); vg->vg_precommitted = NULL; - if (!(cft = export_vg_to_config_tree(vg))) + if (vg->cft_precommitted) { + dm_config_destroy(vg->cft_precommitted); + vg->cft_precommitted = NULL; + } + + if (!(vg->cft_precommitted = export_vg_to_config_tree(vg))) return_0; - if (!(vg->vg_precommitted = import_vg_from_config_tree(cft, vg->fid))) - stack; + if (!(vg->vg_precommitted = import_vg_from_config_tree(vg->cft_precommitted, vg->fid))) { + dm_config_destroy(vg->cft_precommitted); + vg->cft_precommitted = NULL; + return_0; + } - dm_config_destroy(cft); - - return vg->vg_precommitted ? 1 : 0; + return 1; } static int _vg_update_vg_ondisk(struct volume_group *vg) @@ -893,6 +897,10 @@ static int _vg_update_vg_ondisk(struct volume_group *vg) vg->vg_ondisk = vg->vg_precommitted; vg->vg_precommitted = NULL; + if (vg->cft_precommitted) { + dm_config_destroy(vg->cft_precommitted); + vg->cft_precommitted = NULL; + } return 1; } @@ -2695,6 +2703,9 @@ int vg_write(struct volume_group *vg) } } + if (!_vg_update_vg_precommitted(vg)) /* prepare precommited */ + return_0; + /* * If precommit is not supported, changes take effect immediately. * FIXME Replace with a more-accurate FMT_COMMIT flag. @@ -2702,9 +2713,6 @@ int vg_write(struct volume_group *vg) if (!(vg->fid->fmt->features & FMT_PRECOMMIT) && !lvmetad_vg_update(vg)) return_0; - if (!_vg_update_vg_precommitted(vg)) /* prepare precommited */ - return_0; - return 1; } @@ -2773,6 +2781,10 @@ int vg_commit(struct volume_group *vg) release_vg(vg->vg_ondisk); vg->vg_ondisk = vg->vg_precommitted; vg->vg_precommitted = NULL; + if (vg->cft_precommitted) { + dm_config_destroy(vg->cft_precommitted); + vg->cft_precommitted = NULL; + } } /* If update failed, remove any cached precommitted metadata. */ @@ -2791,6 +2803,10 @@ void vg_revert(struct volume_group *vg) release_vg(vg->vg_precommitted); /* VG is no longer needed */ vg->vg_precommitted = NULL; + if (vg->cft_precommitted) { + dm_config_destroy(vg->cft_precommitted); + vg->cft_precommitted = NULL; + } dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) { if (mda->ops->vg_revert && diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c index 8f23d56ed..8ebec99f7 100644 --- a/lib/metadata/vg.c +++ b/lib/metadata/vg.c @@ -90,6 +90,8 @@ void release_vg(struct volume_group *vg) release_vg(vg->vg_ondisk); release_vg(vg->vg_precommitted); + if (vg->cft_precommitted) + dm_config_destroy(vg->cft_precommitted); _free_vg(vg); } diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h index 028471be9..b3b7e93cc 100644 --- a/lib/metadata/vg.h +++ b/lib/metadata/vg.h @@ -57,7 +57,8 @@ struct volume_group { * _vg_update_vg_ondisk. */ struct volume_group *vg_ondisk; - struct volume_group *vg_precommitted; /* Parsed from precommitted */ + struct dm_config_tree *cft_precommitted; /* Precommitted metadata */ + struct volume_group *vg_precommitted; /* Parsed from cft */ alloc_policy_t alloc; struct profile *profile;