summaryrefslogtreecommitdiffstats
path: root/builder
diff options
context:
space:
mode:
authorJonathan Bauer2015-05-28 13:56:27 +0200
committerJonathan Bauer2015-05-28 13:56:27 +0200
commit14dde32029e320b8d36ca4cd1ec2d9b114183a2e (patch)
tree25075f1ee6ca1678b870c992ae24b846d14b853b /builder
parentDO NOT USE YET. YOU'VE BEEN WARNED!!111 (diff)
downloadsystemd-init-14dde32029e320b8d36ca4cd1ec2d9b114183a2e.tar.gz
systemd-init-14dde32029e320b8d36ca4cd1ec2d9b114183a2e.tar.xz
systemd-init-14dde32029e320b8d36ca4cd1ec2d9b114183a2e.zip
restructured
'builder' builds the initramfs with our dracut module 'packager' builds/packs the stage4 rootfs
Diffstat (limited to 'builder')
-rw-r--r--builder/INSTALL19
-rw-r--r--builder/dnbd3-qcow2-rootfs/TODO5
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/binaries/busyboxbin0 -> 504912 bytes
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/binaries/dnbd3-clientbin0 -> 31150 bytes
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/binaries/systemd-preserve-process-markerbin0 -> 7728 bytes
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/debugging_tools/busyboxbin0 -> 931664 bytes
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/debugging_tools/endlessbin0 -> 6752 bytes
-rw-r--r--builder/dnbd3-qcow2-rootfs/debugging_tools/endless.c10
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/debugging_tools/nbd-clientbin0 -> 59639 bytes
-rw-r--r--builder/dnbd3-qcow2-rootfs/debugging_tools/nbd-debugging.kobin0 -> 463248 bytes
-rw-r--r--builder/dnbd3-qcow2-rootfs/debugging_tools/network.functions23
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/debugging_tools/qemu-nbdbin0 -> 7131314 bytes
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/debugging_tools/qemu-nbd-systemd-markbin0 -> 7128103 bytes
-rw-r--r--builder/dnbd3-qcow2-rootfs/debugging_tools/setup-network.sh84
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/hooks/cmdline/enable-sysrq.sh2
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/hooks/cmdline/expand-kcl-ip.sh36
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/hooks/cmdline/mark-root-device.sh9
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/hooks/mount/mount-root-device.sh4
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/hooks/pre-mount/fetch-config.sh39
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/hooks/pre-mount/mount-qcow.sh49
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/hooks/pre-pivot/mount-tmp.sh40
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/hooks/pre-udev/lo-setup.sh1
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/hooks/pre-udev/load-dnbd3-nbd-modules.sh32
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/kernel_modules/dnbd3.kobin0 -> 1345285 bytes
-rw-r--r--builder/dnbd3-qcow2-rootfs/kernel_modules/nbd.kobin0 -> 463216 bytes
-rw-r--r--builder/dnbd3-qcow2-rootfs/module-setup.sh121
-rw-r--r--builder/dnbd3-qcow2-rootfs/readme.md472
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/scripts/prepare-disks211
-rwxr-xr-xbuilder/dnbd3-qcow2-rootfs/scripts/setup-qcow2137
-rw-r--r--builder/dnbd3-qcow2-rootfs/systemd-preserve-process-marker.c33
-rw-r--r--builder/dnbd3-qcow2-rootfs/udev/70-openslx-disk.rules8
31 files changed, 1335 insertions, 0 deletions
diff --git a/builder/INSTALL b/builder/INSTALL
new file mode 100644
index 00000000..e52f0c39
--- /dev/null
+++ b/builder/INSTALL
@@ -0,0 +1,19 @@
+This subfolder is dedicated to dracut related files.
+
+The folder 'dnbd3-qcow2-rootfs' is a dracut module used to setup
+a client's rootfs based on a (read-only) dnbd3 export made writable
+through the qcow2 container format of the qemu ecosystem.
+
+To use this module within dracut, you simply need to copy/link/mount
+the above mentioned folder to '/usr/lib/dracut/modules.d' prefixed
+with a numerical priority. We used '90' so far, so the module was linked
+to '/usr/lib/dracut/modules.d/90dnbd3-qcow2-rootfs'.
+
+Once the module has been integrated in dracut's modules, you can build
+the initramfs with the following command:
+
+ dracut --no-hostonly --modules "dnbd3-qcow2-rootfs" <target_path>
+
+Note that the '--no-hostonly' is critical if the machine dracut is
+executed on and the clients supposed to boot the resulting initramfs
+differ.
diff --git a/builder/dnbd3-qcow2-rootfs/TODO b/builder/dnbd3-qcow2-rootfs/TODO
new file mode 100644
index 00000000..2e92a1d0
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/TODO
@@ -0,0 +1,5 @@
+* Dynamic building of dnbd3 / nbd kernel modules
+* Dynamic building of dnbd3-client / systemd-preserver-process-marker
+
+* Research whether the dracut busybox module satisfies our requirements
+* If not, compiling busybox should be done somehow
diff --git a/builder/dnbd3-qcow2-rootfs/binaries/busybox b/builder/dnbd3-qcow2-rootfs/binaries/busybox
new file mode 100755
index 00000000..7eceacf7
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/binaries/busybox
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/binaries/dnbd3-client b/builder/dnbd3-qcow2-rootfs/binaries/dnbd3-client
new file mode 100755
index 00000000..76924b49
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/binaries/dnbd3-client
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/binaries/systemd-preserve-process-marker b/builder/dnbd3-qcow2-rootfs/binaries/systemd-preserve-process-marker
new file mode 100755
index 00000000..45beb51d
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/binaries/systemd-preserve-process-marker
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/debugging_tools/busybox b/builder/dnbd3-qcow2-rootfs/debugging_tools/busybox
new file mode 100755
index 00000000..1212ae20
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/debugging_tools/busybox
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/debugging_tools/endless b/builder/dnbd3-qcow2-rootfs/debugging_tools/endless
new file mode 100755
index 00000000..de7a8c0a
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/debugging_tools/endless
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/debugging_tools/endless.c b/builder/dnbd3-qcow2-rootfs/debugging_tools/endless.c
new file mode 100644
index 00000000..22c9bc50
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/debugging_tools/endless.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ // Provides a dummy worker.
+ while (1)
+ sleep(999999999);
+}
diff --git a/builder/dnbd3-qcow2-rootfs/debugging_tools/nbd-client b/builder/dnbd3-qcow2-rootfs/debugging_tools/nbd-client
new file mode 100755
index 00000000..7bb2207f
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/debugging_tools/nbd-client
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/debugging_tools/nbd-debugging.ko b/builder/dnbd3-qcow2-rootfs/debugging_tools/nbd-debugging.ko
new file mode 100644
index 00000000..47cf6cd6
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/debugging_tools/nbd-debugging.ko
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/debugging_tools/network.functions b/builder/dnbd3-qcow2-rootfs/debugging_tools/network.functions
new file mode 100644
index 00000000..89ca5a20
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/debugging_tools/network.functions
@@ -0,0 +1,23 @@
+wait_for_iface() {
+ local DEVICE=$1
+ local TIMEOUT=10
+ echo -n "Waiting for interface $DEVICE: "
+ # Some systems don't have operstate. Seems to be hardware dependent
+ [ ! -e "/sys/class/net/${DEVICE}/operstate" ] && usleep 10000
+ if [ -e "/sys/class/net/${DEVICE}/operstate" ]; then
+ while true; do
+ # check linkstate
+ [ "x$(cat "/sys/class/net/${DEVICE}/operstate")" == "xup" ] && break
+ TIMEOUT=$(( $TIMEOUT - 1 )) # don't wait forever, the pcnet iface of vmware will never be "up" although it's working
+ [ "$TIMEOUT" -le 0 ] && break
+ # else
+ echo -n "."
+ usleep 500000
+ done
+ else
+ # we really don't have a operstate .. then just wait a sec and hope for the best.
+ sleep 1
+ fi
+ echo ".$(cat "/sys/class/net/${DEVICE}/operstate" 2>/dev/null)"
+}
+true
diff --git a/builder/dnbd3-qcow2-rootfs/debugging_tools/qemu-nbd b/builder/dnbd3-qcow2-rootfs/debugging_tools/qemu-nbd
new file mode 100755
index 00000000..b34a3ff7
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/debugging_tools/qemu-nbd
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/debugging_tools/qemu-nbd-systemd-mark b/builder/dnbd3-qcow2-rootfs/debugging_tools/qemu-nbd-systemd-mark
new file mode 100755
index 00000000..03c2a6b1
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/debugging_tools/qemu-nbd-systemd-mark
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/debugging_tools/setup-network.sh b/builder/dnbd3-qcow2-rootfs/debugging_tools/setup-network.sh
new file mode 100644
index 00000000..3b32a68c
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/debugging_tools/setup-network.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+
+echo "Setting up network..."
+
+echo "Main MAC address is '$MAC'"
+
+# setup network
+source /inc/network.functions
+
+# set up loopback networking
+echo "Setting up loopback"
+ip link set dev lo up 2>/dev/null
+ip addr add 127.0.0.1/8 dev lo 2>/dev/null
+
+echo "Setting up bridge"
+BRIDGE="br0"
+
+# Following was supposed to prevent scripts from getting confused by multiple interfaces with same MAC - does not work though
+## Flip mac address of original interface - this var is not local so init sees the changes too
+#MAC="$(echo "$MAC" | awk -F ':' '{printf $1 ":" $2 ":" $5 ":" $3 ":" $6 ":" $4}')"
+#ip link set addr "$MAC" "$SLAVE"
+
+mkdir -p "${FUTURE_ROOT}/etc/udev/rules.d"
+
+#IP_OUT=$(ip a | sed -r ':a;N;$!ba;s/: ([a-z0-9]+): /####\1####/g;s/ether ([a-f0-9:]+) /####\1####/g'| grep -E -o '####[^ ]+####' | sed 's/#//g' | grep -B 1 ':')
+IP_OUT=$(ip a | grep -B 1 "/ether" | sed -r '/^--$/d;$!N;s#^[0-9]+: ([a-z0-9\.:]+): .*?/ether ([0-9a-fA-Z:]+) .*$#\1==\2#')
+
+if ! echo "$IP_OUT" | grep -q -- "$MAC"; then
+ drop_shell "Boot interface not found in interface list. NIC driver missing?"
+fi
+
+for LINE in $IP_OUT; do
+ IFACE=$(echo "$LINE" | awk -F '==' '{printf $1}')
+ IFMAC=$(echo "$LINE" | awk -F '==' '{printf $2}' | tr '[A-Z]' '[a-z]') # udev requires mac addesses to be lowercase (a-f), see http://www.debianhelp.co.uk/udev.htm
+ echo "${IFACE} = ${IFMAC}"
+
+ if [ "x$IFMAC" == "x$MAC" ]; then
+ brctl addbr "$BRIDGE" || drop_shell "Could not create bridge $BRIDGE"
+ brctl stp "$BRIDGE" 0
+ brctl setfd "$BRIDGE" 0.000000000001
+ ip link set addr "$IFMAC" "$BRIDGE" || drop_shell "Could not set mac of $BRIDGE"
+ ip link set dev "$IFACE" up
+ wait_for_iface "$IFACE"
+ brctl addif "$BRIDGE" "$IFACE" || drop_shell "Could not add $IFACE to $BRIDGE"
+
+ # save our variables for retry on fail
+ echo "IFACE=$IFACE" > /run/network.conf
+
+ # analyze ip information from the kernel command line and put parts
+ # of it into several variables
+ if [ -n "$CLIENTIP" ] ; then
+ # set static ip address
+ ip addr add "$CLIENTIP/$(ipcalc -s -p "$CLIENTIP" "$SUBNET_MASK" | sed "s/.*=//")" broadcast "$BROADCAST_ADDRESS" dev "$BRIDGE"
+ ip link set dev "$BRIDGE" up
+ [ -n "$GATEWAY" ] && ip route add default via "$GATEWAY" dev "$BRIDGE"
+ else
+ NOIPYET="yes"
+ fi
+ # Ignore this device later on when systemd handles network interfaces (see hacked 99-systemd.rules in systemd data dir)
+ echo "SUBSYSTEM==\"net\", ACTION==\"add\", KERNEL==\"eth*\", ATTR{address}==\"$IFMAC\", TAG+=\"openslxignore\"" >> "${FUTURE_ROOT}/etc/udev/rules.d/01-ignore-boot-interface.rules"
+ fi
+ # youdev
+ echo "SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"?*\", ATTR{address}==\"$IFMAC\", ATTR{dev_id}==\"0x0\", ATTR{type}==\"1\", KERNEL==\"eth*\", NAME=\"$IFACE\"" >> "${FUTURE_ROOT}/etc/udev/rules.d/70-net-boot-nic-name.rules"
+ # continue...
+ IFACE=""
+done
+
+wait_for_iface "$BRIDGE"
+
+# udhcpc
+PARAM=
+if [ -n "$CLIENTIP" ]; then
+ PARAM="-r $CLIENTIP"
+fi
+echo -n "$CLIENTIP" > "/run/firstip"
+echo -n "$GATEWAY" > "/run/firstgw"
+
+# save our variables for retry on fail ff.
+echo "CLIENTIP=$CLIENTIP" >> /run/network.conf
+echo "GATEWAY=$GATEWAY" >> /run/network.conf
+echo "BRIDGE=$BRIDGE" >> /run/network.conf
+
+udhcpc $PARAM -O domain -O nissrv -O nisdomain -O wpad -O search -t 5 -T 2 -s "/inc/udhcpc-trigger" -f -n -q -i "$BRIDGE"
+# udhcpc return value will be return value of this script
diff --git a/builder/dnbd3-qcow2-rootfs/hooks/cmdline/enable-sysrq.sh b/builder/dnbd3-qcow2-rootfs/hooks/cmdline/enable-sysrq.sh
new file mode 100755
index 00000000..f779aa7a
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/hooks/cmdline/enable-sysrq.sh
@@ -0,0 +1,2 @@
+# enables magic sysrq keys
+echo 1 > /proc/sys/kernel/sysrq
diff --git a/builder/dnbd3-qcow2-rootfs/hooks/cmdline/expand-kcl-ip.sh b/builder/dnbd3-qcow2-rootfs/hooks/cmdline/expand-kcl-ip.sh
new file mode 100755
index 00000000..9f617b09
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/hooks/cmdline/expand-kcl-ip.sh
@@ -0,0 +1,36 @@
+command -v warn >/dev/null || . /lib/dracut-lib.sh
+
+# fakes the cmdline to fix the ip parsing in darcut's net-lib.sh
+[ -d /fake ] || mkdir /fake
+
+# need to be a tmpfs for the hack to work
+mount -t tmpfs tmpfs /fake
+
+for parameter in $(getargs ip=); do
+ local temp="$parameter:"
+ set --
+ while [ -n "$temp" ]; do
+ set -- "$@" "${temp%%:*}"
+ temp=${temp#*:}
+ done
+
+ [ -n "$1" ] && ip=$1
+ [ -n "$2" ] && server_ip=$2
+ [ -n "$3" ] && gateway_ip=$3
+ [ -n "$4" ] && net_mask=$4
+
+ warn "PXE given net configuration: ip: $ip server_ip: $server_ip gateway_ip: $gateway_ip net_mask: $net_mask"
+ local final_dracut_ip_config="$ip::$gateway_ip:$net_mask:hiwi-test-28:eno1:none"
+ warn "Final dracut ip config: $final_dracut_ip_config"
+ sed --regexp-extended "s/ip=[^ ]*/ip=$final_dracut_ip_config/g" /proc/cmdline > /fake/cmdline
+done
+
+
+# bind mount it. Can we trust mount return codes here?
+# # if so, we should check what we get in $?
+mount -o bind /fake/cmdline /proc/cmdline
+
+# check if it worked
+if ! grep 'hiwi-test-28:eno1:none' /proc/cmdline; then
+ warn 'Haxing cmdline did not work :( sad pandaz...'
+fi
diff --git a/builder/dnbd3-qcow2-rootfs/hooks/cmdline/mark-root-device.sh b/builder/dnbd3-qcow2-rootfs/hooks/cmdline/mark-root-device.sh
new file mode 100755
index 00000000..b7282521
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/hooks/cmdline/mark-root-device.sh
@@ -0,0 +1,9 @@
+# set rootok and root as dracut expects them to be set by
+# the module preparing the root filesystem.
+#
+# Once the root filesystem is mounted per dnbd3 and
+# exported as qcow2 per nbd, /dev/root will be a symlink
+# to /dev/nbd0 as this is then our rootfs-device
+rootok=1
+root=block:/dev/root
+
diff --git a/builder/dnbd3-qcow2-rootfs/hooks/mount/mount-root-device.sh b/builder/dnbd3-qcow2-rootfs/hooks/mount/mount-root-device.sh
new file mode 100755
index 00000000..d02f9002
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/hooks/mount/mount-root-device.sh
@@ -0,0 +1,4 @@
+# this rudimentary script just mounts the rootfs device that was symlinked to
+# /dev/root to dracut's $NEWROOT (usually /sysroot).
+
+mount /dev/root $NEWROOT
diff --git a/builder/dnbd3-qcow2-rootfs/hooks/pre-mount/fetch-config.sh b/builder/dnbd3-qcow2-rootfs/hooks/pre-mount/fetch-config.sh
new file mode 100755
index 00000000..a90481c8
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/hooks/pre-mount/fetch-config.sh
@@ -0,0 +1,39 @@
+# load dracut functions
+command -v getarg >/dev/null || . /lib/dracut-lib.sh
+
+# read SLX_SERVER and SLX_BASE from the kernel command line
+SLX_SERVER=$(getarg slxsrv)
+SLX_BASE=$(getarg slxbase)
+SLX_CONFIG_DIR="/opt/openslx"
+SLX_CONFIG_FILE="/opt/openslx/config"
+
+if [ -z "$SLX_SERVER" ]; then
+ warn "No 'slxsrv' parameter found in the kernel command line!"
+ warn "Skipping OpenSLX configuration..."
+ return 1
+fi
+if [ -z "$SLX_BASE" ]; then
+ warn "No 'slxbase' parameter found in the kernel command line!"
+ warn "Skipping OpenSLX configuration..."
+ return 1
+fi
+
+info "Getting configuration from OPENSLX-Server..."
+WGET="$(busybox which wget)"
+if [ -z $WGET ]; then
+ # do nothing
+ warn "'wget' not found. Skipping openslx configuration..."
+ return 1
+fi
+
+# ok then we are ready to download the config
+mkdir -p "${SLX_CONFIG_DIR}"
+$WGET -T 5 -q "http://${SLX_SERVER}/${SLX_BASE}/config" -O "${SLX_CONFIG_FILE}"
+RET="$?"
+if [ $RET -ne 0 ]; then
+ warn "Downloading OpenSLX configuration from ${SLX_SERVER}/${SLX_BASE} failed: $RET"
+ emergency_shell -n "$0"
+ return 1
+else
+ return 0
+fi
diff --git a/builder/dnbd3-qcow2-rootfs/hooks/pre-mount/mount-qcow.sh b/builder/dnbd3-qcow2-rootfs/hooks/pre-mount/mount-qcow.sh
new file mode 100755
index 00000000..d70492bf
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/hooks/pre-mount/mount-qcow.sh
@@ -0,0 +1,49 @@
+###############################################################################
+# CHECKS
+#
+
+SETUP_ROOTFS_SCRIPT="/sbin/setup-qcow2"
+
+if [ ! -e "${SETUP_ROOTFS_SCRIPT}" ]; then
+ warn "No such file of directory: ${SETUP_ROOTFS_SCRIPT}"
+ emergency_shell -n "Error in $0"
+ return 1
+fi
+
+if [ ! -x "${SETUP_ROOTFS_SCRIPT}" ]; then
+ warn "Cannot execute: ${SETUP_ROOTFS_SCRIPT}"
+ emergency_shell -n "Error in $0"
+ return 1
+fi
+
+#
+# END CHECKS
+###############################################################################
+
+###############################################################################
+# MAIN CODE
+#
+
+# ok, let's source the setup script
+if ! . ${SETUP_ROOTFS_SCRIPT} ; then
+ warn "Could not source: ${SETUP_ROOTFS_SCRIPT}"
+ emergency_shell -n "Error in $0"
+ return 1
+fi
+
+# just go over the functions in the right order ;-)
+for fun in connect_dnbd3 create_qcow export_qcow connect_qcow; do
+ if ! $fun; then
+ # something failed, drop a shell for debugging
+ warn "'$fun' failed with: $?"
+ emergency_shell -n "Error in $fun"
+ return 1
+ fi
+done
+
+# all good, we are done
+return 0
+
+#
+# END MAIN CODE
+###############################################################################
diff --git a/builder/dnbd3-qcow2-rootfs/hooks/pre-pivot/mount-tmp.sh b/builder/dnbd3-qcow2-rootfs/hooks/pre-pivot/mount-tmp.sh
new file mode 100755
index 00000000..3e702064
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/hooks/pre-pivot/mount-tmp.sh
@@ -0,0 +1,40 @@
+# This script only checks if we found a usable partition for the
+# future /tmp. The discovery of that partition is done by udev during
+# the initqueue. If a valid partition is found (either GPT with the label
+# OPENSLX_TMP or MBR with the type 0x44) its path will be written to
+# /tmp/openslx.tmpdisk
+OPENSLX_TMP_DISK_FLAG="/tmp/openslx.disk.tmp"
+
+if [ ! -e "$OPENSLX_TMP_DISK_FLAG" ]; then
+ warn "'$OPENSLX_TMP_DISK_FLAG' not found!"
+ warn "Systemd will manage $NEWROOT/tmp on its own."
+ # no partition for the future /tmp found, just
+ # let systemd manage it then (probably a tmpfs)
+ return 1
+fi
+
+# in /tmp/openslx.disk.tmp is the name of the device
+# to mount as /tmp in the real system
+# meaning we need to mount it to /sysroot/tmp here.
+
+OPENSLX_TMP_DISK_DEV="$(cat $OPENSLX_TMP_DISK_FLAG)"
+
+# sanity check: is the content a block device?
+if [ ! -b "$OPENSLX_TMP_DISK_DEV" ]; then
+ warn "'$OPENSLX_TMP_DISK_DEV' appears not to be a block device!"
+ warn "Systemd will manage $NEWROOT/tmp on its own."
+ return 1
+fi
+
+# all good, keep on
+if ! mount -t auto "$OPENSLX_TMP_DISK_DEV" $NEWROOT/tmp; then
+ # something else went wrong :(
+ warn "Mounting '$OPENSLX_TMP_DISK_DEV' to '$NEWROOT/tmp' failed with: $!"
+ warn "Systemd will manage $NEWROOT/tmp on its own."
+ return 1
+fi
+
+# still here? mount worked wohoo
+# set permissions
+chmod a+rwxt $NEWROOT/tmp
+return 0
diff --git a/builder/dnbd3-qcow2-rootfs/hooks/pre-udev/lo-setup.sh b/builder/dnbd3-qcow2-rootfs/hooks/pre-udev/lo-setup.sh
new file mode 100755
index 00000000..9103afd9
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/hooks/pre-udev/lo-setup.sh
@@ -0,0 +1 @@
+/sbin/initqueue --name ifup-lo --unique --onetime /sbin/ifup lo -m
diff --git a/builder/dnbd3-qcow2-rootfs/hooks/pre-udev/load-dnbd3-nbd-modules.sh b/builder/dnbd3-qcow2-rootfs/hooks/pre-udev/load-dnbd3-nbd-modules.sh
new file mode 100755
index 00000000..29f9f210
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/hooks/pre-udev/load-dnbd3-nbd-modules.sh
@@ -0,0 +1,32 @@
+# include dracut-lib.sh to use 'warn'
+command -v warn >/dev/null || . /lib/dracut-lib.sh
+
+NBD_MOD_PATH="/usr/lib/modules/current/extra/nbd.ko"
+DNBD3_MOD_PATH="/usr/lib/modules/current/extra/dnbd3.ko"
+
+# do we actually have our modules?
+if [ ! -e "${NBD_MOD_PATH}" ]; then
+ warn "No such file of directory: ${NBD_MOD_PATH}"
+ emergency_shell -n "Error in $0"
+ return 1
+fi
+if [ ! -e "${DNBD3_MOD_PATH}" ]; then
+ warn "No such file of directory: ${DNBD3_MOD_PATH}"
+ emergency_shell -n "Error in $0"
+ return 1
+fi
+
+# load the kernel modules for dnbd3 and nbd
+if ! insmod "${DNBD3_MOD_PATH}"; then
+ warn "Failed to load DNBD3 kernel module..."
+ emergency_shell -n "Error in $0"
+ return 1
+fi
+
+if ! insmod "${NBD_MOD_PATH}"; then
+ warn "Failed to load NBD kernel module..."
+ emergency_shell -n "Error in $0"
+ return 1
+fi
+
+return 0
diff --git a/builder/dnbd3-qcow2-rootfs/kernel_modules/dnbd3.ko b/builder/dnbd3-qcow2-rootfs/kernel_modules/dnbd3.ko
new file mode 100755
index 00000000..d7b7ce3b
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/kernel_modules/dnbd3.ko
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/kernel_modules/nbd.ko b/builder/dnbd3-qcow2-rootfs/kernel_modules/nbd.ko
new file mode 100644
index 00000000..e8c3f40f
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/kernel_modules/nbd.ko
Binary files differ
diff --git a/builder/dnbd3-qcow2-rootfs/module-setup.sh b/builder/dnbd3-qcow2-rootfs/module-setup.sh
new file mode 100644
index 00000000..b3f14c1d
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/module-setup.sh
@@ -0,0 +1,121 @@
+#!/bin/bash
+
+check() {
+ if ! type -f qemu-nbd >/dev/null; then
+ echo "'qemu-nbd' not found on this system, install it to use this module."
+ return 1
+ fi
+ if ! type -f qemu-img >/dev/null; then
+ echo "'qemu-img' not found on this system, install it to use this module."
+ return 1
+ fi
+ if ! type -f nbd-client >/dev/null; then
+ echo "'nbd-client' not found on this system, install it to use this module."
+ return 1
+ else
+ # check version
+ local nbd_client_version="$(nbd-client --help 2>&1 | grep -oE '3\.[0-9]+')"
+ local nbd_client_version_major="${nbd_client_version%.*}"
+ local nbd_client_version_minor="${nbd_client_version#*.}"
+ if [ "${nbd_client_version_major}" -ne 3 ]; then
+ # nbd-client probably too old
+ echo "The nbd-client major version is not 3, meaning its probably too old."
+ return 1
+ fi
+ if [ "${nbd_client_version_minor}" -gt 8 ]; then
+ # TODO check if ver = 3.9 has the same new syntax...
+ echo "The nbd-client minor version is greater than 8. A new syntax has been
+ introduced starting with 3.10 which we do not support."
+ return 1
+ fi
+ return 0
+ fi
+}
+
+depends() {
+ echo base network bash kernel-modules
+ return 0
+}
+
+installkernel() {
+ instmods ext4
+}
+
+install() {
+ ### BINARIES
+ #
+ # busybox: cause we want lightweight tools
+ inst "$moddir/binaries/busybox" /usr/bin/busybox
+ # dnbd3-client: needed to mount remote dnbd3 filesystem.
+ inst "$moddir/binaries/dnbd3-client" /usr/bin/dnbd3-client
+ # A generic wrapper program to prepend a "@" to each process
+ # spawned by given nested programs.
+ inst "$moddir/binaries/systemd-preserve-process-marker" \
+ /usr/bin/systemd-preserve-process-marker
+
+ # NOTE: These modules are build again Kernel: 3.10.0-229.1.2.el7.x86_64
+ # TODO: build these in check() !
+ inst "$moddir/kernel_modules/dnbd3.ko" \
+ /usr/lib/modules/current/extra/dnbd3.ko
+ inst "$moddir/kernel_modules/nbd.ko" \
+ /usr/lib/modules/current/extra/nbd.ko
+
+ ### HOOKS
+ ## HOOK cmdline
+ # enables sysrq-shortcuts
+ inst_hook cmdline 00 "$moddir/hooks/cmdline/enable-sysrq.sh"
+
+ # expands the ip parameter in the kernel command line to
+ # make it dracut-compatible
+ # TODO: dracut still parses this incorrectly...
+ inst_hook cmdline 10 "$moddir/hooks/cmdline/expand-kcl-ip.sh"
+
+ # sets environment variables to tell dracut which device
+ # holds the future root filesystem
+ inst_hook cmdline 90 "$moddir/hooks/cmdline/mark-root-device.sh"
+
+ ## HOOK pre-udev
+ # loads the dnbd3/nbd kernel modules
+ inst_hook pre-udev 00 "$moddir/hooks/pre-udev/load-dnbd3-nbd-modules.sh"
+
+ # setup loopback device
+ inst_hook pre-udev 00 "$moddir/hooks/pre-udev/lo-setup.sh"
+
+ ## HOOK pre-mount
+ # this is the configuration hook where the config stuff is wget'ed
+ inst_hook pre-mount 00 "$moddir/hooks/pre-mount/fetch-config.sh"
+
+ # this is the main hook where all the magic is triggered
+ inst_hook pre-mount 10 "$moddir/hooks/pre-mount/mount-qcow.sh"
+
+ ## HOOK mount
+ # this simply mounts the prepared /dev/root to $NEWROOT
+ # aka "the dracut way"
+ inst_hook mount 10 "$moddir/hooks/mount/mount-root-device.sh"
+
+ ## HOOK pre-pivot
+ # this checks whether we found a partition suitable for
+ # the future /tmp and if so, mounts it
+ inst_hook pre-pivot 00 "$moddir/hooks/pre-pivot/mount-tmp.sh"
+
+ ### SCRIPTS
+ # the main magic script containing all the functions needed
+ # to prepare the qcow2-based root filesystem
+ inst "$moddir/scripts/setup-qcow2" /sbin/setup-qcow2
+
+ # the script triggered by udev upon finding the right partitions
+ inst "$moddir/scripts/prepare-disks" /sbin/prepare-disks
+
+ # udev rules detecting 44, 45, 46 partitions and running
+ # 'prepare-disks' to do then format/mount/use them
+ inst "$moddir/udev/70-openslx-disk.rules" /etc/udev/rules.d/70-openslx-disk.rules
+
+ # Debugging Uncomment this version if you need some useful debugging tools
+ # in your iniramfs.
+ inst_multiple lsblk ping ip ifconfig sshd htop tail head cat vim \
+ touch sed lsmod insmod qemu-img sleep route wget find lsof strace \
+ chroot switch_root pivot_root qemu-nbd mount nbd-client fdisk mkfs.xfs
+ # Production:
+ # inst_multiple insmod qemu-img qemu-nbd
+ return 0
+}
diff --git a/builder/dnbd3-qcow2-rootfs/readme.md b/builder/dnbd3-qcow2-rootfs/readme.md
new file mode 100644
index 00000000..9ad0f968
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/readme.md
@@ -0,0 +1,472 @@
+# TODO --ommit npd
+# TODO Testmenue PW: t
+
+h1. Evaluation, dissection and modification of Linux remote boot
+
+h2. Inhalt
+
+{{toc}}
+
+#h2. Begriffe
+
+#* qcow - qemu copy-on-write
+#* stage3.1 initramfs
+#* stage4 finales System
+
+h2. Aufgabe
+
+Es wird ein Skript bzw. Dracut-Modul benötigt, dass ein initramfs basierend auf
+systemd baut. Das resultierende initramfs muss Netzwerk-Support bereitstellen,
+ein dnbd3 Blockdevice mounten können und einen "switch_root" auf das zuvor
+gemountete Dateisystem umsetzen. Das Framework sollte möglichst
+Distributionsunabhängig konstruiert sein. Es soll bereits vor dem
+"switch_root", also bevor das eigentliche Zielsystem im Root-Verzeichnis
+eingebunden werden systemd als init-System zum Einsatz kommen. Die Kernaufgabe
+eine initramfs ist es alle nötigen Anwendungen bereitzustellen, die benötigt
+werden, um dass finale Zielsystem einzubinden. In dieser konkreten
+Aufgabenstellung muss, dass initramfs ein nicht schreibbares Blockgerät
+eingebunden werden und eine schreibbare Zwischenshicht (Overlayfilesystem)
+zusätzlich eingebunden werden.
+
+h2. Möglicher Technologien für das Overlaykonzept
+
+* Dateibasierte Overlay-FS (Union-FS, Alternat-Union-FS, Overlay-FS)
+ - Funktioniert derzeit nicht auf jedem Zielsystem (Kernel)
+ - Nicht für den Linux-Kernel zertifiziert oder lässt sich nicht über das
+ Root-System legen.
+ - Bei wenigen Änderungen in einer großen Datei muss komplette Datei in
+ der schreibbaren Schicht gespeichert werden.
+* Blockorientierte Overlay-FS (Network-Block-Device, DNBD3, Qemu-Copy-On-Write-Image)
+ - NBD ist für den Linux-Kernel zertifiziert
+ - Weniger Netzwerkverkehr nötig, da nur geänderte Blöcke übertragen werden
+ müssen, statt ganze Dateien zu kopieren.
+ - DNBD3 hat Failover-Strategien, verzichtet auf komplexe Strategien zum
+ Schreiben in geänderte Blöcke über das Netzwerk
+ - Das verfügbare qcow2-Format bietet eine Technologie, um blockorientiert
+ Änderungen in einer zusätzlichen Dateisystemschicht zu speichern.
+
+h2. Zielablauf
+
+Der generelle Ablauf vor bzw. während des Ladens des initramfs und deren
+Minilinux-System:
+
+# Boot PXE
+> # Laden des initramfs images
+> # Laden des Kernels
+# Ausführen des iniramfs
+> # Ausführen von Systemd
+> > # Bereitstellen aller benötigten Dienste und Hardware (Netzwerk hochbringen)
+> > # Mounten des finalen Dateisystems als Wurzel
+> > # Wechsel (switch_root) in die finale Distribution
+> > # Starten / Weiterausführen von Systemd als Init-System
+
+h2. Benötigte Pakete zum bauen des initramfs
+
+> * dracut
+# TODO
+
+h2. Benötigte Pakete innerhalb des resultierenden initramfs
+
+> * systemd
+> * quemu-img
+> * quemu-nbd
+> * nbd-client
+> * dnbd3-client
+
+h2. Aufsetzen einer Test-Arbeitsumgebung für CentOS
+
+h3. CentOS7/ArchLinux/RedHat/Ubuntu + VirtualBox + VirtualBoxGuestAdditions
+
+Aufsetzen des *Dynamic Kernel Module Support*, um einfach neue VBox-Kernel-Module zu aktualisieren:
+
+> # Aktualisiere Paketdatenbank: @yum update@
+> # Intalliere C-Compiler: @yum install gcc@
+> # Lade erweitertes rpmforfe Repository: @wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el7.rf.x86_64.rpm@
+> # Installiere Repository: @rpm -Uvh rpmforge-release-0.5.3-1.el7.rf.x86_64.rpm@
+> # Lade das DKMS-Paket: @wget ftp://rpmfind.net/linux/epel/5/x86_64/dkms-2.2.0.3-29.el5.noarch.rpm@
+> # Installiere DKMS-Paket: @yum localinstall dkms-2.2.0.3-25.el7.noarch.rpm --nogpgcheck@
+> # Aktiviere rpmforge Repository: @yum --enablerepo rpmforge install dkms@
+> # Installiere Entwicklertools zum bauen von Paketen: @yum groupinstall "Development Tools"@
+> # Installiere Metainformation zum Kernel: @yum install kernel-devel@
+
+Installieren der VirtualBox-GuestAddtion:
+
+> # Lege die VirtualBox-GuestAddition-CD ein.
+> # Mounte CD: @mount /dev/sr0 /mnt/ && cd /mnt/ && ./VBoxLinuxAdditions.run && reboot@
+
+Erstellen eines Testboot Eintrags für Grub2:
+
+> - Füge in ??/etc/grub.d/40_custom?? den folgenden Inhalt hinzu:
+
+<pre>
+menuentry 'test' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-123.el7.x86_64-advanced-6c06919a-389a-4a50-8c6b-b086e65db9b0' {
+ load_video
+ set gfxpayload=keep
+ insmod gzio
+ insmod part_msdos
+ insmod xfs
+ set root='hd0,msdos1'
+ if [ x$feature_platform_search_hint = xy ]; then
+ search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 4236333a-a808-4f6b-b4a6-d963f4a69a25
+ else
+ search --no-floppy --fs-uuid --set=root 4236333a-a808-4f6b-b4a6-d963f4a69a25
+ fi
+ linux16 /vmlinuz-3.10.0-123.el7.x86_64 root=UUID=6c06919a-389a-4a50-8c6b-b086e65db9b0 ro rd.lvm.lv=centos/swap crashkernel=auto rd.lvm.lv=centos/root vconsole.font=latarcyrheb-sun16 vconsole.keymap=de rhgb quiet
+ initrd16 /initramfs-test.img
+}
+</pre>
+
+> - Füge neuen Menüeintrag in die automatisch generierte Grub2 Konfigurations2-Datei hinzu: @grub2-mkconfig -o /boot/grub2/grub.cfg@
+
+h2. Bauen eines Test-Initramfs
+
+Mache ein Backup vom aktuellen initamfs:
+@cp -p /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.BACKUP@
+
+Der folgende Befehl ersetzt das aktuelle Standart Initramfs mit dem neu
+gebauten und berücksichtigt dabei alle bisher editierten Dracut-Module in
+??/usr/lib/dracut/modules.d??. Die durchschnittliche Größe des resultierenden
+initramfs beträgt komprimiert: zwischen 11 und 16 MB.
+
+<pre><code class="bash">
+dracut --verbose --force /boot/initramfs-3.10.0-123.el7.x86_64.test.img \
+ 3.10.0-123.el7.x86_64
+</code></pre>
+
+h3. Konfiguration
+
+TODO
+
+# Configure "cmdline" from "Chapter 8. DRACUT.CMDLINE(7)" in virtualbox in "/boot/startup.sh" for uefi or in "/boot/grub2/grub.cfg" for grub2
+
+h2. Bauen eines minimalen individuellen Test-Initramfs
+
+<pre><code class="bash">
+dracut --verbose --hostonly --force
+ /boot/initramfs-3.10.0-123.el7.x86_64.test.img \
+ 3.10.0-123.el7.x86_64
+</code></pre>
+
+Die Option "hostonly" veranlasst Dracut dazu nur alle nötigen Abhängigkeiten
+für das aktuelle System in das resultierende Initramfs zu installieren.
+Andernfalls fügt dracut viele zusätzliche Treiber hinzu, die die Größe der
+resultierenden Datei erheblich vergrößern und damit größer wird als nötig.
+Die durchschnittliche Größe des resultierenden initramfs beträgt
+komprimiert: zwischen 11 und 16 MB.
+
+h2. Erstellen eines eigenen Dracut-Moduls
+
+Alle vorhanden Module befinden sich in ??/usr/lib/dracut/modules.d??.
+
+> # Erstelle ein neues Modul: @mkdir /usr/lib/dracut/modules.d/91test@
+> # Baue neues initramfs und achte darauf, dass ??\*\*Including module: test\*\*?? mit der Command-Line-Option ??--verbose?? ausgegeben wird.
+> # Alle Modul-Installations-Informationen sind in der Datei ??module-setup.sh??: @touch /usr/lib/dracut/modules.d/91test/module-setup.sh@
+> # Konfiguriere Modul:
+> > # Als erstes erstellt man eine ??check??-Funktion, die lediglich ??0??
+ zurückgibt. Diese Funktion wird aufgerufen, wenn entschieden wird, welche
+ Dracutmodule geladen werden sollen. Durch zurückgeben der ??0?? wird das
+ Modul beim nächsten bauen eines Initramfs automatisch hinzugefügt ohne
+ das man es etwas in der ??/etc/dracut.conf?? oder per Command-Line-Option
+ "--add" angeben muss. Wenn die @$hostonly@ Variable gesetzt ist, dann
+ wird das Modul auch im "hostonly" Modus geladen. In diesem Fall sollte
+ die Funktion nur dann ??0?? zurückgeben, wenn das Modul auch wircklich
+ für den aktuellen Host benötigt wird. Wenn 255 zurückgegeben wird, wird
+ das Modul nur dann geladen, wenn es von einem andren Modul als
+ Abhängigkeit deklariert wurde.
+
+<pre><code class="bash">
+check() {
+ return 0
+}
+</code></pre>
+
+Als nächstes wird eine ??install??-Funktion erstellt. Die ??install??-Funktion
+wird aufgerufen, wenn alle nicht Kernel spezifischen Ressourcen installiert
+werden sollen. Es können Binärdateien, Skripte und andere statischen Dateien
+installiert werden. Um einen Datei im aktuellen Modul-Ordner zu addressieren
+sollte die Variable "$moddir" als Prefix eingesetzt werden.
+Eine solche Funktion kann beispielsweise einen ??Command-Line-Hook?? triggern,
+der modulespezifische ??Kernel-Command-Line-Optionen?? verarbeitet während das
+initiale Minilinux bootet. Im folgenden Beispiel werden ??Command-Line-Optionen
+mit Priorität 20 vom Shell-Skript ??parse-insmodpost.sh?? gelesen und
+ausgewertet. Dadurch muss natürlich auch das entsprechende Skript in das
+initramfs kopiert werden. Dies wird durch den Aufruf der Funktion
+??inst_simple?? erreicht.
+
+<pre><code class="bash">
+install() {
+ inst_hook cmdline 20 "$moddir/parse-cmdline.sh"
+ inst_simple "$moddir/parse-cmdline.sh" /sbin/insmodpost.sh
+}
+</code></pre>
+
+Die ??parse-cmdline.sh?? parst die Kernel-Command-Line für die Argumente
+??rd.driver.post??, verhindert, dass die Module automatisch geladen werden und
+installiert den Hook ??hook.sh?? in der ??initqueue/settled??. Der Inhalt von
+??parse-cmdline.sh?? könnte wie folgt aussehen:
+
+<pre><code class="bash">
+for p in $(getargs rd.driver.post=); do
+ echo "blacklist $p" >> /etc/modprobe.d/initramfsblacklist.conf
+done
+</code></pre>
+
+In einer ??depends??-Funktion können andere Dracut-Module als Abhängigkeit
+deklariert werden. Diese müssen einfach per "echo" als String Leerzeichen
+getrennt ausgegeben werden.
+
+<pre><code class="bash">
+depends() {
+ echo 'debug virtfs'
+}
+</code></pre>
+
+Mit dieser Funktion können zusätzliche benötigte Kernel-Command-Line-Argumente
+ausgegeben werden, die benötigt werden um die aktuelle Maschine zu booten.
+Die Ausgabe sollte mit einem Leerzeichen beginnen und keine neuen Zeilen
+ausgeben.
+
+<pre><code class="bash">
+cmdline() {
+ echo 'TODO'
+}
+</code></pre>
+
+Mit der Funktion ??installkernel?? sollen alle kernelspezifischen Dateien
+installiert werden. Siehe hierzu auch den Abschnitt
+??Hilfsfunktionen zur Installation??
+
+<pre><code class="bash">
+installkernel() {
+ TODO
+}
+</code></pre>
+
+h2. Hilfsfunktionen zur Installation
+
+??inst_multiple?? installiert mehrere Binärdateien. Sollten ausführbare Dateien
+ohne entsprechendem Pfad ausgewählt werden, wird dracut folgende die Pfade
+??/usr/sbin??, ??/sbin??, ??/usr/bin??, ??/bin?? durchsuchen, um den Pfad der
+zugehörigen ausführbaren Datei zu ermitteln. Bei dem Kommando-Zeilen-Argument
+??-o?? als erster Parameter werden Fehler bei nicht auffindbaren Dateien
+unterdrückt.
+
+??inst_multiple [-o] <file> [ <file> …]??
+
+??inst?? installiert eine referenzierte Datei an den korrespondierenden Ort im
+??initramfs??. Die Datei wird innerhalb des ??initramfs?? am gleichen Ort zu
+finden sein wie auf der Referenzmaschine. Optional kann als zweites Argument
+ein anderer Ort für das temporäre Dateisystem angegeben werden.
+
+??inst <src> [<dst>]??
+
+??inst_hook?? installiert eine ausführbare Datei im Pfad ??<src>?? im
+Dracut-hook-Ordner ??<hookdir>??. Der Einstiegspunkt wird mit Priorität
+??<prio>?? zur Laufzeit des initialen Mini-Linux-Systems ausgeführt.
+
+??inst_hook <hookdir> <prio> <src>??
+
+??inst_rules?? installiert einen oder mehrere udev-Regeln. Nicht-existente
+udev-Regeln werden beim bauen des initramfs gemeldet, führen aber nicht zum
+Abbruch.
+
+??inst_rules <udevrule> [ <udevrule> …]??
+
+??instmods?? installiert einen oder mehrere Kernel-Module in das initramfs.
+??<kernelmodule>?? kann auch ein komplettes Subsystem darstellen, wenn es mit
+dem Prefiy "=" beginnt (z.B. "=drivers/net/team"). ??instmods?? sollte nur
+innerhalb der ??installkernel()??-Funktion verwendet werden. Ist ??$hostonly??
+gesetzt und das aktuelle Modul nicht im Referenzsystem geladen und wird
+demnach nicht in ??/sys/…/uevent MODALIAS?? verwendet, wird dieses nicht in
+das initramfs integriert. Soll das Modul in jedem Fall geladen werden, kann
+folgende Syntax verwendet werden:
+
+<pre><code class="bash">
+installkernel() {
+ hostonly='' instmods <kernelmodule>
+}
+</code></pre>
+
+??instmods <kernelmodule> [ <kernelmodule> … ]??
+
+h3. Konfiguration
+
+TODO
+
+h3. Debugging
+
+TODO
+
+h2. Build kernel specific dnbd3 kernel module
+
+> # Installiere Metainformation zum Kernel: @yum install kernel-devel@
+> # Installiere cmake zum Bauen von dnbd3: @yum install cmake@
+> # Installiere zlib-devel zum Bauen von dnbd3: @yum install zlib-devel@
+
+Die kernel header Dateien liegen in:
+
+/usr/lib/modules/3.10.0-229.1.2.el7.x86_64
+
+TOOD
+
+dnbd3-client -h 132.230.4.1 -i stage4/torben/test -r 1
+
+> # Installiere qemu-img: @yum install qemu-img@
+> # Installiere nbd: @wget http://dl.fedoraproject.org/pub/epel/6/x86_64/nbd-2.9.20-7.el6.x86_64.rpm && rpm -Uvh nbd-2.9.20-7.el6.x86_64.rpm@
+
+NOTE: Disable NetworkManager to avoid reloading network on boot: systemctl disable NetworkManager
+
+h2. CentOS7 @rpmbuild@
+
+First "Set up RPM build env":http://wiki.centos.org/HowTos/SetupRpmBuildEnvironment
+Now in that user's home, e.g. @/home/builder@:
+<pre>
+# install yumdownloader
+yum install yum-utils
+
+# download source in /home/builder/
+yumdownloader --source systemd
+
+# should have now have a file ~/systemd-208-20.el7_1.2.src.rpm
+# "install" it in ~/rpmbuild
+rpm -ivh systemd-208-20.el7_1.2.src.rpm
+
+# install building deps
+yum-builddep ~/rpmbuild/SPECS/systemd.spec
+
+# now check if everything is working, by running the simple %prep% phase
+# (unpacks source & applies patches)
+rpmbuild -bp ~/rpmbuild/SPECS/systemd.spec
+
+# if it worked, we can probably compile
+# this runs %prep% and %build%
+rpmbuild -bp ~/rpmbuild/SPECS/systemd.spec
+</pre>
+
+dmesg
+ 998 ping 8.8.8.8
+ 999 shutdown .h now
+ 1000 shutdown -h now
+ 1001 y search yumdownloader
+ 1002 y install yum-utils
+ 1003 yumdownloader --help
+ 1004 yumdownloader --source glib2 qemu
+ 1005 yumdownloader --source qemu-img
+ 1006 ls
+ 1007 mkdir glib2_source
+ 1008 cd glib2
+ 1009 cd glib2_source/
+ 1010 rpm2cpio ../glib2-2.40.0-4.el7.src.rpm | cpio -idmv
+ 1011 ls
+ 1012 tar xf glib-2.40.0.tar.xz
+ 1013 ls
+ 1014 cd glib-2.40.0
+ 1015 ls
+ 1016 ./configure --enable-static
+ 1017 make
+ 1018 ls
+ 1019 make
+ 1020 y search zlib
+ 1021 y search zlib-static
+ 1022 y install zlib-static
+ 1023 ./configure --enable-static
+ 1024 y search libffi
+ 1025 y install libffi
+ 1026 y install libffi-devel
+ 1027 ./configure --enable-static
+ 1028 make
+ 1029 ls
+ 1030 cd build/
+ 1031 ls
+ 1032 ..
+ 1033 l
+ 1034 ls
+ 1035 make install
+ 1036 ..
+ 1037 l
+ 1038 ..
+ 1039 l
+ 1040 mkdir qemu-kvm
+ 1041 cd qemu-kvm
+ 1042 ls
+ 1043 rpm2cpio ../qemu-kvm-1.5.3-86.el7_1.1.src.rpm | cpio -idmv
+ 1044 l
+ 1045 pwd
+ 1046 ls
+ 1047 l
+ 1048 ls
+ 1049 ..
+ 1050 l
+ 1051 git clone git://git.qemu.org/qemu.git qemu
+ 1052 ls
+ 1053 rm qemu-kvm -rf
+ 1054 rm qemu-kvm-1.5.3-86.el7_1.1.src.rpm
+ 1055 l
+ 1056 cd qemu/
+ 1057 l
+ 1058 ./configure --static --target-list=x86_64-linux-user
+ 1059 y install zlib
+ 1060 y install zlib-devel
+ 1061 y install zlib2
+ 1062 y search zlib
+ 1063 y install zlib-static
+ 1064 y install zlib
+ 1065 ll /lib64/libz.a
+ 1066 ./configure --static --target-list=x86_64-linux-user
+ 1067 make clean
+ 1068 ./configure --static
+ 1069 y search zlib
+ 1070 y search zlib-static..x86_64
+ 1071 y search zlib-static.x86_64
+ 1072 y install zlib-static.x86_64
+ 1073 ldconfig
+ 1074 ./configure --static
+ 1075 ./configure --help
+ 1076 ./configure --help | grep zlib
+ 1077 y search zlib
+ 1078 y install zlib-devel zlib-static zlib
+ 1079 y deinstall zlib
+ 1080 y remove zlib
+ 1081 y search libz
+ 1082 ls
+ 1083 git submodule update --init dtc
+ 1084 ./configure --static --target-list=x86_64-linux-user
+ 1085 find / -name zlib
+ 1086 find / -name libz
+ 1087 find / -name *libz*
+ 1088 find / -name *zlib*
+ 1089 ls
+ 1090 ./configure --disable-zlib-test --static --target-list=x86_64-linux-user
+ 1091 y search base-devel
+ 1092 y search devel
+ 1093 yum groupinstall "Development Tools"
+ 1094 yum groups mark install
+ 1095 yum group mark install
+ 1096 yum groupinstall "Development Tools"
+ 1097 yum groups mark install
+ 1098 yum grouplist
+ 1099 y search zlibrary
+ 1100 y search glibc
+ 1101 y install glibc-static
+ 1102 ls
+ 1103 ./configure --static --target-list=x86_64-linux-user
+ 1104 y search glib
+ 1105 y search glib-2
+ 1106 y search glib2-devel
+ 1107 y install glib2-devel
+ 1108 ./configure --static --target-list=x86_64-linux-user
+ 1109 git submodule update --init pixman
+ 1110 ./configure --static --target-list=x86_64-linux-user
+ 1111 ls
+ 1112 ll
+ 1113 make -j3
+ 1114 l
+ 1115 ldd qemu-nbd
+ 1116 history
+
+h2. Quellen
+
+* "Main Page Dracut on kerne.org":https://dracut.wiki.kernel.org/index.php/Main_Page
+* "Documentation on kernel.org":https://www.kernel.org/pub/linux/utils/boot/dracut/dracut.html
+* "Enable addional repository":http://www.tecmint.com/enable-rpmforge-repository
+* "Getting Dynamic Kernel Module Support":http://rpmfind.net/linux/rpm2html/search.php?query=dkms
diff --git a/builder/dnbd3-qcow2-rootfs/scripts/prepare-disks b/builder/dnbd3-qcow2-rootfs/scripts/prepare-disks
new file mode 100755
index 00000000..2e68dd9e
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/scripts/prepare-disks
@@ -0,0 +1,211 @@
+#!/bin/bash
+###############################################################################
+# GLOBALS
+#
+
+# flag file containing pids of running instances for concurrency checks
+declare -rg OPENSLX_DISK_FLAG="/tmp/openslx.disk"
+# file that will contain the name of the device used for the /tmp partition
+# - label 'OPENSLX_TMP' in GPT / type '0x44' in MBR
+declare -rg OPENSLX_TMP_MARKER="/tmp/openslx.disk.tmp"
+# file that will contain the name of the device used for storing qcow2
+# - label 'OPENSLX_SYS' in GPT / type '0x46' in MBR
+declare -rg OPENSLX_SYS_MARKER="/tmp/openslx.disk.sys"
+# mount point for system partition
+declare -rg OPENSLX_SYS_MOUNT="/opt/openslx/system"
+
+#
+# END GLOBALS
+###############################################################################
+
+###############################################################################
+# FUNCTION DEFINITIONS
+#
+# helper to mount the OPENSLX_SYS partition to /opt/openslx/system
+# Usage: mount_sys_part <path_to_sys_partition>
+mount_sys_part() {
+ if [ ! -b "$1" ]; then
+ warn "($$) Refusing to mount '$1' as its not a block device!"
+ return 1
+ fi
+
+ local OPENSLX_SYS_DEVICE="$1"
+ mkdir -p ${OPENSLX_SYS_MOUNT}
+ if ! mount -t auto "${OPENSLX_SYS_DEVICE}" "${OPENSLX_SYS_MOUNT}"; then
+ warn "($$) Mounting '${OPENSLX_SYS_DEVICE}' to '${OPENSLX_SYS_MOUNT}' failed."
+ return 1
+ fi
+ return 0
+
+}
+#
+# generic helper to format the given partition with the given filesystem or
+# from the prefdefined list of xfs, ext4, ...
+# Usage: format_disk <dev> <fs>
+# e.g. format_disk /dev/sda1 xfs
+format_disk () {
+ local TARGET_DEVICE="$1"
+ local fslist="xfs ext4"
+ # if we have a second arguments, its the filesystem of choice
+ local fs
+ [ $# -ge 2 ] && fslist="$2"
+ for fs in $fslist ; do
+ unset found
+ local MKFS="$(busybox which mkfs.$fs)"
+ if [ -n $MKFS ]; then
+ found=yes
+ case "mkfs.$fs" in
+ mkfs.xfs) fopt="-fq" ;;
+ mkfs.ext4) fopt="-Fq" ;;
+ esac
+ info "($$) Formatting $TARGET_DEVICE as $fs"
+ return $(${MKFS} ${fopt} "${TARGET_DEVICE}")
+ fi
+ [ -n "$found" ] && break
+ done
+ # still here? then we didn't find a proper formatter...
+ warn "($$) Could not format $PART_DEV as $fs."
+ return 1
+}
+
+#
+# END FUNCTION DEFINITIONS
+###############################################################################
+
+###############################################################################
+# MAIN CODE
+#
+
+command -v warn >/dev/null || . /lib/dracut-lib.sh
+
+# let check the arguments
+if [ "$#" -ne 2 ]; then
+ warn "($$) '$0' need 2 arguments: '$0 [OPENSLX_SYS|OPENSLX_TMP] <dev_path>'"
+ exit 1
+fi
+# $1 sane?
+if [ "x$1" != "xOPENSLX_SYS" ] && [ "x$1" != "xOPENSLX_TMP" ]; then
+ warn "($$) First arg needs to be either 'OPENSLX_SYS' or 'OPENSLX_TMP', given: $1"
+ exit 1
+fi
+# $2 sane?
+if [ ! -b "/dev/$2" ]; then
+ warn "($$) Second arg appears not to be a block device!"
+ exit 1
+fi
+
+# ok all seems well, set the arguments
+PART_TYPE="$1"
+PART_DEV="/dev/$2"
+
+unset OPENSLX_TMP_DEVICE
+unset OPENSLX_SYS_DEVICE
+
+# lets check if we are already running
+INSTANCES="$(grep "$PART_TYPE" "$OPENSLX_DISK_FLAG" | busybox wc -l)"
+if [ "$INSTANCES" -ge 1 ]; then
+ # uhoh we are not alone! Need to check
+ # if the other instance actually did its job
+ warn "($$) '$0' already running for $PART_TYPE on $PART_DEV... checking state."
+ # here two/three cases depending on which PART_TYPE we are
+ # currently processing.
+ for timeout in 1 1 2; do
+ # always give the other instance time to finish
+ # but only check 3 times overall
+ sleep $timeout
+ case "$PART_TYPE" in
+ OPENSLX_TMP)
+ # was the tmp partition marker created with a device?
+ if [ ! -f "${OPENSLX_TMP_MARKER}" ]; then
+ info "($$) Invalid state: no marker for $PART_TYPE"
+ continue
+ fi
+ # it was, is it a valid block device?
+ OPENSLX_TMP_DEVICE="$(cat ${OPENSLX_TMP_MARKER})"
+ if [ -z $OPENSLX_TMP_DEVICE -o ! -b $OPENSLX_TMP_DEVICE ]; then
+ info "($$) Invalid state: no for device $OPENSLX_TMP_DEVICE"
+ continue
+ fi
+ # its detected, its a block device and as mounting is
+ # done later, we can not check for more at this point
+ info "($$) Valid state for $OPENSLX_TMP_DEVICE as $PART_TYPE"
+ exit 0
+ ;;
+ OPENSLX_SYS)
+ # was the system partition marker created with a device?
+ if [ ! -f "${OPENSLX_SYS_MARKER}" ]; then
+ info "($$) Invalid state: no marker for $PART_TYPE"
+ continue
+ fi
+ # it was, is it a valid block device?
+ OPENSLX_SYS_DEVICE="$(cat ${OPENSLX_SYS_MARKER})"
+ if [ -z $OPENSLX_SYS_DEVICE -o ! -b $OPENSLX_SYS_DEVICE ]; then
+ info "($$) Invalid state: no for device $OPENSLX_SYS_DEVICE"
+ continue
+ fi
+ # its detected, its a block device, is it mounted?
+ if mount | grep -qE "^$OPENSLX_SYS_DEVICE\ on $OPENSLX_SYS_MOUNT"; then
+ info "($$) Valid state for $OPENSLX_SYS_DEVICE as $PART_TYPE"
+ exit 0
+ fi
+ # if its not mounted, we want to keep on, so no exit!
+ ;;
+ *)
+ # weird case which should never happen
+ warn "($$) If you see this, then $0 was called with a bad PART_TYPE: $@"
+ continue
+ ;;
+ esac
+ done
+ warn "($$) Timeout reached!"
+ warn "($$) '$PART_TYPE' was found but not device was associated to it!"
+fi
+
+# We write our pid to $OPENSLX_DISK_FLAG in order to make sure
+# we are the only instance of this script running.
+info "($$) Processing: $PART_TYPE -> $PART_DEV ($$)"
+echo "$PART_TYPE.$$" >> "$OPENSLX_DISK_FLAG"
+
+# if we are still here, then we can go on and process the partition
+if [ "$PART_TYPE" = "OPENSLX_TMP" ]; then
+ # always format /tmp partition
+ if ! format_disk "${PART_DEV}" xfs; then
+ # error while formatting, cleanup
+ warn "($$) Error formatting $PART_DEV ... removing $$"
+ sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
+ exit 1
+ fi
+ info "($$) Using '$PART_DEV' as '$PART_TYPE'"
+ # mark it for later: in pre-pivot we will check this file
+ # and mount it as $NEWROOT/tmp
+ echo "$PART_DEV" > "$OPENSLX_TMP_MARKER"
+ # remove our pid from OPENSLX_DISK_FLAG
+ sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
+ exit 0
+fi
+if [ "$PART_TYPE" = "OPENSLX_SYS" ]; then
+ # TODO make the formatting of the system partition configurable
+ if ! format_disk "${PART_DEV}" xfs; then
+ # error while formatting, cleanup
+ warn "($$) Error formatting $PART_DEV ... removing $$"
+ sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
+ exit 1
+ fi
+ # mark it
+ # mount it now, since qemu-nbd needs it asap!
+ if mount_sys_part "$PART_DEV"; then
+ # mount worked, mark it as done
+ info "($$) Using '$PART_DEV' as '$PART_TYPE'"
+ echo "$PART_DEV" > "$OPENSLX_SYS_MARKER"
+ sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
+ exit 0
+ else
+ warn "($$) 'mount_sys_part' failed in $0"
+ sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
+ exit 1
+ fi
+fi
+
+#
+# END MAIN CODE
+###############################################################################
diff --git a/builder/dnbd3-qcow2-rootfs/scripts/setup-qcow2 b/builder/dnbd3-qcow2-rootfs/scripts/setup-qcow2
new file mode 100755
index 00000000..70babc17
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/scripts/setup-qcow2
@@ -0,0 +1,137 @@
+#!/usr/bin/bash
+
+# dracut-lib to use debugging functions
+command -v warn >/dev/null || . /lib/dracut-lib.sh
+command -v emergency_shell >/dev/null || . /lib/dracut-lib.sh
+
+###############################################################################
+# GLOBALS
+#
+# TODO make this configurable
+[ -f /opt/openslx/config ] && . /opt/openslx/config
+[ -z $SLX_DNBD3_SERVER ] && SLX_DNBD3_SERVER="132.230.4.1"
+[ -z $SLX_STAGE4 ] && SLX_STAGE4="stage4/joe/centos7"
+[ -z $SLX_STAGE4_RID ] && SLX_STAGE4_RID="4"
+declare -rg DNBD3_SERVER="$SLX_DNBD3_SERVER"
+declare -rg DNBD3_IMAGE="$SLX_STAGE4"
+declare -rg DNBD3_RID="$SLX_STAGE4_RID"
+declare -rg DNBD3_DEVICE="/dev/dnbd0"
+declare -rg QCOW_CONTAINER="/opt/openslx/system/system.qcow2"
+#
+# END GLOBALS
+###############################################################################
+
+###############################################################################
+# FUNCTION DEFINITIONS
+#
+# helper to do some sanity checks
+check_dnbd3() {
+ if [ ! command -v "dnbd3-client" >/dev/null ]; then
+ warn "No 'dnbd3-client' found. Was the initramfs built correctly?"
+ emergency_shell -n "Error in $0"
+ return 1
+ fi
+ return 0
+}
+
+# helper to connect to the dnbd3-server
+connect_dnbd3() {
+ # check if it already connected
+ local current_image_name="$(cat /sys/block/${DNBD3_DEVICE#/dev/}/net/image_name)"
+ [ "x${current_image_name}" != "x(null)" ] && return 0
+
+ # not connected yet, do it
+ if ! dnbd3-client -h "${DNBD3_SERVER}" \
+ -i "${DNBD3_IMAGE}" \
+ -r "${DNBD3_RID}" \
+ -d "${DNBD3_DEVICE}" ; then
+ warn "Failed to mount $DNBD3_IMAGE from $DNBD3_SERVER to $DNBD3_DEVICE"
+ emergency_shell -n "Error in $0"
+ return 1
+ fi
+ return 0
+}
+
+# helper to create the qcow2 container file using
+# DNBD3_DEVICE as the base of the filesystem
+# QCOW_CONTAINER as the writable file
+# (our future rootfs)
+create_qcow() {
+ # check if we already created the qcow2-container
+ [ -e "$QCOW_CONTAINER" ] && return 0
+
+ # check if we have our target directory, if not create it
+ [ ! -d "$(busybox dirname $QCOW_CONTAINER)" ] && \
+ mkdir -p "$(busybox dirname $QCOW_CONTAINER)"
+
+ # we did not, let's create it
+ if ! qemu-img create -f qcow2 -o \
+ backing_file="$DNBD3_DEVICE",backing_fmt=qcow2 "$QCOW_CONTAINER"; then
+ warn "Failed to create qcow2-Container from $DNBD3_DEVICE"
+ emergency_shell -n "Error in $0"
+ rm -f -- "$QCOW_CONTAINER"
+ return 1
+ fi
+ return 0
+}
+# helper to start qemu-nbd on localhost:2000
+# use our wrapper to set argv[0][0] to '@'
+# this keeps qemu-nbd running after switching root
+export_qcow() {
+ # check if we already have a qemu-nbd
+ if [ -e /tmp/qemu-nbd.pid ]; then
+ kill -0 $(cat /tmp/qemu-nbd.pid) && return 0
+ fi
+ # since we use the wrapper, we need a little more logic to see if it runs
+ /usr/bin/systemd-preserve-process-marker \
+ /usr/bin/qemu-nbd -t -p 2000 "$QCOW_CONTAINER" &
+ # the wrapper returns 255 if the qemu-nbd binary is missing
+ local qemu_nbd_pid="$!"
+ for i in 0.5 1 2; do
+ sleep $i
+ if ! kill -0 $qemu_nbd_pid; then
+ # not running
+ wait $qemu_nbd_pid
+ local ret_wrapper="$?"
+ if [ "${ret_wrapper}" -eq 127 ]; then
+ # wrapper was not found by bash
+ warn "No such file or directory: /usr/bin/systemd-preserve-process-marker"
+ elif [ "${ret_wrapper}" -eq 255 ]; then
+ # qemu-nbd was not found
+ warn "No such file or directory: /usr/bin/qemu-nbd"
+ fi
+ emergency_shell -n "Error in $0"
+ return 1
+ else
+ # all good, qemu-nbd is running, remember its pid
+ echo $qemu_nbd_pid > /tmp/qemu-nbd.pid
+ return 0
+ fi
+ done
+ # fallback
+ return 1
+}
+# helper to mount the qcow2-container per nbd
+connect_qcow() {
+ # try to mount the locally exported qcow2-container using nbd-client
+ if /usr/bin/systemd-preserve-process-marker \
+ nbd-client --persist 127.0.0.1 2000 /dev/nbd0; then
+ # it worked, lets set the symlink to /dev/root as dracut needs it
+ # later on to mount that device to the future root (/sysroot)
+ ln -sf /dev/nbd0 /dev/root
+ return 0
+ else
+ # this is pretty bad, dracut would spawn an emergency later on
+ # since there is no /dev/root to mount.
+ # For debugging purposes, we drop an emergency shell ourselves
+ # if the mount fails.
+ warn "Could not mount /dev/nbd0 from 127.0.0.1:2000."
+ emergency_shell -n "Error in $0"
+ return 1
+ fi
+}
+#
+# END FUNCTION DEFINITIONS
+###############################################################################
+
+# No main, use functions!
diff --git a/builder/dnbd3-qcow2-rootfs/systemd-preserve-process-marker.c b/builder/dnbd3-qcow2-rootfs/systemd-preserve-process-marker.c
new file mode 100644
index 00000000..8f0fc108
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/systemd-preserve-process-marker.c
@@ -0,0 +1,33 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+void print_array(int argc, char *argv[]) {
+ // Helper function to print given array with given length.
+ int i = 0;
+ int j = 0;
+ for (i = 0; i < argc; i ++) {
+ j = 0;
+ while(argv[i][j] != '\0')
+ printf("%c", argv[i][j++]);
+ printf(" ");
+ }
+ printf("\n");
+}
+int main(int argc, char *argv[]) {
+ int count;
+ // Last item acts as null pointer.
+ char **copy = calloc(sizeof(char *), argc);
+ // Slice first given command line argument.
+ for (count = 0; count < argc - 1; count++)
+ copy[count] = strdup(argv[count + 1]);
+ // Adding systemd indicator to preserve wrapped process during changing
+ // root filesystem. We mark wrapper and child process.
+ argv[0][0] = '@';
+ copy[0][0] = '@';
+ if (-1 == execvp(argv[1], copy)) {
+ perror("Executing child process failed.");
+ return -1;
+ }
+}
diff --git a/builder/dnbd3-qcow2-rootfs/udev/70-openslx-disk.rules b/builder/dnbd3-qcow2-rootfs/udev/70-openslx-disk.rules
new file mode 100644
index 00000000..3f5e382f
--- /dev/null
+++ b/builder/dnbd3-qcow2-rootfs/udev/70-openslx-disk.rules
@@ -0,0 +1,8 @@
+# GPT rules
+KERNEL=="sd?[0-9]" SUBSYSTEM=="block" ENV{ID_PART_TABLE_TYPE}=="gpt" ENV{ID_PART_ENTRY_NAME}=="OPENSLX_TMP" RUN+="/sbin/prepare-disks %E{ID_PART_ENTRY_NAME} %k"
+KERNEL=="sd?[0-9]" SUBSYSTEM=="block" ENV{ID_PART_TABLE_TYPE}=="gpt" ENV{ID_PART_ENTRY_NAME}=="OPENSLX_SYS" RUN+="/sbin/prepare-disks %E{ID_PART_ENTRY_NAME} %k"
+
+# MBR rules
+KERNEL=="sd?[0-9]" SUBSYSTEM=="block" ENV{ID_PART_TABLE_TYPE}=="dos" ENV{ID_PART_ENTRY_TYPE}=="0x44" RUN+="/sbin/prepare-disks OPENSLX_TMP %k"
+KERNEL=="sd?[0-9]" SUBSYSTEM=="block" ENV{ID_PART_TABLE_TYPE}=="dos" ENV{ID_PART_ENTRY_TYPE}=="0x46" RUN+="/sbin/prepare-disks OPENSLX_SYS %k"
+