kexec-tools/mkdumprd2

359 lines
8.0 KiB
Bash
Executable File

#!/bin/sh
##########################################################
#File: mkdumprd2
#Author: Neil Horman <nhorman@redhat.com>
#Copyright 2009 Red Hat, Inc.
#Summary: A vastly simplified infrastructure for creating
# initramfs files for use with kdump
#########################################################
. /etc/kdump-adv-conf/mkdumprd2_functions
########################################################
#Global Variables
########################################################
#BASE_DIR is the parent of both TEMP_DIR and STAGE_DIR
BASE_DIR=""
#TEMP_DIR is the directory where any temp files that we
# create during the build process go, that we
# do not want to wind up in our initramfs
TEMP_DIR=""
#STAGE_DIR is the directory we create to do all our
# initramfs creation in
STAGE_DIR=""
#IMG_FILE is the file that is our initramfs after cpio
IMG_FILE=""
########################################################
#Cleanup functions so that we can get out easily and
#sanely when something goes wrong
########################################################
finish_and_exit()
{
local EXIT_CODE=$1
local EXIT_MSG=$2
if [ -n "$EXIT_MSG" ]
then
echo $EXIT_MSG
fi
exit $EXIT_CODE
}
#########################################################
#Clean up our various temporary files
#And exit
########################################################
cleanup_and_exit()
{
EXIT_CODE=$1
if [ -d $BASE_DIR ]
then
rm -rf $BASE_DIR
fi
if [ -f $IMG_FILE ]
then
rm -f $IMG_FILE
fi
finish_and_exit $EXIT_CODE $2
}
#########################################################
# Setup appropriate environment things
#########################################################
setup_env()
{
PATH=/etc/kdump-adv-conf/kdump_build_helpers:$PATH
}
#########################################################
# Handle sigint so we clean up well
#########################################################
handle_sigint()
{
cleanup_and_exit 2 "Caught Sigint"
}
#########################################################
#Trap sigint so we can clean up
#########################################################
setup_traps()
{
trap handle_sigint 2
}
#########################################################
#This creates the directory hierarchy that use to
#start creating a new initramfs
#########################################################
create_new_initramfs_dir()
{
local TMPDIR=`mktemp -d`
if [ ! -d $TMPDIR ]
then
return 1
fi
mkdir $TMPDIR/stage
mkdir $TMPDIR/temp
BASE_DIR=$TMPDIR
STAGE_DIR=$TMPDIR/stage
TEMP_DIR=$TMPDIR/temp
return 0
}
#########################################################
#Helper functions for stage_initramfs
#########################################################
create_initramfs_dirs()
{
mkdir -p $STAGE_DIR/lib || return 1
mkdir -p $STAGE_DIR/lib64 || return 1
mkdir -p $STAGE_DIR/bin || return 1
mkdir -p $STAGE_DIR/etc || return 1
mkdir -p $STAGE_DIR/dev || return 1
mkdir -p $STAGE_DIR/proc || return 1
mkdir -p $STAGE_DIR/sys || return 1
mkdir -p $STAGE_DIR/tmp || return 1
mkdir -p $STAGE_DIR/sysroot || return 1
mkdir -p $STAGE_DIR/modules || return 1
mkdir -p $STAGE_DIR/usr/share/udhcpc || return 1
mkdir -p $STAGE_DIR/var/run || return 1
mkdir -p $STAGE_DIR/etc/network/if-pre-up.d || return 1
mkdir -p $STAGE_DIR/etc/network/if-up.d || return 1
mkdir -p $STAGE_DIR/etc/network/if-pre-down.d || return 1
mkdir -p $STAGE_DIR/etc/network/if-down.d || return 1
mkdir -p $STAGE_DIR/etc/network/if-post-down.d || return 1
$(cd $STAGE_DIR; ln -s bin sbin)
}
#########################################################
#This function is the recepie for populating our initramfs
#with the basic included functions/scripts, loading the
#manifest files, copying in the init script, and doing
#site specific post processing
#########################################################
prep_std_initramfs()
{
#start by creating the directories we need
create_initramfs_dirs
}
##########################################################
#This function validates each line in the manifest file to
#ensure that we sanitize the input
#Args are:
#1 - file type
#2 - File source
#3 - destination path
#4 - optional arguments
##########################################################
validate_manifest_line()
{
case "$1" in
creg|cren)
# Just like reg/ren, but check nothing
# we don't copy anything if its not there
;;
reg|ren)
# Regular file, make sure that the file exists
if [ ! -f $2 ]
then
return 1
fi
;;
gen)
# Generated file, make sure that the script
# exists and is executable
TEST_BIN=$(which $2)
if [ ! -x $TEST_BIN ]
then
return 1
fi
;;
exec)
# exec files have no output, they simply
# provide a means by which to manipulate the
# the initramfs. Just make sure the file exists
TEST_BIN=$(which $2)
if [ ! -x $TEST_BIN ]
then
return 1
fi
;;
*)
echo $1 | grep -q "^#.*$"
if [ $? -eq 0 ]
then
# its a comment
continue
fi
echo $1 | grep -q "^ *$"
if [ $? -eq 0 ]
then
# Blank line
continue
fi
# Unknown manifest type, fail
return 1
;;
esac
return 0
}
##########################################################
#This function reads in our manifest file and moves all
#the specified contents to their respective destinations
#the manifest file has the following format
#
#{type} {source arg} {dest path}
#
#see the kexec-adv-manifest man page for details
##########################################################
populate_from_manifest()
{
local type
local sarg
local dpath
local opts
local ddir
while read type sarg dpath opts
do
validate_manifest_line $type $sarg $dpath $opts
if [ $? != 0 ]
then
cleanup_and_exit 1 "$sarg: Invalid line in manifest"
fi
case "$type" in
creg|cren)
# Conditional regular copy/rename
if [ -f $sarg ]
then
if [ "$type" == "creg" ]
then
ddir=$STAGE_DIR/$dpath
else
ddir=$(dirname $STAGE_DIR/$dpath)
fi
mkdir -p $ddir
cp $sarg $STAGE_DIR/$dpath
fi
;;
reg|ren)
# Just do a raw copy from the source path
# to the dest path
if [ "$type" == "reg" ]
then
ddir=$STAGE_DIR/$dpath
else
ddir=$(dirname $STAGE_DIR/$dpath)
fi
mkdir -p $ddir
cp $sarg $STAGE_DIR/$dpath
;;
gen)
# Generated file: run the sarg with the provided opts
# Assume that the binary will output the generated file
# to stdout
ddir=$(dirname $STAGE_DIR/$dpath)
mkdir -p $ddir
/bin/sh -c "$sarg $opts > $STAGE_DIR/$dpath"
if [ $? != 0 ]
then
cleanup_and_exit 1 "$sarg: Non-zero exit"
fi
;;
exec)
# Just run $sarg as program, passing $BASE_DIR as the
# first argument, and $opts next. This lets us
# manipulate the intiramfs without having to add
# anything to the file
$sarg $BASE_DIR $opts
if [ $? != 0 ]
then
cleanup_and_exit 1 "$sarg: Non-zero exit"
fi
esac
done < /etc/kdump-adv-conf/manifest
}
##########################################################
# This function takes our stage directory, and makes an
# image file out of it
##########################################################
create_initramfs_image()
{
IMG_FILE=$(mktemp $TEMP_DIR/initrd.img.XXXXXX)
(cd $STAGE_DIR; find . | cpio --quiet -c -o) > $IMG_FILE
if [ $? != 0 ]
then
cleanup_and_exit 1 " Could not create initramfs"
fi
# argument 1 is passed in and is the full path to the
# output initramfs name
gzip -9 -c $IMG_FILE > $1
}
##########################################################
#Start the actual code here
##########################################################
# Get our passed in options
INITRAMFS_NAME=$1
#validate the options
if [ -z "INITRAMFS_NAME" ]
then
cleanup_and_exit 1 "Need an initramfs name"
fi
export INITRAMFS_NAME
export KERNEL_NAME
#setup working env
setup_env
setup_traps
# Create a new staging area
create_new_initramfs_dir
if [ $? != 0 ]
then
cleanup_and_exit 1 "Unable to stage a new initramfs area"
fi
# Do staging
prep_std_initramfs
# Pull in the user supplied manifest
populate_from_manifest
# Do image file creation
create_initramfs_image $INITRAMFS_NAME
# Cleanup
cleanup_and_exit 0 ""