From 81516adcb71a47837544340f72eb8ee810274119 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Fri, 22 Feb 2013 17:18:47 +0100 Subject: kernel-install: add kernel-install tool --- Makefile-man.am | 1 + Makefile.am | 3 + man/kernel-install.xml | 138 ++++++++++++++++++++++++++++++++++ src/kernel-install/kernel-install | 152 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 294 insertions(+) create mode 100644 man/kernel-install.xml create mode 100644 src/kernel-install/kernel-install 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 @@ + + + + + + + + + kernel-install + systemd + + + + Developer + Harald + Hoyer + harald@redhat.com + + + + + + kernel-install + 8 + + + + kernel-install + Add and remove kernel and initramfs images to and from /boot + + + + + kernel-install COMMAND KERNEL VERSION KERNEL IMAGE + + + + + Description + + kernel-install is used to install and remove kernel and + initramfs images to and from /boot. + + + kernel-install will execute the files located in the directory /usr/lib/kernel/install.d/ + and the local administration directory /etc/kernel/install.d/. + 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 /etc/kernel/install.d/ take precedence over files with the same name + in /usr/lib/kernel/install.d/. This can be used to override a system-supplied + executables with a local file if needed; a symbolic link in /etc/kernel/install.d/ + with the same name as an executable in /usr/lib/kernel/install.d/, + pointing to /dev/null, disables the executable entirely. Executables must have the + extension .install; other extensions are ignored. + + + + + Commands + The following commands are understood: + + + add <KERNEL VERSION> <KERNEL IMAGE> + + calls every executable /usr/lib/kernel/install.d/*.install + and /etc/kernel/install.d/*.install with the arguments + "add <KERNEL VERSION> /boot/<MACHINE-ID>/<KERNEL VERSION>/" + + kernel-install copies <KERNEL IMAGE> to + /boot/<MACHINE-ID>/<KERNEL VERSION>/linux. + + kernel-install also creates a boot loader entry according to the boot loader specification + in /boot/loader/entries/<OS-ID>-<KERNEL VERSION>-<MACHINE-ID>.conf. + If the file initrd is found next to the linux file, + the initrd will be added to the configuration. + + + + remove <KERNEL VERSION> <KERNEL IMAGE> + calls every executable /usr/lib/kernel/install.d/*.install + and /etc/kernel/install.d/*.install with the arguments: + "remove <KERNEL VERSION> /boot/<MACHINE-ID>/<KERNEL VERSION>/" + + kernel-install removes the entire directory /boot/<MACHINE-ID>/<KERNEL VERSION>/ + and the file /boot/loader/entries/<OS-ID>-<KERNEL VERSION>-<MACHINE-ID>.conf + + + + + + + + + Exit status + If every executable returns with 0, 0 is returned, a non-zero failure code otherwise. + + + + Files + + + + /usr/lib/kernel/install.d/*.install + /etc/kernel/install.d/*.install + + + Drop-in files, which are executed by kernel-install. + + + + + + + See Also + + Boot loader specification + + + + 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 . + +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 " + echo " $0 remove " + } >&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 -- cgit v1.2.3-54-g00ecf