Skip to content

Commit

Permalink
Added support for LVM <= 2.02.98
Browse files Browse the repository at this point in the history
  • Loading branch information
rmetrich committed May 22, 2018
1 parent 311bfb3 commit 84f03a4
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 62 deletions.
78 changes: 52 additions & 26 deletions usr/share/rear/layout/prepare/GNU/Linux/110_include_lvm_code.sh
Expand Up @@ -6,6 +6,11 @@ if ! has_binary lvm; then
return
fi

#
# Refer to usr/share/rear/layout/save/GNU/Linux/220_lvm_layout.sh for the
# corresponding information collected during 'mkrescue'.
#

# Test for features in lvm.
# Versions higher than 2.02.73 need --norestorefile if no UUID/restorefile.
FEATURE_LVM_RESTOREFILE=
Expand All @@ -25,18 +30,20 @@ create_lvmdev() {
local lvmdev vgrp device uuid junk
read lvmdev vgrp device uuid junk < <(grep "^lvmdev.*${1#pv:} " "$LAYOUT_FILE")

local vg=${vgrp#/dev/}

(
echo "LogPrint \"Creating LVM PV $device\""

### Work around automatic volume group activation leading to active disks
echo "lvm vgchange -a n ${vgrp#/dev/} || true"
echo "lvm vgchange -a n $vg || true"

local uuidopt=""
local restorefileopt=""

if ! is_true "$MIGRATION_MODE" && test -e "$VAR_DIR/layout/lvm/${vgrp#/dev/}.cfg" ; then
if ! is_true "$MIGRATION_MODE" && test -e "$VAR_DIR/layout/lvm/${vg}.cfg" ; then
# we have a restore file
restorefileopt=" --restorefile $VAR_DIR/layout/lvm/${vgrp#/dev/}.cfg"
restorefileopt=" --restorefile $VAR_DIR/layout/lvm/${vg}.cfg"
else
if [ -n "$FEATURE_LVM_RESTOREFILE" ] ; then
restorefileopt=" --norestorefile"
Expand All @@ -55,6 +62,8 @@ create_lvmgrp() {
local lvmgrp vgrp extentsize junk
read lvmgrp vgrp extentsize junk < <(grep "^lvmgrp $1 " "$LAYOUT_FILE")

local vg=${vgrp#/dev/}

cat >> "$LAYOUT_CODE" <<EOF
create_volume_group=1
create_logical_volumes=1
Expand All @@ -73,15 +82,15 @@ EOF

if ! is_true "$MIGRATION_MODE" ; then
cat >> "$LAYOUT_CODE" <<EOF
LogPrint "Restoring LVM VG ${vgrp#/dev/}"
LogPrint "Restoring LVM VG '$vg'"
if [ -e "$vgrp" ] ; then
rm -rf "$vgrp"
fi
#
# Restore layout using 'vgcfgrestore', this may fail if there are Thin volumes
#
if lvm vgcfgrestore -f "$VAR_DIR/layout/lvm/${vgrp#/dev/}.cfg" ${vgrp#/dev/} >&2 ; then
lvm vgchange --available y ${vgrp#/dev/} >&2
if lvm vgcfgrestore -f "$VAR_DIR/layout/lvm/${vg}.cfg" $vg >&2 ; then
lvm vgchange --available y $vg >&2
LogPrint "Sleeping 3 seconds to let udev or systemd-udevd create their devices..."
sleep 3 >&2
Expand All @@ -91,11 +100,11 @@ if lvm vgcfgrestore -f "$VAR_DIR/layout/lvm/${vgrp#/dev/}.cfg" ${vgrp#/dev/} >&2
#
# It failed ... restore layout using 'vgcfgrestore --force', but then remove Thin volumes, they are broken
#
elif lvm vgcfgrestore --force -f "$VAR_DIR/layout/lvm/${vgrp#/dev/}.cfg" ${vgrp#/dev/} >&2 ; then
elif lvm vgcfgrestore --force -f "$VAR_DIR/layout/lvm/${vg}.cfg" $vg >&2 ; then
lvm lvs --noheadings -o lv_name,vg_name,lv_layout | while read lv vg layout ; do
# Consider LVs for our VG only
[ \$vg == "${vgrp#/dev/}" ] || continue
[ \$vg == "$vg" ] || continue
# Consider Thin Pools only
[[ ,\$layout, == *,thin,* ]] && [[ ,\$layout, == *,pool,* ]] || continue
# Remove twice, the first time it fails because of thin volumes in the pool
Expand All @@ -121,12 +130,12 @@ EOF

cat >> "$LAYOUT_CODE" <<EOF
if [ \$create_volume_group -eq 1 ] ; then
LogPrint "Creating LVM VG ${vgrp#/dev/}; Warning: some properties may not be preserved..."
LogPrint "Creating LVM VG '$vg'; Warning: some properties may not be preserved..."
if [ -e "$vgrp" ] ; then
rm -rf "$vgrp"
fi
lvm vgcreate --physicalextentsize ${extentsize}k ${vgrp#/dev/} ${devices[@]} >&2
lvm vgchange --available y ${vgrp#/dev/} >&2
lvm vgcreate --physicalextentsize ${extentsize}k $vg ${devices[@]} >&2
lvm vgchange --available y $vg >&2
fi
EOF
}
Expand Down Expand Up @@ -154,6 +163,7 @@ create_lvmvol() {
done

local is_thin=0
local is_raidunknown=0

if [[ ,$layout, == *,thin,* ]] ; then

Expand All @@ -162,13 +172,13 @@ create_lvmvol() {
if [[ ,$layout, == *,pool,* ]] ; then
# Thin Pool

lvopts="${lvopts:+$lvopts }--type thin-pool -L $size"
lvopts="${lvopts:+$lvopts }--type thin-pool -L $size --thinpool $lv"

else
# Thin Volume within Thin Pool

if [[ ,$layout, == *,sparse,* ]] ; then
lvopts="${lvopts:+$lvopts }-V $size"
lvopts="${lvopts:+$lvopts }-V $size -n ${lvname}"
else
BugError "Unsupported Thin LV layout '$layout' for LV '$lv'"
fi
Expand All @@ -177,15 +187,15 @@ create_lvmvol() {

elif [[ ,$layout, == *,linear,* ]] ; then

lvopts="${lvopts:+$lvopts }-L $size"
lvopts="${lvopts:+$lvopts }-L $size -n ${lvname}"

elif [[ ,$layout, == *,mirror,* ]] ; then

lvopts="${lvopts:+$lvopts }--type mirror -L $size"
lvopts="${lvopts:+$lvopts }--type mirror -L $size -n ${lvname}"

elif [[ ,$layout, == *,striped,* ]] ; then

lvopts="${lvopts:+$lvopts }--type striped -L $size"
lvopts="${lvopts:+$lvopts }--type striped -L $size -n ${lvname}"

elif [[ ,$layout, == *,raid,* ]] ; then

Expand All @@ -199,30 +209,46 @@ create_lvmvol() {
fi
done

[ $found -ne 0 ] || BugError "Unsupported LV layout '$layout' found for LV '$lv'"
if [ $found -eq 0 ] ; then
if [[ ,$layout, == *,RAID_UNKNOWNTYPE,* ]] ; then
# Compatibility with older LVM versions (e.g. <= 2.02.98)
is_raidunknown=1
# Don't set '--type', so will be created as a linear volume
else
BugError "Unsupported LV layout '$layout' found for LV '$lv'"
fi
fi

lvopts="${lvopts:+$lvopts }-L $size"
lvopts="${lvopts:+$lvopts }-L $size -n ${lvname}"

else

BugError "Unsupported LV layout '$layout' found for LV '$lv'"

fi

local ifline
local warnraidline

if [ $is_thin -eq 0 ] ; then
cat >> "$LAYOUT_CODE" <<EOF
if [ "\$create_logical_volumes" -eq 1 ] && [ "\$create_thin_volumes_only" -eq 0 ] ; then
EOF
ifline="if [ \"\$create_logical_volumes\" -eq 1 ] && [ \"\$create_thin_volumes_only\" -eq 0 ] ; then"
else
cat >> "$LAYOUT_CODE" <<EOF
if [ "\$create_logical_volumes" -eq 1 ] ; then
EOF
ifline="if [ \"\$create_logical_volumes\" -eq 1 ] ; then"
fi

if [ $is_raidunknown -eq 1 ]; then
warnraidline="LogPrint \"Warning: Don't know how to restore RAID volume '$lv', restoring as linear volume\""
else
warnraidline=""
fi

cat >> "$LAYOUT_CODE" <<EOF
LogPrint "Creating LVM volume ${vgrp#/dev/}/$lvname; Warning: some properties may not be preserved..."
lvm lvcreate $lvopts -n ${lvname} ${vgrp#/dev/} <<<y
$ifline
LogPrint "Creating LVM volume '$vg/$lvname'; Warning: some properties may not be preserved..."
$warnraidline
lvm lvcreate $lvopts $vg <<<y
fi
EOF
Expand Down
130 changes: 95 additions & 35 deletions usr/share/rear/layout/save/GNU/Linux/220_lvm_layout.sh
Expand Up @@ -57,42 +57,102 @@ Log "Saving LVM layout."
## Get all logical volumes
# format: lvmvol <volume_group> <name> <size(bytes)> <layout> [key:value ...]

lvm 8>&- 7>&- lvs --separator=":" --noheadings --units b --nosuffix -o origin,lv_name,vg_name,lv_size,lv_layout,pool_lv,chunk_size,stripes,stripe_size | while read line ; do
# Check for 'lvs' support of lv_layout

if lvm lvs -o lv_layout >/dev/null 2>&1; then

lvm 8>&- 7>&- lvs --separator=":" --noheadings --units b --nosuffix -o origin,lv_name,vg_name,lv_size,lv_layout,pool_lv,chunk_size,stripes,stripe_size | while read line ; do

if [ $header_printed -eq 0 ] ; then
echo "# Format for LVM LVs"
echo "# lvmvol <volume_group> <name> <size(bytes)> <layout> [key:value ...]"
header_printed=1
fi

origin="$(echo "$line" | awk -F ':' '{ print $1 }')"
# Skip snapshots (useless) or caches (dont know how to handle that)
if [ -n "$origin" ] ; then
echo "# Skipped snapshot of cache information '$line'"
continue
fi

lv="$(echo "$line" | awk -F ':' '{ print $2 }')"
vg="$(echo "$line" | awk -F ':' '{ print $3 }')"
size="$(echo "$line" | awk -F ':' '{ print $4 }')"
layout="$(echo "$line" | awk -F ':' '{ print $5 }')"
thinpool="$(echo "$line" | awk -F ':' '{ print $6 }')"
chunksize="$(echo "$line" | awk -F ':' '{ print $7 }')"
stripes="$(echo "$line" | awk -F ':' '{ print $8 }')"
stripesize="$(echo "$line" | awk -F ':' '{ print $9 }')"

kval=""
[ -z "$thinpool" ] || kval="${kval:+$kval }thinpool:$thinpool"
[ $chunksize -eq 0 ] || kval="${kval:+$kval }chunksize:${chunksize}b"
[ $stripesize -eq 0 ] || kval="${kval:+$kval }stripesize:${stripesize}b"
if [[ ,$layout, == *,mirror,* ]] ; then
kval="${kval:+$kval }mirrors:$(($stripes - 1))"
elif [[ ,$layout, == *,striped,* ]] ; then
kval="${kval:+$kval }stripes:$stripes"
fi

echo "lvmvol /dev/$vg $lv ${size}b $layout $kval"
done

else
# Compatibility with older LVM versions (e.g. <= 2.02.98)
# No support for 'lv_layout', too bad, do our best!

lvm 8>&- 7>&- lvs --separator=":" --noheadings --units b --nosuffix -o origin,lv_name,vg_name,lv_size,modules,pool_lv,chunk_size,stripes,stripe_size | while read line ; do

if [ $header_printed -eq 0 ] ; then
echo "# Format for LVM LVs"
echo "# lvmvol <volume_group> <name> <size(bytes)> <layout> [key:value ...]"
header_printed=1
fi

origin="$(echo "$line" | awk -F ':' '{ print $1 }')"
# Skip snapshots (useless) or caches (dont know how to handle that)
if [ -n "$origin" ] ; then
echo "# Skipped snapshot of cache information '$line'"
continue
fi

lv="$(echo "$line" | awk -F ':' '{ print $2 }')"
vg="$(echo "$line" | awk -F ':' '{ print $3 }')"
size="$(echo "$line" | awk -F ':' '{ print $4 }')"
modules="$(echo "$line" | awk -F ':' '{ print $5 }')"
thinpool="$(echo "$line" | awk -F ':' '{ print $6 }')"
chunksize="$(echo "$line" | awk -F ':' '{ print $7 }')"
stripes="$(echo "$line" | awk -F ':' '{ print $8 }')"
stripesize="$(echo "$line" | awk -F ':' '{ print $9 }')"

kval=""
[ -z "$thinpool" ] || kval="${kval:+$kval }thinpool:$thinpool"
[ $chunksize -eq 0 ] || kval="${kval:+$kval }chunksize:${chunksize}b"
[ $stripesize -eq 0 ] || kval="${kval:+$kval }stripesize:${stripesize}b"
if [[ "$modules" == "" ]] ; then
layout="linear"
[ $stripes -eq 0 ] || kval="${kval:+$kval }stripes:$stripes"
elif [[ ,$modules, == *,mirror,* ]] ; then
layout="mirror"
kval="${kval:+$kval }mirrors:$(($stripes - 1))"
elif [[ ,$modules, == *,thin-pool,* ]] ; then
if [ -z "$thinpool" ] ; then
layout="thin,pool"
else
layout="thin,sparse"
fi
elif [[ ,$modules, == *,raid,* ]] ; then
LogPrint "Warning: don't know how to collect RAID information for LV '$lv'. Automatic disk layout recovery may fail."
layout="raid,RAID_UNKNOWNTYPE"
kval="${kval:+$kval }stripes:$stripes"
fi

echo "lvmvol /dev/$vg $lv ${size}b $layout $kval"
done

fi

if [ $header_printed -eq 0 ] ; then
echo "# Format for LVM LVs"
echo "# lvmvol <volume_group> <name> <size(bytes)> <layout> [key:value ...]"
header_printed=1
fi

origin="$(echo "$line" | awk -F ':' '{ print $1 }')"
# Skip snapshots (useless) or caches (dont know how to handle that)
if [ -n "$origin" ] ; then
echo "# Skipped snapshot of cache information '$line'"
continue
fi

lv="$(echo "$line" | awk -F ':' '{ print $2 }')"
vg="$(echo "$line" | awk -F ':' '{ print $3 }')"
size="$(echo "$line" | awk -F ':' '{ print $4 }')"
layout="$(echo "$line" | awk -F ':' '{ print $5 }')"
thinpool="$(echo "$line" | awk -F ':' '{ print $6 }')"
chunksize="$(echo "$line" | awk -F ':' '{ print $7 }')"
stripes="$(echo "$line" | awk -F ':' '{ print $8 }')"
stripesize="$(echo "$line" | awk -F ':' '{ print $9 }')"

kval=""
[ -z "$thinpool" ] || kval="${kval:+$kval }thinpool:$thinpool"
[ $chunksize -eq 0 ] || kval="${kval:+$kval }chunksize:${chunksize}b"
[ $stripesize -eq 0 ] || kval="${kval:+$kval }stripesize:${stripesize}b"
if [[ ,$layout, == *,mirror,* ]] ; then
kval="${kval:+$kval }mirrors:$(($stripes - 1))"
elif [[ ,$layout, == *,striped,* ]] ; then
kval="${kval:+$kval }stripes:$stripes"
fi

echo "lvmvol /dev/$vg $lv ${size}b $layout $kval"
done
) >> $DISKLAYOUT_FILE

# vim: set et ts=4 sw=4:
8 changes: 7 additions & 1 deletion usr/share/rear/prep/GNU/Linux/220_include_lvm_tools.sh
Expand Up @@ -17,5 +17,11 @@ COPY_AS_IS=( "${COPY_AS_IS[@]}"
if lvs --noheadings -o thin_count | grep -q -v "^\s*$" ; then
# There are Thin Pools on the system, include required binaries
PROGS=( "${PROGS[@]}" /usr/sbin/thin_* )
LIBS=( "${LIBS[@]}" /usr/lib64/*lvm2* )
fi

if lvs --noheadings -o modules | grep -q -v "^\s*$" ; then
# There are non-linear LVs on the system, include required libraries
LIBS=( "${LIBS[@]}" /lib64/*lvm2* )
fi

# vim: set et ts=4 sw=4:

0 comments on commit 84f03a4

Please sign in to comment.