]> sourceware.org Git - lvm2.git/commitdiff
Allow non-orphan PVs with two metadata areas to be resized.
authorPeter Rajnoha <prajnoha@redhat.com>
Mon, 28 Feb 2011 13:19:02 +0000 (13:19 +0000)
committerPeter Rajnoha <prajnoha@redhat.com>
Mon, 28 Feb 2011 13:19:02 +0000 (13:19 +0000)
We allow writing non-orphan PVs only for resize now. The "orphan PV" assert
in pv_write fn uses the "allow_non_orphan" parameter to control this assert.
However, we should find a more elaborate solution so we can remove this
restriction altogether (pv_write together with vg_write is not atomic, we
need to find a safe mechanism so there's an easy revert possible in case of
an error).

WHATS_NEW
lib/format_text/format-text.c
lib/metadata/metadata-exported.h
lib/metadata/metadata.c
lib/metadata/metadata.h
tools/pvchange.c
tools/pvresize.c
tools/vgconvert.c
tools/vgreduce.c

index 233fcc945058e41e9ea4b7f9ef3557e4d33e4ca6..3f228e5b53bd9241415797c40ff30f005dd76ba9 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -5,8 +5,8 @@ Version 2.02.85 -
   Improve normal allocation algorithm to include clinging to existing areas.
   Add allocation/maximise_cling & mirror_logs_require_separate_pvs to lvm.conf.
   Fix metadata balance code to work with recent changes in metadata handling.
-  Add old_uuid field to physical_volume and fix pvchange -u for recent changes.
-  Allow pvresize on a PV with two metadata areas (for PVs not in a VG).
+  Add old_id field to physical_volume and fix pvchange -u for recent changes.
+  Allow pvresize on a PV with two metadata areas.
   Change pvcreate to use new metadata handling interface.
   Restructure existing pv_setup and pv_write fn, add pv_initialise fn.
   Add internal interface to support adding and removing metadata areas.
index 703477c1508d8097333212c713d7c74290533fd0..48deaa1970f7f6a4e29535b669e66a2ac7866c8a 100644 (file)
@@ -1273,7 +1273,8 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
 
        /* Add a new cache entry with PV info or update existing one. */
        if (!(info = lvmcache_add(fmt->labeller, (const char *) &pv->id,
-                       pv->dev, FMT_TEXT_ORPHAN_VG_NAME, NULL, 0)))
+                     pv->dev, pv->vg ? pv->vg->name : FMT_TEXT_ORPHAN_VG_NAME,
+                     NULL, 0)))
                return_0;
 
        label = info->label;
@@ -2161,17 +2162,6 @@ static int _text_pv_resize(const struct format_type *fmt,
        /* If there's an mda at the end, move it to a new position. */
        if ((mda = fid_get_mda_indexed(fid, pvid, ID_LEN, 1)) &&
            (mdac = mda->metadata_locn)) {
-               /*
-                * FIXME: Remove this restriction - we need to
-                *        allow writing PV labels on non-orphan VGs
-                *        for this to work correctly.
-                */
-               if (vg) {
-                       log_error("Resizing a PV with two metadata areas "
-                                 "that is part of a VG is not supported.");
-                       return 0;
-               }
-
                /* FIXME: Maybe MDA0 size would be better? */
                mda_size = mdac->area.size >> SECTOR_SHIFT;
                mda_ignored = mda_is_ignored(mda);
index 464c5c1d220446b1d1f64fd815611ab3da72aee2..15d17154cf5d1a1eec7403082097857086a8ad5f 100644 (file)
@@ -384,7 +384,7 @@ struct dm_list *get_vgnames(struct cmd_context *cmd, int include_internal);
 struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal);
 int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings);
 
-int pv_write(struct cmd_context *cmd, struct physical_volume *pv);
+int pv_write(struct cmd_context *cmd, struct physical_volume *pv, int allow_non_orphan);
 int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
            const char *pv_name);
 int move_pvs_used_by_lv(struct volume_group *vg_from,
index 4aa0c31ffc0917a498c187c782c79a54fbc7131a..ff61cbb0bfe3307532f7b5200c7058ea7bbafeef 100644 (file)
@@ -586,7 +586,7 @@ int vg_remove(struct volume_group *vg)
                }
 
                /* FIXME Write to same sector label was read from */
-               if (!pv_write(vg->cmd, pv)) {
+               if (!pv_write(vg->cmd, pv, 0)) {
                        log_error("Failed to remove physical volume \"%s\""
                                  " from volume group \"%s\"",
                                  pv_dev_name(pv), vg->name);
@@ -1511,7 +1511,7 @@ struct physical_volume * pvcreate_single(struct cmd_context *cmd,
        log_very_verbose("Writing physical volume data to disk \"%s\"",
                         pv_name);
 
-       if (!(pv_write(cmd, pv))) {
+       if (!(pv_write(cmd, pv, 0))) {
                log_error("Failed to write physical volume \"%s\"", pv_name);
                goto error;
        }
@@ -3536,7 +3536,7 @@ int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings)
 }
 
 int pv_write(struct cmd_context *cmd __attribute__((unused)),
-            struct physical_volume *pv)
+            struct physical_volume *pv, int allow_non_orphan)
 {
        if (!pv->fmt->ops->pv_write) {
                log_error("Format does not support writing physical volumes");
@@ -3549,7 +3549,8 @@ int pv_write(struct cmd_context *cmd __attribute__((unused)),
         *        to provide some revert mechanism since PV label together
         *        with VG metadata write is not atomic.
         */
-       if (!is_orphan_vg(pv->vg_name) || pv->pe_alloc_count) {
+       if (!allow_non_orphan &&
+           (!is_orphan_vg(pv->vg_name) || pv->pe_alloc_count)) {
                log_error("Assertion failed: can't _pv_write non-orphan PV "
                          "(in VG %s)", pv->vg_name);
                return 0;
@@ -3574,7 +3575,7 @@ int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv)
                return 0;
        }
 
-       if (!pv_write(cmd, pv)) {
+       if (!pv_write(cmd, pv, 0)) {
                log_error("Failed to clear metadata from physical "
                          "volume \"%s\" after removal from \"%s\"",
                          pv_dev_name(pv), old_vg_name);
index 956cc1a1515bfc94c80d1515c3e25bfa855f8f09..1982711d0bffcffa1b6d02cabb6727ea1e66afcb 100644 (file)
@@ -192,6 +192,7 @@ unsigned mda_is_ignored(struct metadata_area *mda);
 void mda_set_ignored(struct metadata_area *mda, unsigned ignored);
 unsigned mda_locns_match(struct metadata_area *mda1, struct metadata_area *mda2);
 void vg_set_fid(struct volume_group *vg, struct format_instance *fid);
+/* FIXME: Add generic interface for mda counts based on given key. */
 int fid_add_mda(struct format_instance *fid, struct metadata_area *mda,
                const char *key, size_t key_len, const unsigned sub_key);
 int fid_add_mdas(struct format_instance *fid, struct dm_list *mdas,
index 254cf91324a368ce46674aa2096500de9625d5e1..58dd64947a91b3087c450879974d1483d4cd09cc 100644 (file)
@@ -140,7 +140,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
 
                        pv->vg_name = pv->fmt->orphan_vg_name;
                        pv->pe_alloc_count = 0;
-                       if (!(pv_write(cmd, pv))) {
+                       if (!(pv_write(cmd, pv, 0))) {
                                log_error("pv_write with new uuid failed "
                                          "for %s.", pv_name);
                                return 0;
@@ -162,7 +162,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
                        return 0;
                }
                backup(vg);
-       } else if (!(pv_write(cmd, pv))) {
+       } else if (!(pv_write(cmd, pv, 0))) {
                log_error("Failed to store physical volume \"%s\"",
                          pv_name);
                return 0;
index 636c0adaae40efc056b98969fee4bcb9bf54e60d..43c0b2ec6b29cfdf409f44b22baeadfc16cc5de2 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "tools.h"
+#include "metadata.h"
 
 struct pvresize_params {
        uint64_t new_size;
@@ -96,6 +97,16 @@ static int _pv_resize_single(struct cmd_context *cmd,
                goto_out;
 
        log_verbose("Updating physical volume \"%s\"", pv_name);
+
+       /* Write PV label only if this an orphan PV or it has 2nd mda. */
+       if ((is_orphan_vg(vg_name) ||
+           fid_get_mda_indexed(vg->fid, (const char *) &pv->id, ID_LEN, 1)) &&
+           !pv_write(cmd, pv, 1)) {
+               log_error("Failed to store physical volume \"%s\"",
+                         pv_name);
+               goto out;
+       }
+
        if (!is_orphan_vg(vg_name)) {
                if (!vg_write(vg) || !vg_commit(vg)) {
                        log_error("Failed to store physical volume \"%s\" in "
@@ -103,10 +114,6 @@ static int _pv_resize_single(struct cmd_context *cmd,
                        goto out;
                }
                backup(vg);
-       } else if (!(pv_write(cmd, pv))) {
-               log_error("Failed to store physical volume \"%s\"",
-                         pv_name);
-               goto out;
        }
 
        log_print("Physical volume \"%s\" changed", pv_name);
index 48e3d59758aab0e9d29e83f556db700aeb704160..5c42f3bc1208e7fd9090ef5a6681a2257ecdf414 100644 (file)
@@ -151,7 +151,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
 
                log_very_verbose("Writing physical volume data to disk \"%s\"",
                                 pv_dev_name(pv));
-               if (!(pv_write(cmd, pv))) {
+               if (!(pv_write(cmd, pv, 0))) {
                        log_error("Failed to write physical volume \"%s\"",
                                  pv_dev_name(pv));
                        log_error("Use pvcreate and vgcfgrestore to repair "
index 8d3cb1cd0f4b05435a70934973aef1b4fb52566b..d497c762a1b25e6856b5d3bde6f4e7508ea34612 100644 (file)
@@ -438,7 +438,7 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
                goto bad;
        }
 
-       if (!pv_write(cmd, pv)) {
+       if (!pv_write(cmd, pv, 0)) {
                log_error("Failed to clear metadata from physical "
                          "volume \"%s\" "
                          "after removal from \"%s\"", name, vg->name);
This page took 0.055395 seconds and 5 git commands to generate.