diff options
author | Dave Reisner <dreisner@archlinux.org> | 2012-05-13 02:14:56 +0200 |
---|---|---|
committer | Dave Reisner <dreisner@archlinux.org> | 2012-05-18 19:08:45 +0200 |
commit | 6df8511544a6a6b959e2cc6dd038f306d3de9685 (patch) | |
tree | 0b1c6a1fc170197f2fc36b7b011b60031e519f89 | |
parent | 1f7f41d1f88c1dd8eb3e70f1955c8bd1b029ca79 (diff) | |
download | mkinitcpio-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-x | lsinitcpio | 63 |
1 files changed, 45 insertions, 18 deletions
@@ -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 |