203 lines
6.1 KiB
Bash
203 lines
6.1 KiB
Bash
#!/bin/bash
|
|
|
|
strip_quotes() {
|
|
local len=${#1} quotes=$'[\'"]' str=${!1}
|
|
|
|
if [[ ${str:0:1} = ${str: -1} && ${str:0:1} = $quotes ]]; then
|
|
printf -v "$1" %s "${str:1:-1}"
|
|
fi
|
|
}
|
|
|
|
add_udev_rule() {
|
|
# Add an udev rules file to the initcpio image. Dependencies on binaries
|
|
# will be discovered and added.
|
|
# $1: path to rules file (or name of rules file)
|
|
|
|
local rules= rule= key= value= binary=
|
|
|
|
rules=$(PATH=/usr/lib/udev/rules.d:/lib/udev/rules.d type -P "$1")
|
|
if [[ -z $rules ]]; then
|
|
# complain about not found rules
|
|
return 1
|
|
fi
|
|
|
|
add_file "$rules"
|
|
|
|
while IFS=, read -ra rule; do
|
|
# skip empty lines, comments
|
|
[[ -z $rule || $rule = @(+([[:space:]])|#*) ]] && continue
|
|
|
|
for pair in "${rule[@]}"; do
|
|
IFS=' =' read -r key value <<< "$pair"
|
|
case $key in
|
|
RUN@({program}|+)|IMPORT{program}|ENV{REMOVE_CMD})
|
|
strip_quotes 'value'
|
|
# just take the first word as the binary name
|
|
binary=${value%% *}
|
|
[[ ${binary:0:1} == '$' ]] && continue
|
|
if [[ ${binary:0:1} != '/' ]]; then
|
|
binary=$(PATH=/usr/lib/udev:/lib/udev type -P "$binary")
|
|
fi
|
|
add_binary "$binary"
|
|
;;
|
|
esac
|
|
done
|
|
done <"$rules"
|
|
}
|
|
|
|
add_systemd_unit() {
|
|
# Add a systemd unit file to the initcpio image. Hard dependencies on binaries
|
|
# and other unit files will be discovered and added.
|
|
# $1: path to rules file (or name of rules file)
|
|
|
|
local unit= rule= entry= key= value= binary= dep=
|
|
|
|
unit=$(PATH=/usr/lib/systemd/system:/lib/systemd/system type -P "$1")
|
|
if [[ -z $unit ]]; then
|
|
# complain about not found unit file
|
|
return 1
|
|
fi
|
|
|
|
add_file "$unit"
|
|
|
|
while IFS='=' read -r key values; do
|
|
read -ra values <<< "$values"
|
|
|
|
case $key in
|
|
Requires|OnFailure)
|
|
# only add hard dependencies (not Wants)
|
|
map add_systemd_unit "${values[@]}"
|
|
;;
|
|
Exec*)
|
|
# don't add binaries unless they are required
|
|
if [[ ${values[0]:0:1} != '-' ]]; then
|
|
add_binary "${values[0]}"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
done <"$unit"
|
|
|
|
# preserve reverse soft dependency
|
|
for dep in {/usr,}/lib/systemd/system/*.wants/${unit##*/}; do
|
|
if [[ -L $dep ]]; then
|
|
add_symlink "$dep"
|
|
fi
|
|
done
|
|
|
|
# add hard dependencies
|
|
if [[ -d $unit.requires ]]; then
|
|
for dep in "$unit".requires/*; do
|
|
add_systemd_unit ${dep##*/}
|
|
done
|
|
fi
|
|
}
|
|
|
|
add_systemd_drop_in() {
|
|
local unit=$1 dropin_name=$2
|
|
|
|
mkdir -p "$BUILDROOT/etc/systemd/system/$unit.d"
|
|
cat >"$BUILDROOT/etc/systemd/system/$unit.d/$2.conf"
|
|
}
|
|
|
|
build() {
|
|
local rules unit
|
|
|
|
# from base
|
|
add_binary /bin/mount
|
|
add_binary /usr/bin/kmod /usr/bin/modprobe
|
|
add_binary /usr/lib/systemd/systemd /init
|
|
add_binary /usr/bin/sulogin
|
|
|
|
map add_binary \
|
|
/usr/bin/systemd-tmpfiles \
|
|
/usr/lib/systemd/systemd-hibernate-resume \
|
|
/usr/lib/systemd/systemd-shutdown \
|
|
/usr/lib/systemd/systemd-sulogin-shell \
|
|
/usr/lib/systemd/system-generators/systemd-fstab-generator \
|
|
/usr/lib/systemd/system-generators/systemd-gpt-auto-generator \
|
|
/usr/lib/systemd/system-generators/systemd-hibernate-resume-generator
|
|
|
|
# for journalctl in emergency shell
|
|
add_binary journalctl
|
|
|
|
# udev rules and systemd units
|
|
map add_udev_rule "$rules" \
|
|
50-udev-default.rules \
|
|
60-persistent-storage.rules \
|
|
64-btrfs.rules \
|
|
80-drivers.rules \
|
|
99-systemd.rules
|
|
|
|
map add_systemd_unit \
|
|
initrd-cleanup.service \
|
|
initrd-fs.target \
|
|
initrd-parse-etc.service \
|
|
initrd-root-fs.target \
|
|
initrd-root-device.target \
|
|
initrd-switch-root.service \
|
|
initrd-switch-root.target \
|
|
initrd-udevadm-cleanup-db.service \
|
|
initrd.target \
|
|
kmod-static-nodes.service \
|
|
local-fs.target \
|
|
local-fs-pre.target \
|
|
paths.target \
|
|
reboot.target \
|
|
slices.target \
|
|
sockets.target \
|
|
swap.target \
|
|
systemd-fsck@.service \
|
|
systemd-hibernate-resume@.service \
|
|
systemd-journald.service \
|
|
systemd-journald-audit.socket \
|
|
systemd-journald-dev-log.socket \
|
|
systemd-modules-load.service \
|
|
systemd-tmpfiles-setup-dev.service \
|
|
systemd-udev-trigger.service \
|
|
systemd-udevd-control.socket \
|
|
systemd-udevd-kernel.socket \
|
|
systemd-udevd.service \
|
|
timers.target \
|
|
rescue.target \
|
|
emergency.target
|
|
|
|
add_symlink "/usr/lib/systemd/system/default.target" "initrd.target"
|
|
add_symlink "/usr/lib/systemd/system/ctrl-alt-del.target" "reboot.target"
|
|
|
|
add_binary "$(readlink -f /usr/lib/libnss_files.so)"
|
|
printf '%s\n' >"$BUILDROOT/etc/nsswitch.conf" \
|
|
'passwd: files' \
|
|
'group: files' \
|
|
'shadow: files'
|
|
|
|
echo "root:x:0:0:root:/:/bin/sh" >"$BUILDROOT/etc/passwd"
|
|
echo "root:x:0:root" >"$BUILDROOT/etc/group"
|
|
echo "root::::::::" >"$BUILDROOT/etc/shadow"
|
|
|
|
add_systemd_drop_in systemd-udevd.service resolve-names <<EOF
|
|
[Service]
|
|
ExecStart=
|
|
ExecStart=/usr/lib/systemd/systemd-udevd --resolve-names=never
|
|
EOF
|
|
|
|
add_dir "/etc/modules-load.d"
|
|
(
|
|
. "$_f_config"
|
|
set -f
|
|
printf '%s\n' ${MODULES[@]} >"$BUILDROOT/etc/modules-load.d/MODULES.conf"
|
|
)
|
|
}
|
|
|
|
help() {
|
|
cat <<HELPEOF
|
|
This will install a basic systemd setup in your initramfs, and is meant to
|
|
replace the 'base', 'usr', 'udev' and 'resume' hooks. Other hooks with runtime
|
|
components will need to be ported, and will not work as intended. You also may
|
|
wish to still include the 'base' hook (before this hook) to ensure that a
|
|
rescue shell exists on your initramfs.
|
|
HELPEOF
|
|
}
|
|
|
|
# vim: set ft=sh ts=4 sw=4 et:
|