diff options
Diffstat (limited to 'src/grp-boot/kernel-install')
-rw-r--r-- | src/grp-boot/kernel-install/50-depmod.install | 8 | ||||
-rw-r--r-- | src/grp-boot/kernel-install/90-loaderentry.install | 89 | ||||
-rw-r--r-- | src/grp-boot/kernel-install/Makefile | 33 | ||||
-rw-r--r-- | src/grp-boot/kernel-install/kernel-install | 159 | ||||
-rw-r--r-- | src/grp-boot/kernel-install/kernel-install.completion.bash | 50 | ||||
-rw-r--r-- | src/grp-boot/kernel-install/kernel-install.completion.zsh | 26 | ||||
-rw-r--r-- | src/grp-boot/kernel-install/kernel-install.xml | 195 |
7 files changed, 560 insertions, 0 deletions
diff --git a/src/grp-boot/kernel-install/50-depmod.install b/src/grp-boot/kernel-install/50-depmod.install new file mode 100644 index 0000000000..68c24bed7a --- /dev/null +++ b/src/grp-boot/kernel-install/50-depmod.install @@ -0,0 +1,8 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +[[ $1 == "add" ]] || exit 0 +[[ $2 ]] || exit 1 + +exec depmod -a "$2" diff --git a/src/grp-boot/kernel-install/90-loaderentry.install b/src/grp-boot/kernel-install/90-loaderentry.install new file mode 100644 index 0000000000..af9f0f9ccd --- /dev/null +++ b/src/grp-boot/kernel-install/90-loaderentry.install @@ -0,0 +1,89 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +COMMAND="$1" +KERNEL_VERSION="$2" +BOOT_DIR_ABS="$3" +KERNEL_IMAGE="$4" + +if [[ -f /etc/machine-id ]]; then + read MACHINE_ID < /etc/machine-id +fi + +if ! [[ $MACHINE_ID ]]; then + exit 1 +fi + +BOOT_DIR="/$MACHINE_ID/$KERNEL_VERSION" +BOOT_ROOT=${BOOT_DIR_ABS%$BOOT_DIR} +LOADER_ENTRY="$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION.conf" + +if [[ $COMMAND == remove ]]; then + exec rm -f "$LOADER_ENTRY" +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="GNU/Linux $KERNEL_VERSION" +fi + +declare -a BOOT_OPTIONS + +if [[ -f /etc/kernel/cmdline ]]; then + read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline +fi + +if ! [[ ${BOOT_OPTIONS[*]} ]]; then + read -r -d '' -a line < /proc/cmdline + for i in "${line[@]}"; do + [[ "${i#initrd=*}" != "$i" ]] && continue + BOOT_OPTIONS+=("$i") + done +fi + +if ! [[ ${BOOT_OPTIONS[*]} ]]; then + echo "Could not determine the kernel command line parameters." >&2 + echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2 + exit 1 +fi + +cp "$KERNEL_IMAGE" "$BOOT_DIR_ABS/linux" && + chown root:root "$BOOT_DIR_ABS/linux" && + chmod 0644 "$BOOT_DIR_ABS/linux" || { + echo "Could not copy '$KERNEL_IMAGE to '$BOOT_DIR_ABS/linux'." >&2 + exit 1 +} + +mkdir -p "${LOADER_ENTRY%/*}" || { + echo "Could not create loader entry directory '${LOADER_ENTRY%/*}'." >&2 + exit 1 +} + +{ + echo "title $PRETTY_NAME" + echo "version $KERNEL_VERSION" + echo "machine-id $MACHINE_ID" + echo "options ${BOOT_OPTIONS[*]}" + echo "linux $BOOT_DIR/linux" + [[ -f $BOOT_DIR_ABS/initrd ]] && \ + echo "initrd $BOOT_DIR/initrd" + : +} > "$LOADER_ENTRY" || { + echo "Could not create loader entry '$LOADER_ENTRY'." >&2 + exit 1 +} +exit 0 diff --git a/src/grp-boot/kernel-install/Makefile b/src/grp-boot/kernel-install/Makefile new file mode 100644 index 0000000000..6a937f516c --- /dev/null +++ b/src/grp-boot/kernel-install/Makefile @@ -0,0 +1,33 @@ +# -*- Mode: makefile; indent-tabs-mode: t -*- +# +# This file is part of systemd. +# +# Copyright 2010-2012 Lennart Poettering +# Copyright 2010-2012 Kay Sievers +# Copyright 2013 Zbigniew Jędrzejewski-Szmek +# Copyright 2013 David Strauss +# Copyright 2016 Luke Shumaker +# +# 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 +# Lesser 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/>. +include $(dir $(lastword $(MAKEFILE_LIST)))/../../../config.mk +include $(topsrcdir)/build-aux/Makefile.head.mk + +dist_bin_SCRIPTS = \ + src/kernel-install/kernel-install + +dist_kernelinstall_SCRIPTS = \ + src/kernel-install/50-depmod.install \ + src/kernel-install/90-loaderentry.install + +include $(topsrcdir)/build-aux/Makefile.tail.mk diff --git a/src/grp-boot/kernel-install/kernel-install b/src/grp-boot/kernel-install/kernel-install new file mode 100644 index 0000000000..0c0ee718ac --- /dev/null +++ b/src/grp-boot/kernel-install/kernel-install @@ -0,0 +1,159 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +# +# This file is part of systemd. +# +# Copyright 2013 Harald Hoyer +# +# 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/>. + +SKIP_REMAINING=77 + +usage() +{ + echo "Usage:" + echo " $0 add KERNEL-VERSION KERNEL-IMAGE" + echo " $0 remove KERNEL-VERSION" +} + +dropindirs_sort() +{ + local suffix=$1; shift + local -a files + local f d i + + readarray -t files < <( + for d in "$@"; do + for i in "$d/"*"$suffix"; do + if [[ -e "$i" ]]; then + echo "${i##*/}" + fi + done + done | sort -Vu + ) + + for f in "${files[@]}"; do + for d in "$@"; do + if [[ -e "$d/$f" ]]; then + echo "$d/$f" + continue 2 + fi + done + done +} + +export LC_COLLATE=C + +for i in "$@"; do + if [ "$i" == "--help" -o "$i" == "-h" ]; then + usage + exit 0 + fi +done + +if [[ "${0##*/}" == 'installkernel' ]]; then + COMMAND='add' +else + COMMAND="$1" + shift +fi + +KERNEL_VERSION="$1" +KERNEL_IMAGE="$2" + +if [[ -f /etc/machine-id ]]; then + read MACHINE_ID < /etc/machine-id +fi + +if ! [[ $MACHINE_ID ]]; then + echo "Could not determine your machine ID from /etc/machine-id." >&2 + echo "Please run 'systemd-machine-id-setup' as root. See man:machine-id(5)" >&2 + exit 1 +fi + +if [[ ! $COMMAND ]] || [[ ! $KERNEL_VERSION ]]; then + echo "Not enough arguments" >&2 + exit 1 +fi + +if [[ -d /efi/loader/entries ]] || [[ -d /efi/$MACHINE_ID ]]; then + BOOT_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION" +elif [[ -d /boot/loader/entries ]] || [[ -d /boot/$MACHINE_ID ]]; then + BOOT_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION" +elif [[ -d /boot/efi/loader/entries ]] || [[ -d /boot/efi/$MACHINE_ID ]]; then + BOOT_DIR_ABS="/boot/efi/$MACHINE_ID/$KERNEL_VERSION" +elif mountpoint -q /efi; then + BOOT_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION" +elif mountpoint -q /boot/efi; then + BOOT_DIR_ABS="/boot/efi/$MACHINE_ID/$KERNEL_VERSION" +else + BOOT_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION" +fi + +ret=0 + +readarray -t PLUGINS < <( + dropindirs_sort ".install" \ + "/etc/kernel/install.d" \ + "/usr/lib/kernel/install.d" +) + +case $COMMAND in + add) + if [[ ! "$KERNEL_IMAGE" ]]; then + echo "Command 'add' requires an argument" >&2 + exit 1 + fi + + mkdir -p "$BOOT_DIR_ABS" || { + echo "Could not create boot directory '$BOOT_DIR_ABS'." >&2 + exit 1 + } + + for f in "${PLUGINS[@]}"; do + if [[ -x $f ]]; then + "$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE" + x=$? + if [[ $x == $SKIP_REMAINING ]]; then + return 0 + fi + ((ret+=$x)) + fi + done + ;; + + remove) + for f in "${PLUGINS[@]}"; do + if [[ -x $f ]]; then + "$f" remove "$KERNEL_VERSION" "$BOOT_DIR_ABS" + x=$? + if [[ $x == $SKIP_REMAINING ]]; then + return 0 + fi + ((ret+=$x)) + fi + done + + rm -rf "$BOOT_DIR_ABS" + ((ret+=$?)) + ;; + + *) + echo "Unknown command '$COMMAND'" >&2 + exit 1 + ;; +esac + +exit $ret diff --git a/src/grp-boot/kernel-install/kernel-install.completion.bash b/src/grp-boot/kernel-install/kernel-install.completion.bash new file mode 100644 index 0000000000..7cd2494cf7 --- /dev/null +++ b/src/grp-boot/kernel-install/kernel-install.completion.bash @@ -0,0 +1,50 @@ +# kernel-install(8) completion -*- shell-script -*- +# +# This file is part of systemd. +# +# Copyright 2013 Kay Sievers +# Copyright 2013 Harald Hoyer +# +# 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/>. + +_kernel_install() { + local comps + local MACHINE_ID + local cur=${COMP_WORDS[COMP_CWORD]} + + case $COMP_CWORD in + 1) + comps="add remove" + ;; + 2) + comps=$(cd /lib/modules; echo [0-9]*) + if [[ ${COMP_WORDS[1]} == "remove" ]] && [[ -f /etc/machine-id ]]; then + read MACHINE_ID < /etc/machine-id + if [[ $MACHINE_ID ]] && ( [[ -d /boot/$MACHINE_ID ]] || [[ -L /boot/$MACHINE_ID ]] ); then + comps=$(cd "/boot/$MACHINE_ID"; echo [0-9]*) + fi + fi + ;; + 3) + [[ "$cur" ]] || cur=/boot/vmlinuz-${COMP_WORDS[2]} + comps=$(compgen -f -- "$cur") + compopt -o filenames + ;; + esac + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} + +complete -F _kernel_install kernel-install diff --git a/src/grp-boot/kernel-install/kernel-install.completion.zsh b/src/grp-boot/kernel-install/kernel-install.completion.zsh new file mode 100644 index 0000000000..4fdd3a4ae7 --- /dev/null +++ b/src/grp-boot/kernel-install/kernel-install.completion.zsh @@ -0,0 +1,26 @@ +#compdef kernel-install + +_images(){ + if [[ "$words[2]" == "remove" ]]; then + _message 'No more options' + else + _path_files -W /boot/ -P /boot/ -g "vmlinuz-*" + fi +} + +_kernels(){ + read _MACHINE_ID < /etc/machine-id + _kernel=( /lib/modules/[0-9]* ) + if [[ "$cmd" == "remove" && -n "$_MACHINE_ID" ]]; then + _kernel=( "/boot/$_MACHINE_ID"/[0-9]* ) + fi + _kernel=( ${_kernel##*/} ) + _describe "installed kernels" _kernel +} + +_arguments \ + '1::add or remove:(add remove)' \ + '2::kernel versions:_kernels' \ + '3::kernel images:_images' + +#vim: set ft=zsh sw=4 ts=4 et diff --git a/src/grp-boot/kernel-install/kernel-install.xml b/src/grp-boot/kernel-install/kernel-install.xml new file mode 100644 index 0000000000..32e6169f63 --- /dev/null +++ b/src/grp-boot/kernel-install/kernel-install.xml @@ -0,0 +1,195 @@ +<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*--> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" +"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> + +<!-- + This file is part of systemd. + + Copyright 2013 Harald Hoyer + + 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 + Lesser 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/>. +--> + +<refentry id="kernel-install"> + + <refentryinfo> + <title>kernel-install</title> + <productname>systemd</productname> + + <authorgroup> + <author> + <contrib>Developer</contrib> + <firstname>Harald</firstname> + <surname>Hoyer</surname> + <email>harald@redhat.com</email> + </author> + </authorgroup> + </refentryinfo> + + <refmeta> + <refentrytitle>kernel-install</refentrytitle> + <manvolnum>8</manvolnum> + </refmeta> + + <refnamediv> + <refname>kernel-install</refname> + <refpurpose>Add and remove kernel and initramfs images to and from /boot</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <cmdsynopsis> + <command>kernel-install</command> + <arg choice="plain">COMMAND</arg> + <arg choice="plain"><replaceable>KERNEL-VERSION</replaceable></arg> + <arg choice="opt"><replaceable>KERNEL-IMAGE</replaceable></arg> + </cmdsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + <para> + <command>kernel-install</command> is used to install and remove kernel and + initramfs images to and from <filename>/boot</filename>. + </para> + + <para><command>kernel-install</command> will execute the files + located in the directory <filename>/usr/lib/kernel/install.d/</filename> + and the local administration directory <filename>/etc/kernel/install.d/</filename>. + All files are collectively sorted and executed in lexical order, regardless of the directory in + which they live. However, files with identical filenames replace each other. + Files in <filename>/etc/kernel/install.d/</filename> take precedence over files with the same name + in <filename>/usr/lib/kernel/install.d/</filename>. This can be used to override a system-supplied + executables with a local file if needed; a symbolic link in <filename>/etc/kernel/install.d/</filename> + with the same name as an executable in <filename>/usr/lib/kernel/install.d/</filename>, + pointing to <filename>/dev/null</filename>, disables the executable entirely. Executables must have the + extension <literal>.install</literal>; other extensions are ignored.</para> + + <para>An executable should return <constant>0</constant> on success. It may also + return <constant>77</constant> to cause the whole operation to terminate + (executables later in lexical order will be skipped).</para> + </refsect1> + + <refsect1> + <title>Commands</title> + <para>The following commands are understood:</para> + <variablelist> + <varlistentry> + <term><command>add <replaceable>KERNEL-VERSION</replaceable> <replaceable>KERNEL-IMAGE</replaceable></command></term> + <listitem> + <para><command>kernel-install</command> creates the directory + <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename> + and calls every executable + <filename>/usr/lib/kernel/install.d/*.install</filename> and + <filename>/etc/kernel/install.d/*.install</filename> with + the arguments + <programlisting>add <replaceable>KERNEL-VERSION</replaceable> <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></programlisting> + </para> + + <para>The kernel-install plugin <filename>50-depmod.install</filename> runs depmod for the <replaceable>KERNEL-VERSION</replaceable>.</para> + + <para>The kernel-install plugin + <filename>90-loaderentry.install</filename> copies + <replaceable>KERNEL-IMAGE</replaceable> to + <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/linux</filename>. + It also creates a boot loader entry according to the boot + loader specification in + <filename>/boot/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>. + The title of the entry is the + <replaceable>PRETTY_NAME</replaceable> parameter specified + in <filename>/etc/os-release</filename> or + <filename>/usr/lib/os-release</filename> (if the former is + missing), or "GNU/Linux + <replaceable>KERNEL-VERSION</replaceable>", if unset. If + the file <filename>initrd</filename> is found next to the + <filename>linux</filename> file, the initrd will be added to + the configuration.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><command>remove <replaceable>KERNEL-VERSION</replaceable></command></term> + <listitem> + <para>Calls every executable <filename>/usr/lib/kernel/install.d/*.install</filename> + and <filename>/etc/kernel/install.d/*.install</filename> with the arguments + <programlisting>remove <replaceable>KERNEL-VERSION</replaceable> <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename></programlisting> + </para> + + <para><command>kernel-install</command> removes the entire directory + <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/</filename> afterwards.</para> + + <para>The kernel-install plugin <filename>90-loaderentry.install</filename> removes the file + <filename>/boot/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>.</para> + </listitem> + </varlistentry> + + </variablelist> + + </refsect1> + + <refsect1> + <title>Exit status</title> + <para>If every executable returns with 0, 0 is returned, a non-zero failure code otherwise.</para> + </refsect1> + + <refsect1> + <title>Files</title> + <variablelist> + <varlistentry> + <term> + <filename>/usr/lib/kernel/install.d/*.install</filename> + <filename>/etc/kernel/install.d/*.install</filename> + </term> + <listitem> + <para>Drop-in files which are executed by kernel-install.</para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <filename>/etc/kernel/cmdline</filename> + <filename>/proc/cmdline</filename> + </term> + <listitem> + <para>The content of the file <filename>/etc/kernel/cmdline</filename> specifies the kernel command line to use. + If that file does not exist, <filename>/proc/cmdline</filename> is used.</para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <filename>/etc/machine-id</filename> + </term> + <listitem> + <para>The content of the file specifies the machine identification <replaceable>MACHINE-ID</replaceable>.</para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <filename>/etc/os-release</filename> + <filename>/usr/lib/os-release</filename> + </term> + <listitem> + <para>The content of the file specifies the operating system title <replaceable>PRETTY_NAME</replaceable>.</para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>See Also</title> + <para> + <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>, + <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>, + <ulink url="http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink> + </para> + </refsect1> + +</refentry> |