mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
vgchange: allow changing system ID with majority of PVs
when used with --majoritypvs. This allows the fail-over of a VG between systems by changing the VG system ID when a PV is missing.
This commit is contained in:
parent
da44f2b6fe
commit
aa85ed1784
@ -22,7 +22,7 @@ print_lvmlocal() {
|
||||
|
||||
. lib/inittest
|
||||
|
||||
aux prepare_devs 1
|
||||
aux prepare_devs 5
|
||||
|
||||
SIDFILE="etc/lvm_test.conf"
|
||||
LVMLOCAL="etc/lvmlocal.conf"
|
||||
@ -541,6 +541,73 @@ echo "$SID1" > "$SIDFILE"
|
||||
clear_df_systemid
|
||||
vgremove $vg1
|
||||
|
||||
# vgchange --systemid --majoritypvs
|
||||
SID1=sidfoofile1
|
||||
SID2=sidfoofile2
|
||||
rm -f "$LVMLOCAL"
|
||||
echo "$SID1" > "$SIDFILE"
|
||||
clear_df_systemid
|
||||
aux lvmconf "global/system_id_source = file" \
|
||||
"global/system_id_file = \"$SIDFILE\""
|
||||
# create a vg
|
||||
vgcreate $vg1 "$dev1" "$dev2" "$dev3"
|
||||
vgcreate $vg2 "$dev4" "$dev5"
|
||||
# normal vgs sees the vg
|
||||
# change the local system_id, making the vg foreign
|
||||
echo "$SID2" > "$SIDFILE"
|
||||
clear_df_systemid
|
||||
# normal vgs doesn't see the vg
|
||||
vgs >err
|
||||
not grep $vg1 err
|
||||
not grep $vg2 err
|
||||
# using --foreign we can see the vg
|
||||
vgs --foreign >err
|
||||
grep $vg1 err
|
||||
grep $vg2 err
|
||||
# cannot clear the system_id of the foreign vg
|
||||
not vgchange --yes --systemid "" $vg1
|
||||
not vgchange --yes --systemid "" $vg2
|
||||
# cannot set the system_id of the foreign vg
|
||||
not vgchange --yes --systemid foo $vg1
|
||||
not vgchange --yes --systemid foo $vg2
|
||||
# we are local node SID2, foreign node is SID1
|
||||
# use extra_system_ids to take over the foreign vg, making it local
|
||||
vgchange --config "local/extra_system_ids=[\"${SID1}\"]" --systemid $SID2 $vg1
|
||||
vgs $vg1
|
||||
# make it foreign again
|
||||
vgchange --yes --systemid sidfoofile1 $vg1
|
||||
not vgs $vg1
|
||||
# both vgs are foreign, drop dev1/dev4 so both vgs are missing a device
|
||||
aux hide_dev "$dev1"
|
||||
aux hide_dev "$dev4"
|
||||
not pvs "$dev1"
|
||||
not pvs "$dev4"
|
||||
# neither VG can be changed because both are missing a dev
|
||||
not vgchange --config "local/extra_system_ids=[\"${SID1}\"]" --systemid $SID2 $vg1
|
||||
not vgchange --config "local/extra_system_ids=[\"${SID1}\"]" --systemid $SID2 $vg2
|
||||
# using majoritypvs, vg1 can be changed because 2 of 3 PVs exist
|
||||
vgchange --majoritypvs --config "local/extra_system_ids=[\"${SID1}\"]" --systemid $SID2 $vg1
|
||||
vgs $vg1
|
||||
# using majoritypvs, vg2 cannot be changed because 1 of 2 PVs exist
|
||||
not vgchange --majoritypvs --config "local/extra_system_ids=[\"${SID1}\"]" --systemid $SID2 $vg2
|
||||
not vgs $vg2
|
||||
vgs --foreign $vg2
|
||||
# dev1/dev4 return so we can take over vg2 now
|
||||
# vg1 will complain about stale metadata on dev1
|
||||
aux unhide_dev "$dev1"
|
||||
aux unhide_dev "$dev4"
|
||||
vgs
|
||||
pvs
|
||||
vgchange --majoritypvs --config "local/extra_system_ids=[\"${SID1}\"]" --systemid $SID2 $vg2
|
||||
vgs $vg2
|
||||
# update metadata on dev1
|
||||
vgck --updatemetadata $vg1
|
||||
vgs $vg1
|
||||
clear_df_systemid
|
||||
vgremove $vg1
|
||||
vgremove $vg2
|
||||
|
||||
|
||||
# vgcfgbackup backs up foreign vg with --foreign
|
||||
SID1=sidfoofile1
|
||||
SID2=sidfoofile2
|
||||
|
@ -416,6 +416,10 @@ arg(logonly_ARG, '\0', "logonly", 0, 0, 0,
|
||||
arg(longhelp_ARG, '\0', "longhelp", 0, 0, 0,
|
||||
"Display long help text.\n")
|
||||
|
||||
arg(majoritypvs_ARG, '\0', "majoritypvs", 0, 0, 0,
|
||||
"Change the VG system ID if the majority of PVs in the VG\n"
|
||||
"are present (one more than half).\n")
|
||||
|
||||
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", sizekb_VAL, 0, 0,
|
||||
"Sets the maximum recovery rate for a RAID LV. The rate value\n"
|
||||
"is an amount of data per second for each device in the array.\n"
|
||||
|
@ -1767,7 +1767,7 @@ ID: vgchange_refresh
|
||||
DESC: Reactivate LVs using the latest metadata.
|
||||
|
||||
vgchange --systemid String VG|Tag|Select
|
||||
OO: --select String
|
||||
OO: --select String, --majoritypvs
|
||||
ID: vgchange_systemid
|
||||
DESC: Change the system ID of a VG.
|
||||
|
||||
|
@ -1383,6 +1383,24 @@ static int _vgchange_systemid_single(struct cmd_context *cmd, const char *vg_nam
|
||||
struct volume_group *vg,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
if (arg_is_set(cmd, majoritypvs_ARG)) {
|
||||
struct pv_list *pvl;
|
||||
int missing_pvs = 0;
|
||||
int found_pvs = 0;
|
||||
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
if (!pvl->pv->dev)
|
||||
missing_pvs++;
|
||||
else
|
||||
found_pvs++;
|
||||
}
|
||||
if (found_pvs <= missing_pvs) {
|
||||
log_error("Cannot change system ID without the majority of PVs (found %d of %d)",
|
||||
found_pvs, found_pvs+missing_pvs);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_vgchange_system_id(cmd, vg))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
@ -1415,6 +1433,9 @@ int vgchange_systemid_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, majoritypvs_ARG))
|
||||
cmd->handles_missing_pvs = 1;
|
||||
|
||||
ret = process_each_vg(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE, 0, handle, &_vgchange_systemid_single);
|
||||
|
||||
destroy_processing_handle(cmd, handle);
|
||||
|
Loading…
Reference in New Issue
Block a user