#!/bin/bash # # systemtap Startup script for SystemTap scripts # # chkconfig: - 00 99 # config: /etc/systemtap/config # config: /etc/systemtap/conf.d ### BEGIN INIT INFO # Provides: SystemTap scripts startup # Required-Start: $local_fs # Required-Stop: $local_fs # Short-Description: Start and stop systemtap scripts # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Description: The systemtap service runs a configured list of scripts at system startup. ### END INIT INFO # Source function library. if [ -f /etc/rc.d/init.d/functions ]; then # This initscript is not compatible with the systemctl redirect on # newer platforms because it omits the command-line parameters for # the standard actions (e.g. start, stop, restart, etc...). SYSTEMCTL_SKIP_REDIRECT=1 # Red Hat init functions . /etc/rc.d/init.d/functions else # Default init functions success () { echo -n "OK" } failure () { echo -n "FAILED" } fi prog=systemtap # Commands STAP=@bindir@/stap STAPRUN=@bindir@/staprun UNAME=/bin/uname LSMOD=/sbin/lsmod DRACUT=@dracutbindir@/dracut NEWKERNELPKG=/sbin/new-kernel-pkg # Not actually used directly, but needed by # stap dracut module for inclusion in initramfs STAPIO=@libexecdir@/systemtap/stapio # Path setup SCRIPT_PATH=@sysconfdir@/systemtap/script.d CONFIG_PATH=@sysconfdir@/systemtap/conf.d CACHE_PATH=@localstatedir@/cache/systemtap STAT_PATH=@localstatedir@/run/systemtap TEMP_PATH=/tmp LOG_FILE=@localstatedir@/log/systemtap.log # NB: this path is also used in 99stap/module-setup.sh DRACUT_SRC=@dracutstap@/params.conf # FAIL unless all scripts succeeded to run PASSALL=yes # Always follows script dependencies RECURSIVE=no # Automatically recompile scripts if caches are old or do not exist. AUTOCOMPILE=yes # Start these scripts by default. If omitted, all scripts are started. DEFAULT_START= # Allow cache only scripts ALLOW_CACHEONLY=no # Log boot-time staprun stderr to /var/run/systemtap/$script.log LOG_BOOT_ERR=no # Optional settings CONFIG=@sysconfdir@/systemtap/config SCRIPTS= KRELEASE=`uname -r` OPT_RECURSIVE= OPT_SCRIPTS= OPTS= OPT_ASSUMEYES= INITRAMFS= BACKUP_INITRAMFS= EXPLICIT_INITRAMFS= echo_usage () { echo $"Usage: $prog {start|stop|status|restart|compile|onboot|cleanup|condrestart|try-restart|reload|force-reload} [OPTIONS] [SCRIPTS]" echo $"Options:" echo $" -b : backup initramfs before overwriting" echo $" -c configfile : specify config file" echo $" -o path.img : specify initramfs output file" echo $" -r kernelrelease: specify kernel release version" echo $" -R : recursively dependency checking" echo $" -y : answer yes for all questions" echo $" script(s) : specify systemtap scripts" echo $"" echo $"See systemtap(8) for full documentation" } #----------------------------------------------------------------- # Helper functions #----------------------------------------------------------------- log () { # message echo `LC_ALL=en date +"%b %e %T"`": $1" >> "$LOG_FILE" } clog () { # message [-n] echo $2 "$1" log "$1" } slog () { # message logger "$1" # if syslogd is running, this message will be sent to syslog. log "$1" } logex () { # command eval log \"Exec: $@\" "$@" >> "$LOG_FILE" 2>&1 return $? } do_warning () { # message slog "Warning: $1" warning "$1" } do_failure () { # message slog "Error: $1" failure "$1" } do_success () { # message log "Pass: $1" success "$1" } # Normalize options check_bool () { # value case $1 in n|N|no|No|NO|0) return 0;; y|Y|yes|Yes|YES|1) return 1;; *) return 2;; esac } ask_yesno () { # message local yn ret=2 [ "$OPT_ASSUMEYES" ] && return 1 while [ $ret -eq 2 ]; do echo -n "$1 [y/N]: " read yn [ -z "$yn" ] && return 0 check_bool $yn ret=$? done return $ret } #------------------------------------------------------------------ # Parameter parsing and setup options #------------------------------------------------------------------ parse_args () { # arguments while [ -n "$1" ]; do case "$1" in -c) CONFIG=$2 shift 1 ;; -r) KRELEASE=$2 shift 1 ;; -R) OPT_RECURSIVE=1 ;; -y) OPT_ASSUMEYES=1 ;; -o) INITRAMFS=$2 shift 1 ;; -b) BACKUP_INITRAMFS=1 ;; --) ;; *) OPT_SCRIPTS=$OPT_SCRIPTS\ $1 ;; esac shift 1 done } CMD=$1 shift 1 OPTS=`getopt -s bash -u -o 'r:c:Ryo:b' -- $@` if [ $? -ne 0 ]; then slog "Error: Argument parse error: $@" failure $"parse error" echo_usage exit 3 fi parse_args $OPTS # Set default output file if not given as an option if [ ! "$INITRAMFS" ]; then INITRAMFS=/boot/initramfs-$KRELEASE.img else # User explicitly specified an img file to output to EXPLICIT_INITRAMFS=1 fi # Include configs . "$CONFIG" for f in "$CONFIG_PATH"/*.conf; do if [ -f "$f" ]; then . "$f" fi done check_bool $PASSALL PASSALL=$? check_bool $RECURSIVE RECURSIVE=$? if [ "$OPT_RECURSIVE" ]; then # -R option overrides RECURSIVE. RECURSIVE=1 fi check_bool $AUTOCOMPILE AUTOCOMPILE=$? CACHE_PATH="$CACHE_PATH/$KRELEASE" check_bool $ALLOW_CACHEONLY ALLOW_CACHEONLY=$? check_bool $LOG_BOOT_ERR LOG_BOOT_ERR=$? is_valid_script_name () { # Same rules as stap -m with the addition of starting # with a non-digit so that valid shell variables can be # formed from it (for the config file). if ! [[ $1 =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then log "$1 is not a valid script name (must match [a-zA-Z_][a-zA-Z0-9_]*)" return 1 fi } __get_all_scripts () { local s if [ $ALLOW_CACHEONLY -eq 1 ]; then for s in "$CACHE_PATH"/*.ko; do if [ -f "$s" ]; then script=`basename "$s" .ko` is_valid_script_name $script [ $? -eq 0 ] && echo $script fi done fi for s in "$SCRIPT_PATH"/*.stp; do if [ -f "$s" ]; then script=`basename "$s" .stp` is_valid_script_name $script [ $? -eq 0 ] && echo $script fi done } get_all_scripts() { __get_all_scripts | sort | uniq } if [ -z "$OPT_SCRIPTS" ]; then SCRIPTS=`get_all_scripts | xargs` RECURSIVE=1 else SCRIPTS="$OPT_SCRIPTS" fi # Create user-defined $STAT_PATH if it does not exist if [ ! -d "$STAT_PATH" ]; then logex mkdir -p "$STAT_PATH" if [ $? -ne 0 ]; then do_failure $"Failed to make stat directory ($STAT_PATH)" exit 1 fi fi # Create pidfiles for running boot-time scripts for srv in $( grep -rl 'running' /proc/systemtap/*/srvstat 2>/dev/null | awk -F\/ '{print $4}' ) do if [ ! -f "$STAT_PATH/$srv" ]; then echo "0" > "$STAT_PATH/$srv" fi done #------------------------------------------------------------------ # Main routine #------------------------------------------------------------------ NR_FAILS=0 might_fail () { # message exitcode if [ $PASSALL -eq 1 ]; then do_failure "$1" echo [ -z "$2" ] && exit 1 exit $2 else log "Warning: "$1 NR_FAILS=$((NR_FAILS+1)) return 0 fi } might_success () { # message if [ $NR_FAILS -ne 0 ]; then log "Warning: $NR_FAILS failure occurred." do_warning "$1" else do_success "$1" fi return 0 } get_all_runnings () { local f for f in "$STAT_PATH"/*; do if [ -f "$f" ]; then basename "$f" fi done } get_daemon_pid () { # script cat "$STAT_PATH/$1" } # Check whether a script is running. Returns: # 0: running # 4: running, but no pidfile # 3: not running # 1: not running, but pidfile remains check_running () { # script local m f f="$STAT_PATH/$1" m=`$LSMOD | grep "^$1 "` if [ -n "$m" ]; then [ -f "$f" ] && return 0 # running return 4 # another script is running else [ -f "$f" ] && return 1 # dead, but pidfile remains return 3 # dead fi } # check whether a script cache need to be updated. check_cache () { # script opts local s tmp tmp2 s=$1; shift 1 [ ! -f "$CACHE_PATH/$s.ko" -o ! -f "$CACHE_PATH/$s.opts" ] && return 1 if [ $ALLOW_CACHEONLY -ne 1 -o -f "$SCRIPT_PATH/$s.stp" ]; then [ "$SCRIPT_PATH/$s.stp" -nt "$CACHE_PATH/$s.ko" ] && return 2 fi tmp=`head -n 1 "$CACHE_PATH/$s.opts"` tmp2=`$UNAME -a` [ "$tmp" != "$tmp2" ] && return 3 tmp=`tail -n 1 "$CACHE_PATH/$s.opts"` tmp2="$*" [ "$tmp" != "$tmp2" ] && return 4 return 0 } stap_getopt () { # opts local ret # TODO: support quoted options getopt -s bash -u \ -l 'vp:,save-uprobes' \ -o 'hVvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:d:L:FS:' -- $@ ret=$? [ $ret -ne 0 ] && slog "Failed to parse parameters. ($@)" return $ret } get_compile_opts () { # opts local opts o skip opts=`stap_getopt $*` [ $? -ne 0 ] && return 1 skip=0 for o in $opts; do if [ $skip -ne 0 ]; then skip=0; continue; fi case $o in -p|-m|-r|-c|-x|-e|-s|-o|-S) skip=1 ;; -h|-V|-k|-F) ;; *) echo -n $o" " ;; esac done } # Returns 0 if something went wrong # Returns 1 if in -L mode # Returns 2 if in -D (daemon) mode get_run_opts () { # normalized_opts local opts o show mode opts=`stap_getopt $*` [ $? -ne 0 ] && return 0 mode='-L' show=0 for o in $opts; do case $o in --save-uprobes) # Use cached uprobes module, if available if [ -f "$CACHE_PATH/uprobes/uprobes.ko" ]; then echo -n "-u$CACHE_PATH/uprobes/uprobes.ko " fi ;; -c|-x|-s|-o|-S) [ $o == '-s' ] && o='-b' [ $o == '-o' ] && mode='-D' echo -n $o" " show=1 ;; *) if [ $show -ne 0 ]; then echo -n $o" " show=0 fi ;; esac done echo -n $mode [ "$mode" == "-L" ] && return 1 [ "$mode" == "-D" ] && return 2 return 0 } prepare_cache_dir () { if [ ! -d "$CACHE_PATH" ]; then logex mkdir -p "$CACHE_PATH" [ $? -ne 0 ] && return 1 fi return 0 } prepare_stat_dir () { if [ ! -d "$STAT_PATH" ]; then logex mkdir -p "$STAT_PATH" [ $? -ne 0 ] && return 1 fi return 0 } compile_script () { # script checkcache local opts f tmpdir ret eval f="$SCRIPT_PATH/$1.stp" if [ ! -f "$f" ]; then if [ $ALLOW_CACHEONLY -eq 1 ]; then clog "Warning: no script file($f). Use compiled cache." return 0 else clog "Error: no script file($f)." return 1 fi fi eval opts=\$$1_OPT opts=`get_compile_opts $opts` [ $? -ne 0 ] && return 2 if [ "$2" = "check" ]; then check_cache $1 $opts [ $? -eq 0 ] && return 0 # already compiled if [ $AUTOCOMPILE -eq 0 ]; then slog "No valid cache for $1" return 1 fi fi clog " Compiling $1 ... " -n tmpdir=`mktemp -d -p "$TEMP_PATH" cache.XXXXXXXX` if [ $? -ne 0 ]; then clog "Failed to create temporary directory." return 1 fi pushd "$tmpdir" &> /dev/null logex $STAP -E "probe procfs(\"srvstat\").read {\$value = \"running\n\"}" \ -m "$1" -p4 -r $KRELEASE --save-uprobes $opts "$f" ret=$? if [ $ret -eq 0 ]; then if [ -f "uprobes/uprobes.ko" ]; then logex touch "$CACHE_PATH/$1.uprobes" logex mkdir -p "$CACHE_PATH/uprobes" logex mv "uprobes/uprobes.ko" "$CACHE_PATH/uprobes/" ret=$? elif [ -f "$CACHE_PATH/$1.uprobes" ]; then rm "$CACHE_PATH/$1.uprobes" fi fi if [ $ret -eq 0 ]; then $UNAME -a > "$1.opts" echo $opts >> "$1.opts" logex mv "$1.ko" "$1.opts" "$CACHE_PATH/" ret=$? else slog "Failed to compile script($1)." fi popd &> /dev/null rm -rf $tmpdir [ $ret -eq 0 ] && clog "done" || clog "error" return $ret } # dependency resolver __SORTED= __follow_dependency () { # script requesters local opts r reqs s ret s=$1 shift 1 r=`echo \ $*\ | grep \ $s\ ` if [ -n "$r" ]; then might_fail $"Dependency loop detected on $s" return 1 fi r=`echo \ $__SORTED\ | grep \ $s\ ` [ -n "$r" ] && return 0 # already listed up eval reqs=\$${s}_REQ if [ -n "$reqs" ]; then for r in $reqs; do __follow_dependency $r $s $* ret=$? if [ $ret -ne 0 ]; then return $ret # if one of requires failed, we can't run this script. fi done fi echo -n "$s " return 0 } sort_dependency () { # scripts local s r=0 __SORTED= for s in $*; do __SORTED="$__SORTED "`__follow_dependency $s` [ $? -ne 0 ] && return 1 done echo $__SORTED return 0 } start_script () { # script local tmpdir s=$1 ret count=0 mode check_running $s ret=$? [ $ret -eq 0 ] && return 0 # already running if [ $ret -eq 4 ]; then clog "$s is dead, but another script is running." return 4 fi compile_script $s check ret=$? [ $ret -ne 0 ] && return $ret eval opts=\$${s}_OPT opts=`get_run_opts $opts` mode=$? [ $mode -eq 0 ] && return 2 if [ -f "$CACHE_PATH/$s.uprobes" ]; then opts="$opts -u$CACHE_PATH/uprobes/uprobes.ko" fi clog " Starting $1 ... " -n tmpdir=`mktemp -d -p "$TEMP_PATH" cache.XXXXXXXX` # bz7097 if [ $? -ne 0 ]; then clog "Failed to create temporary directory." return 1 fi pushd "$tmpdir" &> /dev/null eval log \"Exec: $STAPRUN $opts $CACHE_PATH/$s.ko\" $STAPRUN $opts "$CACHE_PATH/$s.ko" 2>> "$LOG_FILE" > ./pid ret=$? # When the staprun '-D' option (run in background as a daemon) is # used, staprun detaches from the terminal and *then* prints the new # pid. So, it is possible to check the ./pid file before it has # been written. To avoid this, wait a bit (if necessary). if [ $mode -eq 2 ]; then while [ $count -lt 10 ]; do # when the file exists and has a size > 0, quit [ -s ./pid ] && break sleep 1 count=`expr $count + 1` done fi [ x`cat ./pid` = x ] && echo 0 > ./pid if [ $ret -eq 0 ]; then logex cp -f ./pid "$STAT_PATH/$s" fi popd &> /dev/null rm -rf "$tmpdir" [ $ret -eq 0 ] && clog "done" || clog "error" return $ret } start () { local start_scripts s ret clog $"Starting $prog: " -n start_scripts=$SCRIPTS if [ -n "$DEFAULT_START" -a -z "$OPT_SCRIPTS" ]; then # Only pick the names in DEFAULT_START with valid names start_scripts= for s in $DEFAULT_START; do is_valid_script_name $s [ $? -eq 0 ] && start_scripts="$start_scripts $s" done fi if [ -z "$start_scripts" ]; then do_warning $"No scripts exist." return 0 # only a warning fi prepare_stat_dir if [ $? -ne 0 ]; then do_failure $"Failed to make stat directory ($STAT_PATH)" return 1 fi prepare_cache_dir if [ $? -ne 0 ]; then do_failure $"Failed to make cache directory ($CACHE_PATH)" return 1 fi if [ $RECURSIVE -eq 1 ]; then start_scripts=`sort_dependency $start_scripts` if [ $? -ne 0 ]; then do_failure $"Failed to sort dependency" return 6 # program is not configured fi fi for s in $start_scripts; do start_script "$s" ret=$? if [ $ret -ne 0 ]; then might_fail $"Failed to run \"$s\". ($ret)" fi done might_success $"$prog startup" return 0 } stop_script () { # script local p f count=0 f="$STAT_PATH/$1" while [ $count -lt 10 ]; do check_running "$1" ret=$? # If the module is isn't running, we're done. [ $ret -eq 3 ] && return 0 # If the module isn't loaded but the pidfile remains, remove the # old pidfile and return. if [ $ret -eq 1 ]; then rm -f $f return 0 fi # Try to either kill the stap process that is handling the # module (which will cause the module to be unloaded) or use # staprun to delete the module. (Note that staprun will only # delete systemtap modules.) p=`get_daemon_pid $1` if [ $p -ne 0 ]; then logex kill -TERM $p else logex $STAPRUN -d "$1" fi [ $? -ne 0 ] && return 1 # At this point the module should be unloaded, but the pidfile # will still be present. If so, remove the pidfile and return. # Otherwise, wait a bit for the module to unload and try again. check_running "$1" ret=$? [ $ret -eq 3 ] && return 0 if [ $ret -eq 1 ]; then rm -f $f return 0 fi sleep 1 count=`expr $count + 1` done do_failure $"Failed to stop script \"$1\" after $count attempts" return 1 } stop () { local stop_scripts s sl= clog $"Stopping $prog: " -n stop_scripts=$SCRIPTS [ -z "$OPT_SCRIPTS" ] && stop_scripts=`get_all_runnings` if [ $RECURSIVE -eq 1 ]; then stop_scripts=`sort_dependency $stop_scripts` if [ $? -ne 0 ]; then do_failure $"Failed to sort dependency" return 6 # program is not configured fi fi for s in $stop_scripts; do sl="$s $sl" done for s in $sl; do stop_script $s [ $? -ne 0 ] && might_fail $"Failed to stop \"$s\". " done might_success $"$prog stopping " return 0 } rh_status () { local status_scripts s pid ret r status_scripts=$SCRIPTS [ -z "$status_scripts" ] && status_scripts=`get_all_runnings` ret=3 if [ -z "$status_scripts" ] ; then echo "No systemtap scripts are present" return $ret fi for s in $status_scripts; do check_running $s r=$? [ $ret -ne 0 ] && ret=$r case $r in 0) pid=`get_daemon_pid $s` [ $pid -ne 0 ] && pid="($pid)" || pid= echo $"$s$pid is running..." ;; 1|3) echo $"$s is stopped" ;; 4) echo $"$s is dead, but another script is running.";; esac done return $ret } rh_status_q () { rh_status >/dev/null 2>&1 return $? } compile () { local s ss clog $"Compiling systemtap scripts: " -n prepare_cache_dir if [ $? -ne 0 ]; then do_failure $"Failed to make cache directory ($CACHE_PATH)" return 1 fi for s in $SCRIPTS; do ss="$ss "`ls "$CACHE_PATH/$s.ko" "$CACHE_PATH/$s.opts" "$CACHE_PATH/$s.uprobes" 2> /dev/null` done ss=`echo -n $ss` if [ "$ss" ]; then clog "Updating caches: $ss" ask_yesno "Do you really want to update above caches" [ $? -eq 0 ] && return 0 fi for s in $SCRIPTS; do compile_script $s nocheck [ $? -ne 0 ] && might_fail $"$s compilation failed " done might_success $"$prog compiled " return 0 } # Writes info to $DRACUT_SRC, which the stap dracut module will source. # Includes all needed info such as location of stap/staprun, which # scripts to insert, and their options. update_dracut() { # scripts local s opts if [ -f "$DRACUT_SRC" ]; then rm -f "$DRACUT_SRC" fi echo "STAPRUN=\"$STAPRUN\"" >> "$DRACUT_SRC" echo "STAPIO=\"$STAPIO\"" >> "$DRACUT_SRC" echo "CACHE_PATH=\"$CACHE_PATH\"" >> "$DRACUT_SRC" echo "STAT_PATH=\"$STAT_PATH\"" >> "$DRACUT_SRC" echo "KRELEASE=\"$KRELEASE\"" >> "$DRACUT_SRC" echo "LOG_BOOT_ERR=\"$LOG_BOOT_ERR\"" >> "$DRACUT_SRC" echo -n "ONBOOT_SCRIPTS=\"" >> "$DRACUT_SRC" for s in $*; do echo -n "$s " >> "$DRACUT_SRC" done echo "\"" >> "$DRACUT_SRC" for s in $*; do eval opts=\$${s}_OPT opts=`get_run_opts $opts` [ $? -eq 0 ] && return 1 echo -n "$s" >> "$DRACUT_SRC" echo "_OPT=\"$opts\"" >> "$DRACUT_SRC" done } backup_initramfs() { # does target file exist? if [ -f "$INITRAMFS" ]; then clog # don't overwrite an existing backup if [ ! -f "$INITRAMFS.bak" ]; then mv "$INITRAMFS" "$INITRAMFS.bak" clog " Renamed $INITRAMFS" clog " to $INITRAMFS.bak ... " -n RESTORE_INITRAMFS_ON_FAIL=1 else clog " Backup already exists: $INITRAMFS.bak ... " -n fi fi } onboot () { local s ret ss if [ ! -f "$NEWKERNELPKG" ]; then clog "Could not find $NEWKERNELPKG" -n do_failure "$NEWKERNELPKG not found" clog clog "This feature requires $NEWKERNELPKG." clog "If it is located elsewhere, modify the \$NEWKERNELPKG parameter" -n return 1 fi if [ ! -f "$DRACUT" ]; then clog "Could not find $DRACUT" -n do_failure "$DRACUT not found" clog clog "The system must be dracut-based to use this feature" clog "If it is located elsewhere, modify the \$DRACUT parameter" -n return 1 fi if [ ! -d "$(dirname $DRACUT_SRC)" ]; then clog "Could not find dracut module" -n do_failure "SystemTap dracut module $(dirname $DRACUT_SRC) not found" return 1 fi prepare_cache_dir if [ $? -ne 0 ]; then do_failure "Failed to make cache directory ($CACHE_PATH)" return 1 fi # NB: we use OPT_SCRIPTS, not SCRIPTS because we want # no scripts passed to mean building a virgin initramfs for s in $OPT_SCRIPTS; do compile_script $s check ret=$? [ $ret -ne 0 ] && might_fail "Could not compile $s ($ret)" eval opts=\$${s}_OPT opts=`get_run_opts $opts` mode=$? clog " Checking options $s ... " -n [ $mode -eq 0 ] && might_fail "Bad runtime options for script $s" [ $mode -eq 2 ] && might_fail "Unsupported option -o in script $s" if [ $ret -eq 0 ] && [ $mode -eq 1 ]; then ss="$ss$s " clog "done" fi done # User specified script(s) but they were all skipped if [ -n "$OPT_SCRIPTS" ] && [ -z "$ss" ]; then do_failure "No scripts left to operate on" return 1 fi if [ ! "$ss" ]; then clog " Creating initramfs without scripts ... " -n else clog " Creating initramfs with $ss... " -n fi update_dracut $ss if [ $? -ne 0 ]; then do_failure "Call to update_dracut failed. Bad opts?" return 1 fi if [ "$BACKUP_INITRAMFS" ]; then backup_initramfs fi dir=`dirname $INITRAMFS` && TMPINITRAMFS=`mktemp --tmpdir=$dir` if [ $? -ne 0 ]; then do_failure "Failed to make temporary file in $dir" return 1 fi if [ ! "$ss" ]; then # Create the initramfs image without stap module enabled. out=$($DRACUT --force $TMPINITRAMFS $KRELEASE 2>&1) else # Create the initramfs image with stap module enabled. out=$($DRACUT --add stap --force $TMPINITRAMFS $KRELEASE 2>&1) fi # dracut will report success even if some modules (e.g. stap) failed # to install some files, so we need to be a bit more involved in # checking for errors if [ $? -ne 0 ] || \ [[ "$out" == *ERROR* ]] || \ ( [ -n "$ss" ] && ! lsinitrd "$TMPINITRAMFS" | grep -q ${STAPRUN:1} ); then do_failure "The initramfs creation is unsuccessful" if [ -f /var/log/dracut.log ]; then do_failure "See /var/log/dracut.log for more info" else do_failure "See dracut log for more info" fi clog if [ -f "$TMPINITRAMFS" ]; then rm "$TMPINITRAMFS" fi # Put back the initramfs if we moved it (if we didn't move it, then # whatever initramfs they used to boot in is still there) if [ "$RESTORE_INITRAMFS_ON_FAIL" ]; then mv "$INITRAMFS.bak" "$INITRAMFS" clog " Renamed $INITRAMFS.bak" clog " to $INITRAMFS" fi return 1 fi mv "$TMPINITRAMFS" "$INITRAMFS" # The initramfs is in place. If the user explicitly specified an # output file using -o, then we should skip updating the bootloader # (the output file may not even be in /boot/). if [ "$EXPLICIT_INITRAMFS" ]; then might_success "initramfs created" clog clog "NB: bootloader was not updated" -n return 0 fi clog "done" # We're installing the initramfs in the default location, so user # expects the next boot to use it. Let's also update the bootloader. clog " Updating bootloader ... " -n logex $NEWKERNELPKG --initrdfile="$INITRAMFS" \ --update $KRELEASE if [ $? -ne 0 ]; then do_failure "$NEWKERNELPKG exited with nonzero status" return 1 fi might_success "initramfs created and bootloader updated" return 0 } # Cleanup caches cleanup () { local s ss ret clog $"Cleaning up systemtap scripts: " -n if [ ! -d "$CACHE_PATH" ]; then do_success "no cache" return 0 fi for s in $SCRIPTS; do ss="$ss "`ls "$CACHE_PATH/$s.ko" "$CACHE_PATH/$s.opts" "$CACHE_PATH/$s.uprobes" 2> /dev/null` done ss=`echo -n $ss` if [ "$ss" ]; then echo "Removing caches: $ss" ask_yesno "Do you really want to remove above caches" [ $? -eq 0 ] && return 0 for s in $SCRIPTS; do logex rm -f "$CACHE_PATH/$s.ko" "$CACHE_PATH/$s.opts" "$CACHE_PATH/$s.uprobes" [ $? -ne 0 ] && might_fail $"failed to clean cache $s.ko" done fi # If none of the remaining scripts require uprobes.ko, then delete it as well if [ -d "$CACHE_PATH/uprobes" ]; then if ! ls "$CACHE_PATH/*.uprobes" &>/dev/null; then logex rm -rf "$CACHE_PATH/uprobes" fi fi might_success "done" return 0 } # Restart scripts function restart () { stop echo # we need a newline start return $? } RETVAL=0 case $CMD in start) start RETVAL=$? ;; stop) stop RETVAL=$? ;; restart|force-reload|reload) restart RETVAL=$? ;; status) rh_status exit $? ;; compile) compile RETVAL=$? ;; onboot) onboot RETVAL=$? ;; cleanup) cleanup RETVAL=$? ;; condrestart|try-restart) rh_status_q || exit 0 restart RETVAL=$? ;; *) echo_usage RETVAL=3 ;; esac echo exit $RETVAL # vim: sw=2 ts=8