postrun revision 12025
18008N/A# Script for starting a postponed post-installation command in 18008N/A# a Live-Upgrade-safe environment 18008N/A# The contents of this file are subject to the terms of the 18008N/A# Common Development and Distribution License, Version 1.0 only 18008N/A# (the "License"). You may not use this file except in compliance 18008N/A# See the License for the specific language governing permissions 18008N/A# and limitations under the License. 18008N/A# When distributing Covered Code, include this CDDL HEADER in each 18008N/A# If applicable, add the following below this CDDL HEADER, with the 18008N/A# fields enclosed by brackets "[]" replaced with your own identifying 18008N/A# information: Portions Copyright [yyyy] [name of copyright owner] 18008N/A# Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. myuid=
`id | sed -e 's/.* euid=\([0-9][0-9]*\).*$/\1/'` || \
echo "postrun: error: run this script as root" echo 'Usage: postrun [options]' 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 ' -t <n>, --timeout <n>' echo ' Delay the execution of uniq commands by <n> minutes.' echo ' Run the command in the background and return control' echo ' Read the commands from <file> instead of the standard' echo ' Assign this job to class <class>. Useful for querying' echo ' jobs with postrun-query' echo ' Ignore this job if it cannot be executed immediately.' echo ' Display this help' # Solaris 9 doesn't have mktemp, need a substitute in order to be # Note: only creating tmp files is implemented, directories are not #LOCK_UNLOCK_FUNCTIONS_START echo '<POSTRUN_DEBUG>' "[$$]" "$msg" 1>&2 echo "$1" | egrep -vs '^[0-9]+$' && return 1 echo "$1" | egrep -s '^[0-9]+$' || return 1 # lock the postrun spool or log file # if $1 is 'log' then lock the log file, otherwise log the spool if [ "x$1" = xlog ]; then # Read who has the lock. If this process has the lock return | nawk -F' -> ' '$1 ~ /^l/ && NF == 2 { print $NF }') if [ "$pid" = $$ ] ; then # check to be sure the process that holds the lock is still running # if so, wait for it to be freed. If the lock is stale, remove it # so that the next iteration of the loop can take the lock. postrun_debug "postrun_lock escaped the loop - should not b here" # unlock the log file if $1 == 'log', unlock the spool otherwise if [ "x$1" = xlog ]; then | nawk -F' -> ' '$1 ~ /^l/ && NF == 2 { print $NF }') echo "postrun: error: cannot remove lock file $this_lock" 1>&2 #LOCK_UNLOCK_FUNCTIONS_END postrun_debug "Ignoring job, because -i was used and it's not possible to run it now" # check if there's already a spooled job for the same command postrun_debug "matching spooled uniq job (#${uniq_job_nr}) found" # we found a matching spooled uniq job # we need to update the uniq time and make sure it's # FIXME: shouldn't use sed for this, safer to simply append # and process the duplicate entries when reading the file sed -e 's/^uniq_command: .*/uniq_command: yes/' \ -e 's/^\(pkginst: .*\)/\1, '$PKGINST'/' \ -e 's/^uniq_time: /resubmit_time: /' \ # FIXME: add the user name to the control file # Use a new job id so that the job moves to the end of the queue. # Need to do this such a whay that if this process is interrupted at # any stage, the job is not lost and is not in the queue twice: # Step 1: copy the job to the new id: # Step 2: move the original job ctrl file to the new id: # Step 3: replace the original job ctrl file with the updated one: # Step 4: delete the original cmd file # create a background jobs script that executes the commands # then locks the spool/log file and appends the output to the # log file and finally unlocks # copy the postrun_lock and postrun_unlock commands from # this script to the background job script sed -e '1,/#LOCK_UNLOCK_FUNCTIONS_START/d' \ -e '/#LOCK_UNLOCK_FUNCTIONS_END/,$d' $0 >> $cmdfile # save the stdout file description echo 'echo Starting postrun job at `LC_ALL=C date`' >> $cmdfile echo "echo 'This is a spooled background job (#${postrun_job_number})'" >> $cmdfile echo "echo 'This is a spooled foreground job (#${postrun_job_number})'" >> $cmdfile echo 'echo This is an immediate background job' >> $cmdfile echo 'echo This is an immediate foreground job' >> $cmdfile echo 'echo Running commands:' >> $cmdfile echo "echo '>>>' commands follow:" >> $cmdfile sed -e "s/'/'\"'\"'/g" | \ echo "echo '<<<' commands end" >> $cmdfile echo "echo '>>>' Command output follows:" >> $cmdfile # FIXME: send email to $postrun_user if the command failed echo "echo '<<<' Command completed with exit status \$?" \ echo 'echo Job finished at `LC_ALL=C date`' >> $cmdfile # restore PATH in case the command changed it # 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 # usage: is_leap_year yyyy # get_abstime yy mm dd hh mm ss # prints the elapsed time in seconds since 1970.01.01.00.00.00 # JA FE MA AP MY JN JL AU SE OC NO DE set -A
MONTH 0 31 28 31 30 31 30 31 31 30 31 30 31 # the absolute time since 1970... t=$(($t + ($1 - 1970) * 31536000)) # add 1 day for each leap year t=$(($t + ${MONTH[$m]} * 86400)) # 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: # Works for dates after 1970.01.01.00.00.00 day1=$(expr "$1" : "^[^.]*\.[^.]*\.\([^.]*\)\..*") hour1=$(expr "$1" : "^[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*") min1=$(expr "$1" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*") sec1=$(expr "$1" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)") day2=$(expr "$2" : "^[^.]*\.[^.]*\.\([^.]*\)\..*") hour2=$(expr "$2" : "^[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*") min2=$(expr "$2" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*") sec2=$(expr "$2" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)") # calculate seconds since 1970.01.01.00.00.00 test -f "$job" || continue echo "postrun: WARNING: invalid setting in $job: $var" # if it's a uniq job, check if it timed out # calculate time difference (seconds) # try again in at least $tdiff sec time # ignore timeout, just run the job at now "+${timeleft}minutes" \ 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) if [ $# =
1 -a
"x$1" =
'x-q' ];
then # postrun-runq mode, to be run from at(1) # process the command line echo "postrun: error: argument expected after $opt" echo "postrun: error: interger number expected after $opt (found \"$timeout\")" echo "postrun: error: argument expected after $opt" echo "postrun: error: argument expected after $opt" echo "postrun: error: invalid argument: $1" # need to verify if the architecture and Solaris minor version # of / is equal to that of $PKG_INSTALL_ROOT, otherwise # running the script is not okay # save the standard input in a temporary file # Live Upgrade. Unsafe to run the command now. # Put into spool and defer to next boot. # Installation to an alternate root directory # Put command into spool and defer to next boot. # Local package install. Everything's shiny happy, # safe to run the command right now # Note: for alt_root_okay jobs, -u only applies to the case # when we have to spool the job # don't run the command yet in case the same command is requested # within the next postrun_uniq_timeout minutes # do not delete the tmp_cmd_file because it's the only copy of the # commands (since the job is not spooled)