[arch-projects] [mkinitcpio][PATCH 18/19] lsinitcpio: extract the image to a tempdir

Dave Reisner dreisner at archlinux.org
Sun May 13 13:57:21 EDT 2012


We read the image a number of times. Extract the image to a temp
directory so we can just extract it once and use the filesystem to our
advantage. This requires a temp dir which we can nuke on an EXIT trap,
but the whole operation is sped is a bit, especially for larger images.

The real goal of this is to make examination of the hooks easier. Since
we now have multiple hook sets to contend with, dynamically tally up the
available functions in the hook files so we can iterate over specific
functions of interest in the output.

Signed-off-by: Dave Reisner <dreisner at archlinux.org>
---
 lsinitcpio |   59 +++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 18 deletions(-)

diff --git a/lsinitcpio b/lsinitcpio
index 5abe37f..f33d9d3 100755
--- a/lsinitcpio
+++ b/lsinitcpio
@@ -59,7 +59,6 @@ size_to_human() {
     }'
 }
 
-
 OPT_SHORT='ahnvx'
 OPT_LONG=('analyze' 'help' 'nocolor' 'verbose' 'extract')
 
@@ -127,6 +126,9 @@ if (( analyze )); then
     declare -a binaries explicitmod modules foundhooks hooks
     declare kernver ratio columns=$(tput cols)
 
+    workdir=$(mktemp -d --tmpdir="$TMPDIR" lsinitcpio.XXXXXX)
+    trap 'rm -rf "$workdir"' EXIT
+
     # fallback in case tput failed us
     columns=${columns:-80}
 
@@ -139,27 +141,48 @@ if (( analyze )); then
         ratio=.$(( zsize * 1000 / fullsize % 1000 ))
     fi
 
-    # read contents of image
-    while read -r line; do
-        if [[ $line = *.ko?(.?z) ]]; then
-            line=${line##*/}
-            modules+=("${line%.ko?(.?z)}")
-        elif [[ -z $kernver && $line =~ /lib/modules/([^/]+)/ ]]; then
-            kernver=${BASH_REMATCH[1]}
-        elif [[ $line = ./hooks/* ]]; then
-            foundhooks+=("${line##*/}")
-        elif [[ $line = *@(/?(s)bin/)* ]]; then
-            binaries+=("${line##*/}")
-        fi
-    done < <(decomp "$image" | bsdtar tf -)
-
-    read -r version < <(decomp "$image" | bsdtar xOf - VERSION 2>/dev/null)
+    # decompress the image since we need to read from it multiple times
+    decomp "$image" | bsdtar -C "$workdir" -xf -
+
+    # collect stats
+    kernver=("$workdir"/usr/lib/modules/*/)
+    kernver=${kernver%/}
+    kernver=${kernver##*/}
+
+    modules=("$workdir/usr/lib/modules/$kernver"/kernel/*.ko*)
+    modules=("${modules[@]##*/}")
+    modules=("${modules[@]%.ko*}")
+
+    foundhooks=("$workdir"/hooks/*)
+    foundhooks=("${foundhooks[@]##*/}")
+
+    binaries=("$workdir"/usr/bin/*)
+    binaries=("${binaries[@]##*/}")
+
+    read -r version < "$workdir/VERSION"
 
     # source and read config
-    . <(decomp "$image" | bsdtar xOf - config)
+    . "$workdir/config"
+
     explicitmod=($MODULES)
+
     for hook in $HOOKS; do
-        in_array "$hook" "${foundhooks[@]}" && hooks+=("$hook")
+        [[ -e $workdir/hooks/$hook ]] || continue
+
+        mapfile -t funcs < \
+            <(awk '
+                /^[[:space:]]*[[:alnum:]_]+/ && /\([[:space:]]*\)/ {
+                    match($1, /[[:alnum:]_]+/)
+                    print substr($1, RSTART, RLENGTH)
+                }' "$workdir/hooks/$hook")
+
+        for fn in "${funcs[@]}"; do
+            case $fn in
+                run_hook)
+                    hooks+=("$hook")
+                    ;;
+            esac
+        done
     done
 
     # print results
-- 
1.7.10.2



More information about the arch-projects mailing list