348 lines
7.9 KiB
Bash
Executable File
348 lines
7.9 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
|
|
|
|
# Get running kernel version to name the initramfs with
|
|
target=$(uname -r)
|
|
gzip -9 -c $IMG_FILE > ./initrd-$target.img
|
|
}
|
|
|
|
|
|
##########################################################
|
|
#Start the actual code here
|
|
##########################################################
|
|
|
|
# Get our passed in options
|
|
|
|
#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
|
|
|
|
# Cleanup
|
|
cleanup_and_exit 0 ""
|