#!/bin/bash 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="$1" rule= key= value= binary= if [[ ${rules:0:1} != '/' ]]; then rules=$(PATH=/usr/lib/udev/rules.d:/lib/udev/rules.d type -P "$1") fi if [[ -z $rules ]]; then # complain about not found rules return 1 fi add_file "$rules" /usr/lib/udev/rules.d/"${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 binary=${value//[\"\']/} # just take the first word as the binary name binary=${binary%% *} [[ ${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:/usr/lib64/systemd/system:/lib64/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*) # do not add binaries unless they are required, # strip special executable prefixes case ${values[0]} in -*) ;; !!*) add_binary "${values[0]#!!}" ;; *) add_binary "${values[0]#[@!:+]}" ;; esac ;; 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 local libdir if [ -e /usr/lib64 ] ; then libdir="lib64" else libdir="lib" fi add_binary /usr/lib/initcpio/busybox /usr/bin/busybox add_symlink "/bin" /usr/bin for applet in $(/usr/lib/initcpio/busybox --list | grep -v busybox); do add_symlink "/usr/bin/$applet" /usr/bin/busybox done add_binary /usr/bin/sulogin add_binary /usr/lib/systemd/systemd /init add_file /etc/os-release add_file /etc/machine-id add_file /etc/machine-info map add_binary \ /usr/bin/systemd-tmpfiles \ /usr/lib/systemd/systemd-executor \ /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 # 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.target \ local-fs.target \ local-fs-pre.target \ paths.target \ reboot.target \ slices.target \ sockets.target \ systemd-fsck@.service \ systemd-hibernate-resume@.service \ systemd-modules-load.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/$libdir/libnss_files.so.2)" add_binary "$(readlink -f /usr/$libdir/libnss_systemd.so.2)" printf '%s\n' >"$BUILDROOT/etc/nsswitch.conf" \ 'passwd: files systemd' \ 'group: files [SUCCESS=merge] systemd' \ 'shadow: files [UNAVAIL=return] systemd' echo "root:x:0:0:root:/root:/bin/sh" >"$BUILDROOT/etc/passwd" echo 'root::18684::::::' >"$BUILDROOT/etc/shadow" getent group root audio disk input kmem kvm lp optical render sgx storage tty uucp video | awk -F: ' { print $1 ":x:" $3 ":" }' >"$BUILDROOT/etc/group" for sysuserfile in $(ls /usr/lib/sysusers.d/) ; do add_file /usr/lib/sysusers.d/${sysuserfile} done add_dir "/etc/modules-load.d" ( . "$_f_config" set -f printf '%s\n' ${MODULES[@]} >"$BUILDROOT/etc/modules-load.d/MODULES.conf" ) add_dir /etc/systemd echo -e "[Manager]\\nDefaultStandardOutput=inherit" > $BUILDROOT/etc/systemd/system.conf } help() { cat <