[arch-projects] [mkinitcpio][PATCH] [WIP] systemd: add systemd hook and needed files

Tom Gundersen teg at jklm.no
Thu Nov 22 12:44:38 EST 2012


This is based on dracut, but with all the glue-scripts removed.

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

Note: generate initramfs with
 HOOKS=('base' 'fsck' 'systemd')
to get all the needed binaries (such as mount and fsck and busybox for
debugging).

TODO:

 * patch systemctl to read init= from /proc/cmdline if it is not given as
   an argument to switch-root (now it always reexecs systemd)
 * make a rootfs-mount-from-proc-cmdline generator instead of a
   hardcoded new_root.mount
 * 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
---
 initrd-pre-switch-root.service | 19 ++++++++++++
 initrd-switch-root.service     | 20 +++++++++++++
 initrd-switch-root.target      | 16 ++++++++++
 install/systemd                | 68 ++++++++++++++++++++++++++++++++++++++++++
 new_root.mount                 | 15 ++++++++++
 udevadm-cleanup-db.service     | 18 +++++++++++
 6 files changed, 156 insertions(+)
 create mode 100644 initrd-pre-switch-root.service
 create mode 100644 initrd-switch-root.service
 create mode 100644 initrd-switch-root.target
 create mode 100644 install/systemd
 create mode 100644 new_root.mount
 create mode 100644 udevadm-cleanup-db.service

diff --git a/initrd-pre-switch-root.service b/initrd-pre-switch-root.service
new file mode 100644
index 0000000..ae6a731
--- /dev/null
+++ b/initrd-pre-switch-root.service
@@ -0,0 +1,19 @@
+#  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
+ConditionPathExists=/etc/initrd-release
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/systemctl --no-block isolate initrd-switch-root.target
diff --git a/initrd-switch-root.service b/initrd-switch-root.service
new file mode 100644
index 0000000..03ff9a8
--- /dev/null
+++ b/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.service
+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/initrd-switch-root.target b/initrd-switch-root.target
new file mode 100644
index 0000000..fd23908
--- /dev/null
+++ b/initrd-switch-root.target
@@ -0,0 +1,16 @@
+#  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
+ConditionPathExists=/etc/initrd-release
diff --git a/install/systemd b/install/systemd
new file mode 100644
index 0000000..9b38bdf
--- /dev/null
+++ b/install/systemd
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+build() {
+    local rules tool socket service
+
+    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 /bin/bash
+    add_binary /usr/bin/journalctl
+
+    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 debug-shell; 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 local-fs local-fs-pre remote-fs remote-fs-pre initrd-switch-root; do
+        add_file "/usr/lib/systemd/system/$target.target"
+    done
+
+    # 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/libnsl-2.16.so"
+    add_symlink "/lib/libnsl.so" "libnsl.so.1"
+    add_symlink "/lib/libnsl.so.1" "libnsl-2.16.so"
+    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 at .service"
+    add_file "/usr/lib/systemd/system/initrd-switch-root.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"
+
+    # this should be done by a generator (based on /proc/cmdline), and not be hardcoded for my machine...
+    add_file "/usr/lib/systemd/system/new_root.mount"
+    add_symlink "/usr/lib/systemd/system/local-fs.target.wants/new_root.mount" "../new_root.mount"
+}
+
+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/new_root.mount b/new_root.mount
new file mode 100644
index 0000000..9cb8338
--- /dev/null
+++ b/new_root.mount
@@ -0,0 +1,15 @@
+# Automatically generated by systemd-root-proc-cmdline-generator
+
+[Unit]
+SourcePath=/proc/cmdline
+DefaultDependencies=no
+After=local-fs-pre.target
+Wants=local-fs-pre.target
+Before=local-fs.target
+
+[Mount]
+What=/dev/sda3
+Where=/new_root
+Type=btrfs
+FsckPassNo=0
+Options=defaults
diff --git a/udevadm-cleanup-db.service b/udevadm-cleanup-db.service
new file mode 100644
index 0000000..983189e
--- /dev/null
+++ b/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



More information about the arch-projects mailing list