diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 13:54:25 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 13:54:25 +0000 |
commit | 9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a (patch) | |
tree | 2efb72864cc69e174c9c5ee33efb88a5f1553b48 /modules.d/90dmsquash-live | |
parent | Initial commit. (diff) | |
download | dracut-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-x | modules.d/90dmsquash-live/apply-live-updates.sh | 22 | ||||
-rw-r--r-- | modules.d/90dmsquash-live/checkisomd5@.service | 14 | ||||
-rwxr-xr-x | modules.d/90dmsquash-live/dmsquash-generator.sh | 80 | ||||
-rwxr-xr-x | modules.d/90dmsquash-live/dmsquash-live-genrules.sh | 18 | ||||
-rwxr-xr-x | modules.d/90dmsquash-live/dmsquash-live-root.sh | 432 | ||||
-rwxr-xr-x | modules.d/90dmsquash-live/dmsquash-liveiso-genrules.sh | 9 | ||||
-rwxr-xr-x | modules.d/90dmsquash-live/iso-scan.sh | 38 | ||||
-rwxr-xr-x | modules.d/90dmsquash-live/module-setup.sh | 39 | ||||
-rwxr-xr-x | modules.d/90dmsquash-live/parse-dmsquash-live.sh | 57 | ||||
-rwxr-xr-x | modules.d/90dmsquash-live/parse-iso-scan.sh | 9 |
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 |