From 51a5a93e320aa51be42fb05c20de427012d82bf0 Mon Sep 17 00:00:00 2001 From: Eric Curtin Date: Wed, 10 Jan 2024 12:58:43 +0000 Subject: [PATCH] add throwaway Signed-off-by: Eric Curtin --- bin/initoverlayfs-install | 10 +- initoverlayfs.spec.in | 16 ++- .../modules.d/81initoverlayfs/module-setup.sh | 111 ++++++++++++++++-- .../pre-initoverlayfs-switch-root.service | 15 +++ .../pre-initoverlayfs-switch-root.target | 10 ++ lib/systemd/system/pre-initoverlayfs.service | 18 +++ lib/systemd/system/pre-initoverlayfs.target | 10 ++ scripts/install.sh | 16 +++ storage-init.c | 29 ++++- 9 files changed, 210 insertions(+), 25 deletions(-) create mode 100644 lib/systemd/system/pre-initoverlayfs-switch-root.service create mode 100644 lib/systemd/system/pre-initoverlayfs-switch-root.target create mode 100644 lib/systemd/system/pre-initoverlayfs.service create mode 100644 lib/systemd/system/pre-initoverlayfs.target create mode 100755 scripts/install.sh diff --git a/bin/initoverlayfs-install b/bin/initoverlayfs-install index d2baa95..663df4a 100755 --- a/bin/initoverlayfs-install +++ b/bin/initoverlayfs-install @@ -1,6 +1,6 @@ #!/bin/bash -set -e +set -ex # Constants with default value CAT="lz4cat" @@ -59,9 +59,7 @@ exec_ext4() { } detect_initramfs() { - if [ ! -d "${INITRAMFS_DUMP_DIR}" ]; then - mkdir -p "${INITRAMFS_DUMP_DIR}" - fi + mkdir -p "${INITRAMFS_DUMP_DIR}" echo "Extracting initrd into initoverlayfs..." @@ -124,7 +122,7 @@ extract_initrd_into_initoverlayfs() { ;; esac - rm -rf "$INITRAMFS_DUMP_DIR" & +# rm -rf "$INITRAMFS_DUMP_DIR" & } # main() @@ -165,7 +163,7 @@ if ! [ -e "$INITOVERLAYFS_CONF" ] || ! grep -q '[^[:space:]]' "$INITOVERLAYFS_CO "bootfs $boot_partition" \ "bootfstype ext4" \ "initoverlayfs_builder dracut -H -f -v -M --reproducible -o \"initoverlayfs\"" \ - "initrd_builder dracut -H -f -v -M --reproducible -m \"kernel-modules udev-rules initoverlayfs\" -o \"bash systemd systemd-initrd i18n kernel-modules-extra rootfs-block dracut-systemd usrmount base fs-lib microcode_ctl-fw_dir_override shutdown nss-softokn\"" \ + "initrd_builder dracut -H -f -v -M --reproducible -m \"kernel-modules udev-rules initoverlayfs systemd base\" -o \"bash systemd-initrd i18n kernel-modules-extra rootfs-block dracut-systemd usrmount fs-lib microcode_ctl-fw_dir_override shutdown nss-softokn\"" \ "udev_trigger udevadm trigger --type=devices --action=add --subsystem-match=module --subsystem-match=block --subsystem-match=virtio --subsystem-match=pci --subsystem-match=nvme --subsystem-match=mmc --subsystem-match=mmc_host --subsystem-match=platform" \ "udev_trigger_generic udevadm trigger --type=devices --action=add" > $INITOVERLAYFS_CONF diff --git a/initoverlayfs.spec.in b/initoverlayfs.spec.in index b767d29..ee55b1b 100644 --- a/initoverlayfs.spec.in +++ b/initoverlayfs.spec.in @@ -7,9 +7,9 @@ URL: https://github.com/containers/initoverlayfs Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz BuildRequires: gcc -Recommends: erofs-utils Recommends: lz4 Recommends: gzip +Requires: erofs-utils Requires: dracut %global debug_package %{nil} @@ -26,16 +26,24 @@ gcc ${RPM_OPT_FLAGS} storage-init.c -o storage-init %install install -D -m755 bin/initoverlayfs-install ${RPM_BUILD_ROOT}/%{_bindir}/initoverlayfs-install -install -D -m755 storage-init ${RPM_BUILD_ROOT}/%{_prefix}/sbin/storage-init -install -D -m755 lib/dracut/modules.d/81initoverlayfs/module-setup.sh $RPM_BUILD_ROOT/%{_prefix}/lib/dracut/modules.d/81initoverlayfs/module-setup.sh +install -D -m755 storage-init ${RPM_BUILD_ROOT}/%{_sbindir}/storage-init +install -D -m755 lib/dracut/modules.d/81initoverlayfs/module-setup.sh ${RPM_BUILD_ROOT}/%{_prefix}/lib/dracut/modules.d/81initoverlayfs/module-setup.sh +install -D -m644 lib/systemd/system/pre-initoverlayfs.target ${RPM_BUILD_ROOT}/%{_prefix}/lib/systemd/system/pre-initoverlayfs.target +install -D -m644 lib/systemd/system/pre-initoverlayfs.service ${RPM_BUILD_ROOT}/%{_prefix}/lib/systemd/system/pre-initoverlayfs.service +install -D -m644 lib/systemd/system/pre-initoverlayfs-switch-root.service ${RPM_BUILD_ROOT}/%{_prefix}/lib/systemd/system/pre-initoverlayfs-switch-root.service +ln -s ../pre-initoverlayfs.service ${RPM_BUILD_ROOT}/%{_prefix}/lib/systemd/system/pre-initoverlayfs.service +ln -s ../pre-initoverlayfs-switch-root.service ${RPM_BUILD_ROOT}/%{_prefix}/lib/systemd/system/pre-initoverlayfs-switch-root.service %files %license LICENSE %doc README.md %attr(0755,root,root) %{_bindir}/initoverlayfs-install -%{_prefix}/sbin/storage-init +%{_sbindir}/storage-init %{_prefix}/lib/dracut/modules.d/81initoverlayfs/ +%{_prefix}/lib/systemd/system/pre-initoverlayfs.target +%{_prefix}/lib/systemd/system/pre-initoverlayfs.service +%{_prefix}/lib/systemd/system/pre-initoverlayfs-switch-root.service %changelog * Thu Dec 14 2023 Stephen Smoogen - 0.99-1 diff --git a/lib/dracut/modules.d/81initoverlayfs/module-setup.sh b/lib/dracut/modules.d/81initoverlayfs/module-setup.sh index d4859c0..bba0831 100644 --- a/lib/dracut/modules.d/81initoverlayfs/module-setup.sh +++ b/lib/dracut/modules.d/81initoverlayfs/module-setup.sh @@ -1,22 +1,71 @@ #!/usr/bin/bash installkernel() { - hostonly="" instmods erofs overlay + hostonly="" instmods erofs overlay loop +} + +# called by dracut +depends() { + echo "systemd" +} + +initrd-release() { + local VERSION="" + local PRETTY_NAME="" + # Derive an os-release file from the host, if it exists + if [[ -e $dracutsysrootdir/etc/os-release ]]; then + # shellcheck disable=SC1090 + . "$dracutsysrootdir"/etc/os-release + grep -hE -ve '^VERSION=' -ve '^PRETTY_NAME' "$dracutsysrootdir"/etc/os-release > "${initdir}"/usr/lib/initrd-release + [[ -n ${VERSION} ]] && VERSION+=" " + [[ -n ${PRETTY_NAME} ]] && PRETTY_NAME+=" " + else + # Fall back to synthesizing one, since dracut is presently used + # on non-systemd systems as well. + { + echo "NAME=dracut" + echo "ID=dracut" + echo "VERSION_ID=\"$DRACUT_VERSION\"" + echo 'ANSI_COLOR="0;34"' + } > "${initdir}"/usr/lib/initrd-release + fi + VERSION+="dracut-$DRACUT_VERSION" + PRETTY_NAME+="dracut-$DRACUT_VERSION (Initramfs)" + { + echo "VERSION=\"$VERSION\"" + echo "PRETTY_NAME=\"$PRETTY_NAME\"" + # This addition is relatively new, intended to allow software + # to easily detect the dracut version if need be without + # having it mixed in with the real underlying OS version. + echo "DRACUT_VERSION=\"${DRACUT_VERSION}\"" + } >> "$initdir"/usr/lib/initrd-release + echo "dracut-$DRACUT_VERSION" > "$initdir/lib/dracut/dracut-$DRACUT_VERSION" + ln -sf ../usr/lib/initrd-release "$initdir"/etc/initrd-release + ln -sf initrd-release "$initdir"/usr/lib/os-release + ln -sf initrd-release "$initdir"/etc/os-release } install() { +if false; then # /usr/sbin/storage-init local _initbinary="/usr/lib/systemd/systemd" - inst_multiple -o /etc/initoverlayfs.conf - inst_multiple "$_initbinary" "$systemdutildir"/systemd-udevd \ - udevadm modprobe \ - /usr/lib/systemd/system/systemd-udev-settle.service \ - /usr/lib/systemd/system/systemd-udev-trigger.service \ - /usr/lib/systemd/system/systemd-udevd.service - - inst_dir /boot /initrofs /overlay /overlay/upper /overlay/work \ - /initoverlayfs + inst_multiple "$_initbinary" "${systemdutildir}/systemd-udevd" \ + udevadm modprobe systemctl \ + "${systemdsystemunitdir}/basic.target" \ + "${systemdsystemunitdir}/sysinit.target" \ + "${systemdsystemunitdir}/initrd.target" \ + "${systemdsystemunitdir}/systemd-udev-settle.service" \ + "${systemdsystemunitdir}/systemd-udev-trigger.service" \ + "${systemdsystemunitdir}/systemd-udevd.service" \ + "${systemdsystemunitdir}/initrd-switch-root.target" \ + "${systemdsystemunitdir}/initrd-switch-root.service" \ + "${systemdsystemunitdir}/initrd-usr-fs.target" \ + "${systemdsystemunitdir}/sockets.target.wants/systemd-journald-dev-log.socket" \ + "${systemdsystemunitdir}/sockets.target.wants/systemd-journald.socket" \ + "${systemdsystemunitdir}/systemd-journald-dev-log.socket" \ + "${systemdsystemunitdir}/systemd-journald.socket" \ + "${systemdsystemunitdir}/systemd-vconsole-setup.service" if [ ! -e "/init" ]; then ln_r "$_initbinary" "/init" @@ -26,6 +75,48 @@ install() { ln_r "$_initbinary" "/sbin/init" fi + ln_r "${systemdsystemunitdir}/pre-initoverlayfs.target" \ + "${systemdsystemunitdir}/default.target" + + for i in \ + emergency.target \ + rescue.target \ + systemd-ask-password-console.service \ + systemd-ask-password-plymouth.service; do + [[ -f "$systemdsystemunitdir"/$i ]] || continue + $SYSTEMCTL -q --root "$initdir" add-wants "$i" systemd-vconsole-setup.service + done + + initrd-release +fi + + inst_multiple -o /etc/initoverlayfs.conf /usr/sbin/storage-init \ + "$systemdsystemunitdir/pre-initoverlayfs.service" \ + "$systemdsystemunitdir/sysinit.target.wants/pre-initoverlayfs.service" \ + "$systemdsystemunitdir/pre-initoverlayfs.target" \ + "$systemdsystemunitdir/pre-initoverlayfs-switch-root.service" + + + inst_dir /boot /initrofs /overlay /overlay/upper /overlay/work \ + /initoverlayfs + + $SYSTEMCTL -q --root "$initdir" set-default pre-initoverlayfs.target + $SYSTEMCTL -q --root "$initdir" enable pre-initoverlayfs.service + $SYSTEMCTL -q --root "$initdir" enable pre-initoverlayfs-switch-root.service + > "${initdir}/usr/bin/bash" + +if false; then # only needed if systemd-initrd is included + local initsystemd="${initdir}/${systemdsystemunitdir}" + rm -f "${initsystemd}/initrd-root-device.target" \ + "${initsystemd}/initrd-root-fs.target" \ + "${initsystemd}/initrd-parse-etc.service" \ + "${initsystemd}/initrd-fs.target" \ + "${initsystemd}/initrd.target" \ + "${initsystemd}/initrd-cleanup.service" \ + "${initsystemd}/initrd-udevadm-cleanup-db.service" \ + "${initsystemd}/initrd-switch-root.target" \ + "${initsystemd}/initrd-switch-root.service" +fi } diff --git a/lib/systemd/system/pre-initoverlayfs-switch-root.service b/lib/systemd/system/pre-initoverlayfs-switch-root.service new file mode 100644 index 0000000..f4b110f --- /dev/null +++ b/lib/systemd/system/pre-initoverlayfs-switch-root.service @@ -0,0 +1,15 @@ +[Unit] +Description=Switch Root pre-initoverlayfs +AssertPathExists=/etc/initrd-release +DefaultDependencies=no +ConditionPathExists=/etc/initrd-release +AllowIsolate=yes +OnFailure=emergency.target +OnFailureJobMode=replace-irreversibly +Before=sysinit.target pre-initoverlayfs.target +After=systemd-journald.service pre-initoverlayfs.service + +[Service] +Type=oneshot +ExecStart=systemctl --no-block switch-root /initoverlayfs + diff --git a/lib/systemd/system/pre-initoverlayfs-switch-root.target b/lib/systemd/system/pre-initoverlayfs-switch-root.target new file mode 100644 index 0000000..dc4cb30 --- /dev/null +++ b/lib/systemd/system/pre-initoverlayfs-switch-root.target @@ -0,0 +1,10 @@ +[Unit] +Description=Switch Root pre-initoverlayfs +AssertPathExists=/etc/initrd-release +DefaultDependencies=no +Wants=pre-initoverlayfs-switch-root.service +Before=pre-initoverlayfs-switch-root.service +AllowIsolate=yes +Wants=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target systemd-journald.service initrd-cleanup.service +After=initrd-udevadm-cleanup-db.service initrd-root-fs.target initrd-fs.target emergency.service emergency.target initrd-cleanup.service + diff --git a/lib/systemd/system/pre-initoverlayfs.service b/lib/systemd/system/pre-initoverlayfs.service new file mode 100644 index 0000000..7799758 --- /dev/null +++ b/lib/systemd/system/pre-initoverlayfs.service @@ -0,0 +1,18 @@ +[Unit] +Description=Pre-Initoverlayfs initialization +AssertPathExists=/etc/initrd-release +DefaultDependencies=no +ConditionPathExists=/etc/initrd-release +OnFailure=emergency.target +OnFailureJobMode=replace-irreversibly +Before=sysinit.target pre-initoverlayfs.target +After=systemd-journald.service + +[Service] +Type=oneshot +ExecStart=/usr/sbin/storage-init +StandardInput=null +StandardOutput=journal+console +StandardError=journal+console +RemainAfterExit=yes + diff --git a/lib/systemd/system/pre-initoverlayfs.target b/lib/systemd/system/pre-initoverlayfs.target new file mode 100644 index 0000000..202f956 --- /dev/null +++ b/lib/systemd/system/pre-initoverlayfs.target @@ -0,0 +1,10 @@ +[Unit] +Description=Pre-Initoverlayfs Default Target +OnFailure=emergency.target +OnFailureJobMode=replace-irreversibly +AssertPathExists=/etc/initrd-release +Requires=basic.target +#Wants=initrd-root-fs.target initrd-root-device.target initrd-fs.target initrd-usr-fs.target initrd-parse-etc.service +After=pre-initoverlayfs.service rescue.target +AllowIsolate=yes + diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..6d797e6 --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -ex + +REL="$(git tag | tail -1)" +mkdir -p $HOME/rpmbuild/SOURCES/ +git archive -o $HOME/rpmbuild/SOURCES/initoverlayfs-$REL.tar.gz --prefix initoverlayfs-$REL/ HEAD +./build-scripts/create-spec.sh +rpmbuild_output=$(rpmbuild -bb initoverlayfs.spec 2>&1) +rpm_to_install=$(echo "$rpmbuild_output" | grep "Wrote:" | awk '{print $2}') +if rpm -Uvh $rpm_to_install; then + echo "$rpmbuild_output" +fi + +initoverlayfs-install + diff --git a/storage-init.c b/storage-init.c index 553fa44..05f03d7 100644 --- a/storage-init.c +++ b/storage-init.c @@ -509,6 +509,8 @@ static inline int convert_fs(conf* c) { "redirect_dir=on,lowerdir=/initrofs,upperdir=/overlay/upper,workdir=/" \ "overlay/work" +#define SYSROOT "/initoverlayfs" + static inline void mounts(const conf* c) { autofree char* dev_loop = 0; if (c->fs.val->c_str && losetup(&dev_loop, c->fs.val->c_str)) @@ -521,19 +523,19 @@ static inline void mounts(const conf* c) { "%d (%s)\n", dev_loop, c->fstype.val->c_str, errno, strerror(errno)); - if (mount("overlay", "/initoverlayfs", "overlay", 0, + if (mount("overlay", SYSROOT, "overlay", 0, "volatile," OVERLAY_STR) && errno == EINVAL && - mount("overlay", "/initoverlayfs", "overlay", 0, OVERLAY_STR)) + mount("overlay", SYSROOT, "overlay", 0, OVERLAY_STR)) print( - "mount(\"overlay\", \"/initoverlayfs\", \"overlay\", 0, \"" OVERLAY_STR + "mount(\"overlay\", \"" SYSROOT "\", \"overlay\", 0, \"" OVERLAY_STR "\") %d (%s)\n", errno, strerror(errno)); - if (mount("/boot", "/initoverlayfs/boot", c->bootfstype.val->c_str, MS_MOVE, + if (mount("/boot", SYSROOT "/boot", c->bootfstype.val->c_str, MS_MOVE, NULL)) print( - "mount(\"/boot\", \"/initoverlayfs/boot\", \"%s\", MS_MOVE, NULL) " + "mount(\"/boot\", \"" SYSROOT "/boot\", \"%s\", MS_MOVE, NULL) " "%d (%s)\n", c->bootfstype.val->c_str, errno, strerror(errno)); } @@ -575,6 +577,7 @@ static inline char** cmd_to_argv(char* cmd) { } void wait_mount_bootfs(const conf* c) { +#if 0 pid_t udev_wait_pid; fork_execlp_no_wait(udev_wait_pid, "udevadm", "wait", "-t", "8", c->bootfs.val->c_str); @@ -589,6 +592,7 @@ void wait_mount_bootfs(const conf* c) { udev_trigger(udev_trigger_generic_argv); waitpid(udev_trigger_generic_pid, 0, 0); } +#endif fork_execlp("udevadm", "wait", c->bootfs.val->c_str); @@ -608,13 +612,17 @@ void exec_init(void) { } int main(void) { +#if 0 mount_proc_sys_dev(); autofclose FILE* kmsg_f_scoped = log_open_kmsg(); kmsg_f = kmsg_f_scoped; pid_t udevd_pid; fork_execl_no_wait(udevd_pid, "/lib/systemd/systemd-udevd", "--daemon"); +#endif pid_t loop_pid; fork_execl_no_wait(loop_pid, "/usr/sbin/modprobe", "loop"); + pid_t erofs_pid; + fork_execl_no_wait(erofs_pid, "/usr/sbin/modprobe", "erofs"); autofree_conf conf conf = {.bootfs = {0, 0}, .bootfstype = {0, 0}, .fs = {0, 0}, @@ -625,24 +633,35 @@ int main(void) { return 0; conf_read(&conf, "/etc/initoverlayfs.conf"); +#if 0 autofree char** udev_trigger_argv = cmd_to_argv(conf.udev_trigger.val->c_str); waitpid(udevd_pid, 0, 0); const pid_t udev_trigger_pid = udev_trigger(udev_trigger_argv); +#endif + const bool do_bootfs = convert_bootfs(&conf); convert_fs(&conf); + +#if 0 waitpid(udev_trigger_pid, 0, 0); +#endif + waitpid(loop_pid, 0, 0); + waitpid(erofs_pid, 0, 0); if (do_bootfs) wait_mount_bootfs(&conf); errno = 0; mounts(&conf); + +#if 0 if (switchroot("/initoverlayfs")) { print("switchroot(\"/initoverlayfs\") %d (%s)\n", errno, strerror(errno)); return 0; } exec_init(); +#endif return 0; }