[arch-projects] [mkinitcpio][PATCH] functions: add_udev_rules and add_systemd_unit

Tom Gundersen teg at jklm.no
Tue May 7 15:20:10 EDT 2013


add_udev_rules() adds a rules file and pulls in the necessary binaries udev
rules by automatically pulling in the necessary binaries.

add_systemd_unit() pulls in the necessary binaries, and also Requires= and
OnFailure= units. Moreover, it respects reverse soft dependencies by including
all the *.wants/ symlinks pointing to the unit.
---
 functions            | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 man/mkinitcpio.8.txt | 14 +++++++++
 2 files changed, 95 insertions(+)

diff --git a/functions b/functions
index bb28f34..0ee91d4 100644
--- a/functions
+++ b/functions
@@ -587,6 +587,87 @@ add_binary() {
     return 0
 }
 
+add_udev_rules() {
+    # 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
+        for pair in "${rule[@]}"; do
+            IFS='=' read -r key value <<< "$pair"
+
+            case $key in
+                RUN@({program}|)@(+|)|IMPORT{program}|ENV{REMOVE_CMD})
+                    binary=${value[0]#\"}
+                    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,/lib/systemd/system}/*.wants/${unit##*/}; do
+        if [[ -h "${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
+}
+
 parse_config() {
     # parse key global variables set by the config file.
 
diff --git a/man/mkinitcpio.8.txt b/man/mkinitcpio.8.txt
index 56ac571..ea56741 100644
--- a/man/mkinitcpio.8.txt
+++ b/man/mkinitcpio.8.txt
@@ -166,6 +166,20 @@ functions exist to facilitate this.
 	script. The name of the script is guaranteed to match the name of the hook the
 	script is called from.
 
+*add_udev_rules*::
+
+	Adds a udev rules file. Also pulls in the necessary binaries referenced in
+	the rules.
+
+*add_systemd_unit*::
+
+	Adds a systemd unit file. Also pulls in the necessary binaries referenced in
+	the unit, but only hard dependencies, so not ones prefixed with '-'.
+	Moreover, hard dependencies on other unit files are added, and reverse soft
+	dependencies are respected. The latter means that if A wants B and A is
+	included in the initramfs, the necessary symlink to make A want B in the
+	initramfs is included if and only if B is included.
+
 About Runtime Hooks
 -------------------
 Runtime hooks added to the image via the *add_runscript* function from an
-- 
1.8.2.2



More information about the arch-projects mailing list