]> sourceware.org Git - lvm2.git/commitdiff
vgck: fix updatemetadata writing different descriptions
authorDavid Teigland <teigland@redhat.com>
Tue, 8 Oct 2019 19:36:55 +0000 (14:36 -0500)
committerDavid Teigland <teigland@redhat.com>
Fri, 11 Oct 2019 17:57:32 +0000 (12:57 -0500)
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.)

lib/format_text/format-text.c
lib/format_text/format-text.h
tools/vgck.c

index be4730bd8329539d65dc59d5f0dd81ae2b617ddf..6ec47bfcef997f33c297da6f4441183fcbbb606b 100644 (file)
@@ -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;
index 2345d52a971549231c10a8c5c90a27b0288ba03f..552bfb73e7d7622b9b348bba74f206c5c08a41ca 100644 (file)
@@ -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
index 46ad59499da049b5368b0f967534d4a541d72ca3..4e797e71763834cb9e0c0c0691eebaa7f9e1f424 100644 (file)
@@ -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;
 }
 
This page took 0.039356 seconds and 5 git commands to generate.