Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save adisheshsm/0262151b25c4a14d2893e49e235eeba7 to your computer and use it in GitHub Desktop.
Save adisheshsm/0262151b25c4a14d2893e49e235eeba7 to your computer and use it in GitHub Desktop.
lvm merge
#!/bin/bash
#
# How to prepare:
# - ensure that the lvm thin pool is big enough
# - backup any (most likely /boot and /boot/efi) device with:
# # mkdir /restoredev
# # dev=<device>; dd if="$dev" of=/restoredev/$(systemd-escape -p "$dev")
# - make a thin snapshot
# - remove /restoredev
#
# If the thin snapshot is tagged with the <tag> specified with rd.lvm.mergetags=<tag>
# dracut will
# - make a copy of the snapshot
# - merge it back to the original
# - rename the copy back to the name of the snapshot
# - if /restordev appears in the root, then it will restore the images found in
# that directory. This can be used to restore /boot and /boot/efi
#
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
do_merge() {
local _conffix
for tag in $(getargs rd.lvm.mergetags); do
lvm vgs --noheadings -o vg_name | \
while read -r vg || [[ -n $vg ]]; do
unset LVS
declare -a LVS
lvs=$(lvm lvs --noheadings -o lv_name "$vg")
for lv in $lvs; do
tags=$(trim "$(lvm lvs --noheadings -o lv_tags "$vg/$lv")")
strstr ",${tags}," ",${tag}," || continue
if [[ -z $_conffix ]]; then
sed -i -e 's/\(^[[:space:]]*\)locking_type[[:space:]]*=[[:space:]]*[[:digit:]]/\1locking_type = 1/' \
/etc/lvm/lvm.conf
_conffix=1
fi
info "Creating backup ${lv}_dracutsnap of $vg/$lv"
lvm lvcreate -pr -s "$vg/$lv" --name "${lv}_dracutsnap"
info "Merging back $vg/$lv to the original LV"
lvm lvconvert --merge "$vg/$lv"
LVS+=($lv)
done
udevadm settle
lvm vgchange -an "$vg"
udevadm settle
lvm vgchange -ay "$vg"
udevadm settle
for lv in "${LVS[@]}"; do
info "Renaming ${lv}_dracutsnap backup to $vg/$lv"
lvm lvrename "$vg" "${lv}_dracutsnap" "${lv}"
done
done
done
systemctl start sysroot.mount
if [[ -d /sysroot/restoredev ]]; then
(
if cd /sysroot/restoredev; then
for i in *; do
target=$(systemd-escape -pu "$i")
if ! [[ -b $target ]]; then
warn "Not restoring $target, as the device does not exist"
continue
fi
if ! umount "$target" &> /dev/null; then
error "umount '$target' failed"
continue
fi
info "Restoring $target"
dd if="$i" of="$target" |& vinfo
done
fi
)
fi
systemctl stop sysroot.mount
info "Rebooting"
reboot
}
if getarg rd.lvm.mergetags; then
do_merge
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment