diff options
Diffstat (limited to '')
-rwxr-xr-x | modules.d/80lvmmerge/lvmmerge.sh | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/modules.d/80lvmmerge/lvmmerge.sh b/modules.d/80lvmmerge/lvmmerge.sh new file mode 100755 index 0000000..b8dbfa8 --- /dev/null +++ b/modules.d/80lvmmerge/lvmmerge.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +do_merge() { + sed -i -e 's/\(^[[:space:]]*\)locking_type[[:space:]]*=[[:space:]]*[[:digit:]]/\1locking_type = 1/' \ + /etc/lvm/lvm.conf + + systemctl --no-block stop sysroot.mount + swapoff -a + umount -R /sysroot + + 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 + lvm lvchange -an "$vg/$lv" + + tags=$(trim "$(lvm lvs --noheadings -o lv_tags "$vg/$lv")") + strstr ",${tags}," ",${tag}," || continue + + if ! lvm lvs --noheadings -o lv_name "${vg}/${lv}_dracutsnap" &> /dev/null; then + info "Creating backup ${lv}_dracutsnap of ${vg}/${lv}" + lvm lvcreate -pr -s "${vg}/${lv}" --name "${lv}_dracutsnap" + fi + lvm lvchange --addtag "$tag" "${vg}/${lv}_dracutsnap" + + info "Merging back ${vg}/${lv} to the original LV" + lvm lvconvert --merge "${vg}/${lv}" + + LVS+=("$lv") + done + + systemctl --no-block stop sysroot.mount + udevadm settle + + for ((i = 0; i < 100; i++)); do + lvm vgchange -an "$vg" && break + sleep 0.5 + done + + 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 + udevadm settle + done + done + + systemctl --no-block reset-failed systemd-fsck-root + systemctl --no-block start systemd-fsck-root + systemctl --no-block reset-failed sysroot.mount + systemctl --no-block start sysroot.mount + + for ((i = 0; i < 100; i++)); do + [[ -d /sysroot/dev ]] && break + sleep 0.5 + systemctl --no-block start sysroot.mount + done + + if [[ -d /sysroot/restoredev ]]; then + ( + if cd /sysroot/restoredev; then + # restore devices and partitions + 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 + + # Just in case + umount "$target" &> /dev/null + + info "Restoring $target" + dd if="$i" of="$target" |& vinfo + done + fi + ) + mount -o remount,rw /sysroot + rm -fr /sysroot/restoredev + fi + info "Rebooting" + reboot +} + +if getarg rd.lvm.mergetags; then + do_merge +fi |