Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scripts/hooks: Sort kernel package names #19

Merged
merged 4 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions booster-um
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ main() {
# Always regenerate initramfs
# Generate UKI file for specified kernel package name
shift
_generate_kernel_uki "$1"
_generate_kernel_uki "$@"
;;
-r)
# Remove UKI file and other leftovers for specified kernel package name
shift
_remove_uki "$1"
_remove_uki "$@"
;;
-p)
# This argument is used in libalpm remove hook
Expand Down
1 change: 0 additions & 1 deletion completions/zsh/_booster-um
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ _init() {
}

_kernel_comp() {
(( CURRENT == 2 )) &&
compadd $(find /usr/lib/modules/* \
-mindepth 1 -maxdepth 1 \
! -path '*/\.*' ! -path '*/build' -type f -name 'pkgbase' \
Expand Down
2 changes: 1 addition & 1 deletion libalpm/hooks/90-booster-um-install.hook
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Operation = Upgrade
Target = usr/bin/ukify
Target = usr/bin/booster
Target = usr/lib/booster/*
Target = usr/lib/**/efi/*.efi*
Target = usr/lib/**/efi/*.stub
Target = usr/lib/modules/*/vmlinuz

[Trigger]
Expand Down
57 changes: 37 additions & 20 deletions libalpm/scripts/booster-um-install
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,71 @@

set -e

all=0
sign_all=0
declare -A unames
# Generate and sign all UKI files
declare -g SIGN_ALL=1

add_uname() {
# Generate all UKI files
declare -g ALL=1

# Associative array with the kernel package name as the key and uname as the value
declare -A kernels

# An array of sorted pkgbases
declare -a sorted_pkgbases=()

add_kernel() {
local file="$1"
local kernel_dir pkgbase modules_suffix

# Get the uname
modules_suffix="${file##usr/lib/modules/}"
uname="${modules_suffix%%/*}"
unames["$uname"]=""
kernel_dir="/usr/lib/modules/${uname}"

# If pkgbase does not belong to any package then skip this kernel
if ! pacman -Qqo -- "${kernel_dir}/pkgbase" > /dev/null 2>&1; then return; fi

# Return if there is a pkgbase key
read -r pkgbase < "${kernel_dir}/pkgbase"
[[ -v kernels[$pkgbase] ]] && return

# Assign the uname value for kernel pkgbase
kernels["$pkgbase"]="$uname"
}

while read -r line; do
case "$line" in
usr/bin/booster | usr/bin/booster-um | usr/bin/ukify)
sign_all=1
SIGN_ALL=0
break
;;
usr/lib/booster/* | usr/lib/firmware/* | usr/src/*/dkms.conf)
sign_all=1
SIGN_ALL=0
break
;;
usr/lib/modules/*/vmlinuz | usr/lib/modules/*/extramodules/*)
add_uname "$line"
add_kernel "$line"
;;
*)
all=1
ALL=0
break
;;
esac
done

# Generate and sign UKI files for all kernels
if [[ $sign_all -eq 1 ]]; then booster-um -G; exit; fi
if [[ $SIGN_ALL -eq 0 ]]; then booster-um -G; exit; fi

# Sbctl hook should sign the UKI file if it already exists in database
export ALWAYS_SIGN=1

# Generate UKI files for all kernels
if [[ $all -eq 1 ]]; then booster-um -G; exit; fi
if [[ $ALL -eq 0 ]]; then booster-um -G; exit; fi

for uname in "${!unames[@]}"; do
kernel_dir="/usr/lib/modules/${uname}"
if ! pacman -Qqo "${kernel_dir}/pkgbase" > /dev/null 2>&1; then
# if pkgbase does not belong to any package then skip this kernel
continue
fi
read -r pkgbase < "${kernel_dir}/pkgbase"
# Sort the pkgbases
readarray -t sorted_pkgbases < <(printf '%s\n' "${!kernels[@]}" | sort)

for pkgbase in "${sorted_pkgbases[@]}"; do
# Genearate UKI file for updated kernel
booster-um -u "$pkgbase" "$uname"
done
booster-um -u "$pkgbase" "${kernels[$pkgbase]}"
done
36 changes: 25 additions & 11 deletions libalpm/scripts/booster-um-remove
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,26 @@

set -e

kernels=()
# Associative array with the kernel package name as the key
declare -A kernels

# An array of sorted pkgbases
declare -a sorted_pkgbases=()

add_kernel() {
local kernel_dir="$1"
local pkgbase

# If pkgbase does not belong to any package then skip this kernel
if ! pacman -Qqo "${kernel_dir}/pkgbase" > /dev/null 2>&1; then return; fi

# Return if there is a pkgbase key
read -r pkgbase < "${kernel_dir}/pkgbase"
[[ -v kernels[$pkgbase] ]] && return

# Assign the uname value for kernel pkgbase
kernels["$pkgbase"]="$kernel_dir"
}

while read -r line; do
case "$line" in
Expand All @@ -11,18 +30,13 @@ while read -r line; do
exit
;;
usr/lib/modules/*/vmlinuz)
kernels+=("/${line%/vmlinuz}")
add_kernel "/${line%/vmlinuz}"
;;
esac
done

for kernel in "${kernels[@]}"; do
if ! pacman -Qqo -- "${kernel}/pkgbase" > /dev/null 2>&1; then
# if pkgbase does not belong to any package then skip this kernel
continue
fi
read -r pkgbase < "${kernel}/pkgbase"
# Sort the pkgbases
readarray -t sorted_pkgbases < <(printf '%s\n' "${!kernels[@]}" | sort)

# Remove the UKI file
export REMOVE_EFI=1; booster-um -r "$pkgbase"
done
# Remove UKI for specified kernels
export REMOVE_EFI=1; booster-um -r "${sorted_pkgbases[@]}"
2 changes: 1 addition & 1 deletion scripts/cmdline
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ _get_cmdline() {
cmdline="@${default_cmdline}"
fi
echo "$cmdline"
}
}
47 changes: 26 additions & 21 deletions scripts/common
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,21 @@ B='\033[1;34m' # Blue
Y='\033[1;33m' # Yellow
NC='\033[0m' # No color

# Associative array with the kernel package name as the key and uname as the value
declare -A kernels

# An array of sorted pkgbases
declare -a sorted_pkgbases=()

# Checks if specified command exists
_command_exists() {
command -v -- "$1" > /dev/null 2>&1
}

# Gets the index for the specified element in array
_get_array_index() {
local index=0
local -n array="$1"
local search="$2"
index="$(printf "%s\n" "${array[@]}" | grep -n "^${search}$" | sed "s/:${search}//")"
echo "$((index-1))"
}

# Checks if the pkgbase exists
_pkgbase_exists() {
local pkgbase="$1"
printf '%s\0' "${pkgbases[@]}" | grep -Fqxz -- "$pkgbase"
return $?
[[ -v kernels[$pkgbase] ]]
}

# Checks if the package name is actually a kernel package name
Expand All @@ -41,18 +37,27 @@ _check_pkgbase() {

# Find out all package names of installed kernels
_find_kernels() {
kernels=()
readarray -t -O "${#kernels[@]}" kernels < <(find /usr/lib/modules \
local pkgbase uname
local -a kernel_paths=()

# Find all kernel paths
# Example: /usr/lib/modules/6.6.10-arch1-1
readarray -t -O "${#kernel_paths[@]}" kernel_paths < <(find /usr/lib/modules \
-maxdepth 1 ! -path '*/\.*' -type d ! -name 'modules' \
-exec sh -c 'for path; do if pacman -Qqo -- "$path/pkgbase" > /dev/null 2>&1; then echo $path; fi; done' _ {} +)

# Generate array of valid kernel package names
readarray -t pkgbases < <(printf '%s/pkgbase\n' "${kernels[@]}" | xargs -I {} cat {} 2>/dev/null)
}
# Fill the kernels array
for kernel_path in "${kernel_paths[@]}"; do
# Save the key and values to the associative array
read -r pkgbase < "${kernel_path}/pkgbase"
uname="${kernel_path##/usr/lib/modules/}"
kernels["$pkgbase"]="$uname"
done

# Do not sort pkgbases if the kernels array is empty or has only one item
[[ ${#kernels[@]} -eq 0 ]] && return
[[ ${#kernels[@]} -eq 1 ]] && sorted_pkgbases=("${!kernels[@]}") && return

# Returns the uname for the specified kernel dir
_get_kernel_uname() {
local kernel="$1"
uname="${kernel##/usr/lib/modules/}"
echo "$uname"
# Sort the pkgbase keys
readarray -t sorted_pkgbases < <(printf '%s\n' "${!kernels[@]}" | sort)
}
4 changes: 2 additions & 2 deletions scripts/config
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ _is_bmp() {
# Sets the initramfs config for all kernels
_set_initramfs_config() {
local -a value=()
for pkgbase in "${pkgbases[@]}"; do
for pkgbase in "${sorted_pkgbases[@]}"; do
readarray value < <(yq ".initramfs_config.${pkgbase}[]" "$CONFIG");
if [[ ${#value[@]} -eq 1 && "${value[@]}" =~ "fallback" ]] && ! _should_generate_fallback; then
value=(default)
Expand Down Expand Up @@ -132,4 +132,4 @@ _get_splash_path() {

# Finally, return the splash path if the splash is a BMP file
if _is_bmp "$splash"; then echo "$splash"; fi
}
}
38 changes: 16 additions & 22 deletions scripts/generate
Original file line number Diff line number Diff line change
Expand Up @@ -97,41 +97,35 @@ _generate_uki() {

# Generates UKI file for specified kernel package name
_generate_kernel_uki() {
local pkgbase="$1"
_check_pkgbase "$pkgbase"
local -a input_pkgbases
readarray -t input_pkgbases < <(printf '%s\n' "$@" | sort -u)
for pkgbase in "${input_pkgbases[@]}"; do
_check_pkgbase "$pkgbase"

# Get the index of pkgbase
index="$(_get_array_index pkgbases $pkgbase)"
local kernel="${kernels[$index]}"
local uname="$(_get_kernel_uname $kernel)"
# Get the uname
local uname="${kernels[$pkgbase]}"

# Generate initramfs
_generate_initramfs "$pkgbase" "$uname" || return
# Generate initramfs
_generate_initramfs "$pkgbase" "$uname" || return

# Generate and sign UKI file
_generate_uki "$pkgbase" "$uname"
# Generate and sign UKI file
_generate_uki "$pkgbase" "$uname"
done
}

# Generates UKI files for all installed kernels
_generate_all_uki() {
local uname
for kernel in "${kernels[@]}"; do
read -r pkgbase < "${kernel}/pkgbase"
uname="$(_get_kernel_uname $kernel)"

for pkgbase in "${sorted_pkgbases[@]}"; do
# Generate and sign UKI file
_generate_uki "$pkgbase" "$uname"
_generate_uki "$pkgbase" "${kernels[$pkgbase]}"
done
}

# Generates initramfs and fallback initramfs
_regenerate_images() {
local pids=()
local pkgbase
for kernel in "${kernels[@]}"; do
read -r pkgbase < "${kernel}/pkgbase"
uname="$(_get_kernel_uname $kernel)"
_generate_initramfs "$pkgbase" "$uname" & pids+=( $! )
for pkgbase in "${sorted_pkgbases[@]}"; do
_generate_initramfs "$pkgbase" "${kernels[$pkgbase]}" & pids+=( $! )
done

# Wait for all background jobs
Expand Down Expand Up @@ -215,4 +209,4 @@ _regenerate_all() {
_regenerate_images || :
echo -e "${B}::${W} Generating UKI files for all installed kernels...${NC}"
_generate_all_uki
}
}
Loading