Merge pull request #865 from SUSE/ramdisk_deployment

Support ramdisk deployment in OEM images
This commit is contained in:
Marcus Schäfer 2018-11-05 09:00:12 +01:00 committed by GitHub
commit 4fdeee3faa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 156 additions and 6 deletions

View File

@ -1,3 +1,5 @@
.. _oem:
Build an OEM Expandable Disk Image
==================================

View File

@ -18,3 +18,4 @@ different image types.
working_with_images/uninstall_package_requests
working_with_images/vagrant_setup
working_with_images/pxe_live_iso_boot
working_with_images/oem_ramdisk_deployment

View File

@ -0,0 +1,86 @@
.. _ramdisk_deployment:
Deploy and Run System in a RamDisk
==================================
.. sidebar:: Abstract
This page provides further information for handling
oem images built with KIWI and references the following
articles:
* :ref:`oem`
If a machine should run the OS completely in memory without
the need for any persistent storage, the approach to deploy
the image into a ramdisk serves this purpose. KIWI allows
to create a bootable ISO image which deploys the image
into a ramdisk and activates that image with the following
oem type definition:
.. code:: xml
<type image="oem" filesystem="ext4" installiso="true" bootloader="grub2" initrd_system="dracut" installboot="install" boottimeout="1" kernelcmdline="rd.kiwi.ramdisk ramdisk_size=2048000">
<oemconfig>
<oem-skip-verify>true</oem-skip-verify>
<oem-unattended>true</oem-unattended>
<oem-unattended-id>/dev/ram1</oem-unattended-id>
<oem-swap>false</oem-swap>
<oem-multipath-scan>false</oem-multipath-scan>
</oemconfig>
</type>
The type specification above builds an installation ISO image
which deploys the System Image into the specified ramdisk
device (/dev/ram1). The setup of the ISO image boots with a
short boot timeout of 1sec and just runs through the process
without asking any questions. In a ramdisk deployment the
optional target verification, swap space and multipath targets
are out of scope and therefore disabled.
The configured size of the ramdisk specifies the size of the
OS disk and must be at least of the size of the System Image.
The disk size can be configured with the following value in
the kernelcmdline attribute:
* ramdisk_size=kbyte-value"
An image built with the above setup can be tested in QEMU as
follows:
.. code:: bash
$ qemu -cdrom LimeJeOS-Leap-42.3.x86_64-1.42.3.install.iso
.. note:: Enough Main Memory
The machine, no matter if it's a virtual machine like QEMU
or a real machine, must provide enough RAM to hold the image
in the ramdisk as well as have enough RAM available to operate
the OS and its applications. The KIWI build image with the
extension .raw provides the System Image which gets deployed
into the RAM space. Substract the size of the System Image
from the RAM space the machine offers and make sure the result
is still big enough for the use case of the appliance. In
case of a virtual machine, attach enough main memory to fit
this calculation. In case of QEMU this can be done with
the `-m` option
Like all other oem KIWI images, also the ramdisk setup supports
all the deployments methods as explained in :ref:`deployment_methods`
This means it's also possible to dump the ISO image on a USB
stick let the system boot from it and unplug the stick from
the machine because the system was deployed into RAM
.. note:: Limitations Of RamDisk Deployments
Only standard images which can be booted by a simple root mount
and root switch can be used. Usually KIWI calls kexec after deployment
such that the correct, for the image created dracut initrd, will boot
the image. In case of a RAM only system kexec does not work because
it would loose the ramdisk contents. Thus the dracut initrd driving
the deployment is also the environment to boot the system.
There are cases where this environment is not suitable to boot
the system. One example would be luks encrypted images which requires
to run unlock code inside of the initrd which is not present in the
initrd created for deployment.

View File

@ -36,14 +36,29 @@ function get_disk_list {
local disk_meta
local item_status=on
local list_items
local blk_opts
if [ ! -z "${kiwi_devicepersistency}" ];then
disk_id=${kiwi_devicepersistency}
fi
if [ ! -z "${kiwi_oemmultipath_scan}" ];then
if getargbool 0 rd.kiwi.ramdisk; then
# target should be a ramdisk on request. Thus actively
# load the ramdisk block driver and support custom sizes
local rd_size
local modfile=/etc/modprobe.d/99-brd.conf
rd_size=$(getarg ramdisk_size=)
if [ ! -z "${rd_size}" ];then
echo "options brd rd_size=${rd_size}" > ${modfile}
fi
modprobe brd
udev_pending
# target should be a ramdisk on request. Thus instruct
# lsblk to list only ramdisk devices (Major=1)
blk_opts="-I 1"
elif [ ! -z "${kiwi_oemmultipath_scan}" ];then
scan_multipath_devices
fi
for disk_meta in $(
lsblk -p -n -r -o NAME,SIZE,TYPE | grep disk | tr ' ' ":"
lsblk "${blk_opts}" -p -n -r -o NAME,SIZE,TYPE | grep disk | tr ' ' ":"
);do
disk_device="$(echo "${disk_meta}" | cut -f1 -d:)"
if [ "$(blkid "${disk_device}" -s LABEL -o value)" = \
@ -373,6 +388,14 @@ fi
check_image_integrity "${image_target}"
boot_installed_system
exit 0
if getargbool 0 rd.kiwi.ramdisk; then
# For ramdisk deployment a kexec boot is not possible as it
# will wipe the contents of the ramdisk. Therefore we prepare
# the switch_root from this deployment initrd. Also see the
# unit generator: dracut-kiwi-ramdisk-generator
kpartx -s -a "${image_target}"
else
# Standard deployment will use kexec to activate and boot the
# deployed system
boot_installed_system
fi

View File

@ -0,0 +1,33 @@
#!/bin/bash
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
GENERATOR_DIR="$1"
[ -z "${GENERATOR_DIR}" ] && exit 1
[ -d "${GENERATOR_DIR}" ] || mkdir -p "${GENERATOR_DIR}"
root_uuid=$(
while read -r -d ' ' opt; do echo "${opt}";done < /config.bootoptions |\
grep root= | cut -f2- -d=
)
{
echo "[Unit]"
echo "Before=initrd-root-fs.target"
echo "[Mount]"
echo "Where=/sysroot"
echo "What=${root_uuid}"
_dev=RamDisk_rootfs
} > "$GENERATOR_DIR"/sysroot.mount
if [ ! -e "$GENERATOR_DIR/initrd-root-fs.target.requires/sysroot.mount" ]; then
mkdir -p "$GENERATOR_DIR"/initrd-root-fs.target.requires
ln -s "$GENERATOR_DIR"/sysroot.mount \
"$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount
fi
mkdir -p "$GENERATOR_DIR/$_dev.device.d"
{
echo "[Unit]"
echo "JobTimeoutSec=60"
} > "$GENERATOR_DIR/$_dev.device.d/timeout.conf"

View File

@ -14,8 +14,9 @@ installkernel() {
# called by dracut
install() {
declare moddir=${moddir}
declare systemdutildir=${systemdutildir}
inst_multiple \
tr lsblk dd md5sum head pv kexec basename awk
tr lsblk dd md5sum head pv kexec basename awk kpartx
inst_hook pre-udev 30 "${moddir}/kiwi-installer-genrules.sh"
inst_hook pre-udev 60 "${moddir}/kiwi-dump-net-genrules.sh"
@ -25,6 +26,10 @@ install() {
inst_hook cmdline 30 "${moddir}/parse-kiwi-install.sh"
inst_hook pre-mount 30 "${moddir}/kiwi-dump-image.sh"
inst_script "${moddir}/kiwi-ramdisk-deployment-generator.sh" \
"${systemdutildir}/system-generators/dracut-kiwi-ramdisk-generator"
inst_rules 60-cdrom_id.rules
dracut_need_initqueue
}