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 unusable and requires a reboot. A
-persistent overlay is marked Invalid, and requires a difficult recovery.
-Non-persistent overlays default to 512 MiB in RAM, but the size can be adjusted
-with the **rd.live.overlay.size=** kernel command line option.
+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.
+
The filesystem structure is expected to be:
+
squashfs.img | Squashfs from LiveCD .iso downloaded via network
!(mount)
/LiveOS
- |- ext3fs.img | Filesystem image to mount read-only
+ |- rootfs.img | Filesystem image to mount read-only
!(mount)
/bin | Live filesystem
/boot |
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, `ext3fs.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
Enables debug output from the live boot process.
**rd.live.dir=**__<path>__::
-Specifies the directory within the squashfs where the ext3fs.img or rootfs.img
-can be found. By default, this is __LiveOS__.
+Specifies the directory within the boot device where the squashfs.img or
+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.
**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.
+
[listing]
.Example
--
**rd.live.overlay.size=**__<size_MiB>__::
-Specifies a non-persistent overlay size in MiB. The default is _512_.
+Specifies a non-persistent 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
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
+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
+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.
+
+If a persistent overlay is detected at the standard LiveOS path, the overlay &
+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
+been implemented through the multiple lower layers feature of OverlayFS.
+
Plymouth Boot Splash
~~~~~~~~~~~~~~~~~~~~
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=512
+[ -z "$overlay_size" ] && overlay_size=32768
getargbool 0 rd.live.overlay.thin && thin_snapshot="yes"
+getargbool 0 rd.live.overlay.overlayfs && overlayfs="yes"
# CD/DVD media check
[ -b $livedev ] && fs=$(blkid -s TYPE -o value $livedev)
setup=""
if [ -n "$devspec" -a -n "$pathspec" -a -n "$overlay" ]; then
mkdir -m 0755 /run/initramfs/overlayfs
+ opt=''
+ [ -n "$readonly_overlay" ] && opt=-r
mount -n -t auto $devspec /run/initramfs/overlayfs || :
if [ -f /run/initramfs/overlayfs$pathspec -a -w /run/initramfs/overlayfs$pathspec ]; then
- losetup $OVERLAY_LOOPDEV /run/initramfs/overlayfs$pathspec
- if [ -n "$reset_overlay" ]; then
- dd if=/dev/zero of=$OVERLAY_LOOPDEV bs=64k count=1 conv=fsync 2>/dev/null
+ losetup $opt $OVERLAY_LOOPDEV /run/initramfs/overlayfs$pathspec
+ 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="yes"
+ fi
+ setup="yes"
+ else
+ mount -n -t $oltype $opt $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$opt
+ ln -s /run/initramfs/overlayfs/ovlwork /run/ovlwork$opt
+ if [ -z "$overlayfs" ]; then
+ overlayfs="yes"
+ [ -n "$DRACUT_SYSTEMD" ] && reloadsysrootmountunit="yes"
+ fi
+ 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$opt
+ ln -s /run/initramfs/overlayfs$pathspec/../ovlwork /run/ovlwork$opt
+ if [ -z "$overlayfs" ]; then
+ overlayfs="yes"
+ [ -n "$DRACUT_SYSTEMD" ] && reloadsysrootmountunit="yes"
fi
setup="yes"
fi
- umount -l /run/initramfs/overlayfs || :
+ fi
+ if [ -n "$overlayfs" ]; then
+ modprobe overlay
+ if [ $? != 0 ]; then
+ echo "OverlayFS is not available; using temporary Device-mapper overlay." > /dev/kmsg
+ unset -v overlayfs setup
+ [ -n "$reloadsysrootmountunit" ] && unset -v reloadsysrootmountunit
+ sleep 5
+ 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
- warn "Unable to find persistent overlay; using temporary"
+ echo "Unable to find persistent overlay; using temporary." > /dev/kmsg
sleep 5
fi
-
- 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 )
- losetup $RO_OVERLAY_LOOPDEV /overlay
+ if [ -n "$overlayfs" ]; then
+ mkdir -m 0755 /run/overlayfs
+ mkdir -m 0755 /run/ovlwork
else
- losetup $OVERLAY_LOOPDEV /overlay
+ 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 )
+ losetup $RO_OVERLAY_LOOPDEV /overlay
+ else
+ losetup $OVERLAY_LOOPDEV /overlay
+ fi
fi
fi
# set up the snapshot
sz=$(blockdev --getsz $BASE_LOOPDEV)
- if [ -n "$readonly_overlay" ]; then
- echo 0 $sz snapshot $BASE_LOOPDEV $OVERLAY_LOOPDEV N 8 | dmsetup create --readonly live-ro
- base="/dev/mapper/live-ro"
- over=$RO_OVERLAY_LOOPDEV
- else
- base=$BASE_LOOPDEV
- over=$OVERLAY_LOOPDEV
+ if [ -z "$overlayfs" ]; then
+ if [ -n "$readonly_overlay" ]; then
+ echo 0 $sz snapshot $BASE_LOOPDEV $OVERLAY_LOOPDEV P 8 | dmsetup create --readonly live-ro
+ base="/dev/mapper/live-ro"
+ over=$RO_OVERLAY_LOOPDEV
+ else
+ base=$BASE_LOOPDEV
+ over=$OVERLAY_LOOPDEV
+ fi
fi
if [ -n "$thin_snapshot" ]; then
modprobe dm_thin_pool
- mkdir /run/initramfs/thin-overlay
+ mkdir -m 0755 /run/initramfs/thin-overlay
# In block units (512b)
thin_data_sz=$(( $overlay_size * 1024 * 1024 / 512 ))
# Create a snapshot of the base image
echo 0 $sz thin /dev/mapper/live-overlay-pool 0 $base | dmsetup create live-rw
- else
+ elif [ -z "$overlayfs" ]; then
echo 0 $sz snapshot $base $over PO 8 | dmsetup create live-rw
fi
echo 0 $sz linear $BASE_LOOPDEV 0 | dmsetup create --readonly live-base
}
-# live cd helper function
-do_live_from_base_loop() {
- do_live_overlay
-}
-
# we might have a genMinInstDelta delta file for anaconda to take advantage of
if [ -e /run/initramfs/live/${live_dir}/osmin.img ]; then
OSMINSQFS=/run/initramfs/live/${live_dir}/osmin.img
-fi
-
-if [ -n "$OSMINSQFS" ]; then
# decompress the delta data
dd if=$OSMINSQFS of=/run/initramfs/osmin.img 2> /dev/null
OSMIN_SQUASHED_LOOPDEV=$( losetup -f )
if [ -e /run/initramfs/live/${live_dir}/${squash_image} ]; then
SQUASHED="/run/initramfs/live/${live_dir}/${squash_image}"
fi
-
-if [ -e "$SQUASHED" ] ; then
+if [ -e "$SQUASHED" ]; then
if [ -n "$live_ram" ]; then
- echo "Copying live image to RAM..."
- echo "(this may take a few minutes)"
+ 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."
+ echo 'Done copying live image to RAM.' > /dev/kmsg
SQUASHED="/run/initramfs/squashed.img"
fi
mkdir -m 0755 -p /run/initramfs/squashfs
mount -n -t squashfs -o ro $SQUASHED_LOOPDEV /run/initramfs/squashfs
- if [ -f /run/initramfs/squashfs/LiveOS/ext3fs.img ]; then
- FSIMG="/run/initramfs/squashfs/LiveOS/ext3fs.img"
- elif [ -f /run/initramfs/squashfs/LiveOS/rootfs.img ]; 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
else
# we might have an embedded fs image to use as rootfs (uncompressed live)
- if [ -e /run/initramfs/live/${live_dir}/ext3fs.img ]; then
- FSIMG="/run/initramfs/live/${live_dir}/ext3fs.img"
- elif [ -e /run/initramfs/live/${live_dir}/rootfs.img ]; then
+ 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...'
- echo '(this may take a few minutes)'
+ 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.'
+ echo 'Done copying live image to RAM.' > /dev/kmsg
FSIMG='/run/initramfs/rootfs.img'
fi
fi
if [ -n "$writable_fsimg" ] ; then
# mount the provided filesystem read/write
- echo "Unpacking live filesystem (may take some time)"
- mkdir /run/initramfs/fsimg/
+ echo "Unpacking live filesystem (may take some time)" > /dev/kmsg
+ mkdir -m 0755 /run/initramfs/fsimg/
if [ -n "$SQUASHED" ]; then
cp -v $FSIMG /run/initramfs/fsimg/rootfs.img
else
fi
FSIMG=/run/initramfs/fsimg/rootfs.img
fi
- if [ -n "$writable_fsimg" ] || [ -z "$SQUASHED" -a -n "$live_ram" ] ||
+ if [ -n "$writable_fsimg" ] || [ -z "$SQUASHED" -a -n "$live_ram" -a -z "$overlayfs" ] ||
[ "$overlay" = none -o "$overlay" = None -o "$overlay" = NONE ]; then
losetup $BASE_LOOPDEV $FSIMG
sz=$(blockdev --getsz $BASE_LOOPDEV)
echo 0 $sz linear $BASE_LOOPDEV 0 | dmsetup create live-rw
else
- # mount the filesystem read-only and add a dm snapshot for writes
+ # Attach the filesystem read-only and add a DM snapshot or OverlayFS for writes.
losetup -r $BASE_LOOPDEV $FSIMG
- do_live_from_base_loop
+ do_live_overlay
fi
fi
-[ -e "$SQUASHED" ] && umount -l /run/initramfs/squashfs
+[ -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
- echo "0 $( blockdev --getsz $BASE_LOOPDEV ) snapshot $BASE_LOOPDEV $OSMIN_LOOPDEV N 8" | dmsetup create --readonly live-osimg-min
+ echo "0 $sz snapshot $BASE_LOOPDEV $OSMIN_LOOPDEV P 8" | dmsetup create --readonly live-osimg-min
fi
-ROOTFLAGS="$(getarg rootflags)"
-if [ -n "$ROOTFLAGS" ]; then
- ROOTFLAGS="-o $ROOTFLAGS"
+if [ -n "$reloadsysrootmountunit" ]; then
+ > /xor_overlayfs
+ systemctl daemon-reload
fi
-ln -s /dev/mapper/live-rw /dev/root
+ROOTFLAGS="$(getarg rootflags)"
-if [ -z "$DRACUT_SYSTEMD" ]; then
- printf 'mount %s /dev/mapper/live-rw %s\n' "$ROOTFLAGS" "$NEWROOT" > $hookdir/mount/01-$$-live.sh
+if [ -n "$overlayfs" ]; then
+ mkdir -m 0755 /run/rootfsbase
+ if [ -n "$reset_overlay" ] && [ -L /run/overlayfs ]; then
+ ovlfs=$(readlink /run/overlayfs)
+ info "Resetting the OverlayFS overlay directory."
+ rm -r -- ${ovlfs}/* ${ovlfs}/.* >/dev/null 2>&1
+ fi
+ if [ -n "$readonly_overlay" ]; then
+ mkdir -m 0755 /run/rootfsbase-r
+ mount -r $FSIMG /run/rootfsbase-r
+ mount -t overlay LiveOS_rootfs-r -oro,lowerdir=/run/overlayfs-r:/run/rootfsbase-r /run/rootfsbase
+ else
+ mount -r $FSIMG /run/rootfsbase
+ fi
+ if [ -z "$DRACUT_SYSTEMD" ]; then
+ #FIXME What to link to /dev/root? Is it even needed?
+ printf 'mount -t overlay LiveOS_rootfs -o%s,%s %s\n' "$ROOTFLAGS" \
+ 'lowerdir=/run/rootfsbase,upperdir=/run/overlayfs,workdir=/run/ovlwork' \
+ "$NEWROOT" > $hookdir/mount/01-$$-live.sh
+ fi
+else
+ ln -s /dev/mapper/live-rw /dev/root
+ 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
need_shutdown