postrun revision 7985
#
# Script for starting a postponed post-installation command in
# a Live-Upgrade-safe environment
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License"). You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
echo "postrun: error: run this script as root"
exit 1
fi
LOGFILE="$MYDIR/../../var/log/postrun.log"
echo 'Usage: postrun [options]'
echo
echo 'Options:'
echo ' -u, --uniq'
echo ' If the same command is requested multiple times, the command'
echo ' is only run once. If it is safe to execute the command'
echo ' immediately, it will be delayed by 5 minutes, or as set'
echo ' using the --timeout option'
echo
echo ' -t <n>, --timeout <n>'
echo ' Delay the execution of uniq commands by <n> minutes.'
echo
echo ' -b, --bg'
echo ' Run the command in the background and return control'
echo ' immediately'
echo
echo ' -f <file>'
echo ' Read the commands from <file> instead of the standard'
echo ' input.'
echo
echo ' -h, -?, --help'
echo ' Display this help'
exit 1
}
done
fi
}
#LOCK_UNLOCK_FUNCTIONS_START
# lock the postrun spool or log file
# if $1 is 'log' then lock the log file, otherwise log the spool
fi
# lock file exists (contains the pid of the process that locked it
while test -f $this_lock; do
# get the pid that holds the lock
# already locked by this process
# check if the process is still running or else delete the lock
&& sleep 1 || rm -f $this_lock
done
# run false so that we enter the while loop
false
while [ $? != 0 ]; do
# write the pid to the lock file
echo "postrun: error: cannot create lock file $this_lock"
exit 1
fi
# read it back in case another process also wrote it's pid there
# in the meantime
pid=`cat $this_lock 2>/dev/null`
# the loop will restart is the file cannot be read
done
# check if this process holds the lock or else try the whole thing again
}
# release the lock
# unlock the log file if $1 == 'log', unlock the spool otherwise
fi
if ! rm -f $this_lock; then
echo "postrun: error: cannot remove lock file $this_lock"
exit 1
fi
}
#LOCK_UNLOCK_FUNCTIONS_END
# get the next job id
echo $next_seq
}
return 0
}
cd $SPOOLDIR
# check if there's already a spooled job for the same command
IFS=' '
test -f "$f" || continue
cmp -s $postrun_command_file $f && {
if [ $postrun_is_uniq = yes ]; then
uniq_job_nr=`basename $f .cmd`
break
fi
uniq_job_nr=`basename $f .cmd`
break
}
}
done
postrun_debug "matching spooled uniq job (#${uniq_job_nr}) found"
# we found a matching spooled uniq job
# all we need to do is update the uniq time and make sure it's
# flagged as a uniq job
#
# FIXME: shouldn't use sed for this, safer to simply append
# and process the duplicate entries when reading the file
#
#
# FIXME: add the user name to the contol file
#
# run the spooled jobs in postrun_uniq_timeout minutes
# FIXME: kill the previous at(1) job?
else
postrun_debug "spooling command as job #${job_seq}"
cat /dev/null > $ctrl_file
fi
}
# create a background jobs script that executes the commands
# log file and finally unlocks
# copy the postrun_lock and postrun_unlock commands from
# this script to the background job script
# save the stdout file description
if [ $postrun_bg_job = yes ]; then
else
fi
>> $cmdfile
else
if [ $postrun_bg_job = yes ]; then
else
fi
>> $cmdfile
fi
#
# FIXME: send email to $postrun_user if the command failed
#
echo "echo '<<<' Command completed with exit status \$?" \
>> $cmdfile
# restore PATH in case the command changed it
# restore stdout
# close file descriptor 3
# append the messages to the real log file
# need to lock the log file to avoid 2 postrun commands
# writing at the same time and messing up the log
if [ $postrun_bg_job = yes ]; then
$cmdfile &
else
fi
exitval=$?
}
# default settings
postrun_job_number='???'
}
# usage: is_leap_year yyyy
return 1
}
# get_abstime yy mm dd hh mm ss
#
# prints the elapsed time in seconds since 1970.01.01.00.00.00
#Length of the months:
# JA FE MA AP MY JN JL AU SE OC NO DE
# the absolute time since 1970...
t=0
# number of years
t=$(($t + ($1 - 1970) * 31536000))
# add 1 day for each leap year
y=1972
end_y=$1
if [ $2 -lt 2 ]; then
fi
y=$(($y + 4))
done
# number of months
m=1
while [ $m -lt $2 ]; do
m=$(($m + 1))
done
# number of days, hours, minutes and seconds:
echo $(($t + ($3 - 1) * 86400 + $4 * 3600 + $5 * 60 + $6))
}
# get_timediff: prints the difference in seconds between 2 time strings
# the time strings should be of the following format:
# YYYY.MM.DD.HH.MM.SS as printed by date +%Y.%m.%d.%H.%M.%S
#
# Works for dates after 1970.01.01.00.00.00
#
# calculate seconds since 1970.01.01.00.00.00
# print difference
}
cd $SPOOLDIR
IFS=' '
pkginst: )
;;
submit_time: )
;;
uniq_command: )
;;
uniq_time: )
;;
uniq_timeout: )
;;
background: )
;;
user: )
;;
* )
;;
esac
done < $job
if [ $postrun_ignore_timeout = no ]; then
# if it's a uniq job, check if it timed out
# calculate time difference (seconds)
if [ $tdiff -ge $timeout_sec ]; then
fi
else
fi
else
# ignore timeout, just run the job
fi
done
exit 0
}
exitval=0
if [ $# = 1 -a "x$1" = 'x-qf' ]; then
# postrun-runq mode (ignore timeout for uniq jobs, since this is
# expected to be run at system boot)
exit 1
fi
if [ $# = 1 -a "x$1" = 'x-q' ]; then
# postrun-runq mode, to be run from at(1)
exit 1
fi
# process the command line
while [ $# -gt 0 ]; do
case "$1" in
-h|-\?|--help)
;;
-u|--uniq)
;;
-b|--bg)
;;
-t|--timeout)
opt="$1"
if [ $# == 0 ]; then
echo "postrun: error: argument expected after $opt"
exit 1
fi
shift
timeout=$1
exit 1
fi
;;
-f)
opt="$1"
if [ $# == 0 ]; then
echo "postrun: error: argument expected after $opt"
exit 1
fi
shift
postrun_command_file="$1"
;;
-a)
;;
--)
break
;;
*)
echo "postrun: error: invalid argument: $1"
exit 1
;;
esac
shift
done
if [ "x$postrun_command_file" = x ]; then
# save the standard input in a temporary file
fi
if [ "$LUBIN" != "" ]; then
#
# Live Upgrade. Unsafe to run the command now.
# Put into spool and defer to next boot.
#
postrun_spool_command "${@}"
"x$postrun_alt_root_okay" != xyes ]; then
#
# Installation to an alternate root directory
# Put command into spool and defer to next boot.
#
postrun_spool_command "${@}"
else
#
# Local package install. Everything's shiny happy,
# safe to run the command right now
#
if [ $postrun_is_uniq = yes ]; then
# don't run the command yet in case the same command is requested
# within the next postrun_uniq_timeout minutes
postrun_spool_command "${@}"
# run the spooled jobs in postrun_uniq_timeout minutes
echo "$MYDIR/postrun -q" | \
else
postrun_debug "Executing commands immediately"
postrun_run_command "${@}"
# do not delete the tmp_cmd_file because it's the only copy of the
# commands (since the job is not spooled)
tmp_cmd_file=''
fi
fi
if [ "x$tmp_cmd_file" != x ]; then
rm -f $tmp_cmd_file
fi
exit $exitval