[arch-projects] [mkinitcpio][PATCH v2] [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 against systemd to support root= and init= natively. 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 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 --- v2: move init=/root= parsing into systemd patches, no longer depend on the base hook Makefile | 11 +++++ install/systemd | 73 ++++++++++++++++++++++++++++++++++ systemd/initrd-pre-switch-root.service | 20 ++++++++++ systemd/initrd-switch-root.service | 20 ++++++++++ systemd/initrd-switch-root.target | 17 ++++++++ systemd/udevadm-cleanup-db.service | 18 +++++++++ 6 files changed, 159 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..ef20b69 --- /dev/null +++ b/install/systemd @@ -0,0 +1,73 @@ +#!/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 + + add_binary /usr/lib/systemd/systemd /init + add_binary /usr/bin/systemctl + add_binary /bin/mount + add_binary /usr/bin/udevadm + add_binary /usr/lib/systemd/systemd-udevd + add_binary /usr/lib/systemd/systemd-journald + # for debugging + add_binary /usr/bin/journalctl + add_binary /bin/bash + add_symlink /bin/sh bash + add_binary /sbin/sulogin + + 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-generators/systemd-fstab-generator" + + # wtf? + add_file "/etc/passwd" + add_file "/etc/shadow" + add_file "/etc/group" + add_file "/etc/gshadow" + add_file "/etc/nsswitch.conf" + # (wtf?)^2 + 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" + + + 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_file "/usr/lib/systemd/system/emergency.service" + add_symlink "/usr/lib/systemd/system/emergency.target.wants/emergency.service" "../emergency.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..745fb14 --- /dev/null +++ b/systemd/initrd-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. + +[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 +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
On 11/27/2012 09:02 PM, Tom Gundersen wrote:
Note: generate initramfs with HOOKS=('systemd' 'block' 'fsck')
This is based on dracut, but with all the glue-scripts removed. It relies on patches against systemd to support root= and init= natively.
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 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 ---
v2: move init=/root= parsing into systemd patches, no longer depend on the base hook
Interesting, where are these patches? Thanks.
Makefile | 11 +++++ install/systemd | 73 ++++++++++++++++++++++++++++++++++ systemd/initrd-pre-switch-root.service | 20 ++++++++++ systemd/initrd-switch-root.service | 20 ++++++++++ systemd/initrd-switch-root.target | 17 ++++++++ systemd/udevadm-cleanup-db.service | 18 +++++++++ 6 files changed, 159 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..ef20b69 --- /dev/null +++ b/install/systemd @@ -0,0 +1,73 @@ +#!/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 + + add_binary /usr/lib/systemd/systemd /init + add_binary /usr/bin/systemctl + add_binary /bin/mount + add_binary /usr/bin/udevadm + add_binary /usr/lib/systemd/systemd-udevd + add_binary /usr/lib/systemd/systemd-journald + # for debugging + add_binary /usr/bin/journalctl + add_binary /bin/bash + add_symlink /bin/sh bash + add_binary /sbin/sulogin + + 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-generators/systemd-fstab-generator" + + # wtf? + add_file "/etc/passwd" + add_file "/etc/shadow" + add_file "/etc/group" + add_file "/etc/gshadow" + add_file "/etc/nsswitch.conf" + # (wtf?)^2 + 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" + + + 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_file "/usr/lib/systemd/system/emergency.service" + add_symlink "/usr/lib/systemd/system/emergency.target.wants/emergency.service" "../emergency.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..745fb14 --- /dev/null +++ b/systemd/initrd-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. + +[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 +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
-- Gerardo Exequiel Pozzi \cos^2\alpha + \sin^2\alpha = 1
On Wed, Nov 28, 2012 at 1:28 AM, Gerardo Exequiel Pozzi <vmlinuz386@yahoo.com.ar> wrote:
On 11/27/2012 09:02 PM, Tom Gundersen wrote:
This is based on dracut, but with all the glue-scripts removed. It relies on patches against systemd to support root= and init= natively.
Interesting, where are these patches?
Here: <http://lists.freedesktop.org/archives/systemd-devel/2012-November/007575.html>. Cheers, Tom
On 11/27/2012 09:33 PM, Tom Gundersen wrote:
On Wed, Nov 28, 2012 at 1:28 AM, Gerardo Exequiel Pozzi <vmlinuz386@yahoo.com.ar> wrote:
On 11/27/2012 09:02 PM, Tom Gundersen wrote:
This is based on dracut, but with all the glue-scripts removed. It relies on patches against systemd to support root= and init= natively.
Interesting, where are these patches?
Here: <http://lists.freedesktop.org/archives/systemd-devel/2012-November/007575.html>.
Cheers,
Tom
hehe thanks I just received from systemd-devel :P I need to know how these things works for archiso ;) -- Gerardo Exequiel Pozzi \cos^2\alpha + \sin^2\alpha = 1
On Wed, Nov 28, 2012 at 1:37 AM, Gerardo Exequiel Pozzi <vmlinuz386@yahoo.com.ar> wrote:
I need to know how these things works for archiso ;)
I hope we can do exciting things! I had a quick look at archiso, but I don't know it well enough to make any suggestions yet. My initial thought was if some scripts could be replaced by an fstab file so that systemd would deal with all the mounting you do. -t
On Wed, Nov 28, 2012 at 1:39 AM, Tom Gundersen <teg@jklm.no> wrote:
On Wed, Nov 28, 2012 at 1:37 AM, Gerardo Exequiel Pozzi <vmlinuz386@yahoo.com.ar> wrote:
I need to know how these things works for archiso ;)
I hope we can do exciting things! I had a quick look at archiso, but I don't know it well enough to make any suggestions yet. My initial thought was if some scripts could be replaced by an fstab file so that systemd would deal with all the mounting you do.
By the way, in case my systemd patches are not accepted, they should not be necessary for archiso at all. An entry for /new_root can simply be put in the fstab file in the initramfs and no root=/init= entries are necessary. -t
Am 28.11.2012 01:39, schrieb Tom Gundersen:
My initial thought was if some scripts could be replaced by an fstab file so that systemd would deal with all the mounting you do.
For archiso, I'd rather rely on mount units only.
On Nov 28, 2012 10:29 AM, "Thomas Bächler" <thomas@archlinux.org> wrote:
Am 28.11.2012 01:39, schrieb Tom Gundersen:
My initial thought was if some scripts could be replaced by an fstab file so that systemd would deal with all the mounting you do.
For archiso, I'd rather rely on mount units only.
yeah, might as well
participants (3)
-
Gerardo Exequiel Pozzi
-
Thomas Bächler
-
Tom Gundersen