postrun revision 8282
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder#!/bin/ksh
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder#
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski# Script for starting a postponed post-installation command in
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder# a Live-Upgrade-safe environment
97018cf5fa25b494adffd7e9b4e87320dae6bf47Christian Maeder#
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder# CDDL HEADER START
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder#
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# The contents of this file are subject to the terms of the
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# Common Development and Distribution License, Version 1.0 only
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski# (the "License"). You may not use this file except in compliance
49588f3d624e56594d888bc622bc90618ae3c2c5Till Mossakowski# with the License.
57d320fc4d0fe1a1c08cfe6cd9ebec09b86c2cbfTill Mossakowski#
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
49588f3d624e56594d888bc622bc90618ae3c2c5Till Mossakowski# or http://www.opensolaris.org/os/licensing.
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# See the License for the specific language governing permissions
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# and limitations under the License.
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder#
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# When distributing Covered Code, include this CDDL HEADER in each
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# If applicable, add the following below this CDDL HEADER, with the
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# fields enclosed by brackets "[]" replaced with your own identifying
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# information: Portions Copyright [yyyy] [name of copyright owner]
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder#
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# CDDL HEADER END
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder#
57d320fc4d0fe1a1c08cfe6cd9ebec09b86c2cbfTill Mossakowski#
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder# Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
57d320fc4d0fe1a1c08cfe6cd9ebec09b86c2cbfTill Mossakowski# Use is subject to license terms.
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder#
57d320fc4d0fe1a1c08cfe6cd9ebec09b86c2cbfTill Mossakowski
4e2331b387b90a234dc36b12c778914d3e202718Christian Maederexport PATH=/usr/bin
4e2331b387b90a234dc36b12c778914d3e202718Christian MaederLC_ALL=C
4e2331b387b90a234dc36b12c778914d3e202718Christian Maederexport LC_ALL
6528ec34ad606aecb68cbeccd7408ea2a1e99a65Christian MaederMYDIR=$(cd $(dirname $0); pwd)
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian MaederSPOOLDIR="$MYDIR/../../var/spool/postrun"
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian MaederLOCKFILE="$SPOOLDIR/.lock"
2272b992302eb61b2a039033cb8cdaf7809fe682Christian MaederLOGFILE="$MYDIR/../../var/log/postrun.log"
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian MaederSEQFILE="$SPOOLDIR/.seq"
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maederid | grep " euid=" && \
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder myuid=`id | sed -e 's/.* euid=\([0-9][0-9]*\).*$/\1/'` || \
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder myuid=`id | sed -e 's/uid=\([0-9][0-9]*\).*/\1/'`
2272b992302eb61b2a039033cb8cdaf7809fe682Christian Maeder
2272b992302eb61b2a039033cb8cdaf7809fe682Christian Maederif [ "$myuid" != 0 ]; then
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder echo "postrun: error: run this script as root"
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder exit 1
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maederfi
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maederumask 0133
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich
2272b992302eb61b2a039033cb8cdaf7809fe682Christian Maederusage() {
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder echo 'Usage: postrun [options]'
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder echo
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder echo 'Options:'
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder echo ' -u, --uniq'
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder echo ' If the same command is requested multiple times, the command'
2272b992302eb61b2a039033cb8cdaf7809fe682Christian Maeder echo ' is only run once. If it is safe to execute the command'
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo ' immediately, it will be delayed by 5 minutes, or as set'
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo ' using the --timeout option'
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo ' -t <n>, --timeout <n>'
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo ' Delay the execution of uniq commands by <n> minutes.'
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder echo
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo ' -b, --bg'
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo ' Run the command in the background and return control'
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo ' immediately'
e5b79e9fe9606fd386dc840ea9f1514e7b9b32b9Christian Maeder echo
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo ' -f <file>'
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo ' Read the commands from <file> instead of the standard'
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo ' input.'
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo ' -h, -?, --help'
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo ' Display this help'
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder exit 1
8a8880f1b6a0681e636480991d45dfea11d62ff8Christian Maeder}
cd25621939b8f27c6c7e2933ece72bc2d91b00f7Christian Maeder
04d04d19fdd5320953c78ad5b6d2d11f85bc4bcfChristian Maederpostrun_debug() {
8a8880f1b6a0681e636480991d45dfea11d62ff8Christian Maeder if [ "x$POSTRUN_DEBUG" = xyes ]; then
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder for msg in "${@}"; do
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich echo '<POSTRUN_DEBUG>' "$msg" 1>&2
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich done
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich fi
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich}
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich#LOCK_UNLOCK_FUNCTIONS_START
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettichis_number() {
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich echo "$1" | egrep -vs '^[0-9]+$' && return 1
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich echo "$1" | egrep -s '^[0-9]+$' || return 1
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich return 0
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich}
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder# lock the postrun spool or log file
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder# if $1 is 'log' then lock the log file, otherwise log the spool
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maederpostrun_lock() {
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich this_lock=$LOCKFILE
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich if [ "x$1" = xlog ]; then
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich this_lock=${LOCKFILE}.log
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich fi
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich # lock file exists (contains the pid of the process that locked it)
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich while test -f $this_lock; do
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich # get the pid that holds the lock
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder pid=`cat $this_lock 2>/dev/null` || continue
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder # is the lock held by this process?
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich test "$pid" == "$$" && return
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder # check if the process is still running or else it's a stale lock
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich is_number "$pid" && {
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder ps -g $pid -o 'pid' | egrep -s "$pid\$" 2>&1 || {
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder sleep 1
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder postrun_lock $1
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder return
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder }
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich }
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder # we have a stale lock situation, let's try and take ownership
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich # of the lock
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder chmod 644 ${this_lock}
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder echo "$$" > ${this_lock}
54a0a1e10bd93721cf52dbd9b816c8f108997ec0Christian Maeder chmod 444 ${this_lock}
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder # if we successfully took ownership of the lock, this loop
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder # will read our own pid back and return
2de8dfc30c926ee27254bfa32230a01435530efeKlaus Luettich # otherwise
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder done
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder # create a read-only lock file
54a0a1e10bd93721cf52dbd9b816c8f108997ec0Christian Maeder umask 0333
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder # run false so that we enter the while loop
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder false
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder while [ $? != 0 ]; do
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder # write the pid to the lock file
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder # recurse if failed. recursion here helps to avoid an infinite
9603ad7198b72e812688ad7970e4eac4b553837aKlaus Luettich # loop -- ksh will kill the script after 128 attempts
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder echo "$$" > $this_lock || postrun_lock $1
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich # read it back in case another process also wrote its pid there
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich # in the meantime
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder pid=`cat $this_lock 2>/dev/null`
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder # the loop will restart is the file cannot be read
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder done
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder umask 0133
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder # check if this process holds the lock or else try the whole thing again
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder test "$pid" == "$$" || postrun_lock $1
9603ad7198b72e812688ad7970e4eac4b553837aKlaus Luettich}
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich# release the lock
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich# unlock the log file if $1 == 'log', unlock the spool otherwise
4e2331b387b90a234dc36b12c778914d3e202718Christian Maederpostrun_unlock() {
9603ad7198b72e812688ad7970e4eac4b553837aKlaus Luettich this_lock=$LOCKFILE
04d04d19fdd5320953c78ad5b6d2d11f85bc4bcfChristian Maeder if [ "x$1" = xlog ]; then
0ee3933098d65199ae39ea41cfc62634226dad15Klaus Luettich this_lock=${LOCKFILE}.log
0ee3933098d65199ae39ea41cfc62634226dad15Klaus Luettich fi
04d04d19fdd5320953c78ad5b6d2d11f85bc4bcfChristian Maeder if ! rm -f $this_lock; then
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder echo "postrun: error: cannot remove lock file $this_lock"
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder exit 1
ebdce567033765c1f16ccf25d721c02986a5da33Klaus Luettich fi
e24d81c69aecd41abb2f4969519c9e7126b1d687Christian Maeder}
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder#LOCK_UNLOCK_FUNCTIONS_END
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder
9603ad7198b72e812688ad7970e4eac4b553837aKlaus Luettich# get the next job id
4e2331b387b90a234dc36b12c778914d3e202718Christian Maederpostrun_get_seq() {
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder postrun_lock
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder seq=`cat $SEQFILE 2>/dev/null`
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder next_seq=$(($seq + 1))
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo $next_seq > $SEQFILE
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder postrun_unlock
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder echo $next_seq
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder}
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder
7bf4436b6f9987b070033a323757b206c898c1beChristian Maederpostrun_spool_command() {
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder cd $SPOOLDIR
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder # check if there's already a spooled job for the same command
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder new_job=0
33c33fde308de14d34177617a28524312f5f0ad8Christian Maeder uniq_job_nr=
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder IFS=' '
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder postrun_lock
04d04d19fdd5320953c78ad5b6d2d11f85bc4bcfChristian Maeder for f in *.cmd; do
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder test -f "$f" || continue
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder cmp -s $postrun_command_file $f && {
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder if [ $postrun_is_uniq = yes ]; then
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder uniq_job_nr=`basename $f .cmd`
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder break
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder fi
4e2331b387b90a234dc36b12c778914d3e202718Christian Maeder egrep -s '^uniq_command: yes' `basename $f .cmd`.ctrl && {
04d04d19fdd5320953c78ad5b6d2d11f85bc4bcfChristian Maeder uniq_job_nr=`basename $f .cmd`
04d04d19fdd5320953c78ad5b6d2d11f85bc4bcfChristian Maeder break
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder }
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder }
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich done
f64f3dc78de82101483fe97bf109a42ca4d59d77Klaus Luettich if [ "x$uniq_job_nr" != x ]; then
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich postrun_debug "matching spooled uniq job (#${uniq_job_nr}) found"
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder # we found a matching spooled uniq job
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder # all we need to do is update the uniq time and make sure it's
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich # flagged as a uniq job
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich new_job=1
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich #
0ee3933098d65199ae39ea41cfc62634226dad15Klaus Luettich # FIXME: shouldn't use sed for this, safer to simply append
7bf4436b6f9987b070033a323757b206c898c1beChristian Maeder # and process the duplicate entries when reading the file
709653bffee501341e2fdc55b9223e4921047c65Till Mossakowski #
709653bffee501341e2fdc55b9223e4921047c65Till Mossakowski sed -e 's/^uniq_command: .*/uniq_command: yes/' \
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich -e 's/^\(pkginst: .*\)/\1, '$PKGINST'/' \
6a9b85953df4e29a996536ffc7dbf7ef9dbc64c7Cui Jian -e 's/^uniq_time: .*/uniq_time: '`date +%Y.%m.%d.%H.%M.%S`'/' \
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder -e 's/^uniq_timeout: .*/uniq_timeout: '"$postrun_uniq_timeout"'/' \
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder $uniq_job_nr.ctrl > $uniq_job_nr.ctrl.new
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich
57d320fc4d0fe1a1c08cfe6cd9ebec09b86c2cbfTill Mossakowski #
57d320fc4d0fe1a1c08cfe6cd9ebec09b86c2cbfTill Mossakowski # FIXME: add the user name to the control file
f4ae50539e67874b6162f8334f6782a0d66acefaCui Jian #
f4ae50539e67874b6162f8334f6782a0d66acefaCui Jian
57d320fc4d0fe1a1c08cfe6cd9ebec09b86c2cbfTill Mossakowski mv $uniq_job_nr.ctrl.new $uniq_job_nr.ctrl
57d320fc4d0fe1a1c08cfe6cd9ebec09b86c2cbfTill Mossakowski else
d19b839f3726cc508e3c52a7af227167a9e38f45Klaus Luettich postrun_unlock
57d320fc4d0fe1a1c08cfe6cd9ebec09b86c2cbfTill Mossakowski job_seq=`postrun_get_seq`
04d04d19fdd5320953c78ad5b6d2d11f85bc4bcfChristian Maeder postrun_debug "spooling command as job #${job_seq}"
333780eae2be9f20fe46dedbf5eb46ffa0cbfd02Christian Maeder postrun_lock
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich user_name=${EMAIL:-root}
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich ctrl_file="$SPOOLDIR/$job_seq.ctrl"
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich cmd_file="$SPOOLDIR/$job_seq.cmd"
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich cat $postrun_command_file > $cmd_file
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich cat /dev/null > $ctrl_file
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo "pkginst: $PKGINST" >> $ctrl_file
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo "submit_time: `date +%Y.%m.%d.%H.%M.%S`" >> $ctrl_file
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo "uniq_command: $postrun_is_uniq" >> $ctrl_file
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo "uniq_time: `date +%Y.%m.%d.%H.%M.%S`" >> $ctrl_file
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo "uniq_timeout: $postrun_uniq_timeout" >> $ctrl_file
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder echo "background: $postrun_bg_job" >> $ctrl_file
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo "user: $user_name" >> $ctrl_file
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich fi
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich postrun_unlock
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich return $new_job
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich}
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettichpostrun_run_command() {
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich cmdout=`mktemp /tmp/postrun.out.XXXX`
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich # create a background jobs script that executes the commands
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich # then locks the spool/log file and appends the output to the
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder # log file and finally unlocks
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder cmdfile=`mktemp /tmp/postrun.job.XXXX`
ef7d1a1d5454458d46b9acefeda94b12bdc695b2Christian Maeder cat /dev/null > $cmdfile
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich cat /dev/null > $cmdout
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich echo '#!/bin/ksh' >> $cmdfile
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich # copy the postrun_lock and postrun_unlock commands from
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich # this script to the background job script
e550da81778d64d06c7950b1d578a1cc307ee280Klaus Luettich echo "LOCKFILE=$LOCKFILE" >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich sed -e '1,/#LOCK_UNLOCK_FUNCTIONS_START/d' \
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich -e '/#LOCK_UNLOCK_FUNCTIONS_END/,$d' $0 >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich # save the stdout file description
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo 'exec 3<&1' >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo "exec >> $cmdout 2>&1" >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo 'PATH=/usr/bin; export PATH' >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo 'echo Starting postrun job at `LC_ALL=C date`' >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich if [ "x$postrun_submit_time" != x ]; then
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich if [ $postrun_bg_job = yes ]; then
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo "echo 'This is a spooled background job (#${postrun_job_number})'" >> $cmdfile
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder else
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder echo "echo 'This is a spooled foreground job (#${postrun_job_number})'" >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich fi
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo "echo Job submitted by $postrun_pkginst at $postrun_submit_time" \
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich >> $cmdfile
e24d81c69aecd41abb2f4969519c9e7126b1d687Christian Maeder else
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder if [ $postrun_bg_job = yes ]; then
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich echo 'echo This is an immediate background job' >> $cmdfile
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder else
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder echo 'echo This is an immediate foreground job' >> $cmdfile
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich fi
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich echo "echo Job submitted by $postrun_pkginst"\
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder >> $cmdfile
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich fi
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich echo 'echo Running commands:' >> $cmdfile
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich echo "echo '>>>' commands follow:" >> $cmdfile
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich cat $postrun_command_file | \
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder sed -e "s/'/'\"'\"'/g" | \
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich sed -e "s/^/echo '/" \
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich -e "s/\$/'/" >> $cmdfile
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich echo "echo '<<<' commands end" >> $cmdfile
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich echo "echo '>>>' Command output follows:" >> $cmdfile
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder echo "chmod 700 $postrun_command_file" >> $cmdfile
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich echo "$postrun_command_file" >> $cmdfile
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich #
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder # FIXME: send email to $postrun_user if the command failed
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich #
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder echo "echo '<<<' Command completed with exit status \$?" \
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich >> $cmdfile
33c33fde308de14d34177617a28524312f5f0ad8Christian Maeder echo 'echo Job finished at `LC_ALL=C date`' >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo 'echo --' >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich # restore PATH in case the command changed it
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder echo 'PATH=/usr/bin; export PATH' >> $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich # restore stdout
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder echo 'exec 1<&3' >> $cmdfile
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder # close file descriptor 3
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder echo 'exec 3<&-' >> $cmdfile
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder echo 'exec 2>&1' >> $cmdfile
833baa690207430f9cc3ca599039954a7840fa30Klaus Luettich # append the messages to the real log file
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder # need to lock the log file to avoid 2 postrun commands
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder # writing at the same time and messing up the log
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich echo 'postrun_lock log' >> $cmdfile
833baa690207430f9cc3ca599039954a7840fa30Klaus Luettich echo "cat $cmdout >> $LOGFILE" >> $cmdfile
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder echo 'postrun_unlock log' >> $cmdfile
724be620c516160e7d2c203999f01df4ccc53048Klaus Luettich echo "rm -f $cmdout" >> $cmdfile
724be620c516160e7d2c203999f01df4ccc53048Klaus Luettich echo "rm -f $cmdfile" >> $cmdfile
833baa690207430f9cc3ca599039954a7840fa30Klaus Luettich echo "rm -f $postrun_command_file" >> $cmdfile
833baa690207430f9cc3ca599039954a7840fa30Klaus Luettich chmod 700 $cmdfile
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder if [ $postrun_bg_job = yes ]; then
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich $cmdfile &
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich else
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich $cmdfile
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich fi
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich exitval=$?
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich}
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettichusername=${EMAIL:-root}
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maederpostrun_defaults() {
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich # default settings
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder postrun_pkginst="$PKGINST"
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder postrun_submit_time=''
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich postrun_uniq_time=''
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder postrun_is_uniq=no
33fc94b09b906329ca7505caa1ddcddf67e3f8daTill Mossakowski postrun_uniq_timeout=5
33fc94b09b906329ca7505caa1ddcddf67e3f8daTill Mossakowski postrun_bg_job=no
33fc94b09b906329ca7505caa1ddcddf67e3f8daTill Mossakowski postrun_command_file=''
33fc94b09b906329ca7505caa1ddcddf67e3f8daTill Mossakowski postrun_user=${username}
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder postrun_job_number='???'
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder postrun_alt_root_okay=no
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder}
5ef395ccb7c654b00f393715176a0c8f9ae69b77Klaus Luettich
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich# usage: is_leap_year yyyy
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettichis_leap_year() {
eac3174ea16c143bfaeb3f2e2103a11a2f162c6cChristian Maeder cal 02 $1 | egrep -s 29 && return 0
5fcb1cb8c190e9bfb8d5c06c2e7d7a4b65f361acKlaus Luettich return 1
0206ab93ef846e4e0885996d052b9b73b9dc66b0Christian Maeder}
# 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
set -A MONTH 0 31 28 31 30 31 30 31 31 30 31 30 31
get_abstime() {
# 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
end_y=$(($1 - 1))
fi
while [ $y -le $end_y ]; do
is_leap_year $y && t=$(($t + 86400))
y=$(($y + 4))
done
# number of months
m=1
while [ $m -lt $2 ]; do
t=$(($t + ${MONTH[$m]} * 86400))
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
#
get_timediff() {
year1=$(expr "$1" : "^\([^.]*\)\..*")
month1=$(expr "$1" : "^[^.]*\.\([^.]*\)\..*")
day1=$(expr "$1" : "^[^.]*\.[^.]*\.\([^.]*\)\..*")
hour1=$(expr "$1" : "^[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*")
min1=$(expr "$1" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*")
sec1=$(expr "$1" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)")
year2=$(expr "$2" : "^\([^.]*\)\..*")
month2=$(expr "$2" : "^[^.]*\.\([^.]*\)\..*")
day2=$(expr "$2" : "^[^.]*\.[^.]*\.\([^.]*\)\..*")
hour2=$(expr "$2" : "^[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*")
min2=$(expr "$2" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*")
sec2=$(expr "$2" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)")
# calculate seconds since 1970.01.01.00.00.00
t1=`get_abstime $year1 $month1 $day1 $hour1 $min1 $sec1`
t2=`get_abstime $year2 $month2 $day2 $hour2 $min2 $sec2`
# print difference
expr $t1 - $t2
}
postrun_runq() {
cd $SPOOLDIR
IFS=' '
timeleft=0
postrun_lock
for job in *.ctrl; do
test -f "$job" || continue
postrun_defaults
while read var val; do
case "$var" in
pkginst: )
postrun_pkginst="$val"
;;
submit_time: )
postrun_submit_time="$val"
;;
uniq_command: )
postrun_is_uniq="$val"
;;
uniq_time: )
postrun_uniq_time="$val"
;;
uniq_timeout: )
postrun_uniq_timeout="$val"
;;
background: )
postrun_bg_job="$val"
;;
user: )
postrun_user="$val"
;;
* )
echo "postrun: WARNING: invalid setting in $job: $var"
;;
esac
done < $job
postrun_command_file=$SPOOLDIR/`basename $job .ctrl`.cmd
postrun_job_number=`basename $job .ctrl`
if [ $postrun_ignore_timeout = no ]; then
# if it's a uniq job, check if it timed out
if [ "x$postrun_is_uniq" = xyes ]; then
# calculate time difference (seconds)
tdiff=$(get_timediff $(date +%Y.%m.%d.%H.%M.%S) \
$postrun_uniq_time)
timeout_sec=$((postrun_uniq_timeout * 60))
if [ $tdiff -ge $timeout_sec ]; then
postrun_run_command
rm -f $job
else
# try again in at least $tdiff sec time
tl=$(($tdiff / 60 + 1))
if [ $tl -gt $timeleft ]; then
timeleft=$tl
fi
fi
else
postrun_run_command
rm -f $job
fi
else
# ignore timeout, just run the job
postrun_run_command
rm -f $job
fi
done
if [ $timeleft -gt 0 ]; then
echo "$MYDIR/postrun -q" |
at now "+${timeleft}minutes" \
> /dev/null 2>&1
fi
postrun_unlock
exit 0
}
postrun_defaults
exitval=0
postrun_ignore_timeout=no
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)
postrun_ignore_timeout=yes
postrun_runq
exit 1
fi
if [ $# = 1 -a "x$1" = 'x-q' ]; then
# postrun-runq mode, to be run from at(1)
postrun_runq
exit 1
fi
# process the command line
while [ $# -gt 0 ]; do
case "$1" in
-h|-\?|--help)
usage
;;
-u|--uniq)
postrun_is_uniq=yes
;;
-b|--bg)
postrun_bg_job=yes
;;
-t|--timeout)
opt="$1"
if [ $# == 0 ]; then
echo "postrun: error: argument expected after $opt"
exit 1
fi
shift
timeout=$1
if ! is_number "$timeout"; then
echo "postrun: error: interger number expected after $opt (found \"$timeout\")"
exit 1
fi
postrun_uniq_timeout=$timeout
;;
-f)
opt="$1"
if [ $# == 0 ]; then
echo "postrun: error: argument expected after $opt"
exit 1
fi
shift
postrun_command_file="$1"
;;
-a)
postrun_alt_root_okay=yes
;;
--)
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
tmp_cmd_file=`mktemp /tmp/postrun.cmd.XXXX`
cat > $tmp_cmd_file
postrun_command_file=$tmp_cmd_file
fi
if [ "$LUBIN" != "" ]; then
#
# Live Upgrade. Unsafe to run the command now.
# Put into spool and defer to next boot.
#
postrun_spool_command "${@}"
elif [ "$PKG_INSTALL_ROOT" != "" -a "$PKG_INSTALL_ROOT" != "/" -a \
"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 "${@}" && {
echo "$MYDIR/postrun -q" | \
at now "+${postrun_uniq_timeout}minutes" > /dev/null 2>&1
}
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