summaryrefslogtreecommitdiffstats
path: root/modules.d/90dmsquash-live
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 13:54:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 13:54:25 +0000
commit9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a (patch)
tree2efb72864cc69e174c9c5ee33efb88a5f1553b48 /modules.d/90dmsquash-live
parentInitial commit. (diff)
downloaddracut-9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a.tar.xz
dracut-9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a.zip
Adding upstream version 060+5.upstream/060+5
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules.d/90dmsquash-live')
-rwxr-xr-xmodules.d/90dmsquash-live/apply-live-updates.sh22
-rw-r--r--modules.d/90dmsquash-live/checkisomd5@.service14
-rwxr-xr-xmodules.d/90dmsquash-live/dmsquash-generator.sh80
-rwxr-xr-xmodules.d/90dmsquash-live/dmsquash-live-genrules.sh18
-rwxr-xr-xmodules.d/90dmsquash-live/dmsquash-live-root.sh432
-rwxr-xr-xmodules.d/90dmsquash-live/dmsquash-liveiso-genrules.sh9
-rwxr-xr-xmodules.d/90dmsquash-live/iso-scan.sh38
-rwxr-xr-xmodules.d/90dmsquash-live/module-setup.sh39
-rwxr-xr-xmodules.d/90dmsquash-live/parse-dmsquash-live.sh57
-rwxr-xr-xmodules.d/90dmsquash-live/parse-iso-scan.sh9
10 files changed, 718 insertions, 0 deletions
diff --git a/modules.d/90dmsquash-live/apply-live-updates.sh b/modules.d/90dmsquash-live/apply-live-updates.sh
new file mode 100755
index 0000000..a5a5a39
--- /dev/null
+++ b/modules.d/90dmsquash-live/apply-live-updates.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+if [ -h /dev/root ] && [ -d /run/initramfs/live/updates -o -d /updates ]; then
+ info "Applying updates to live image..."
+ mount -o bind /run "$NEWROOT"/run
+ # avoid overwriting symlinks (e.g. /lib -> /usr/lib) with directories
+ for d in /updates /run/initramfs/live/updates; do
+ [ -d "$d" ] || continue
+ (
+ cd "$d" || return 0
+ find . -depth -type d -exec mkdir -p "$NEWROOT/{}" \;
+ find . -depth \! -type d -exec cp -a "{}" "$NEWROOT/{}" \;
+ )
+ done
+ umount "$NEWROOT"/run
+fi
+# release resources on iso-scan boots with rd.live.ram
+if [ -d /run/initramfs/isoscan ] \
+ && [ -f /run/initramfs/squashed.img -o -f /run/initramfs/rootfs.img ]; then
+ umount --detach-loop /run/initramfs/live
+ umount /run/initramfs/isoscan
+fi
diff --git a/modules.d/90dmsquash-live/checkisomd5@.service b/modules.d/90dmsquash-live/checkisomd5@.service
new file mode 100644
index 0000000..c4ca10f
--- /dev/null
+++ b/modules.d/90dmsquash-live/checkisomd5@.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Media check on %f
+DefaultDependencies=no
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+ExecStart=/bin/checkisomd5 --verbose %f
+StandardInput=tty-force
+StandardOutput=inherit
+StandardError=inherit
+TimeoutSec=0
+SuccessExitStatus=2
diff --git a/modules.d/90dmsquash-live/dmsquash-generator.sh b/modules.d/90dmsquash-live/dmsquash-generator.sh
new file mode 100755
index 0000000..8e3dfe8
--- /dev/null
+++ b/modules.d/90dmsquash-live/dmsquash-generator.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
+
+[ -z "$root" ] && root=$(getarg root=)
+
+# support legacy syntax of passing liveimg and then just the base root
+if getargbool 0 rd.live.image -d -y liveimg; then
+ liveroot="live:$root"
+fi
+
+if [ "${root%%:*}" = "live" ]; then
+ liveroot=$root
+fi
+
+[ "${liveroot%%:*}" = "live" ] || exit 0
+
+case "$liveroot" in
+ live:LABEL=* | LABEL=* | live:UUID=* | UUID=* | live:PARTUUID=* | PARTUUID=* | live:PARTLABEL=* | PARTLABEL=*)
+ root="live:$(label_uuid_to_dev "${root#live:}")"
+ rootok=1
+ ;;
+ live:CDLABEL=* | CDLABEL=*)
+ root="${root#live:}"
+ root="$(echo "$root" | sed 's,/,\\x2f,g;s, ,\\x20,g')"
+ root="live:/dev/disk/by-label/${root#CDLABEL=}"
+ rootok=1
+ ;;
+ live:/*.[Ii][Ss][Oo] | /*.[Ii][Ss][Oo])
+ root="${root#live:}"
+ root="liveiso:${root}"
+ rootok=1
+ ;;
+ live:/dev/*)
+ rootok=1
+ ;;
+ live:/*.[Ii][Mm][Gg] | /*.[Ii][Mm][Gg])
+ [ -f "${root#live:}" ] && rootok=1
+ ;;
+esac
+
+[ "$rootok" != "1" ] && exit 0
+
+GENERATOR_DIR="$2"
+[ -z "$GENERATOR_DIR" ] && exit 1
+[ -d "$GENERATOR_DIR" ] || mkdir -p "$GENERATOR_DIR"
+
+getargbool 0 rd.live.overlay.readonly -d -y readonly_overlay && readonly_overlay="--readonly" || readonly_overlay=""
+getargbool 0 rd.live.overlay.overlayfs && overlayfs="yes"
+[ -e /xor_overlayfs ] && xor_overlayfs="yes"
+[ -e /xor_readonly ] && xor_readonly="--readonly"
+ROOTFLAGS="$(getarg rootflags)"
+{
+ echo "[Unit]"
+ echo "Before=initrd-root-fs.target"
+ echo "[Mount]"
+ echo "Where=/sysroot"
+ if [ "$overlayfs$xor_overlayfs" = "yes" ]; then
+ echo "What=LiveOS_rootfs"
+ if [ "$readonly_overlay$xor_readonly" = "--readonly" ]; then
+ ovlfs=lowerdir=/run/overlayfs-r:/run/rootfsbase
+ else
+ ovlfs=lowerdir=/run/rootfsbase
+ fi
+ echo "Options=${ROOTFLAGS},${ovlfs},upperdir=/run/overlayfs,workdir=/run/ovlwork"
+ echo "Type=overlay"
+ _dev=LiveOS_rootfs
+ else
+ echo "What=/dev/mapper/live-rw"
+ [ -n "$ROOTFLAGS" ] && echo "Options=${ROOTFLAGS}"
+ _dev='dev-mapper-live\x2drw'
+ fi
+} > "$GENERATOR_DIR"/sysroot.mount
+
+mkdir -p "$GENERATOR_DIR/$_dev.device.d"
+{
+ echo "[Unit]"
+ echo "JobTimeoutSec=3000"
+ echo "JobRunningTimeoutSec=3000"
+} > "$GENERATOR_DIR/$_dev.device.d/timeout.conf"
diff --git a/modules.d/90dmsquash-live/dmsquash-live-genrules.sh b/modules.d/90dmsquash-live/dmsquash-live-genrules.sh
new file mode 100755
index 0000000..8c7cad8
--- /dev/null
+++ b/modules.d/90dmsquash-live/dmsquash-live-genrules.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+case "$root" in
+ live:/dev/*)
+ {
+ printf 'KERNEL=="%s", RUN+="/sbin/initqueue --settled --onetime --unique /sbin/dmsquash-live-root %s"\n' \
+ "${root#live:/dev/}" "${root#live:}"
+ printf 'SYMLINK=="%s", RUN+="/sbin/initqueue --settled --onetime --unique /sbin/dmsquash-live-root %s"\n' \
+ "${root#live:/dev/}" "${root#live:}"
+ } >> /etc/udev/rules.d/99-live-squash.rules
+ wait_for_dev -n "${root#live:}"
+ ;;
+ live:*)
+ if [ -f "${root#live:}" ]; then
+ /sbin/initqueue --settled --onetime --unique /sbin/dmsquash-live-root "${root#live:}"
+ fi
+ ;;
+esac
diff --git a/modules.d/90dmsquash-live/dmsquash-live-root.sh b/modules.d/90dmsquash-live/dmsquash-live-root.sh
new file mode 100755
index 0000000..e808339
--- /dev/null
+++ b/modules.d/90dmsquash-live/dmsquash-live-root.sh
@@ -0,0 +1,432 @@
+#!/bin/sh
+
+type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
+type det_fs > /dev/null 2>&1 || . /lib/fs-lib.sh
+
+command -v unpack_archive > /dev/null || . /lib/img-lib.sh
+
+PATH=/usr/sbin:/usr/bin:/sbin:/bin
+
+if getargbool 0 rd.live.debug -n -y rdlivedebug; then
+ exec > /tmp/liveroot.$$.out
+ exec 2>> /tmp/liveroot.$$.out
+ set -x
+fi
+
+[ -z "$1" ] && exit 1
+livedev="$1"
+
+# parse various live image specific options that make sense to be
+# specified as their own things
+live_dir=$(getarg rd.live.dir -d live_dir)
+[ -z "$live_dir" ] && live_dir="LiveOS"
+squash_image=$(getarg rd.live.squashimg)
+[ -z "$squash_image" ] && squash_image="squashfs.img"
+
+getargbool 0 rd.live.ram -d -y live_ram && live_ram="yes"
+getargbool 0 rd.live.overlay.reset -d -y reset_overlay && reset_overlay="yes"
+getargbool 0 rd.live.overlay.readonly -d -y readonly_overlay && readonly_overlay="--readonly" || readonly_overlay=""
+overlay=$(getarg rd.live.overlay -d overlay)
+getargbool 0 rd.writable.fsimg -d -y writable_fsimg && writable_fsimg="yes"
+overlay_size=$(getarg rd.live.overlay.size=)
+[ -z "$overlay_size" ] && overlay_size=32768
+
+getargbool 0 rd.live.overlay.thin && thin_snapshot="yes"
+getargbool 0 rd.live.overlay.overlayfs && overlayfs="yes"
+
+# Take a path to a disk label and return the parent disk if it is a partition
+# Otherwise returns the original path
+get_check_dev() {
+ local _udevinfo
+ dev_path="$(udevadm info -q path --name "$1")"
+ _udevinfo="$(udevadm info -q property --path "${dev_path}")"
+ strstr "$_udevinfo" "DEVTYPE=partition" || {
+ echo "$1"
+ return
+ }
+ parent="${dev_path%/*}"
+ _udevinfo="$(udevadm info -q property --path "${parent}")"
+ strstr "$_udevinfo" "DEVTYPE=disk" || {
+ echo "$1"
+ return
+ }
+ strstr "$_udevinfo" "ID_FS_TYPE=iso9660" || {
+ echo "$1"
+ return
+ }
+
+ # Return the name of the parent disk device
+ echo "$_udevinfo" | grep "DEVNAME=" | sed 's/DEVNAME=//'
+}
+
+# Find the right device to run check on
+check_dev=$(get_check_dev "$livedev")
+# CD/DVD media check
+[ -b "$check_dev" ] && fs=$(det_fs "$check_dev")
+if [ "$fs" = "iso9660" -o "$fs" = "udf" ]; then
+ check="yes"
+fi
+getarg rd.live.check -d check || check=""
+if [ -n "$check" ]; then
+ type plymouth > /dev/null 2>&1 && plymouth --hide-splash
+ if [ -n "$DRACUT_SYSTEMD" ]; then
+ p=$(dev_unit_name "$check_dev")
+ systemctl start checkisomd5@"${p}".service
+ else
+ checkisomd5 --verbose "$check_dev"
+ fi
+ if [ $? -eq 1 ]; then
+ die "CD check failed!"
+ exit 1
+ fi
+ type plymouth > /dev/null 2>&1 && plymouth --show-splash
+fi
+
+ln -s "$livedev" /run/initramfs/livedev
+
+# determine filesystem type for a filesystem image
+det_img_fs() {
+ udevadm settle >&2
+ blkid -s TYPE -u noraid -o value "$1"
+}
+
+load_fstype squashfs
+CMDLINE=$(getcmdline)
+for arg in $CMDLINE; do
+ case $arg in
+ ro | rw) liverw=$arg ;;
+ esac
+done
+
+# mount the backing of the live image first
+mkdir -m 0755 -p /run/initramfs/live
+if [ -f "$livedev" ]; then
+ # no mount needed - we've already got the LiveOS image in initramfs
+ # check filesystem type and handle accordingly
+ fstype=$(det_img_fs "$livedev")
+ case $fstype in
+ squashfs) SQUASHED=$livedev ;;
+ auto) die "cannot mount live image (unknown filesystem type)" ;;
+ *) FSIMG=$livedev ;;
+ esac
+ [ -e /sys/fs/"$fstype" ] || modprobe "$fstype"
+else
+ livedev_fstype=$(det_fs "$livedev")
+ if [ "$livedev_fstype" = "squashfs" ]; then
+ # no mount needed - we've already got the LiveOS image in $livedev
+ SQUASHED=$livedev
+ elif [ "$livedev_fstype" != "ntfs" ]; then
+ if ! mount -n -t "$livedev_fstype" -o "${liverw:-ro}" "$livedev" /run/initramfs/live; then
+ die "Failed to mount block device of live image"
+ exit 1
+ fi
+ else
+ [ -x "/sbin/mount-ntfs-3g" ] && /sbin/mount-ntfs-3g -o "${liverw:-ro}" "$livedev" /run/initramfs/live
+ fi
+fi
+
+# overlay setup helper function
+do_live_overlay() {
+ # create a sparse file for the overlay
+ # overlay: if non-ram overlay searching is desired, do it,
+ # otherwise, create traditional overlay in ram
+
+ l=$(blkid -s LABEL -o value "$livedev") || l=""
+ u=$(blkid -s UUID -o value "$livedev") || u=""
+
+ if [ -z "$overlay" ]; then
+ pathspec="/${live_dir}/overlay-$l-$u"
+ elif strstr "$overlay" ":"; then
+ # pathspec specified, extract
+ pathspec=${overlay##*:}
+ fi
+
+ if [ -z "$pathspec" -o "$pathspec" = "auto" ]; then
+ pathspec="/${live_dir}/overlay-$l-$u"
+ fi
+ devspec=${overlay%%:*}
+
+ # need to know where to look for the overlay
+ if [ -z "$setup" -a -n "$devspec" -a -n "$pathspec" -a -n "$overlay" ]; then
+ mkdir -m 0755 -p /run/initramfs/overlayfs
+ if ismounted "$devspec"; then
+ devmnt=$(findmnt -e -v -n -o 'TARGET' --source "$devspec")
+ # We need $devspec writable for overlay storage
+ mount -o remount,rw "$devspec"
+ mount --bind "$devmnt" /run/initramfs/overlayfs
+ else
+ mount -n -t auto "$devspec" /run/initramfs/overlayfs || :
+ fi
+ if [ -f /run/initramfs/overlayfs$pathspec -a -w /run/initramfs/overlayfs$pathspec ]; then
+ OVERLAY_LOOPDEV=$(losetup -f --show ${readonly_overlay:+-r} /run/initramfs/overlayfs$pathspec)
+ over=$OVERLAY_LOOPDEV
+ umount -l /run/initramfs/overlayfs || :
+ oltype=$(det_img_fs "$OVERLAY_LOOPDEV")
+ if [ -z "$oltype" ] || [ "$oltype" = DM_snapshot_cow ]; then
+ if [ -n "$reset_overlay" ]; then
+ info "Resetting the Device-mapper overlay."
+ dd if=/dev/zero of="$OVERLAY_LOOPDEV" bs=64k count=1 conv=fsync 2> /dev/null
+ fi
+ if [ -n "$overlayfs" ]; then
+ unset -v overlayfs
+ [ -n "$DRACUT_SYSTEMD" ] && reloadsysrootmountunit=":>/xor_overlayfs;"
+ fi
+ setup="yes"
+ else
+ mount -n -t "$oltype" ${readonly_overlay:+-r} "$OVERLAY_LOOPDEV" /run/initramfs/overlayfs
+ if [ -d /run/initramfs/overlayfs/overlayfs ] \
+ && [ -d /run/initramfs/overlayfs/ovlwork ]; then
+ ln -s /run/initramfs/overlayfs/overlayfs /run/overlayfs${readonly_overlay:+-r}
+ ln -s /run/initramfs/overlayfs/ovlwork /run/ovlwork${readonly_overlay:+-r}
+ if [ -z "$overlayfs" ] && [ -n "$DRACUT_SYSTEMD" ]; then
+ reloadsysrootmountunit=":>/xor_overlayfs;"
+ fi
+ overlayfs="required"
+ setup="yes"
+ fi
+ fi
+ elif [ -d /run/initramfs/overlayfs$pathspec ] \
+ && [ -d /run/initramfs/overlayfs$pathspec/../ovlwork ]; then
+ ln -s /run/initramfs/overlayfs$pathspec /run/overlayfs${readonly_overlay:+-r}
+ ln -s /run/initramfs/overlayfs$pathspec/../ovlwork /run/ovlwork${readonly_overlay:+-r}
+ if [ -z "$overlayfs" ] && [ -n "$DRACUT_SYSTEMD" ]; then
+ reloadsysrootmountunit=":>/xor_overlayfs;"
+ fi
+ overlayfs="required"
+ setup="yes"
+ fi
+ fi
+ if [ -n "$overlayfs" ]; then
+ if ! load_fstype overlay; then
+ if [ "$overlayfs" = required ]; then
+ die "OverlayFS is required but not available."
+ exit 1
+ fi
+ [ -n "$DRACUT_SYSTEMD" ] && reloadsysrootmountunit=":>/xor_overlayfs;"
+ m='OverlayFS is not available; using temporary Device-mapper overlay.'
+ info "$m"
+ unset -v overlayfs setup
+ fi
+ fi
+
+ if [ -z "$setup" -o -n "$readonly_overlay" ]; then
+ if [ -n "$setup" ]; then
+ warn "Using temporary overlay."
+ elif [ -n "$devspec" -a -n "$pathspec" ]; then
+ [ -z "$m" ] \
+ && m=' Unable to find a persistent overlay; using a temporary one.'
+ m="$m"'
+ All root filesystem changes will be lost on shutdown.
+ Press [Enter] to continue.'
+ printf "\n\n\n\n%s\n\n\n" "${m}" > /dev/kmsg
+ if [ -n "$DRACUT_SYSTEMD" ]; then
+ if type plymouth > /dev/null 2>&1 && plymouth --ping; then
+ if getargbool 0 rhgb || getargbool 0 splash; then
+ m='>>>
+>>>
+>>>
+
+
+'"$m"
+ m="${m%n.*}"'n.
+
+
+<<<
+<<<
+<<<'
+ plymouth display-message --text="${m}"
+ else
+ plymouth ask-question --prompt="${m}" --command=true
+ fi
+ else
+ m=">>>$(printf '%s' "$m" | tr -d '\n') <<<"
+ systemd-ask-password --timeout=0 "${m}"
+ fi
+ else
+ type plymouth > /dev/null 2>&1 && plymouth --ping && plymouth --quit
+ printf '\n\n%s' "$m"
+ read -r _
+ fi
+ fi
+ if [ -n "$overlayfs" ]; then
+ if [ -n "$readonly_overlay" ] && ! [ -h /run/overlayfs-r ]; then
+ info "No persistent overlay found."
+ unset -v readonly_overlay
+ [ -n "$DRACUT_SYSTEMD" ] && reloadsysrootmountunit="${reloadsysrootmountunit}:>/xor_readonly;"
+ fi
+ else
+ dd if=/dev/null of=/overlay bs=1024 count=1 seek=$((overlay_size * 1024)) 2> /dev/null
+ if [ -n "$setup" -a -n "$readonly_overlay" ]; then
+ RO_OVERLAY_LOOPDEV=$(losetup -f --show /overlay)
+ over=$RO_OVERLAY_LOOPDEV
+ else
+ OVERLAY_LOOPDEV=$(losetup -f --show /overlay)
+ over=$OVERLAY_LOOPDEV
+ fi
+ fi
+ fi
+
+ # set up the snapshot
+ if [ -z "$overlayfs" ]; then
+ if [ -n "$readonly_overlay" ] && [ -n "$OVERLAY_LOOPDEV" ]; then
+ echo 0 "$sz" snapshot "$BASE_LOOPDEV" "$OVERLAY_LOOPDEV" P 8 | dmsetup create --readonly live-ro
+ base="/dev/mapper/live-ro"
+ else
+ base=$BASE_LOOPDEV
+ fi
+ fi
+
+ if [ -n "$thin_snapshot" ]; then
+ modprobe dm_thin_pool
+ mkdir -m 0755 -p /run/initramfs/thin-overlay
+
+ # In block units (512b)
+ thin_data_sz=$((overlay_size * 1024 * 1024 / 512))
+ thin_meta_sz=$((thin_data_sz / 10))
+
+ # It is important to have the backing file on a tmpfs
+ # this is needed to let the loopdevice support TRIM
+ dd if=/dev/null of=/run/initramfs/thin-overlay/meta bs=1b count=1 seek=$((thin_meta_sz)) 2> /dev/null
+ dd if=/dev/null of=/run/initramfs/thin-overlay/data bs=1b count=1 seek=$((thin_data_sz)) 2> /dev/null
+
+ THIN_META_LOOPDEV=$(losetup --show -f /run/initramfs/thin-overlay/meta)
+ THIN_DATA_LOOPDEV=$(losetup --show -f /run/initramfs/thin-overlay/data)
+
+ echo 0 $thin_data_sz thin-pool "$THIN_META_LOOPDEV" "$THIN_DATA_LOOPDEV" 1024 1024 | dmsetup create live-overlay-pool
+ dmsetup message /dev/mapper/live-overlay-pool 0 "create_thin 0"
+
+ # Create a snapshot of the base image
+ echo 0 "$sz" thin /dev/mapper/live-overlay-pool 0 "$base" | dmsetup create live-rw
+ elif [ -z "$overlayfs" ]; then
+ echo 0 "$sz" snapshot "$base" "$over" PO 8 | dmsetup create live-rw
+ fi
+
+ # Create a device for the ro base of overlaid file systems.
+ if [ -z "$overlayfs" ]; then
+ echo 0 "$sz" linear "$BASE_LOOPDEV" 0 | dmsetup create --readonly live-base
+ fi
+ ln -s "$BASE_LOOPDEV" /dev/live-base
+}
+# end do_live_overlay()
+
+# we might have an embedded fs image on squashfs (compressed live)
+if [ -e /run/initramfs/live/${live_dir}/${squash_image} ]; then
+ SQUASHED="/run/initramfs/live/${live_dir}/${squash_image}"
+fi
+if [ -e "$SQUASHED" ]; then
+ if [ -n "$live_ram" ]; then
+ imgsize=$(($(stat -c %s -- $SQUASHED) / (1024 * 1024)))
+ check_live_ram $imgsize
+ echo 'Copying live image to RAM...' > /dev/kmsg
+ echo ' (this may take a minute)' > /dev/kmsg
+ dd if=$SQUASHED of=/run/initramfs/squashed.img bs=512 2> /dev/null
+ echo 'Done copying live image to RAM.' > /dev/kmsg
+ SQUASHED="/run/initramfs/squashed.img"
+ fi
+
+ SQUASHED_LOOPDEV=$(losetup -f)
+ losetup -r "$SQUASHED_LOOPDEV" $SQUASHED
+ mkdir -m 0755 -p /run/initramfs/squashfs
+ mount -n -t squashfs -o ro "$SQUASHED_LOOPDEV" /run/initramfs/squashfs
+
+ if [ -d /run/initramfs/squashfs/LiveOS ]; then
+ if [ -f /run/initramfs/squashfs/LiveOS/rootfs.img ]; then
+ FSIMG="/run/initramfs/squashfs/LiveOS/rootfs.img"
+ elif [ -f /run/initramfs/squashfs/LiveOS/ext3fs.img ]; then
+ FSIMG="/run/initramfs/squashfs/LiveOS/ext3fs.img"
+ fi
+ elif [ -d /run/initramfs/squashfs/proc ]; then
+ FSIMG=$SQUASHED
+ if [ -z "$overlayfs" ] && [ -n "$DRACUT_SYSTEMD" ]; then
+ reloadsysrootmountunit=":>/xor_overlayfs;"
+ fi
+ overlayfs="required"
+ else
+ die "Failed to find a root filesystem in $SQUASHED."
+ exit 1
+ fi
+else
+ # we might have an embedded fs image to use as rootfs (uncompressed live)
+ if [ -e /run/initramfs/live/${live_dir}/rootfs.img ]; then
+ FSIMG="/run/initramfs/live/${live_dir}/rootfs.img"
+ elif [ -e /run/initramfs/live/${live_dir}/ext3fs.img ]; then
+ FSIMG="/run/initramfs/live/${live_dir}/ext3fs.img"
+ fi
+ if [ -n "$live_ram" ]; then
+ echo 'Copying live image to RAM...' > /dev/kmsg
+ echo ' (this may take a minute or so)' > /dev/kmsg
+ dd if=$FSIMG of=/run/initramfs/rootfs.img bs=512 2> /dev/null
+ echo 'Done copying live image to RAM.' > /dev/kmsg
+ FSIMG='/run/initramfs/rootfs.img'
+ fi
+fi
+
+if [ -n "$FSIMG" ]; then
+ if [ -n "$writable_fsimg" ]; then
+ # mount the provided filesystem read/write
+ echo "Unpacking live filesystem (may take some time)" > /dev/kmsg
+ mkdir -m 0755 -p /run/initramfs/fsimg/
+ if [ -n "$SQUASHED" ]; then
+ cp -v $FSIMG /run/initramfs/fsimg/rootfs.img
+ else
+ unpack_archive $FSIMG /run/initramfs/fsimg/
+ fi
+ FSIMG=/run/initramfs/fsimg/rootfs.img
+ fi
+ # For writable DM images...
+ readonly_base=1
+ if [ -z "$SQUASHED" -a -n "$live_ram" -a -z "$overlayfs" ] \
+ || [ -n "$writable_fsimg" ] \
+ || [ "$overlay" = none -o "$overlay" = None -o "$overlay" = NONE ]; then
+ if [ -z "$readonly_overlay" ]; then
+ unset readonly_base
+ setup=rw
+ else
+ setup=yes
+ fi
+ fi
+ if [ "$FSIMG" = "$SQUASHED" ]; then
+ BASE_LOOPDEV=$SQUASHED_LOOPDEV
+ else
+ BASE_LOOPDEV=$(losetup -f --show ${readonly_base:+-r} $FSIMG)
+ sz=$(blockdev --getsz "$BASE_LOOPDEV")
+ fi
+ if [ "$setup" = rw ]; then
+ echo 0 "$sz" linear "$BASE_LOOPDEV" 0 | dmsetup create live-rw
+ else
+ # Add a DM snapshot or OverlayFS for writes.
+ do_live_overlay
+ fi
+fi
+
+if [ -n "$reloadsysrootmountunit" ]; then
+ eval "$reloadsysrootmountunit"
+ systemctl daemon-reload
+fi
+
+ROOTFLAGS="$(getarg rootflags)"
+
+if [ "$overlayfs" = required ]; then
+ echo "rd.live.overlay.overlayfs=1" > /etc/cmdline.d/dmsquash-need-overlay.conf
+fi
+
+if [ -n "$overlayfs" ]; then
+ if [ -n "$FSIMG" ]; then
+ mkdir -m 0755 -p /run/rootfsbase
+ mount -r $FSIMG /run/rootfsbase
+ else
+ ln -sf /run/initramfs/live /run/rootfsbase
+ fi
+else
+ if [ -z "$DRACUT_SYSTEMD" ]; then
+ [ -n "$ROOTFLAGS" ] && ROOTFLAGS="-o $ROOTFLAGS"
+ printf 'mount %s /dev/mapper/live-rw %s\n' "$ROOTFLAGS" "$NEWROOT" > "$hookdir"/mount/01-$$-live.sh
+ fi
+fi
+[ -e "$SQUASHED" ] && umount -l /run/initramfs/squashfs
+
+ln -s null /dev/root
+
+need_shutdown
+
+exit 0
diff --git a/modules.d/90dmsquash-live/dmsquash-liveiso-genrules.sh b/modules.d/90dmsquash-live/dmsquash-liveiso-genrules.sh
new file mode 100755
index 0000000..a5810f7
--- /dev/null
+++ b/modules.d/90dmsquash-live/dmsquash-liveiso-genrules.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+if [ "${root%%:*}" = "liveiso" ]; then
+ {
+ # shellcheck disable=SC2016
+ printf 'KERNEL=="loop-control", RUN+="/sbin/initqueue --settled --onetime --unique /sbin/dmsquash-live-root `/sbin/losetup -f --show %s`"\n' \
+ "${root#liveiso:}"
+ } >> /etc/udev/rules.d/99-liveiso-mount.rules
+fi
diff --git a/modules.d/90dmsquash-live/iso-scan.sh b/modules.d/90dmsquash-live/iso-scan.sh
new file mode 100755
index 0000000..fa06b33
--- /dev/null
+++ b/modules.d/90dmsquash-live/iso-scan.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
+
+PATH=/usr/sbin:/usr/bin:/sbin:/bin
+
+isofile=$1
+
+[ -z "$isofile" ] && exit 1
+
+ismounted "/run/initramfs/isoscan" && exit 0
+
+mkdir -p "/run/initramfs/isoscan"
+
+do_iso_scan() {
+ local _name
+ local dev
+ for dev in /dev/disk/by-uuid/*; do
+ _name=$(dev_unit_name "$dev")
+ [ -e /tmp/isoscan-"${_name}" ] && continue
+ : > /tmp/isoscan-"${_name}"
+ mount -t auto -o ro "$dev" "/run/initramfs/isoscan" || continue
+ if [ -f "/run/initramfs/isoscan/$isofile" ]; then
+ losetup -f "/run/initramfs/isoscan/$isofile"
+ udevadm trigger --action=add > /dev/null 2>&1
+ ln -s "$dev" /run/initramfs/isoscandev
+ rm -f -- "$job"
+ exit 0
+ else
+ umount "/run/initramfs/isoscan"
+ fi
+ done
+}
+
+do_iso_scan
+
+rmdir "/run/initramfs/isoscan"
+exit 1
diff --git a/modules.d/90dmsquash-live/module-setup.sh b/modules.d/90dmsquash-live/module-setup.sh
new file mode 100755
index 0000000..b905e3d
--- /dev/null
+++ b/modules.d/90dmsquash-live/module-setup.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# called by dracut
+check() {
+ # a live host-only image doesn't really make a lot of sense
+ [[ $hostonly ]] && return 1
+ return 255
+}
+
+# called by dracut
+depends() {
+ # if dmsetup is not installed, then we cannot support fedora/red hat
+ # style live images
+ echo dm rootfs-block img-lib overlayfs
+ return 0
+}
+
+# called by dracut
+installkernel() {
+ instmods squashfs loop iso9660
+}
+
+# called by dracut
+install() {
+ inst_multiple umount dmsetup blkid dd losetup blockdev find rmdir grep
+ inst_multiple -o checkisomd5
+ inst_hook cmdline 30 "$moddir/parse-dmsquash-live.sh"
+ inst_hook cmdline 31 "$moddir/parse-iso-scan.sh"
+ inst_hook pre-udev 30 "$moddir/dmsquash-live-genrules.sh"
+ inst_hook pre-udev 30 "$moddir/dmsquash-liveiso-genrules.sh"
+ inst_hook pre-pivot 20 "$moddir/apply-live-updates.sh"
+ inst_script "$moddir/dmsquash-live-root.sh" "/sbin/dmsquash-live-root"
+ inst_script "$moddir/iso-scan.sh" "/sbin/iso-scan"
+ if dracut_module_included "systemd-initrd"; then
+ inst_script "$moddir/dmsquash-generator.sh" "$systemdutildir"/system-generators/dracut-dmsquash-generator
+ inst_simple "$moddir/checkisomd5@.service" "/etc/systemd/system/checkisomd5@.service"
+ fi
+ dracut_need_initqueue
+}
diff --git a/modules.d/90dmsquash-live/parse-dmsquash-live.sh b/modules.d/90dmsquash-live/parse-dmsquash-live.sh
new file mode 100755
index 0000000..de910b3
--- /dev/null
+++ b/modules.d/90dmsquash-live/parse-dmsquash-live.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+# live images are specified with
+# root=live:backingdev
+
+[ -z "$root" ] && root=$(getarg root=)
+
+# support legacy syntax of passing liveimg and then just the base root
+if getargbool 0 rd.live.image -d -y liveimg; then
+ liveroot="live:$root"
+fi
+
+if [ "${root%%:*}" = "live" ]; then
+ liveroot=$root
+fi
+
+[ "${liveroot%%:*}" = "live" ] || return 1
+
+modprobe -q loop
+
+case "$liveroot" in
+ live:LABEL=* | LABEL=* | live:UUID=* | UUID=* | live:PARTUUID=* | PARTUUID=* | live:PARTLABEL=* | PARTLABEL=*)
+ root="live:$(label_uuid_to_dev "${root#live:}")"
+ rootok=1
+ ;;
+ live:CDLABEL=* | CDLABEL=*)
+ root="${root#live:}"
+ root="$(echo "$root" | sed 's,/,\\x2f,g;s, ,\\x20,g')"
+ root="live:/dev/disk/by-label/${root#CDLABEL=}"
+ rootok=1
+ ;;
+ live:/*.[Ii][Ss][Oo] | /*.[Ii][Ss][Oo])
+ root="${root#live:}"
+ root="liveiso:${root}"
+ rootok=1
+ ;;
+ live:/dev/*)
+ root="live:${root#live:}"
+ rootok=1
+ ;;
+ live:/*.[Ii][Mm][Gg] | /*.[Ii][Mm][Gg])
+ [ -f "${root#live:}" ] && rootok=1
+ ;;
+ live:nfs*)
+ rootok=1
+ ;;
+esac
+
+[ "$rootok" = "1" ] || return 1
+
+info "root was $liveroot, is now $root"
+
+# make sure that init doesn't complain
+[ -z "$root" ] && root="live"
+
+wait_for_dev -n /dev/root
+
+return 0
diff --git a/modules.d/90dmsquash-live/parse-iso-scan.sh b/modules.d/90dmsquash-live/parse-iso-scan.sh
new file mode 100755
index 0000000..1dd2d37
--- /dev/null
+++ b/modules.d/90dmsquash-live/parse-iso-scan.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# live images are specified with
+# root=live:backingdev
+
+isofile=$(getarg iso-scan/filename)
+
+if [ -n "$isofile" ]; then
+ /sbin/initqueue --settled --unique /sbin/iso-scan "$isofile"
+fi