diff options
author | Harald Hoyer <harald@redhat.com> | 2013-02-22 17:18:47 +0100 |
---|---|---|
committer | Harald Hoyer <harald@redhat.com> | 2013-02-25 18:58:06 +0100 |
commit | 81516adcb71a47837544340f72eb8ee810274119 (patch) | |
tree | 17f7ff511b485629caab5c717a8fe0859284f927 | |
parent | 1ddf879acf388a4625150c3a97b76458f6d2a070 (diff) |
kernel-install: add kernel-install tool
-rw-r--r-- | Makefile-man.am | 1 | ||||
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | man/kernel-install.xml | 138 | ||||
-rw-r--r-- | src/kernel-install/kernel-install | 152 |
4 files changed, 294 insertions, 0 deletions
diff --git a/Makefile-man.am b/Makefile-man.am index e4eb26ce6e..526c05d521 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -9,6 +9,7 @@ MANPAGES += \ man/journalctl.1 \ man/journald.conf.5 \ man/kernel-command-line.7 \ + man/kernel-install.8 \ man/locale.conf.5 \ man/localtime.5 \ man/machine-id.5 \ diff --git a/Makefile.am b/Makefile.am index f0f0ebcbb0..74534cce82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -278,6 +278,9 @@ bin_PROGRAMS = \ systemd-delta \ systemd-analyze +bin_SCRIPTS = \ + src/kernel-install/kernel-install + rootlibexec_PROGRAMS = \ systemd \ systemd-cgroups-agent \ diff --git a/man/kernel-install.xml b/man/kernel-install.xml new file mode 100644 index 0000000000..06939fa090 --- /dev/null +++ b/man/kernel-install.xml @@ -0,0 +1,138 @@ +<?xml version='1.0'?> <!--*-nxml-*--> +<!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="req">COMMAND</arg> <arg choice="req">KERNEL VERSION</arg> <arg choice="req">KERNEL IMAGE</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>kernel-install 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 directories in + which they live. However, files with identical file names 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 /dev/null, disables the executable entirely. Executables must have the + extension .install; other extensions are ignored.</para> + + </refsect1> + + <refsect1> + <title>Commands</title> + <para>The following commands are understood:</para> + <variablelist> + <varlistentry> + <term>add <KERNEL VERSION> <KERNEL IMAGE></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 + "add <KERNEL VERSION> <filename>/boot/<MACHINE-ID>/<KERNEL VERSION>/</filename>"</para> + + <para>kernel-install copies <KERNEL IMAGE> to + <filename>/boot/<MACHINE-ID>/<KERNEL VERSION>/linux</filename>.</para> + + <para>kernel-install also creates a boot loader entry according to the boot loader specification + in <filename>/boot/loader/entries/<OS-ID>-<KERNEL VERSION>-<MACHINE-ID>.conf</filename>. + 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>remove <KERNEL VERSION> <KERNEL IMAGE></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: + "remove <KERNEL VERSION> <filename>/boot/<MACHINE-ID>/<KERNEL VERSION>/</filename>" + </para> + <para>kernel-install removes the entire directory <filename>/boot/<MACHINE-ID>/<KERNEL VERSION>/</filename> + and the file <filename>/boot/loader/entries/<OS-ID>-<KERNEL VERSION>-<MACHINE-ID>.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> + </variablelist> + </refsect1> + + <refsect1> + <title>See Also</title> + <para> + <ulink url="http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink> + </para> + </refsect1> + +</refentry> diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install new file mode 100644 index 0000000000..1bbbc17556 --- /dev/null +++ b/src/kernel-install/kernel-install @@ -0,0 +1,152 @@ +#!/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/>. + +export LC_COLLATE=C + +COMMAND="$1" +KERNEL_VERSION="$2" +KERNEL_IMAGE="$3" + +[[ -f /etc/os-release ]] && . /etc/os-release +if ! [[ $ID ]]; then + echo "Can't determine the name of your distribution. Please create /etc/os-release." >&2 + echo "See http://www.freedesktop.org/software/systemd/man/os-release.html" >&2 + exit 1 +fi + +[[ -f /etc/machine-id ]] && read MACHINE_ID < /etc/machine-id +if ! [[ $MACHINE_ID ]]; then + echo "Can't determine your machine id. Please create /etc/machine-id!" >&2 + echo "See http://www.freedesktop.org/software/systemd/man/machine-id.html" >&2 + exit 1 +fi + +if [[ -f /etc/kernel/cmdline ]]; then + readarray -t BOOT_OPTIONS < /etc/kernel/cmdline +fi + +if ! [[ "${BOOT_OPTIONS[@]}" ]]; then + readarray -t BOOT_OPTIONS < /proc/cmdline +fi + +if ! [[ $BOOT_OPTIONS ]]; then + echo "Can't determine the kernel command line parameters." >&2 + echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2 + exit 1 +fi + +usage() +{ + { + echo "Usage:" + echo " $0 add <kernel-version> <kernel-image>" + echo " $0 remove <kernel-version> <kernel-image>" + } >&2 +} + +if ! ( [[ $COMMAND ]] && [[ $KERNEL_VERSION ]] && [[ $KERNEL_IMAGE ]] ); then + usage + exit 1 +fi + +BOOT_DIR="/boot/$MACHINE_ID/$KERNEL_VERSION" +ret=0 + +dropindirs_sort() +{ + suffix=$1; shift + readarray -t files< <( + for d in "$@"; do + for i in "${d}/"*${suffix}; do + [[ -e $i ]] && echo ${i##*/} + 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 +} + +readarray -t PLUGINS < <( + dropindirs_sort ".install" \ + "/etc/kernel/install.d" \ + "/usr/lib/kernel/install.d" +) + +case "$COMMAND" in + add) + mkdir -p "$BOOT_DIR" || exit 1 + + for f in "${PLUGINS[@]}"; do + [[ -x $f ]] && "$f" add "$KERNEL_VERSION" "$BOOT_DIR" + ((ret+=$?)) + done + + if ! cp --preserve "$KERNEL_IMAGE" "$BOOT_DIR"/linux; then + echo "Can't copy '$KERNEL_IMAGE to '$BOOT_DIR/linux'!" >&2 + fi + + [[ -d /boot/loader/entries ]] || mkdir -p /boot/loader/entries + + { + 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}"/initrd ]] && \ + echo "initrd $BOOT_DIR/initrd" + : + } > "/boot/loader/entries/${ID}-${KERNEL_VERSION}-${MACHINE_ID}.conf" +export LANG=C + + ((ret+=$?)) + + if ! [[ -f "/boot/loader/entries/${ID}-${KERNEL_VERSION}-${MACHINE_ID}.conf" ]]; then + echo "Could not create '/boot/loader/entries/${ID}-${KERNEL_VERSION}-${MACHINE_ID}.conf'!" >&2 + fi + + ;; + + remove) + for f in "${PLUGINS[@]}"; do + [[ -x $f ]] && "$f" remove "$KERNEL_VERSION" "$BOOT_DIR" + ((ret+=$?)) + done + + rm -fr "$BOOT_DIR" + rm -f "/boot/loader/entries/${ID}-${KERNEL_VERSION}-${MACHINE_ID}.conf" + ;; + + *) + usage + ret=1;; +esac + +((ret+=$?)) + +exit $ret |