[arch-projects] [mkinitcpio][PATCH v3] [WIP] systemd: add systemd hook and needed files
Note: generate initramfs with HOOKS=('systemd' 'block' 'fsck') This is based on dracut, but with all the glue-scripts removed. It relies on patches posted to the systemd ML to support root= and init= natively, as well as current systemd git to avoid a cycle in /shutdown. Idea is: * start systemd/udevd/journald * wait for the root device to appear * mount the rootfs * isolate the switch-root target * this shuts down/cleans up everything * then copies the initramfs to /run/initramfs (for the shutdown hook) * then calls systemctl to switch to the new root and reexec systemd TODO: * include more systemd units and helpers, should reveiw them all * discuss with dracut/systemd people the possibility of putting something like this in the systemd repo so we don't have to duplicate work * write a separate 'debug' hook, including emergency.service++ --- v3: incorporate shutdown hook and clean up a bit Makefile | 11 ++++++ install/systemd | 65 ++++++++++++++++++++++++++++++++++ systemd/initrd-pre-switch-root.service | 20 +++++++++++ systemd/initrd-switch-root.service | 21 +++++++++++ systemd/initrd-switch-root.target | 17 +++++++++ systemd/udevadm-cleanup-db.service | 18 ++++++++++ 6 files changed, 152 insertions(+) create mode 100644 install/systemd create mode 100644 systemd/initrd-pre-switch-root.service create mode 100644 systemd/initrd-switch-root.service create mode 100644 systemd/initrd-switch-root.target create mode 100644 systemd/udevadm-cleanup-db.service diff --git a/Makefile b/Makefile index 88f82db..93289b5 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,8 @@ DIRS = \ /usr/lib/initcpio/hooks \ /usr/lib/initcpio/install \ /usr/lib/initcpio/udev \ + /usr/lib/systemd/system \ + /usr/lib/systemd/generators \ /usr/share/man/man8 \ /usr/share/man/man5 \ /usr/share/man/man1 @@ -43,6 +45,15 @@ install: all install -m644 -t $(DESTDIR)/usr/lib/initcpio init_functions functions install -m644 01-memdisk.rules $(DESTDIR)/usr/lib/initcpio/udev/01-memdisk.rules + install -m644 systemd/initrd-pre-switch-root.service \ + $(DESTDIR)/usr/lib/systemd/system/initrd-pre-switch-root.service + install -m644 systemd/initrd-switch-root.service \ + $(DESTDIR)/usr/lib/systemd/system/initrd-switch-root.service + install -m644 systemd/udevadm-cleanup-db.service \ + $(DESTDIR)/usr/lib/systemd/system/udevadm-cleanup-db.service + install -m644 systemd/initrd-switch-root.target \ + $(DESTDIR)/usr/lib/systemd/system/initrd-switch-root.target + cp -at $(DESTDIR)/usr/lib/initcpio/hooks hooks/* cp -at $(DESTDIR)/usr/lib/initcpio/install install/* cp -at $(DESTDIR)/etc/mkinitcpio.d mkinitcpio.d/* diff --git a/install/systemd b/install/systemd new file mode 100644 index 0000000..9a2c887 --- /dev/null +++ b/install/systemd @@ -0,0 +1,65 @@ +#!/bin/bash + +build() { + local rules tool socket service + + # from base + add_binary /usr/bin/kmod + add_symlink /usr/bin/modprobe kmod + add_binary /bin/mount + + # systemd + add_binary /usr/lib/systemd/systemd /init + add_binary /usr/bin/systemctl + add_binary /usr/bin/udevadm + add_binary /usr/lib/systemd/systemd-udevd + add_binary /usr/lib/systemd/systemd-journald + + # shutdown + add_binary /usr/bin/cp + add_binary /usr/lib/systemd/systemd-shutdown /shutdown + + # generate new_root.mount + add_file "/usr/lib/systemd/system-generators/systemd-fstab-generator" + + # needed by libdbus, maybe it should be patched to special-case uid=0 and avoid the dep? + add_file "/lib/libnss_files-2.16.so" + add_symlink "/lib/libnss_files.so" "libnss_files.so.2" + add_symlink "/lib/libnss_files.so.2" "libnss_files-2.16.so" + + # udev rules and systemd units + for rules in 50-udev-default.rules 60-persistent-storage.rules 64-btrfs.rules 80-drivers.rules 99-systemd.rules; do + add_file "/usr/lib/udev/rules.d/$rules" + done + for tool in ata_id scsi_id; do + add_file "/usr/lib/udev/$tool" + done + for socket in systemd-udevd-control systemd-udevd-kernel systemd-journald; do + add_file "/usr/lib/systemd/system/$socket.socket" + add_symlink "/usr/lib/systemd/system/sockets.target.wants/$socket.socket" "../$socket.socket" + done + for service in systemd-udevd systemd-udev-trigger systemd-journald; do + add_file "/usr/lib/systemd/system/$service.service" + add_symlink "/usr/lib/systemd/system/sysinit.target.wants/$service.service" "../$service.service" + done + for target in sysinit sockets basic emergency local-fs local-fs-pre remote-fs remote-fs-pre ctrl-alt-del initrd-switch-root; do + add_file "/usr/lib/systemd/system/$target.target" + done + + add_file "/usr/lib/systemd/system/systemd-fsck@.service" + add_file "/usr/lib/systemd/system/initrd-switch-root.service" + add_file "/usr/lib/systemd/system/systemd-reboot.service" + add_symlink "/usr/lib/systemd/system/initrd-switch-root.target.wants/initrd-switch-root.service" "../initrd-switch-root.service" + add_file "/usr/lib/systemd/system/initrd-pre-switch-root.service" + add_symlink "/usr/lib/systemd/system/basic.target.wants/initrd-pre-switch-root.service" "../initrd-pre-switch-root.service" + + add_symlink "/usr/lib/systemd/system/default.target" "basic.target" +} + +help() { + cat <<HELPEOF +This will install a basic systemd setup on your initrd, you might want to add more hooks to get more advanced functionality. +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/systemd/initrd-pre-switch-root.service b/systemd/initrd-pre-switch-root.service new file mode 100644 index 0000000..516be94 --- /dev/null +++ b/systemd/initrd-pre-switch-root.service @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +# See systemd.special(7) for details + +[Unit] +Description=Waiting for new root device to appear +DefaultDependencies=no +Requires=new_root.mount +After=new_root.mount +OnFailure=emergency.target +ConditionPathExists=/etc/initrd-release + +[Service] +Type=oneshot +ExecStart=/usr/bin/systemctl --no-block isolate initrd-switch-root.target diff --git a/systemd/initrd-switch-root.service b/systemd/initrd-switch-root.service new file mode 100644 index 0000000..84d706f --- /dev/null +++ b/systemd/initrd-switch-root.service @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Switch Root +DefaultDependencies=no +ConditionPathExists=/etc/initrd-release +OnFailure=emergency.target +After=initrd-switch-root.target new_root.mount +AllowIsolate=yes + +[Service] +Type=oneshot +# we have to use "--force" here, otherwise systemd would umount /run +ExecStartPre=/bin/cp -ax / /run/initramfs +ExecStart=/usr/bin/systemctl --no-block --force switch-root /new_root +KillMode=none diff --git a/systemd/initrd-switch-root.target b/systemd/initrd-switch-root.target new file mode 100644 index 0000000..74647a5 --- /dev/null +++ b/systemd/initrd-switch-root.target @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +# See systemd.special(7) for details + +[Unit] +Description=Switch Root +DefaultDependencies=no +Requires=initrd-switch-root.service +Before=initrd-switch-root.service +AllowIsolate=yes +Wants=systemd-journald.service +ConditionPathExists=/etc/initrd-release diff --git a/systemd/udevadm-cleanup-db.service b/systemd/udevadm-cleanup-db.service new file mode 100644 index 0000000..983189e --- /dev/null +++ b/systemd/udevadm-cleanup-db.service @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Cleanup udevd DB +DefaultDependencies=no +ConditionPathExists=/etc/initrd-release +Conflicts=systemd-udevd.service systemd-udevd-control.socket systemd-udevd-kernel.socket +After=systemd-udevd.service systemd-udevd-control.socket systemd-udevd-kernel.socket +Before=initrd-switch-root.target + +[Service] +Type=oneshot +ExecStart=-/usr/bin/udevadm info --cleanup-db -- 1.8.0.1
participants (1)
-
Tom Gundersen