summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Reisner <dreisner@archlinux.org>2012-05-13 02:14:56 +0200
committerDave Reisner <dreisner@archlinux.org>2012-05-18 19:08:45 +0200
commit6df8511544a6a6b959e2cc6dd038f306d3de9685 (patch)
tree0b1c6a1fc170197f2fc36b7b011b60031e519f89
parent1f7f41d1f88c1dd8eb3e70f1955c8bd1b029ca79 (diff)
downloadmkinitcpio-6df8511544a6a6b959e2cc6dd038f306d3de9685.tar.gz
mkinitcpio-6df8511544a6a6b959e2cc6dd038f306d3de9685.tar.xz
lsinitcpio: extract the image to a tempdir
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. Signed-off-by: Dave Reisner <dreisner@archlinux.org>
-rwxr-xr-xlsinitcpio63
1 files changed, 45 insertions, 18 deletions
diff --git a/lsinitcpio b/lsinitcpio
index 5abe37f..1c52d68 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,52 @@ 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*)
+ if [[ -f ${modules[0]} ]]; then
+ modules=("${modules[@]##*/}")
+ modules=("${modules[@]%.ko*}")
+ else
+ unset modules
+ fi
+
+ foundhooks=("$workdir"/hooks/*)
+ [[ -f ${foundhooks[0]} ]] && foundhooks=("${foundhooks[@]##*/}") || unset 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