]> sourceware.org Git - lvm2.git/commitdiff
Implement vgextend --restoremissing (BZ 537913), which makes it possible to
authorPetr Rockai <prockai@redhat.com>
Wed, 13 Oct 2010 10:34:31 +0000 (10:34 +0000)
committerPetr Rockai <prockai@redhat.com>
Wed, 13 Oct 2010 10:34:31 +0000 (10:34 +0000)
re-add a physical volume that has gone missing previously, due to a transient
device failure, without re-initialising it.

Signed-off-by: Petr Rockai <prockai@redhat.com>
Reviewed-by: Alasdair Kergon <agk@redhat.com>
man/vgextend.8.in
tools/args.h
tools/commands.h
tools/vgextend.c

index fffb17672757a10de116ca8806c75a8ec8fc4fb9..4ae2f089a5b20eeaa90dd5ab88116f30c8a75755 100644 (file)
@@ -4,6 +4,7 @@ vgextend \- add physical volumes to a volume group
 .SH SYNOPSIS
 .B vgextend
 [\-A|\-\-autobackup y|n] [\-d|\-\-debug] [\-h|\-?|\-\-help] 
+[\-\-restoremissing]
 [\-f|\-\-force]
 [\-t|\-\-test]
 [\-v|\-\-verbose]
@@ -12,7 +13,10 @@ VolumeGroupName PhysicalDevicePath [PhysicalDevicePath...]
 .SH DESCRIPTION
 vgextend allows you to add one or more initialized physical volumes ( see
 .B pvcreate(8)
-) to an existing volume group to extend it in size.
+) to an existing volume group to extend it in size. Moreover, it allows you to
+re-add a physical volume that has gone missing previously, due to a transient
+device failure, without re-initialising it. Use vgextend \-\-restoremissing to
+that effect.
 .sp
 If \fIPhysicalDevicePath\fP was not previously configured for LVM with
 \fBpvcreate (8)\fP, the device will be initialized with the same
index 91d7b0957b6cc59b0849472d1f75bd35c8fc1d3b..4920290fd29633ec2adea519e0329f102439497e 100644 (file)
@@ -38,6 +38,7 @@ arg(segments_ARG, '\0', "segments", NULL, 0)
 arg(units_ARG, '\0', "units", string_arg, 0)
 arg(nosuffix_ARG, '\0', "nosuffix", NULL, 0)
 arg(removemissing_ARG, '\0', "removemissing", NULL, 0)
+arg(restoremissing_ARG, '\0', "restoremissing", NULL, 0)
 arg(abort_ARG, '\0', "abort", NULL, 0)
 arg(addtag_ARG, '\0', "addtag", tag_arg, 0)
 arg(deltag_ARG, '\0', "deltag", tag_arg, 0)
index 1c113201dc27387d4486187dcc03b459ba7313fe..8e3c5d6ce95ddb5d66db9cad18b1b28483b74882 100644 (file)
@@ -848,6 +848,7 @@ xx(vgextend,
    0,
    "vgextend\n"
    "\t[-A|--autobackup y|n]\n"
+   "\t[--restoremissing]\n"
    "\t[-d|--debug]\n"
    "\t[-f|--force]\n"
    "\t[-h|--help]\n"
@@ -860,7 +861,8 @@ xx(vgextend,
    autobackup_ARG, test_ARG,
    force_ARG, yes_ARG, zero_ARG, labelsector_ARG, metadatatype_ARG,
    metadatasize_ARG, pvmetadatacopies_ARG, metadatacopies_ARG,
-   metadataignore_ARG, dataalignment_ARG, dataalignmentoffset_ARG)
+   metadataignore_ARG, dataalignment_ARG, dataalignmentoffset_ARG,
+   restoremissing_ARG)
 
 xx(vgimport,
    "Register exported volume group with system",
index 81bae186c69f408dd9625c6cf4390fd0c022fdb1..2ae24f7d19f6f70513c75af1f30d6c81b8937f06 100644 (file)
 
 #include "tools.h"
 
+static int _restore_pv(struct volume_group *vg, char *pv_name)
+{
+       struct pv_list *pvl = NULL;
+       pvl = find_pv_in_vg(vg, pv_name);
+       if (!pvl) {
+               log_warn("WARNING: PV %s not found in VG %s", pv_name, vg->name);
+               return 0;
+       }
+
+       if (!(pvl->pv->status & MISSING_PV)) {
+               log_warn("WARNING: PV %s was not missing in VG %s", pv_name, vg->name);
+               return 0;
+       }
+
+       if (!pvl->pv->dev) {
+               log_warn("WARNING: The PV %s is still missing.", pv_name);
+               return 0;
+       }
+
+       pvl->pv->status &= ~MISSING_PV;
+       return 1;
+}
+
 int vgextend(struct cmd_context *cmd, int argc, char **argv)
 {
        char *vg_name;
        struct volume_group *vg = NULL;
        int r = ECMD_FAILED;
        struct pvcreate_params pp;
+       int fixed = 0, i = 0;
 
        if (!argc) {
                log_error("Please enter volume group name and "
@@ -42,6 +66,9 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
                return EINVALID_CMD_LINE;
        }
 
+       if (arg_count(cmd, restoremissing_ARG))
+               cmd->handles_missing_pvs = 1;
+
        log_verbose("Checking for volume group \"%s\"", vg_name);
        vg = vg_read_for_update(cmd, vg_name, NULL, 0);
        if (vg_read_error(vg)) {
@@ -50,41 +77,52 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
                return ECMD_FAILED;
        }
 
-       if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
-               log_error("Can't get lock for orphan PVs");
-               unlock_and_release_vg(cmd, vg, vg_name);
-               return ECMD_FAILED;
-       }
-
        if (!archive(vg))
                goto_bad;
 
-       if (arg_count(cmd, metadataignore_ARG) &&
-           (vg_mda_copies(vg) != VGMETADATACOPIES_UNMANAGED) &&
-           (pp.force == PROMPT) &&
-           yes_no_prompt("Override preferred number of copies "
+       if (arg_count(cmd, restoremissing_ARG)) {
+               for (i = 0; i < argc; ++i) {
+                       if (_restore_pv(vg, argv[i]))
+                               ++ fixed;
+               }
+               if (!fixed) {
+                       log_error("No PV has been restored.");
+                       goto_bad;
+               }
+       } else { /* no --restore, normal vgextend */
+               if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
+                       log_error("Can't get lock for orphan PVs");
+                       unlock_and_release_vg(cmd, vg, vg_name);
+                       return ECMD_FAILED;
+               }
+
+               if (arg_count(cmd, metadataignore_ARG) &&
+                   (vg_mda_copies(vg) != VGMETADATACOPIES_UNMANAGED) &&
+                   (pp.force == PROMPT) &&
+                   yes_no_prompt("Override preferred number of copies "
                          "of VG %s metadata? [y/n]: ",
-                         vg_name) == 'n') {
-               log_error("Volume group %s not changed", vg_name);
-               goto_bad;
-       }
+                                 vg_name) == 'n') {
+                       log_error("Volume group %s not changed", vg_name);
+                       goto_bad;
+               }
 
-       /* extend vg */
-       if (!vg_extend(vg, argc, argv, &pp))
-               goto_bad;
+               /* extend vg */
+               if (!vg_extend(vg, argc, argv, &pp))
+                       goto_bad;
 
-       if (arg_count(cmd, metadataignore_ARG) &&
-           (vg_mda_copies(vg) != VGMETADATACOPIES_UNMANAGED) &&
-           (vg_mda_copies(vg) != vg_mda_used_count(vg))) {
-               log_warn("WARNING: Changing preferred number of copies of VG %s "
+               if (arg_count(cmd, metadataignore_ARG) &&
+                   (vg_mda_copies(vg) != VGMETADATACOPIES_UNMANAGED) &&
+                   (vg_mda_copies(vg) != vg_mda_used_count(vg))) {
+                       log_warn("WARNING: Changing preferred number of copies of VG %s "
                         "metadata from %"PRIu32" to %"PRIu32, vg_name,
-                        vg_mda_copies(vg), vg_mda_used_count(vg));
-               vg_set_mda_copies(vg, vg_mda_used_count(vg));
-       }
+                                vg_mda_copies(vg), vg_mda_used_count(vg));
+                       vg_set_mda_copies(vg, vg_mda_used_count(vg));
+               }
 
-       /* ret > 0 */
-       log_verbose("Volume group \"%s\" will be extended by %d new "
-                   "physical volumes", vg_name, argc);
+               /* ret > 0 */
+               log_verbose("Volume group \"%s\" will be extended by %d new "
+                           "physical volumes", vg_name, argc);
+       }
 
        /* store vg on disk(s) */
        if (!vg_write(vg) || !vg_commit(vg))
This page took 0.044527 seconds and 5 git commands to generate.