From 56b1139ef2660535b112d0be4ddb2806f75298a8 Mon Sep 17 00:00:00 2001 From: Stephane Desneux Date: Mon, 23 May 2016 17:53:36 +0200 Subject: add layer meta-netboot to enable network boot over NBD (Network Block Device) To enable the build of network bootable images, the following line must be added to conf/local.conf: INHERIT += "netboot" This layer contains recipes for the following components: * busybox: activate the built-in NBD client * initramfs-netboot: contains the init script started by the kernel, responsible for mounting the remote root filesystem then pivoting and exec'ing systemd * initramfs-netboot-image: image to specify for building the initrd More details are available in meta-netboot/README. Bug-AGL: SPEC-175 Change-Id: Id2328dd9233d238cde77311e64e58344be244988 Signed-off-by: Stephane Desneux --- .../recipes-core/busybox/busybox_%.bbappend | 6 + .../recipes-core/busybox/files/enable_nbd.cfg | 1 + .../recipes-core/images/initramfs-netboot-image.bb | 19 +++ .../recipes-core/initramfs-netboot/files/init.sh | 149 +++++++++++++++++++++ .../initramfs-netboot/initramfs-netboot_1.0.bb | 19 +++ 5 files changed, 194 insertions(+) create mode 100644 meta-netboot/recipes-core/busybox/busybox_%.bbappend create mode 100644 meta-netboot/recipes-core/busybox/files/enable_nbd.cfg create mode 100644 meta-netboot/recipes-core/images/initramfs-netboot-image.bb create mode 100644 meta-netboot/recipes-core/initramfs-netboot/files/init.sh create mode 100644 meta-netboot/recipes-core/initramfs-netboot/initramfs-netboot_1.0.bb (limited to 'meta-netboot/recipes-core') diff --git a/meta-netboot/recipes-core/busybox/busybox_%.bbappend b/meta-netboot/recipes-core/busybox/busybox_%.bbappend new file mode 100644 index 000000000..358913448 --- /dev/null +++ b/meta-netboot/recipes-core/busybox/busybox_%.bbappend @@ -0,0 +1,6 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/files:" + +SRC_URI += " \ + file://enable_nbd.cfg \ + " + diff --git a/meta-netboot/recipes-core/busybox/files/enable_nbd.cfg b/meta-netboot/recipes-core/busybox/files/enable_nbd.cfg new file mode 100644 index 000000000..7d6c7423f --- /dev/null +++ b/meta-netboot/recipes-core/busybox/files/enable_nbd.cfg @@ -0,0 +1 @@ +CONFIG_NBDCLIENT=y diff --git a/meta-netboot/recipes-core/images/initramfs-netboot-image.bb b/meta-netboot/recipes-core/images/initramfs-netboot-image.bb new file mode 100644 index 000000000..8b461e555 --- /dev/null +++ b/meta-netboot/recipes-core/images/initramfs-netboot-image.bb @@ -0,0 +1,19 @@ +# Netboot initramfs image. +DESCRIPTION = "Netboot initrd image" + +PACKAGE_INSTALL = "initramfs-netboot busybox base-passwd ${ROOTFS_BOOTSTRAP_INSTALL}" + +# Do not pollute the initrd image with rootfs features +IMAGE_FEATURES = "" + +export IMAGE_BASENAME = "initramfs-netboot-image" +IMAGE_LINGUAS = "" + +LICENSE = "MIT" + +IMAGE_FSTYPES = "${INITRAMFS_FSTYPES}" +inherit core-image + +IMAGE_ROOTFS_SIZE = "8192" + +BAD_RECOMMENDATIONS += "busybox-syslog" diff --git a/meta-netboot/recipes-core/initramfs-netboot/files/init.sh b/meta-netboot/recipes-core/initramfs-netboot/files/init.sh new file mode 100644 index 000000000..dae9a85cb --- /dev/null +++ b/meta-netboot/recipes-core/initramfs-netboot/files/init.sh @@ -0,0 +1,149 @@ +#!/bin/sh + +################################################################################ +# +# Init script to boot over network through NBD +# +# Contact: Stéphane Desneux +# +################################################################################ + +# banner generator: echo "AGL - Netboot" | figlet -f slant -w 80 -c +cat <<'EOF' >&2 +________________________________________________________________________________ + ___ ________ _ __ __ __ __ + / | / ____/ / / | / /__ / /_/ /_ ____ ____ / /_ + / /| |/ / __/ / ______ / |/ / _ \/ __/ __ \/ __ \/ __ \/ __/ + / ___ / /_/ / /___ /_____/ / /| / __/ /_/ /_/ / /_/ / /_/ / /_ + /_/ |_\____/_____/ /_/ |_/\___/\__/_.___/\____/\____/\__/ +________________________________________________________________________________ +EOF + +# global variables + +SMACK=n +NBD_SERVER= +NBD_PORT=10809 +NBD_DEV=/dev/nbd0 +DEBUG=n + +# ------------------------------------------- + +log_info() { echo "$0[$$]: $@" >&2; } +log_error() { echo "$0[$$]: ERROR $@" >&2; } + +do_mount_fs() { + log_info "mounting FS: $@" + [[ -e /proc/filesystems ]] && { grep -q "$1" /proc/filesystems || { log_error "Unknown filesystem"; return 1; } } + [[ -d "$2" ]] || mkdir -p "$2" + [[ -e /proc/mounts ]] && { grep -q -e "^$1 $2 $1" /proc/mounts && { log_info "$2 ($1) already mounted"; return 0; } } + mount -t "$1" "$1" "$2" +} + +bail_out() { + log_error "$@" + check_debug "Reboot will occur after exiting this shell." + log_info "Rebooting..." + exec reboot -f +} + +check_debug() { + case $DEBUG in + Y|y|yes|1|true) + log_info "$@" + /bin/sh -i + ;; + esac +} + +# ------------------------------------------- + +export PATH=/sbin:/usr/sbin:/bin:/usr/bin + +log_info "starting initrd script" + +do_mount_fs proc /proc +do_mount_fs sysfs /sys +do_mount_fs devtmpfs /dev +do_mount_fs devpts /dev/pts +do_mount_fs tmpfs /dev/shm +do_mount_fs tmpfs /tmp +do_mount_fs tmpfs /run + +# parse kernel commandline to get NBD server +for x in $(cat /proc/cmdline); do + case $x in + nbd.server=*) NBD_SERVER=${x/*=/};; + nbd.port=*) NBD_PORT=${x/*=/};; + nbd.dev=*) NBD_DEV=/dev/${x/*=/};; + nbd.debug=*) DEBUG=${x/*=/};; + esac +done + +check_debug "Debug point 1. Exit to continue initrd script (mount NBD device)." + +log_info "NBD parameters: device $NBD_DEV, server $NBD_SERVER:$NBD_PORT" + +# check if smack is active (and if so, mount smackfs) +grep -q smackfs /proc/filesystems && { + SMACK=y + + do_mount_fs smackfs /sys/fs/smackfs + + # adjust current label and network label + echo System >/proc/self/attr/current + echo System >/sys/fs/smackfs/ambient +} + +# start nbd client +try=5 +while :;do + log_info "Starting NBD client" + nbd-client $NBD_SERVER $NBD_PORT $NBD_DEV && { log_info "NBD client successfully started"; break; } + log_info "NBD client failed" + [[ $try -gt 0 ]] && { log_info "Retrying ($try trie(s) left)..."; sleep 3; try=$(( try - 1 )); continue; } + + bail_out "Unable to mount NBD device $NBD_DEV using server $NBD_SERVER:$NBD_PORT" +done + +# mount NBD device +mkdir -p /sysroot +mount $NBD_DEV /sysroot || bail_out "Unable to mount root NBD device" + +# move mounted devices to new root +cd /sysroot +for x in dev proc sys tmp run; do + log_info "Moving /$x to new rootfs" + mount -o move /$x $x +done + +# switch to new rootfs +log_info "Switching to new rootfs" +mkdir -p run/initramfs +pivot_root . run/initramfs || bail_out "pivot_root failed." + +# workaround for connman (avoid bringing down the network interface used for booting) +if [[ -f /lib/systemd/system/connman.service ]]; then + log_info "Adjusting Connman configuration" + iface=$(ip -o link show up | tr ':' ' ' | awk '{print $2}' | grep -v -e "^lo$" | head -1) + sed -i "s|connmand -n\$|connmand -n -I $iface|g" /lib/systemd/system/connman.service +fi + +# finally, run systemd +check_debug "Debug point 2. Exit to continue initrd script (run systemd)." + +log_info "Exec'ing systemd" +# banner generator: echo "AGL Booting . . ." | figlet -f slant -w 80 -c +cat <<'EOF' >&2 +________________________________________________________________________________ + ___ ________ ____ __ _ + / | / ____/ / / __ )____ ____ / /_(_)___ ____ _ + / /| |/ / __/ / / __ / __ \/ __ \/ __/ / __ \/ __ `/ + / ___ / /_/ / /___ / /_/ / /_/ / /_/ / /_/ / / / / /_/ / _ _ _ + /_/ |_\____/_____/ /_____/\____/\____/\__/_/_/ /_/\__, / (_) (_) (_) +_____________________________________________________/____/_____________________ +EOF + +exec /lib/systemd/systemd /dev/console 2>&1 +bail_out + diff --git a/meta-netboot/recipes-core/initramfs-netboot/initramfs-netboot_1.0.bb b/meta-netboot/recipes-core/initramfs-netboot/initramfs-netboot_1.0.bb new file mode 100644 index 000000000..5c85bee8f --- /dev/null +++ b/meta-netboot/recipes-core/initramfs-netboot/initramfs-netboot_1.0.bb @@ -0,0 +1,19 @@ +SUMMARY = "Extremely basic live image init script" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" +SRC_URI = "file://init.sh" + +S = "${WORKDIR}" + +do_install() { + install -dm 0755 ${D}/etc + touch ${D}/etc/initrd-release + install -dm 0755 ${D}/dev + install -dm 0755 ${D}/sbin + install -m 0755 ${WORKDIR}/init.sh ${D}/sbin/init +} + +inherit allarch + +FILES_${PN} += " /dev /etc/initrd-release /sbin/init " + -- cgit 1.2.3-korg