commit:     944da1fc61bd64a47c2bc6415da5e5d5611b6ff5
Author:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Tue Jul 14 14:17:30 2020 +0000
Commit:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Thu Jul 16 14:29:15 2020 +0000
URL:        https://gitweb.gentoo.org/proj/genkernel.git/commit/?id=944da1fc

gen_initramfs.sh: create_initramfs(): Move and unify validation of 
--compress-initramfs-type to determine_real_args()

This will allow us to error out early if required user space tool
needed to compress initramfs based on specified --compress-initramfs-type
is missing or selected type is invalid/unsupported.

Best/fastest list is based on results from [Link1][Link2][Link3].

Link1: 
https://events.static.linuxfound.org/sites/events/files/lcjpcojp13_klee.pdf
Link2: 
https://kernel.ubuntu.com/~cking/boot-speed-eoan-5.3/kernel-compression-method.txt
Link3: https://lwn.net/Articles/817134/
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>

 defaults/compression_methods.sh | 37 +++++++++++++++++
 doc/genkernel.8.txt             | 10 +++--
 gen_cmdline.sh                  |  3 +-
 gen_determineargs.sh            | 91 +++++++++++++++++++++++++++++++++++++++++
 gen_funcs.sh                    | 24 +++++++++++
 gen_initramfs.sh                | 67 +++---------------------------
 genkernel                       |  1 +
 7 files changed, 168 insertions(+), 65 deletions(-)

diff --git a/defaults/compression_methods.sh b/defaults/compression_methods.sh
new file mode 100644
index 0000000..41ee9c4
--- /dev/null
+++ b/defaults/compression_methods.sh
@@ -0,0 +1,37 @@
+# NOTE:
+# - This file (compression_methods.sh) is sourced by genkernel.
+#   Rather than changing this very file, please override specific variables
+#   somewhere in /etc/genkernel.conf .
+#
+# - This file should not override previously defined variables, as their 
values may
+#   originate from user changes to /etc/genkernel.conf .
+
+GKICM_BZ2_KOPTNAME="BZIP2"
+GKICM_BZ2_CMD="bzip2 -z -f -9"
+GKICM_BZ2_EXT=".bz2"
+GKICM_BZ2_PKG="app-arch/bzip2"
+
+GKICM_GZ_KOPTNAME="GZIP"
+GKICM_GZ_CMD="gzip -f -9"
+GKICM_GZ_EXT=".gz"
+GKICM_GZ_PKG="app-arch/gzip"
+
+GKICM_LZO_KOPTNAME="LZO"
+GKICM_LZO_CMD="lzop -f -9"
+GKICM_LZO_EXT=".lzo"
+GKICM_LZO_PKG="app-arch/lzop"
+
+GKICM_LZ4_KOPTNAME="LZ4"
+GKICM_LZ4_CMD="lz4 -f -9 -l -q"
+GKICM_LZ4_EXT=".lz4"
+GKICM_LZ4_PKG="app-arch/lz4"
+
+GKICM_LZMA_KOPTNAME="LZMA"
+GKICM_LZMA_CMD="lzma -z -f -9"
+GKICM_LZMA_EXT=".lzma"
+GKICM_LZMA_PKG="app-arch/xz-utils"
+
+GKICM_XZ_KOPTNAME="XZ"
+GKICM_XZ_CMD="xz -e --check=none -z -f -9"
+GKICM_XZ_EXT=".xz"
+GKICM_XZ_PKG="app-arch/xz-utils"

diff --git a/doc/genkernel.8.txt b/doc/genkernel.8.txt
index 494a29c..40c591e 100644
--- a/doc/genkernel.8.txt
+++ b/doc/genkernel.8.txt
@@ -598,9 +598,13 @@ NOTE: System.map filename and System.map symlink name must 
be different.
     Deprecated alias for *--*[*no-*]*compress-initramfs*.
 
 *--compress-initramfs-type*=<arg>::
-    Compression type for initramfs (best, xz, lzma, bzip2, gzip, lzop, lz4).
-    "Best" causes selection of the best available algorithm that is selected
-    in your kernel configuration.
+    Compression type for initramfs (best, bzip2, fastest, gzip, lz4, lzma, 
lza, xz).
++
+*best* will select the algorithm providing best compression
+from those selected in your kernel configuration.
++
+*fastest* will select the algorithm providing fastest decompression
+from those selected in your kernel configuration.
 
 *--strip*=<all|kernel|modules|none>::
     Strip debug symbols from none, all, installed kernel (obsolete) or

diff --git a/gen_cmdline.sh b/gen_cmdline.sh
index 9e59ed2..1daee5c 100755
--- a/gen_cmdline.sh
+++ b/gen_cmdline.sh
@@ -243,7 +243,8 @@ longusage() {
   echo "       --compress-initrd       Deprecated alias for 
--compress-initramfs"
   echo "       --no-compress-initrd    Deprecated alias for 
--no-compress-initramfs"
   echo "       --compress-initramfs-type=<arg>"
-  echo "                               Compression type for initramfs (best, 
xz, lzma, bzip2, gzip, lzop, lz4)"
+  echo "                               Compression type for initramfs (best, 
bzip2, fastest, gzip, lz4,"
+  echo "                               lzma, lza, xz)"
   echo "       --strip=(all|kernel|modules|none)"
   echo "                               Strip debug symbols from none, all, 
installed kernel (obsolete) or"
   echo "                               modules (default)"

diff --git a/gen_determineargs.sh b/gen_determineargs.sh
index 0cbba36..406d1d5 100755
--- a/gen_determineargs.sh
+++ b/gen_determineargs.sh
@@ -619,6 +619,73 @@ determine_real_args() {
        done
        unset v pn pn_varname pkg_prefixes
 
+       declare -gA GKICM_LOOKUP_TABLE_CMD=()
+       declare -gA GKICM_LOOKUP_TABLE_EXT=()
+       declare -gA GKICM_LOOKUP_TABLE_PKG=()
+       local known_initramfs_compression_methods_by_compression=( 
$(get_initramfs_compression_method_by_compression) )
+       local known_initramfs_compression_methods_by_speed=( 
$(get_initramfs_compression_method_by_speed) )
+       local initramfs_compression_methods=( $(compgen -A variable |grep 
'^GKICM_.*_KOPTNAME$') )
+       local initramfs_compression_method key var_name var_prefix
+       for initramfs_compression_method in 
"${initramfs_compression_methods[@]}"
+       do
+               if [ -z "${!initramfs_compression_method}" ]
+               then
+                       gen_die "Invalid config found: Check value of 
'${initramfs_compression_method}'!"
+               fi
+
+               if [[ "${known_initramfs_compression_methods_by_compression[@]} 
" != *"${!initramfs_compression_method}"* ]]
+               then
+                       gen_die "Internal error: Initramfs compression method 
'${!initramfs_compression_method}' was not added to 
get_initramfs_compression_method_by_compression()!"
+               else
+                       known_initramfs_compression_methods_by_compression=( 
$(printf '%s\n' 
"${known_initramfs_compression_methods_by_compression[@]//${!initramfs_compression_method}/}")
 )
+               fi
+
+               if [[ "${known_initramfs_compression_methods_by_speed[@]} " != 
*"${!initramfs_compression_method}"* ]]
+               then
+                       gen_die "Internal error: Initramfs compression method 
'${!initramfs_compression_method}' was not added to 
get_initramfs_compression_method_by_speed()!"
+               else
+                       known_initramfs_compression_methods_by_speed=( $(printf 
'%s\n' 
"${known_initramfs_compression_methods_by_speed[@]//${!initramfs_compression_method}/}")
 )
+               fi
+
+               var_prefix="${initramfs_compression_method%_KOPTNAME}"
+
+               for key in CMD EXT PKG
+               do
+                       var_name="${var_prefix}_${key}"
+                       if [ -z "${!var_name}" ]
+                       then
+                               gen_die "Internal error: Variable '${var_name}' 
is not set!"
+                       fi
+
+                       case ${key} in
+                               CMD)
+                                       
GKICM_LOOKUP_TABLE_CMD[${!initramfs_compression_method}]="${!var_name}"
+                                       ;;
+                               EXT)
+                                       
GKICM_LOOKUP_TABLE_EXT[${!initramfs_compression_method}]="${!var_name}"
+                                       ;;
+                               PKG)
+                                       
GKICM_LOOKUP_TABLE_PKG[${!initramfs_compression_method}]="${!var_name}"
+                                       ;;
+                       esac
+               done
+       done
+       unset initramfs_compression_methods initramfs_compression_method key 
var_name var_prefix
+
+       # It is enough to check just one data set because we validated
+       # both data sets above.
+       if [[ ${#known_initramfs_compression_methods_by_compression[@]} -gt 0 ]]
+       then
+               local unhandled_method
+               for unhandled_method in 
"${known_initramfs_compression_methods_by_compression[@]}"
+               do
+                       print_error 1 "Do not know how to handle initramfs 
compression type '${unhandled_method}'!"
+               done
+
+               gen_die "Internal error: Not all known initramfs compression 
methods are defined!"
+       fi
+       unset known_initramfs_compression_methods_by_compression 
known_initramfs_compression_methods_by_speed
+
        if [ -n "${CMD_BOOTLOADER}" ]
        then
                BOOTLOADER="${CMD_BOOTLOADER}"
@@ -1009,6 +1076,30 @@ determine_real_args() {
                        gen_die "'\"${LDDTREE_COMMAND}\" -l 
\"${CPIO_COMMAND}\"' failed -- cannot generate initramfs without working 
lddtree!"
                fi
 
+               if isTrue "${COMPRESS_INITRD}"
+               then
+                       local pattern_auto='^(BEST|FASTEST)$'
+                       local 
pattern_manual="$(get_initramfs_compression_method_by_speed)"
+                       pattern_manual=${pattern_manual// /|}
+                       pattern_manual="^(${pattern_manual})$"
+
+                       if [[ "${COMPRESS_INITRD_TYPE^^}" =~ ${pattern_auto} ]]
+                       then
+                               # Will be handled in 
set_initramfs_compression_method()
+                               :;
+                       elif [[ ! "${COMPRESS_INITRD_TYPE^^}" =~ 
${pattern_manual} ]]
+                       then
+                               gen_die "Specified --compress-initramfs-type 
'${COMPRESS_INITRD_TYPE}' is unknown"
+                       elif ! hash 
${GKICM_LOOKUP_TABLE_CMD[${COMPRESS_INITRD_TYPE^^}]/%\ */} &>/dev/null
+                       then
+                               gen_die 
"'${GKICM_LOOKUP_TABLE_CMD[${COMPRESS_INITRD_TYPE^^}]/%\ */}', the tool to 
compress initramfs based on selected --compress-initramfs-type was not found. 
Is ${GKICM_LOOKUP_TABLE_PKG[${COMPRESS_INITRD_TYPE^^}]} installed?"
+                       fi
+                       unset pattern_auto pattern_manual
+
+                       # Ensure that value matches keys in GKICM_* arrays
+                       COMPRESS_INITRD_TYPE=${COMPRESS_INITRD_TYPE^^}
+               fi
+
                SANDBOX_COMMAND=
                if isTrue "${SANDBOX}"
                then

diff --git a/gen_funcs.sh b/gen_funcs.sh
index 8c6f412..e681c1e 100755
--- a/gen_funcs.sh
+++ b/gen_funcs.sh
@@ -464,6 +464,30 @@ get_indent() {
        echo "${_indent}"
 }
 
+get_initramfs_compression_method_by_compression() {
+       local -a methods=()
+       methods+=( XZ )
+       methods+=( LZMA )
+       methods+=( GZIP )
+       methods+=( BZIP2 )
+       methods+=( LZO )
+       methods+=( LZ4 )
+
+       echo "${methods[@]}"
+}
+
+get_initramfs_compression_method_by_speed() {
+       local -a methods=()
+       methods+=( LZ4 )
+       methods+=( LZO )
+       methods+=( GZIP )
+       methods+=( BZIP2 )
+       methods+=( LZMA )
+       methods+=( XZ )
+
+       echo "${methods[@]}"
+}
+
 setup_cache_dir() {
        if [ ! -d "${GK_V_CACHEDIR}" ]
        then

diff --git a/gen_initramfs.sh b/gen_initramfs.sh
index fd9583b..617c656 100755
--- a/gen_initramfs.sh
+++ b/gen_initramfs.sh
@@ -1770,7 +1770,6 @@ append_data() {
 }
 
 create_initramfs() {
-       local compress_ext=""
        print_info 1 "initramfs: >> Initializing ..."
 
        # Create empty cpio
@@ -1894,6 +1893,8 @@ create_initramfs() {
                print_info 1 "$(get_indent 1)>> --integrated-initramfs is set; 
Setting CONFIG_INITRAMFS_* options ..."
 
                [ -f "${KCONFIG_MODIFIED_MARKER}" ] && rm 
"${KCONFIG_MODIFIED_MARKER}"
+               [ -f "${KCONFIG_REQUIRED_OPTIONS}" ] && rm 
"${KCONFIG_REQUIRED_OPTIONS}"
+
                kconfig_set_opt "${KERNEL_OUTPUTDIR}/.config" 
"CONFIG_BLK_DEV_INITRD" "y"
                kconfig_set_opt "${KERNEL_OUTPUTDIR}/.config" 
"CONFIG_INITRAMFS_SOURCE" "\"${CPIO_ARCHIVE}.cpio\""
                kconfig_set_opt "${KERNEL_OUTPUTDIR}/.config" 
"CONFIG_INITRAMFS_ROOT_UID" "0"
@@ -1911,66 +1912,10 @@ create_initramfs() {
        else
                if isTrue "${COMPRESS_INITRD}"
                then
-                       local cmd_xz=$(type -p xz)
-                       local cmd_lzma=$(type -p lzma)
-                       local cmd_bzip2=$(type -p bzip2)
-                       local cmd_gzip=$(type -p gzip)
-                       local cmd_lzop=$(type -p lzop)
-                       local cmd_lz4=$(type -p lz4)
-                       local pkg_xz='app-arch/xz-utils'
-                       local pkg_lzma='app-arch/xz-utils'
-                       local pkg_bzip2='app-arch/bzip2'
-                       local pkg_gzip='app-arch/gzip'
-                       local pkg_lzop='app-arch/lzop'
-                       local pkg_lz4='app-arch/lz4'
-                       local compression
-                       case ${COMPRESS_INITRD_TYPE} in
-                               xz|lzma|bzip2|gzip|lzop|lz4) 
compression=${COMPRESS_INITRD_TYPE} ;;
-                               lzo) compression=lzop ;;
-                               best|fastest)
-                                       local tuple
-                                       for tuple in \
-                                                       'CONFIG_RD_XZ    cmd_xz 
   xz' \
-                                                       'CONFIG_RD_LZMA  
cmd_lzma  lzma' \
-                                                       'CONFIG_RD_BZIP2 
cmd_bzip2 bzip2' \
-                                                       'CONFIG_RD_GZIP  
cmd_gzip  gzip' \
-                                                       'CONFIG_RD_LZO   
cmd_lzop  lzop' \
-                                                       'CONFIG_RD_LZ4   
cmd_lz4   lz4' \
-                                                       ; do
-                                               set -- ${tuple}
-                                               local kernel_option=${1}
-                                               local cmd_variable_name=${2}
-                                               if ${CONFGREP} -q 
"^${kernel_option}=y" "${ACTUAL_KERNEL_CONFIG}" && test -n 
"${!cmd_variable_name}" ; then
-                                                       compression=${3}
-                                                       [[ 
${COMPRESS_INITRD_TYPE} == best ]] && break
-                                               fi
-                                       done
-                                       [[ -z "${compression}" ]] && gen_die 
"None of the initramfs compression methods we tried are supported by your 
kernel (config file \"${ACTUAL_KERNEL_CONFIG}\"), strange!?"
-                                       ;;
-                               *)
-                                       gen_die "Compression 
'${COMPRESS_INITRD_TYPE}' unknown"
-                                       ;;
-                       esac
-
-                       # Check for actual availability
-                       local cmd_variable_name=cmd_${compression}
-                       local pkg_variable_name=pkg_${compression}
-                       [[ -z "${!cmd_variable_name}" ]] && gen_die 
"Compression '${compression}' is not available. Please install package 
'${!pkg_variable_name}'."
-
-                       local compress_ext compress_cmd
-                       case ${compression} in
-                               xz) compress_ext='.xz' compress_cmd="${cmd_xz} 
-e --check=none -z -f -9" ;;
-                               lzma) compress_ext='.lzma' 
compress_cmd="${cmd_lzma} -z -f -9" ;;
-                               bzip2) compress_ext='.bz2' 
compress_cmd="${cmd_bzip2} -z -f -9" ;;
-                               gzip) compress_ext='.gz' 
compress_cmd="${cmd_gzip} -f -9" ;;
-                               lzop) compress_ext='.lzo' 
compress_cmd="${cmd_lzop} -f -9" ;;
-                               lz4) compress_ext='.lz4' 
compress_cmd="${cmd_lz4} -f -9 -l -q" ;;
-                       esac
-
-                       print_info 1 "$(get_indent 1)>> Compressing cpio data 
(${compress_ext}) ..."
-                       print_info 3 "COMMAND: ${compress_cmd} ${CPIO_ARCHIVE}" 
1 0 1
-                       ${compress_cmd} "${CPIO_ARCHIVE}" || gen_die 
"Compression (${compress_cmd}) failed"
-                       mv -f "${CPIO_ARCHIVE}${compress_ext}" 
"${CPIO_ARCHIVE}" || gen_die "Rename failed"
+                       print_info 1 "$(get_indent 1)>> Compressing cpio data 
(${GKICM_LOOKUP_TABLE_EXT[${COMPRESS_INITRD_TYPE}]}) ..."
+                       print_info 3 "COMMAND: 
${GKICM_LOOKUP_TABLE_CMD[${COMPRESS_INITRD_TYPE}]} ${CPIO_ARCHIVE}" 1 0 1
+                       ${GKICM_LOOKUP_TABLE_CMD[${COMPRESS_INITRD_TYPE}]} 
"${CPIO_ARCHIVE}" || gen_die "Initramfs compression using 
'${GKICM_LOOKUP_TABLE_CMD[${COMPRESS_INITRD_TYPE}]}' failed"
+                       mv -f 
"${CPIO_ARCHIVE}${GKICM_LOOKUP_TABLE_EXT[${COMPRESS_INITRD_TYPE}]}" 
"${CPIO_ARCHIVE}" || gen_die "Rename failed"
                else
                        print_info 3 "$(get_indent 1)>> --no-compress-initramfs 
is set; Skipping compression of initramfs ..."
                fi

diff --git a/genkernel b/genkernel
index 0856e25..c0fd96d 100755
--- a/genkernel
+++ b/genkernel
@@ -69,6 +69,7 @@ source "${_GENKERNEL_CONF}" || small_die "Could not read 
${_GENKERNEL_CONF}"
 LOGLEVEL=${LOGLEVEL:-1}
 
 # Start sourcing other scripts
+source "${GK_SHARE}"/defaults/compression_methods.sh || small_die "Could not 
read '${GK_SHARE}/defaults/compression_methods.sh'"
 source "${GK_SHARE}"/defaults/software.sh || small_die "Could not read 
'${GK_SHARE}/defaults/software.sh'"
 source "${GK_SHARE}"/defaults/config.sh || small_die "Could not read 
'${GK_SHARE}/defaults/config.sh'"
 source "${GK_SHARE}"/gen_funcs.sh || small_die "Could not read 
'${GK_SHARE}/gen_funcs.sh'"

Reply via email to