From: David Teigland Date: Tue, 8 Oct 2019 19:36:55 +0000 (-0500) Subject: vgck: fix updatemetadata writing different descriptions X-Git-Tag: v2_03_06~55 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=d6ffc990523468e46ae03a462ef1ec73067f9934;p=lvm2.git vgck: fix updatemetadata writing different descriptions vgck --updatemetadata would write the same correct metadata to good mdas, and then to bad mdas, but the sequence of vg_write/vg_commit calls betwen good and bad mdas could cause a different description field to be generated for good/bad mdas. (The description field describing the command was recently included in the ondisk copy of the metadata text.) --- diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index be4730bd8..6ec47bfce 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -41,8 +41,35 @@ struct text_fid_context { char *write_buf; /* buffer containing metadata text to write to disk */ uint32_t write_buf_size; /* mem size of write_buf, increases in 64K multiples */ uint32_t new_metadata_size; /* size of text metadata in buf */ + unsigned preserve:1; }; +void preserve_text_fidtc(struct volume_group *vg) +{ + struct format_instance *fid = vg->fid; + struct text_fid_context *fidtc = (struct text_fid_context *)fid->private; + + if (fidtc) + fidtc->preserve = 1; +} + +void free_text_fidtc(struct volume_group *vg) +{ + struct format_instance *fid = vg->fid; + struct text_fid_context *fidtc = (struct text_fid_context *)fid->private; + + if (!fidtc) + return; + + fidtc->preserve = 0; + + if (fidtc->write_buf) + free(fidtc->write_buf); + fidtc->write_buf = NULL; + fidtc->write_buf_size = 0; + fidtc->new_metadata_size = 0; +} + int rlocn_is_ignored(const struct raw_locn *rlocn) { return (rlocn->flags & RAW_LOCN_IGNORED ? 1 : 0); @@ -1183,7 +1210,7 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid, r = 1; out: - if (!precommit) { + if (!precommit && !fidtc->preserve) { free(fidtc->write_buf); fidtc->write_buf = NULL; fidtc->write_buf_size = 0; diff --git a/lib/format_text/format-text.h b/lib/format_text/format-text.h index 2345d52a9..552bfb73e 100644 --- a/lib/format_text/format-text.h +++ b/lib/format_text/format-text.h @@ -80,4 +80,7 @@ struct data_area_list { int text_wipe_outdated_pv_mda(struct cmd_context *cmd, struct device *dev, struct metadata_area *mda); +void preserve_text_fidtc(struct volume_group *vg); +void free_text_fidtc(struct volume_group *vg); + #endif diff --git a/tools/vgck.c b/tools/vgck.c index 46ad59499..4e797e717 100644 --- a/tools/vgck.c +++ b/tools/vgck.c @@ -14,6 +14,7 @@ */ #include "tools.h" +#include "lib/format_text/format-text.h" /* * TODO: we cannot yet repair corruption in label_header, pv_header/locations, @@ -39,6 +40,14 @@ static int _update_metadata_single(struct cmd_context *cmd __attribute__((unused return 0; } + /* + * Prevent vg_commit from freeing the metadata + * buffer that vg_write wrote to disk so that + * vg_write_commit_bad_mdas() can use the same + * metadata buffer to write to the bad mdas. + */ + preserve_text_fidtc(vg); + if (!vg_commit(vg)) { log_error("Failed to commit VG."); return 0; @@ -53,6 +62,12 @@ static int _update_metadata_single(struct cmd_context *cmd __attribute__((unused */ vg_write_commit_bad_mdas(cmd, vg); + /* + * Now free the metadata buffer that was + * preserved above. + */ + free_text_fidtc(vg); + return 1; }