diff --git a/kexec-bootloader b/kexec-bootloader new file mode 100644 index 0000000..937fa33 --- /dev/null +++ b/kexec-bootloader @@ -0,0 +1,183 @@ +#!/usr/bin/perl +# +# This program is free software; you can redistribute it and/or {{{ +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. }}} +# +use Bootloader::Tools; +use strict; +use Getopt::Long; + +use constant FALSE => 0; +use constant TRUE => 1; + +my $GRUBDIR = "/boot/grub"; +my $GRUBDEFAULT = "$GRUBDIR/default"; +my $debug = FALSE; + +# +# Prints the given stuff (variable number of arguments) if debugging has +# been enabled. Does nothing otherwise. +sub print_debug(@) # {{{ +{ + if ($debug) { + print STDERR @_; + print STDERR "\n"; + } +} # }}} + +# +# Returns the value stored with "grubonce". If no value has been stored +# or the /boot/grub/default file is not readable, then -1 is returned. +sub get_grubonce() # {{{ +{ + # no /boot/grub/default file + if (! -f $GRUBDEFAULT) { + print_debug("get_grubonce(): No $GRUBDEFAULT."); + return -1; + } + + # read /boot/grub/default + open(FH, $GRUBDEFAULT) or return -1; + my $value; + my $ret = sysread(FH, $value, 10); + close FH; + + # only if we have read 4 bytes it's valid + if ($ret != 10) { + print_debug("get_grubonce(): Read returned $ret instead of 4."); + return -1; + } + + + $value =~ s/\n//g; + my $once = int($value); + + # 0x4000 is the "magic once flag" + if ($once & 0x4000) { + return $once & ~0x4000; + } else { + print_debug("get_grubonce(): No magic 0x40000."); + return -1; + } +} # }}} + +# +# Parses command line options and sets global variables. +sub parse_options() # {{{ +{ + GetOptions( + "D|debug" => \$debug + ); +} # }}} + + +parse_options(); +Bootloader::Tools::InitLibrary(); +my $loader = Bootloader::Tools::GetBootloader(); +my $default = -1; + +if ($loader =~ m/GRUB/i) { + $default = get_grubonce(); + print_debug("GRUB Default: $default"); +} + +my $section = undef; +# do we have a default? +if ($default > 0) { + my @sections = Bootloader::Tools::GetSectionList(); + print_debug("Number of sections: " . $#sections); + + if ($#sections < 0 || $#sections < $default) { + print STDERR "WARNING: grubonce default number ($default) is invalid.\n"; + print STDERR " Falling back to the default GRUB section.\n"; + } else { + my $sect_name = $sections[$default]; + $section = Bootloader::Tools::GetSection($sect_name); + } +} + +# use the default section if we didn't get any default otherwise +if (!$section) { + $section = Bootloader::Tools::GetDefaultSection(); +} + +if ($debug) { + print "Type : " . $section->{"type"}."\n"; + print "Name : " . $section->{"name"}."\n"; + print "Image : " . $section->{"image"}."\n"; + print "Initrd : " . $section->{"initrd"}."\n"; + print "VGA : " . $section->{"vgamode"}."\n"; + print "Append : " . $section->{"append"}."\n"; + print "Root : " . $section->{"root"}."\n"; +} + +if ($section->{"type"} ne "image") { + print STDERR "Default boot section is no image."; + exit(1); +} + +# check if the image exists +if (! -f $section->{"image"}) { + print STDERR "Image '" . $section->{"image"} . "' does not exist.\n"; + exit(1); +} + +# check if the initrd exists +if ($section->{"initrd"} && ! -f $section->{"initrd"}) { + print STDERR "Initrd '" . $section->{"initrd"} . "' does not exist.\n"; + exit(1); +} + +# Do we have kexec? +if (system("which kexec &>/dev/null") != 0) { + print STDERR "kexec not available. Install kexec-tools.\n"; + exit(1); +} + +# build the command list +my $cmd = "kexec"; + +# append image +$cmd .= " -l '" . $section->{"image"} . "'"; + +# append initrd if available +if ($section->{"initrd"}) { + $cmd .= " --initrd='" . $section->{"initrd"} . "'"; +} + +# build append line +my $append = ""; +if ($section->{"root"}) { + $append .= "root=" . $section->{"root"}; +} +if ($section->{"vga"}) { + $append .= " vga=" . $section->{"vga"}; +} +if ($section->{"append"}) { + $append .= " " . $section->{"append"}; +} + +# and tell that kexec +$cmd .= " --append='" . $append . "'"; + +print_debug("Kexec call: " . $cmd); +if (system($cmd) != 0) { + print STDERR "kexec($cmd) failed."; + exit(1); +} + +exit(0); + +# :vim set ts=4 sw=4 et fdm=markers: :collapseFolds=1: diff --git a/kexec-bootloader.8.txt b/kexec-bootloader.8.txt new file mode 100644 index 0000000..1276169 --- /dev/null +++ b/kexec-bootloader.8.txt @@ -0,0 +1,81 @@ +//{{{ Copyright (c) 2008, SUSE LINUX Products GmbH +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// Neither the name of the Novell nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ONANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +//}}} + +kexec-bootloader(8) +=================== +:man source: SUSE +:man manual: User Manuals +Bernhard Walle + +Name +---- +kexec-bootloader - Load kexec kernel from bootloader configuration + +Synopsis +-------- +kexec-bootloader [-D] + +Description +----------- +kexec-bootloader takes the default section of bootloader configuration and +loads that kernel, initrd with _kexec -l_ and the respective command line. + +Options +------- +*-h* | *--help*:: + Shows a short usage message. + +*-D* | *--debug*:: + Prints debugging output. + +*-o* _options_ | *--options* _options_:: + Specify additional _options_ passed to *kexec*(8). + +Return Value +------------ +The program returns *0* on success and *1* on failure. + +Bugs +---- +Please report bugs and enhancement requests at https://bugzilla.novell.com[]. + +Copying +------- +Copyright (c) 2008 Bernhard Walle . Free use of this software is +granted under the terms of the GNU General Public License (GPL), version 2 or +later. + +See also +-------- +*kexec*(8) + + +// vim: set sw=4 ts=4 et tw=80 fdm=marker: :collapseFolds=1: diff --git a/kexec-tools.changes b/kexec-tools.changes index d96c9b4..2c05005 100644 --- a/kexec-tools.changes +++ b/kexec-tools.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Sat Aug 16 11:04:55 CEST 2008 - bwalle@suse.de + +- mark /etc/init.d/kexec as %config +- remove (empty) %preun + +------------------------------------------------------------------- +Fri Aug 15 09:35:48 CEST 2008 - bwalle@suse.de + +- add /etc/init.d/kexec to be able to reboot with kexec(8) + (FATE#302238) + ------------------------------------------------------------------- Sat Jul 19 16:54:57 CEST 2008 - bwalle@suse.de diff --git a/kexec-tools.spec b/kexec-tools.spec index 0fd617a..4a87761 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -2,9 +2,16 @@ # spec file for package kexec-tools (Version 2.0.0) # # Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. -# This file and all modifications and additions to the pristine -# package are under the same license as the package itself. # +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + # Please submit bugfixes or comments via http://bugs.opensuse.org/ # @@ -17,15 +24,19 @@ BuildRequires: gcc-64bit glibc-devel-64bit %endif License: GPL v2 or later Group: System/Kernel -Requires: %insserv_prereq %fillup_prereq +Requires: perl-Bootloader +PreReq: %insserv_prereq %fillup_prereq AutoReqProv: on Summary: Tools for fast kernel loading Version: 2.0.0 -Release: 1 +Release: 14 Source: %{name}-%{version}.tar.bz2 +Source1: kexec-bootloader +Source2: kexec-bootloader.8.txt +Source3: kexec.init Url: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/ BuildRoot: %{_tmppath}/%{name}-%{version}-build -BuildRequires: zlib-devel +BuildRequires: asciidoc zlib-devel %description Kexec is a user space utility for loading another kernel and asking the @@ -62,25 +73,51 @@ CFLAGS=$RPM_OPT_FLAGS BUILD_CFLAGS=$RPM_OPT_FLAGS \ --sbindir=/sbin \ --libdir=/%_lib || true make +# manpage +cp %{S:1} . +cp %{S:2} . +cp %{S:3} . +a2x -d manpage -f manpage kexec-bootloader.8.txt %install make DESTDIR=$RPM_BUILD_ROOT install mkdir -p $RPM_BUILD_ROOT%{_mandir}/man8 install -c -m 0644 kexec/kexec.8 $RPM_BUILD_ROOT%{_mandir}/man8 +install -c -m 0644 kexec-bootloader.8 $RPM_BUILD_ROOT%{_mandir}/man8 +mkdir -p $RPM_BUILD_ROOT%{_sbindir} +install -m 0755 kexec-bootloader $RPM_BUILD_ROOT%{_sbindir} +mkdir -p ${RPM_BUILD_ROOT}/etc/init.d +install -m 0755 kexec.init ${RPM_BUILD_ROOT}/etc/init.d/kexec %clean [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +%post +%{fillup_and_insserv -n kexec kexec} +# %preun +# no stop on removal because the "rckexec stop" actually loads kernel + +%postun +%insserv_cleanup + %files %defattr(-, root, root) %doc AUTHORS COPYING News TODO doc %doc %{_mandir}/man*/* /sbin/* +%{_sbindir}/kexec-bootloader +%config /etc/init.d/kexec %ifarch %ix86 x86_64 /%_lib/kexec-tools* %endif %changelog +* Sat Aug 16 2008 bwalle@suse.de +- mark /etc/init.d/kexec as %%config +- remove (empty) %%preun +* Fri Aug 15 2008 bwalle@suse.de +- add /etc/init.d/kexec to be able to reboot with kexec(8) + (FATE#302238) * Sat Jul 19 2008 bwalle@suse.de - update to kexec-tools 2.0.0 (final) o Allow BUILD_CFLAGS and TARGET_CFLAGS to be specified at diff --git a/kexec.init b/kexec.init new file mode 100644 index 0000000..21476fb --- /dev/null +++ b/kexec.init @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Copyright (c) 2008 SUSE LINUX Products GmbH +# Author: Bernhard Walle +# +### BEGIN INIT INFO +# Provides: kexec +# Required-Start: $remote_fs +# Should-Start: +# Should-Stop: +# Required-Stop: $remote_fs +# Default-Start: $null +# Default-Stop: 1 2 3 5 +# Short-Description: Enables reboot through kexec +# Description: Enables reboot through kexec +### END INIT INFO + +. /etc/rc.status + +KEXEC_BOOTLOADER=/usr/sbin/kexec-bootloader + +case "$1" in + start) + ;; + stop) + if ! [ -f /sys/kernel/kexec_loaded ] ; then + echo -n "Cannot check if kexec kernel has been loaded." + rc_failed + else + read -t 2 kexec_loaded < /sys/kernel/kexec_loaded + if [ "$kexec_loaded" -ne 0 ] ; then + echo -n "kexec kernel already loaded." + rc_status -s + else + echo -n "Loading kexec kernel for reboot ..." + $KEXEC_BOOTLOADER + rc_status -v + fi + fi + ;; + status) + echo "not implemented" + rc_status -s + ;; + restart|reload) + $0 stop + $0 start + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|reload|try-reload}" + exit 1 +esac + +rc_exit + +# vim: set ts=4 sw=4 et: :mode=shellscript: