2 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3 # ex: ts=8 sw=4 sts=4 et filetype=sh
4 # SPDX-License-Identifier: LGPL-2.1-or-later
6 # This file is part of systemd.
8 # systemd is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU Lesser General Public License as published by
10 # the Free Software Foundation; either version 2.1 of the License, or
11 # (at your option) any later version.
13 # systemd is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # General Public License for more details.
18 # You should have received a copy of the GNU Lesser General Public License
19 # along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 echo " kernel-install [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD-FILE...]"
27 echo " kernel-install [OPTIONS...] remove KERNEL-VERSION"
28 echo " kernel-install [OPTIONS...] inspect"
30 echo " -h, --help Print this help and exit"
31 echo " --version Print version string and exit"
32 echo " -v, --verbose Increase verbosity"
41 for i
in "$d/"*"$suffix"; do
42 [ -e "$i" ] && echo "${i##*/}"
44 done |
sort -Vu |
while read -r f
; do
46 if [ -e "$d/$f" ]; then
47 [ -x "$d/$f" ] && echo "$d/$f"
57 if [ "$i" = "--help" ] ||
[ "$i" = "-h" ]; then
64 if [ "$i" = "--version" ]; then
65 echo "kernel-install {{PROJECT_VERSION}} ({{GIT_VERSION}})"
70 export KERNEL_INSTALL_VERBOSE
=0
71 if [ "$1" = "--verbose" ] ||
[ "$1" = "-v" ]; then
73 KERNEL_INSTALL_VERBOSE
=1
76 if [ "${0##*/}" = "installkernel" ]; then
78 # make install doesn't pass any initrds
84 if [ "$COMMAND" = "inspect" ]; then
88 echo "Error: not enough arguments" >&2
96 # These two settings are settable in install.conf
100 if [ -r "/etc/kernel/install.conf" ]; then
101 .
/etc
/kernel
/install.conf
102 elif [ -r "/usr/lib/kernel/install.conf" ]; then
103 .
/usr
/lib
/kernel
/install.conf
106 # If /etc/machine-id is initialized we'll use it, otherwise we'll use a freshly
107 # generated one. If the user configured an explicit machine ID to use in
108 # /etc/machine-info to use for our purpose, we'll use that instead (for
110 [ -z "$MACHINE_ID" ] && [ -r /etc
/machine-info
] && .
/etc
/machine-info
&& MACHINE_ID
="$KERNEL_INSTALL_MACHINE_ID"
111 [ -z "$MACHINE_ID" ] && [ -r /etc
/machine-id
] && read -r MACHINE_ID
</etc
/machine-id
112 [ -z "$MACHINE_ID" ] && MACHINE_ID
="$(systemd-id128 new)"
114 # Now that we determined the machine ID to use, let's determine the "token" for
115 # the boot loader entry to generate. We use that for naming the directory below
116 # $BOOT where we want to place the kernel/initrd and related resources, as well
117 # for naming the .conf boot loader spec entry. Typically this is just the
118 # machine ID, but it can be anything else, too, if we are told so.
119 [ -z "$ENTRY_TOKEN" ] && [ -r /etc
/kernel
/entry-token
] && read -r ENTRY_TOKEN
</etc
/kernel
/entry-token
120 if [ -z "$ENTRY_TOKEN" ]; then
121 # If not configured explicitly, then use a few candidates: the machine ID,
122 # the IMAGE_ID= and ID= fields from /etc/os-release and finally the fixed
124 ENTRY_TOKEN_SEARCH
="$MACHINE_ID"
125 [ -r /etc
/os-release
] && .
/etc
/os-release
126 [ -n "$IMAGE_ID" ] && ENTRY_TOKEN_SEARCH
="$ENTRY_TOKEN_SEARCH $IMAGE_ID"
127 [ -n "$ID" ] && ENTRY_TOKEN_SEARCH
="$ENTRY_TOKEN_SEARCH $ID"
128 ENTRY_TOKEN_SEARCH
="$ENTRY_TOKEN_SEARCH Default"
130 ENTRY_TOKEN_SEARCH
="$ENTRY_TOKEN"
133 # NB: The $MACHINE_ID is guaranteed to be a valid machine ID, but
134 # $ENTRY_TOKEN can be any string that fits into a VFAT filename, though
135 # typically is just the machine ID.
137 [ -z "$BOOT_ROOT" ] && for suff
in $ENTRY_TOKEN_SEARCH; do
138 for pref
in "/efi" "/boot" "/boot/efi"; do
139 if [ -d "$pref/$suff" ]; then
147 [ -z "$BOOT_ROOT" ] && for pref
in "/efi" "/boot" "/boot/efi"; do
148 if [ -d "$pref/loader/entries" ]; then
154 [ -z "$BOOT_ROOT" ] && for pref
in "/efi" "/boot/efi"; do
155 if mountpoint
-q "$pref"; then
161 [ -z "$BOOT_ROOT" ] && BOOT_ROOT
="/boot"
163 [ -z "$ENTRY_TOKEN" ] && ENTRY_TOKEN
="$MACHINE_ID"
165 if [ -z "$layout" ]; then
166 # No layout configured by the administrator. Let's try to figure it out
167 # automatically from metadata already contained in $BOOT_ROOT.
168 if [ -e "$BOOT_ROOT/loader/entries.srel" ]; then
169 read -r ENTRIES_SREL
<"$BOOT_ROOT/loader/entries.srel"
170 if [ "$ENTRIES_SREL" = "type1" ]; then
171 # The loader/entries.srel file clearly indicates that the installed
172 # boot loader implements the proper standard upstream boot loader
173 # spec for Type #1 entries. Let's default to that, then.
176 # The loader/entries.srel file indicates some other spec is
177 # implemented and owns the /loader/entries/ directory. Since we
178 # have no idea what that means, let's stay away from it by default.
181 elif [ -d "$BOOT_ROOT/$ENTRY_TOKEN" ]; then
182 # If the metadata in $BOOT_ROOT doesn't tell us anything, then check if
183 # the entry token directory already exists. If so, let's assume it's
184 # the standard boot loader spec, too.
187 # There's no metadata in $BOOT_ROOT, and apparently no entry token
188 # directory installed? Then we really don't know anything.
193 ENTRY_DIR_ABS
="$BOOT_ROOT/$ENTRY_TOKEN/$KERNEL_VERSION"
195 # Provide a directory where to store generated initrds
197 [ -n "$KERNEL_INSTALL_STAGING_AREA" ] && rm -rf "$KERNEL_INSTALL_STAGING_AREA"
202 KERNEL_INSTALL_STAGING_AREA
="$(mktemp -d -t -p /tmp kernel-install.staging.XXXXXXX)"
204 export KERNEL_INSTALL_MACHINE_ID
="$MACHINE_ID"
205 export KERNEL_INSTALL_ENTRY_TOKEN
="$ENTRY_TOKEN"
206 export KERNEL_INSTALL_BOOT_ROOT
="$BOOT_ROOT"
207 export KERNEL_INSTALL_LAYOUT
="$layout"
208 export KERNEL_INSTALL_INITRD_GENERATOR
="$initrd_generator"
209 export KERNEL_INSTALL_STAGING_AREA
211 [ "$layout" = "bls" ]
212 MAKE_ENTRY_DIR_ABS
=$?
217 dropindirs_sort ".
install" \
218 "/etc
/kernel
/install.d
" \
219 "/usr
/lib
/kernel
/install.d
"
226 if [ $# -lt 1 ]; then
227 echo "Error: command 'add' requires a kernel image" >&2
231 if ! [ -f "$1" ]; then
232 echo "Error: kernel image argument $1 not a file" >&2
236 if [ "$MAKE_ENTRY_DIR_ABS" -eq 0 ]; then
237 # Compatibility with earlier versions that used the presence of $BOOT_ROOT/$ENTRY_TOKEN
238 # to signal to 00-entry-directory to create $ENTRY_DIR_ABS
239 # to serve as the indication to use or to not use the BLS
240 if [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ]; then
241 echo "+mkdir -v -p $ENTRY_DIR_ABS"
242 mkdir
-v -p "$ENTRY_DIR_ABS" ||
exit 1
244 mkdir
-p "$ENTRY_DIR_ABS" ||
exit 1
248 for f
in $PLUGINS; do
249 [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "+$f add $KERNEL_VERSION $ENTRY_DIR_ABS $*"
250 "$f" add
"$KERNEL_VERSION" "$ENTRY_DIR_ABS" "$@"
252 [ $err -eq $skip_remaining ] && break
258 for f
in $PLUGINS; do
259 [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "+$f remove $KERNEL_VERSION $ENTRY_DIR_ABS"
260 "$f" remove
"$KERNEL_VERSION" "$ENTRY_DIR_ABS"
262 [ $err -eq $skip_remaining ] && break
266 if [ "$MAKE_ENTRY_DIR_ABS" -eq 0 ]; then
267 [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Removing $ENTRY_DIR_ABS/"
268 rm -rf "$ENTRY_DIR_ABS"
273 echo "KERNEL_INSTALL_MACHINE_ID: $KERNEL_INSTALL_MACHINE_ID"
274 echo "KERNEL_INSTALL_ENTRY_TOKEN: $KERNEL_INSTALL_ENTRY_TOKEN"
275 echo "KERNEL_INSTALL_BOOT_ROOT: $KERNEL_INSTALL_BOOT_ROOT"
276 echo "KERNEL_INSTALL_LAYOUT: $KERNEL_INSTALL_LAYOUT"
277 echo "KERNEL_INSTALL_INITRD_GENERATOR: $KERNEL_INSTALL_INITRD_GENERATOR"
278 echo "ENTRY_DIR_ABS: $KERNEL_INSTALL_BOOT_ROOT/$ENTRY_TOKEN/\$KERNEL_VERSION"
280 # Assert that ENTRY_DIR_ABS actually matches what we are printing here
281 [ "${ENTRY_DIR_ABS%/*}" = "$KERNEL_INSTALL_BOOT_ROOT/$ENTRY_TOKEN" ] ||
{ echo "Assertion didn't pass." >&2; exit 1; }
285 echo "Error: unknown command '$COMMAND'" >&2