b14857c
From 5d5d1db3ca621eb80b9481924d1fc470571cfc09 Mon Sep 17 00:00:00 2001
b14857c
From: Pavel Cahyna <pcahyna@redhat.com>
b14857c
Date: Mon, 30 Aug 2021 12:00:43 +0200
b14857c
Subject: [PATCH] Avoid vgcfgrestore on thin volumes/pools
b14857c
b14857c
and any other unsupported volume types.
b14857c
b14857c
vgcfgrestore is not supposed to be able to restore any logical volumes
b14857c
that use kernel metadata. All volume types except linear and striped use
b14857c
kernel metadata. Main purpose of vgcfgrestore (with mandatory --force
b14857c
option) is to let users fix existing thin-pool, not to recreate the pool
b14857c
on empty disks. Do not even try vgcfgrestore on VGs that need any kernel
b14857c
metadata, because it might lead to an inconsistent state (if there are
b14857c
data that the kernel might interpret as LV metadata present on the disks).
b14857c
b14857c
For VGs that have any volume with kernel metadata and are thus
b14857c
unsupported by vgcfgrestore, switch automatically to LV creation using
b14857c
lvcreate, similarly to MIGRATION_MODE.
b14857c
b14857c
Avoid vgcfgrestore --force entirely, since it should not be needed now.
b14857c
b14857c
This mostly reverts changes in commits
b14857c
311bfb3da1d5e47a2ff144123a2457e634f67893 and
b14857c
1b779abfbf56693877fe666f56253ec623599674. The former code is preserved
b14857c
and gets enabled if FORCE_VGCFGRESTORE=y. This option is on purpose
b14857c
undocumented though and may be removed in the future.
b14857c
---
b14857c
 .../prepare/GNU/Linux/110_include_lvm_code.sh |  8 +++++-
b14857c
 usr/share/rear/lib/layout-functions.sh        | 26 +++++++++++++++++++
b14857c
 2 files changed, 33 insertions(+), 1 deletion(-)
b14857c
d6e39f5
diff --git a/usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh b/usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh
b14857c
index 5babce228..54a55e688 100644
d6e39f5
--- a/usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh
d6e39f5
+++ b/usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh
d6e39f5
@@ -83,7 +83,7 @@ EOF
d6e39f5
     # '--mirrorlog', etc.
d6e39f5
     # Also, we likely do not support every layout yet (e.g. 'cachepool').
d6e39f5
 
d6e39f5
-    if ! is_true "$MIGRATION_MODE" ; then
d6e39f5
+    if ! is_true "$MIGRATION_MODE" && lvmgrp_supports_vgcfgrestore "$vgrp" ; then
d6e39f5
         cat >> "$LAYOUT_CODE" <
d6e39f5
 LogPrint "Restoring LVM VG '$vg'"
d6e39f5
 if [ -e "$vgrp" ] ; then
b14857c
@@ -100,6 +100,9 @@ if lvm vgcfgrestore -f "$VAR_DIR/layout/lvm/${vg}.cfg" $vg >&2 ; then
b14857c
     create_volume_group=( \$( RmInArray "$vg" "\${create_volume_group[@]}" ) )
b14857c
     create_logical_volumes=( \$( RmInArray "$vg" "\${create_logical_volumes[@]}" ) )
d6e39f5
 
d6e39f5
+EOF
d6e39f5
+        if is_true "${FORCE_VGCFGRESTORE-no}"; then
d6e39f5
+            cat >> "$LAYOUT_CODE" <
d6e39f5
 #
d6e39f5
 # It failed ... restore layout using 'vgcfgrestore --force', but then remove Thin volumes, they are broken
d6e39f5
 #
b14857c
@@ -124,6 +127,9 @@ elif lvm vgcfgrestore --force -f "$VAR_DIR/layout/lvm/${vg}.cfg" $vg >&2 ; then
b14857c
     create_volume_group=( \$( RmInArray "$vg" "\${create_volume_group[@]}" ) )
b14857c
     create_thin_volumes_only+=( "$vg" )
d6e39f5
  
d6e39f5
+EOF
d6e39f5
+        fi
d6e39f5
+        cat >> "$LAYOUT_CODE" <
d6e39f5
 #
d6e39f5
 # It failed also ... restore using 'vgcreate/lvcreate' commands
d6e39f5
 #
d6e39f5
diff --git a/usr/share/rear/lib/layout-functions.sh b/usr/share/rear/lib/layout-functions.sh
b14857c
index 249ad0cd6..77107ae63 100644
d6e39f5
--- a/usr/share/rear/lib/layout-functions.sh
d6e39f5
+++ b/usr/share/rear/lib/layout-functions.sh
b14857c
@@ -1387,4 +1387,30 @@ delete_dummy_partitions_and_resize_real_ones() {
d6e39f5
     last_partition_number=0
d6e39f5
 }
d6e39f5
 
d6e39f5
+# vgcfgrestore can properly restore only volume groups that do not use
d6e39f5
+# any kernel metadata. All volume types except linear and striped use
d6e39f5
+# kernel metadata.
d6e39f5
+# Check whether a VG (given as /dev/<vgname> in the first argument)
d6e39f5
+# doesn't contain any LVs that use kernel metadata.
d6e39f5
+# If the function returns true, we can safely use vgcfgrestore to restore the VG.
d6e39f5
+function lvmgrp_supports_vgcfgrestore() {
d6e39f5
+    if is_true "${FORCE_VGCFGRESTORE-no}"; then
d6e39f5
+        # If we are willing to use vgcfgrestore --force and then remove broken volumes,
d6e39f5
+        # then everything can be considered supported. Don't do it by default though.
d6e39f5
+        return 0
d6e39f5
+    fi
d6e39f5
+
d6e39f5
+    local lvmvol vgrp lvname size layout kval
d6e39f5
+
d6e39f5
+    local supported_layouts=("linear" "striped")
d6e39f5
+
d6e39f5
+    while read lvmvol vgrp lvname size layout kval; do
d6e39f5
+        [ "$vgrp" == "$1" ] || BugError "vgrp '$vgrp' != '$1'"
d6e39f5
+        if ! IsInArray $layout "${supported_layouts[@]}"; then
d6e39f5
+            LogPrint "Layout '$layout' of LV '$lvname' in VG '$vgrp' not supported by vgcfgrestore"
d6e39f5
+            return 1
d6e39f5
+        fi
d6e39f5
+    done < <(grep "^lvmvol $1 " "$LAYOUT_FILE")
d6e39f5
+}
d6e39f5
+
d6e39f5
 # vim: set et ts=4 sw=4: