From 789668deb3e6f8584ffab964d2204ddcb75f0a06 Mon Sep 17 00:00:00 2001
From: Frederick Grose <fgrose@sugarlabs.org>
Date: Mon, 20 Aug 2018 09:47:50 -0400
Subject: [PATCH] dmsquash-live: Support a flattened squashfs.img
A simplified root filesystem structure may be provided for OverlayFS
overlays by squashing the root filesystem directly instead of squashing
an embedded image file at /LiveOS/rootfs.img. Detect and configure
such a squashed root filesystem for live booting.
For OverlayFS boots, avoid the read-only Device-mapper linear device
at /dev/mapper/live-base.
Create a consistent device link at /dev/live-base for the read-only
base loop device for all overlayed live root filesystems.
Consistently provide a link at /dev/root for wait_for_dev.
Update documentation.
---
dracut.cmdline.7.asc | 126 +++++++++++++++---------
modules.d/90dmsquash-live/dmsquash-live-root.sh | 51 ++++++----
2 files changed, 110 insertions(+), 67 deletions(-)
diff --git a/dracut.cmdline.7.asc b/dracut.cmdline.7.asc
index df633e5d..882035af 100644
--- a/dracut.cmdline.7.asc
+++ b/dracut.cmdline.7.asc
@@ -838,23 +838,24 @@ Booting live images
Dracut offers multiple options for live booted images:
=====================
-SquashFS with read-only filesystem image::: The system will boot with a read
-only filesystem from the SquashFS and apply a writable device-mapper snapshot
-over the read only filesystem. Using this method ensures a relatively fast
-boot and lower RAM usage. Users **must be careful** to avoid writing too many
-blocks to the snapshot volume. Once the blocks of the snapshot overlay are
-exhausted, the root filesystem becomes read only and may cause application
-failures. The overlay file is marked 'Overflow', and a difficult recovery is
-required to repair and enlarge the overlay offline. Non-persistent overlays
-are sparse files in RAM that only consume content space as required blocks are
-allocated. They default to an apparent size of 32 GiB in RAM. The size can be
-adjusted with the **rd.live.overlay.size=** kernel command line option.
+SquashFS with read-only filesystem image::: The system will boot with a
+read-only filesystem from the SquashFS and apply a writable Device-mapper
+snapshot or an OverlayFS overlay mount for the read-only base filesystem. This
+method ensures a relatively fast boot and lower RAM usage. Users **must be
+careful** to avoid writing too many blocks to a snapshot volume. Once the
+blocks of the snapshot overlay are exhausted, the root filesystem becomes
+read-only and may cause application failures. The snapshot overlay file is
+marked 'Overflow', and a difficult recovery is required to repair and enlarge
+the overlay offline. Non-persistent overlays are sparse files in RAM that only
+consume content space as required blocks are allocated. They default to an
+apparent size of 32 GiB in RAM. The size can be adjusted with the
+**rd.live.overlay.size=** kernel command line option.
+
-The filesystem structure is expected to be:
+The filesystem structure is traditionally expected to be:
+
[listing]
--
-squashfs.img | Squashfs from LiveCD .iso downloaded via network
+squashfs.img | SquashFS from LiveCD .iso
!(mount)
/LiveOS
|- rootfs.img | Filesystem image to mount read-only
@@ -865,21 +866,35 @@ squashfs.img | Squashfs from LiveCD .iso downloaded via network
... |
--
+
-Dracut uses this method of live booting by default. No additional command line
-options are required other than **root=live:<URL>** to specify the location
-of your squashed filesystem.
+For OverlayFS mount overlays, the filesystem structure may also be a direct
+compression of the root filesystem:
++
+[listing]
+--
+squashfs.img | SquashFS from LiveCD .iso
+ !(mount)
+ /bin | Live filesystem
+ /boot |
+ /dev |
+ ... |
+--
++
+Dracut uses one of the overlay methods of live booting by default. No
+additional command line options are required other than **root=live:<URL>** to
+specify the location of your squashed filesystem.
+
- The compressed SquashFS image can be copied during boot to RAM at
`/run/initramfs/squashed.img` by using the **rd.live.ram=1** option.
-- A device with a persistent overlay can be booted read only by using the
+- A device with a persistent overlay can be booted read-only by using the
**rd.live.overlay.readonly** option on the kernel command line. This will
-cause a temporary, writable overlay to be stacked over a read-only snapshot
-of the root filesystem.
+either cause a temporary, writable overlay to be stacked over a read-only
+snapshot of the root filesystem or the OverlayFS mount will use an additional
+lower layer with the root filesystem.
+
Uncompressed live filesystem image:::
When the live system was installed with the '--skipcompress' option of the
__livecd-iso-to-disk__ installation script for Live USB devices, the root
-filesystem image, `rootfs.img`, is expanded on installation and no SquashFS
+filesystem image, __rootfs.img__, is expanded on installation and no SquashFS
is involved during boot.
+
- If **rd.live.ram=1** is used in this situation, the full, uncompressed
@@ -887,12 +902,12 @@ root filesystem is copied during boot to `/run/initramfs/rootfs.img` in the
`/run` tmpfs.
+
- If **rd.live.overlay=none** is provided as a kernel command line option,
-a writable, linear device-mapper target is created on boot with no overlay.
+a writable, linear Device-mapper target is created on boot with no overlay.
-writable filesystem image:::
+Writable filesystem image:::
The system will retrieve a compressed filesystem image, extract it to
`/run/initramfs/fsimg/rootfs.img`, connect it to a loop device, create a
-writable, linear device-mapper target at `/dev/mapper/live-rw`, and mount that
+writable, linear Device-mapper target at `/dev/mapper/live-rw`, and mount that
as a writable volume at `/`. More RAM is required during boot but the live
filesystem is easier to manage if it becomes full. Users can make a filesystem
image of any size and that size will be maintained when the system boots. There
@@ -902,7 +917,7 @@ The filesystem structure is expected to be:
+
[listing]
--
-rootfs.tgz | Compressed tarball containing fileystem image
+rootfs.tgz | Compressed tarball containing filesystem image
!(unpack)
/rootfs.img | Filesystem image at /run/initramfs/fsimg/
!(mount)
@@ -930,11 +945,11 @@ NOTE: There must be enough free RAM available to hold the complete image.
This method is very suitable for diskless boots.
**root=**live:__<url>__::
-Boots a live image retrieved from __<url>__. Requires dracut 'livenet' module.
-Valid handlers: __http, https, ftp, torrent, tftp__.
+Boots a live image retrieved from __<url>__. Requires the dracut 'livenet'
+module. Valid handlers: __http, https, ftp, torrent, tftp__.
+
[listing]
-.Example
+.Examples
--
root=live:http://example.com/liveboot.img
root=live:ftp://ftp.example.com/liveboot.img
@@ -946,7 +961,7 @@ Enables debug output from the live boot process.
**rd.live.dir=**__<path>__::
Specifies the directory within the boot device where the squashfs.img or
-rootfs.img can be found. By default, this is __LiveOS__.
+rootfs.img can be found. By default, this is `/LiveOS`.
**rd.live.squashimg=**__<filename of SquashFS image>__::
Specifies the filename for a SquashFS image of the root filesystem.
@@ -954,35 +969,52 @@ By default, this is __squashfs.img__.
**rd.live.ram=**1::
Copy the complete image to RAM and use this for booting. This is useful
-when the image resides on, i.e., a DVD which needs to be ejected later on.
+when the image resides on, e.g., a DVD which needs to be ejected later on.
**rd.live.overlay={**__<devspec>__[:__{<pathspec>|auto}__]|__none__}::
-Allow the usage of a permanent overlay.
-- _<devspec>_ specifies the path to a device with a mountable filesystem.
-- _<pathspec>_ is the path to a file within that filesystem, which shall be
+Manage the usage of a permanent overlay.
++
+--
+* _<devspec>_ specifies the path to a device with a mountable filesystem.
+* _<pathspec>_ is the path to a file within that filesystem, which shall be
used to persist the changes made to the device specified by the
**root=live:__<url>__** option.
-- _none_ specifies no overlay when an uncompressed live root filesystem is
-available.
-If a persistent overlay is detected at the standard LiveOS path, the overlay &
-overlay type detected (whether Device-mapper or OverlayFS) will be used.
++
+The default _pathspec_, when _auto_ or no _:<pathspec>_ is given, is
+`/<+++<b>rd.live.dir</b>+++>/overlay-<label>-<uuid>`, where _<label>_ is the
+device LABEL, and _<uuid>_ is the device UUID.
+* _none_ (the word itself) specifies that no overlay will be used, such as when
+an uncompressed, writable live root filesystem is available.
++
+If a persistent overlay __is detected__ at the standard LiveOS path, the
+overlay & overlay type detected, whether Device-mapper or OverlayFS, will be
+used.
+--
+
[listing]
-.Example
+.Examples
--
rd.live.overlay=/dev/sdb1:persistent-overlay.img
+rd.live.overlay=UUID=99440c1f-8daa-41bf-b965-b7240a8996f4
--
**rd.live.overlay.size=**__<size_MiB>__::
-Specifies a non-persistent overlay size in MiB. The default is _32768_.
+Specifies a non-persistent Device-mapper overlay size in MiB. The default is
+_32768_.
**rd.live.overlay.readonly=**1::
-Specifies a non-persistent, writable snapshot overlay to be stacked over a
-read-only snapshot of the root filesystem, `/dev/mapper/live-ro`, or a read-
-only loop device of a writable `rootfs.img`.
+This is used to boot with a normally read-write persistent overlay in a
+read-only mode. With this option, either an additional, non-persistent,
+writable snapshot overlay will be stacked over a read-only snapshot,
+`/dev/mapper/live‑ro`, of the base filesystem with the persistent overlay, or a
+read-only loop device, in the case of a writable __rootfs.img__, or an OverlayFS
+mount will use the persistent overlay directory linked at `/run/overlayfs‑r` as
+an additional lower layer along with the base root filesystem and apply a
+transient, writable upper directory overlay, in order to complete the booted
+root filesystem.
**rd.live.overlay.reset=**1::
-Specifies that a persistent overlay should be reset on boot. All root
+Specifies that a persistent overlay should be reset on boot. All previous root
filesystem changes are vacated by this action.
**rd.live.overlay.thin=**1::
@@ -993,25 +1025,25 @@ that memory is given back to the kernel when the filesystem does not claim it
anymore.
**rd.live.overlay.overlayfs=**1::
-Enables the use of the **OverlayFS** kernel module, if available, to provide a
+Enables the use of the *OverlayFS* kernel module, if available, to provide a
copy-on-write union directory for the root filesystem. OverlayFS overlays are
directories of the files that have changed on the read-only base (lower)
filesystem. The root filesystem is provided through a special overlay type
mount that merges the lower and upper directories. If an OverlayFS upper
directory is not present on the boot device, a tmpfs directory will be created
-at /run/overlayfs to provide temporary storage. Persistent storage can be
+at `/run/overlayfs` to provide temporary storage. Persistent storage can be
provided on vfat or msdos formatted devices by supplying the OverlayFS upper
directory within an embedded filesystem that supports the creation of trusted.*
extended attributes and provides a valid d_type in readdir responses, such as
with ext4 and xfs. On non-vfat-formatted devices, a persistent OverlayFS
overlay can extend the available root filesystem storage up to the capacity of
-the LiveOS device.
+the LiveOS disk device.
+
If a persistent overlay is detected at the standard LiveOS path, the overlay &
-overlay type detected (whether OverlayFS or Device-mapper) will be used.
+overlay type detected, whether OverlayFS or Device-mapper, will be used.
+
The **rd.live.overlay.readonly** option, which allows a persistent overlayfs to
-be mounted read only through a higher level transient overlay directory, has
+be mounted read-only through a higher level transient overlay directory, has
been implemented through the multiple lower layers feature of OverlayFS.
diff --git a/modules.d/90dmsquash-live/dmsquash-live-root.sh b/modules.d/90dmsquash-live/dmsquash-live-root.sh
index ac603408..0c5e010e 100755
--- a/modules.d/90dmsquash-live/dmsquash-live-root.sh
+++ b/modules.d/90dmsquash-live/dmsquash-live-root.sh
@@ -250,13 +250,11 @@ do_live_overlay() {
echo 0 $sz snapshot $base $over PO 8 | dmsetup create live-rw
fi
- # Create a device that always points to a ro base image
- if [ -n "$overlayfs" ]; then
- BASE_LOOPDUP=$(losetup -f --show -r $BASE_LOOPDEV)
- echo 0 $sz linear $BASE_LOOPDUP 0 | dmsetup create --readonly live-base
- else
+ # Create a device for the ro base of overlayed 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
}
# we might have a genMinInstDelta delta file for anaconda to take advantage of
@@ -291,10 +289,21 @@ if [ -e "$SQUASHED" ]; then
mkdir -m 0755 -p /run/initramfs/squashfs
mount -n -t squashfs -o ro $SQUASHED_LOOPDEV /run/initramfs/squashfs
- 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"
+ 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" ]; then
+ overlayfs="yes"
+ [ -n "$DRACUT_SYSTEMD" ] && reloadsysrootmountunit="yes"
+ fi
+ 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)
@@ -312,8 +321,8 @@ else
fi
fi
-if [ -n "$FSIMG" ] ; then
- if [ -n "$writable_fsimg" ] ; then
+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 /run/initramfs/fsimg/
@@ -336,9 +345,13 @@ if [ -n "$FSIMG" ] ; then
setup=yes
fi
fi
- BASE_LOOPDEV=$(losetup -f --show $opt $FSIMG)
- sz=$(blockdev --getsz $BASE_LOOPDEV)
- if [ "$setup" == rw ]; then
+ if [ "$FSIMG" = "$SQUASHED" ]; then
+ BASE_LOOPDEV=$SQUASHED_LOOPDEV
+ else
+ BASE_LOOPDEV=$(losetup -f --show $opt $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.
@@ -346,8 +359,6 @@ if [ -n "$FSIMG" ] ; then
fi
fi
-[ -e "$SQUASHED" ] && [ -z "$overlayfs" ] && umount -l /run/initramfs/squashfs
-
if [ -b "$OSMIN_LOOPDEV" ]; then
# set up the devicemapper snapshot device, which will merge
# the normal live fs image, and the delta, into a minimzied fs image
@@ -380,17 +391,17 @@ if [ -n "$overlayfs" ]; then
'lowerdir=/run/rootfsbase,upperdir=/run/overlayfs,workdir=/run/ovlwork' \
"$NEWROOT" > $hookdir/mount/01-$$-live.sh
fi
- _dev=/run/rootfsbase
else
- _dev=/dev/mapper/live-rw
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
- ln -s $BASE_LOOPDEV /run/rootfsbase
fi
-ln -s $_dev /dev/root
+[ -e "$SQUASHED" ] && umount -l /run/initramfs/squashfs
+
+ln -s null /dev/root
need_shutdown
exit 0
+