summaryrefslogtreecommitdiff
path: root/src/kernel-install/90-loaderentry.install
blob: 75218d0deea87010eaaf1cf7809efec6a1e06e4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# systemd is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <http://www.gnu.org/licenses/>.

COMMAND="$1"
KERNEL_VERSION="$2"
ENTRY_DIR_ABS="$3"
KERNEL_IMAGE="$4"
INITRD_OPTIONS_START="5"

if ! [[ $KERNEL_INSTALL_MACHINE_ID ]]; then
    exit 0
fi

if ! [[ -d "$ENTRY_DIR_ABS" ]]; then
    exit 0
fi

MACHINE_ID=$KERNEL_INSTALL_MACHINE_ID

BOOT_ROOT=${ENTRY_DIR_ABS%/$MACHINE_ID/$KERNEL_VERSION}
BOOT_MNT=$(stat -c %m $BOOT_ROOT)
if [[ $BOOT_MNT == '/' ]]; then
    ENTRY_DIR=$ENTRY_DIR_ABS
else
    ENTRY_DIR=${ENTRY_DIR_ABS#$BOOT_MNT}
fi

if [[ $COMMAND == remove ]]; then
    rm -f "$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION.conf"
    rm -f "$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION+"*".conf"
    exit 0
fi

if ! [[ $COMMAND == add ]]; then
    exit 1
fi

if ! [[ $KERNEL_IMAGE ]]; then
    exit 1
fi

if [[ -f /etc/os-release ]]; then
    . /etc/os-release
elif [[ -f /usr/lib/os-release ]]; then
    . /usr/lib/os-release
fi

if ! [[ $PRETTY_NAME ]]; then
    PRETTY_NAME="Linux $KERNEL_VERSION"
fi

if [[ -f /etc/kernel/cmdline ]]; then
    read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline
elif [[ -f /usr/lib/kernel/cmdline ]]; then
    read -r -d '' -a BOOT_OPTIONS < /usr/lib/kernel/cmdline
else
    declare -a BOOT_OPTIONS

    read -r -d '' -a line < /proc/cmdline
    for i in "${line[@]}"; do
        [[ "${i#initrd=*}" != "$i" ]] && continue
        [[ "${i#BOOT_IMAGE=*}" != "$i" ]] && continue
        BOOT_OPTIONS+=("$i")
    done
fi

if [[ -f /etc/kernel/tries ]]; then
    read -r TRIES </etc/kernel/tries
    if ! [[ "$TRIES" =~ ^[0-9]+$ ]] ; then
        echo "/etc/kernel/tries does not contain an integer." >&2
        exit 1
    fi
    LOADER_ENTRY="$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION+$TRIES.conf"
else
    LOADER_ENTRY="$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION.conf"
fi

cp "$KERNEL_IMAGE" "$ENTRY_DIR_ABS/linux" &&
    chown root:root "$ENTRY_DIR_ABS/linux" &&
    chmod 0644 "$ENTRY_DIR_ABS/linux" || {
        echo "Could not copy '$KERNEL_IMAGE to '$ENTRY_DIR_ABS/linux'." >&2
        exit 1
    }

INITRD_OPTIONS=( "${@:${INITRD_OPTIONS_START}}" )

for initrd in "${INITRD_OPTIONS[@]}"; do
    if [[ -f "${initrd}" ]]; then
        initrd_basename="$(basename ${initrd})"
        [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
            echo "Installing $ENTRY_DIR_ABS/${initrd_basename}"
        cp "${initrd}" "$ENTRY_DIR_ABS/${initrd_basename}" &&
            chown root:root "$ENTRY_DIR_ABS/${initrd_basename}" &&
            chmod 0644 "$ENTRY_DIR_ABS/${initrd_basename}" || {
                echo "Could not copy '${initrd}' to '$ENTRY_DIR_ABS/${initrd_basename}'." >&2
                exit 1
            }
    fi
done

# If no initrd option is supplied, fall back to "initrd" which is
# the name used by dracut when generating it in its kernel-install hook
[[ ${#INITRD_OPTIONS[@]} == 0 ]] && INITRD_OPTIONS=( initrd )

mkdir -p "${LOADER_ENTRY%/*}" || {
    echo "Could not create loader entry directory '${LOADER_ENTRY%/*}'." >&2
    exit 1
}

[ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
    echo "Creating $LOADER_ENTRY"
{
    echo "title      $PRETTY_NAME"
    echo "version    $KERNEL_VERSION"
    echo "machine-id $MACHINE_ID"
    echo "options    ${BOOT_OPTIONS[*]}"
    echo "linux      $ENTRY_DIR/linux"
    for initrd in "${INITRD_OPTIONS[@]}"; do
        [[ -f $ENTRY_DIR_ABS/$(basename ${initrd}) ]] && \
            echo "initrd     $ENTRY_DIR/$(basename ${initrd})"
    done
    :
} > "$LOADER_ENTRY" || {
    echo "Could not create loader entry '$LOADER_ENTRY'." >&2
    exit 1
}
exit 0