#
# 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.
#
LC_ALL=C
export LC_ALL
LOGFILE="$MYDIR/../../log/postrun.log"
if [ "$myuid" != 0 ]; then
echo "postrun: error: run this script as root"
exit 1
fi
umask 0133
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 ' -c <class>'
echo ' Assign this job to class <class>. Useful for querying'
echo ' jobs with postrun-query'
echo
echo ' -i'
echo ' Ignore this job if it cannot be executed immediately.'
echo
echo ' -h, -?, --help'
echo ' Display this help'
exit 1
}
# Solaris 9 doesn't have mktemp, need a substitute in order to be
# Live Upgrade compliant
# Note: only creating tmp files is implemented, directories are not
return
}
while [ -f $tempname ]; do
done
echo $tempname
}
#LOCK_UNLOCK_FUNCTIONS_START
done
fi
}
return 0
}
# lock the postrun spool or log file
# if $1 is 'log' then lock the log file, otherwise log the spool
fi
postrun_debug "Taking lock on $this_lock"
while true ; do
# Try to take the lock
ln -s $$ $this_lock 2>/dev/null
if [ $? = 0 ] ; then
postrun_debug "Lock on $this_lock taken"
return
fi
# Read who has the lock. If this process has the lock return
typeset pid=$(ls -ld $this_lock \
postrun_debug "Lock on $this_lock already held by this pid ($$)"
return
fi
# 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 "Waiting for $pid to release $this_lock"
sleep 1
else
postrun_debug "Stale lock $this_lock from $pid being released"
rm -f $this_lock
fi
done
postrun_debug "postrun_lock escaped the loop - should not b here"
}
# release the lock
# unlock the log file if $1 == 'log', unlock the spool otherwise
fi
postrun_debug "Releasing lock on $this_lock"
typeset pid=$(ls -ld $this_lock \
if ! rm -f $this_lock; then
exit 1
fi
postrun_debug "Released lock on $this_lock taken by pid $pid"
}
#LOCK_UNLOCK_FUNCTIONS_END
# get the next job id
echo $next_seq
}
if [ $postrun_no_spool = yes ]; then
postrun_debug "Ignoring job, because -i was used and it's not possible to run it now"
return 1
fi
cd $SPOOLDIR
# check if there's already a spooled job for the same command
new_job=0
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
# we need to update the uniq time and make sure it's
# flagged as a uniq job
new_job=1
#
# FIXME: shouldn't use sed for this, safer to simply append
# and process the duplicate entries when reading the file
#
-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
rm -f $uniq_job_nr.cmd
else
postrun_debug "spooling command as job #${job_seq}"
cat /dev/null > $ctrl_file
fi
return $new_job
}
# 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='
'
timeleft=0
pkginst: )
;;
submit_time: )
;;
;;
uniq_command: )
;;
uniq_time: )
;;
uniq_timeout: )
;;
background: )
;;
user: )
;;
class: )
;;
* )
;;
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
else
# try again in at least $tdiff sec time
fi
fi
else
fi
else
# ignore timeout, just run the job
fi
done
fi
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
;;
-i|--ignore)
;;
-f)
opt="$1"
if [ $# == 0 ]; then
echo "postrun: error: argument expected after $opt"
exit 1
fi
shift
postrun_command_file="$1"
;;
-c)
opt="$1"
if [ $# == 0 ]; then
echo "postrun: error: argument expected after $opt"
exit 1
fi
shift
postrun_job_class="$1"
;;
-a)
;;
--)
break
;;
*)
echo "postrun: error: invalid argument: $1"
exit 1
;;
esac
shift
done
return 1
fi
# 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
this_sol_minor=`echo "$this_solnm_pkginfo" |grep VERSION| sed -e 's/^.*VERSION: *\([0-9]*\),REV=.*/\1/'`
alt_root_sol_minor=`echo "$alt_root_solnm_pkginfo" |grep VERSION| sed -e 's/^.*VERSION: *\([0-9]*\),REV=.*/\1/'`
postrun_debug "/ is Solaris $this_sol_minor, $PKG_INSTALL_ROOT is Solaris $alt_root_sol_minor"
return 1
fi
alt_root_sol_arch=`echo "$alt_root_solnm_pkginfo" |grep ARCH|sed -e 's/^.*ARCH: *\([a-z0-9]*\).*/\1/'`
return 1
fi
return 0
}
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
#
# 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
}
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