mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +03:00
Implement vgextend --restoremissing (BZ 537913), which makes it possible to
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>
This commit is contained in:
parent
7dddc57bde
commit
49908a9a33
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -15,12 +15,36 @@
|
||||
|
||||
#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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user