1 #!/bin/ksh 2 # 3 # Script for starting a postponed post-installation command in 4 # a Live-Upgrade-safe environment 5 # 6 # CDDL HEADER START 7 # 8 # The contents of this file are subject to the terms of the 9 # Common Development and Distribution License, Version 1.0 only 10 # (the "License"). You may not use this file except in compliance 11 # with the License. 12 # 13 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 14 # or http://www.opensolaris.org/os/licensing. 15 # See the License for the specific language governing permissions 16 # and limitations under the License. 17 # 18 # When distributing Covered Code, include this CDDL HEADER in each 19 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. 20 # If applicable, add the following below this CDDL HEADER, with the 21 # fields enclosed by brackets "[]" replaced with your own identifying 22 # information: Portions Copyright [yyyy] [name of copyright owner] 23 # 24 # CDDL HEADER END 25 # 26 # 27 # Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved. 28 # Use is subject to license terms. 29 # 30 31 export PATH=/usr/bin 32 LC_ALL=C 33 export LC_ALL 34 MYDIR=$(cd $(dirname $0); pwd) 35 SPOOLDIR="$MYDIR/../../spool/postrun" 36 LOCKFILE="/var/run/postrun.lock" 37 LOGFILE="$MYDIR/../../log/postrun.log" 38 SEQFILE="$SPOOLDIR/.seq" 39 40 id | grep " euid=" && \ 41 myuid=`id | sed -e 's/.* euid=\([0-9][0-9]*\).*$/\1/'` || \ 42 myuid=`id | sed -e 's/uid=\([0-9][0-9]*\).*/\1/'` 43 44 if [ "$myuid" != 0 ]; then 45 echo "postrun: error: run this script as root" 46 exit 1 47 fi 48 49 umask 0133 50 51 usage() { 52 echo 'Usage: postrun [options]' 53 echo 54 echo 'Options:' 55 echo ' -u, --uniq' 56 echo ' If the same command is requested multiple times, the command' 57 echo ' is only run once. If it is safe to execute the command' 58 echo ' immediately, it will be delayed by 5 minutes, or as set' 59 echo ' using the --timeout option' 60 echo 61 echo ' -t <n>, --timeout <n>' 62 echo ' Delay the execution of uniq commands by <n> minutes.' 63 echo 64 echo ' -b, --bg' 65 echo ' Run the command in the background and return control' 66 echo ' immediately' 67 echo 68 echo ' -f <file>' 69 echo ' Read the commands from <file> instead of the standard' 70 echo ' input.' 71 echo 72 echo ' -c <class>' 73 echo ' Assign this job to class <class>. Useful for querying' 74 echo ' jobs with postrun-query' 75 echo 76 echo ' -i' 77 echo ' Ignore this job if it cannot be executed immediately.' 78 echo 79 echo ' -h, -?, --help' 80 echo ' Display this help' 81 exit 1 82 } 83 84 # Solaris 9 doesn't have mktemp, need a substitute in order to be 85 # Live Upgrade compliant 86 # Note: only creating tmp files is implemented, directories are not 87 postrun_mktemp () { 88 test -x /usr/bin/mktemp && { 89 /usr/bin/mktemp $1 90 return 91 } 92 tempname="$1.$$.`date +%H%M%S`" 93 while [ -f $tempname ]; do 94 tempname="$tempname.`date +%S`" 95 done 96 touch $tempname && chmod 700 $tempname || exit 1 97 echo $tempname 98 } 99 100 #LOCK_UNLOCK_FUNCTIONS_START 101 postrun_debug() { 102 if [ "x$POSTRUN_DEBUG" = xyes ]; then 103 for msg in "${@}"; do 104 echo '<POSTRUN_DEBUG>' "[$$]" "$msg" 1>&2 105 done 106 fi 107 } 108 109 is_number() { 110 echo "$1" | egrep -vs '^[0-9]+$' && return 1 111 echo "$1" | egrep -s '^[0-9]+$' || return 1 112 return 0 113 } 114 115 # lock the postrun spool or log file 116 # if $1 is 'log' then lock the log file, otherwise log the spool 117 postrun_lock() { 118 typeset this_lock=$LOCKFILE 119 if [ "x$1" = xlog ]; then 120 this_lock=${LOCKFILE}.log 121 fi 122 postrun_debug "Taking lock on $this_lock" 123 124 while true ; do 125 # Try to take the lock 126 ln -s $$ $this_lock 2>/dev/null 127 if [ $? = 0 ] ; then 128 postrun_debug "Lock on $this_lock taken" 129 return 130 fi 131 132 # Read who has the lock. If this process has the lock return 133 typeset pid=$(ls -ld $this_lock \ 134 | nawk -F' -> ' '$1 ~ /^l/ && NF == 2 { print $NF }') 135 if [ "$pid" = $$ ] ; then 136 postrun_debug "Lock on $this_lock already held by this pid ($$)" 137 return 138 fi 139 140 # check to be sure the process that holds the lock is still running 141 # if so, wait for it to be freed. If the lock is stale, remove it 142 # so that the next iteration of the loop can take the lock. 143 if is_number "$pid" && kill -0 "$pid" 2>/dev/null ; then 144 postrun_debug "Waiting for $pid to release $this_lock" 145 sleep 1 146 else 147 postrun_debug "Stale lock $this_lock from $pid being released" 148 rm -f $this_lock 149 fi 150 done 151 postrun_debug "postrun_lock escaped the loop - should not b here" 152 153 } 154 155 # release the lock 156 # unlock the log file if $1 == 'log', unlock the spool otherwise 157 postrun_unlock() { 158 typeset this_lock=$LOCKFILE 159 if [ "x$1" = xlog ]; then 160 this_lock=${LOCKFILE}.log 161 fi 162 postrun_debug "Releasing lock on $this_lock" 163 164 typeset pid=$(ls -ld $this_lock \ 165 | nawk -F' -> ' '$1 ~ /^l/ && NF == 2 { print $NF }') 166 167 if ! rm -f $this_lock; then 168 echo "postrun: error: cannot remove lock file $this_lock" 1>&2 169 exit 1 170 fi 171 postrun_debug "Released lock on $this_lock taken by pid $pid" 172 } 173 #LOCK_UNLOCK_FUNCTIONS_END 174 175 # get the next job id 176 postrun_get_seq() { 177 postrun_lock 178 seq=`cat $SEQFILE 2>/dev/null` 179 next_seq=$(($seq + 1)) 180 echo $next_seq > $SEQFILE 181 postrun_unlock 182 echo $next_seq 183 } 184 185 postrun_spool_command() { 186 if [ $postrun_no_spool = yes ]; then 187 postrun_debug "Ignoring job, because -i was used and it's not possible to run it now" 188 return 1 189 fi 190 cd $SPOOLDIR 191 # check if there's already a spooled job for the same command 192 new_job=0 193 uniq_job_nr= 194 job_seq=`postrun_get_seq` 195 IFS=' ' 196 postrun_lock 197 for f in *.cmd; do 198 test -f "$f" || continue 199 cmp -s $postrun_command_file $f && { 200 if [ $postrun_is_uniq = yes ]; then 201 uniq_job_nr=`basename $f .cmd` 202 break 203 fi 204 egrep -s '^uniq_command: yes' `basename $f .cmd`.ctrl && { 205 uniq_job_nr=`basename $f .cmd` 206 break 207 } 208 } 209 done 210 if [ "x$uniq_job_nr" != x ]; then 211 postrun_debug "matching spooled uniq job (#${uniq_job_nr}) found" 212 # we found a matching spooled uniq job 213 # we need to update the uniq time and make sure it's 214 # flagged as a uniq job 215 216 new_job=1 217 218 # 219 # FIXME: shouldn't use sed for this, safer to simply append 220 # and process the duplicate entries when reading the file 221 # 222 sed -e 's/^uniq_command: .*/uniq_command: yes/' \ 223 -e 's/^\(pkginst: .*\)/\1, '$PKGINST'/' \ 224 -e 's/^uniq_time: /resubmit_time: /' \ 225 -e 's/^uniq_timeout: .*/uniq_timeout: '"$postrun_uniq_timeout"'/' \ 226 $uniq_job_nr.ctrl > $uniq_job_nr.ctrl.new 227 echo 'uniq_time: '`date +%Y.%m.%d.%H.%M.%S` >> $uniq_job_nr.ctrl.new 228 grep "^class: $postrun_job_class$" $uniq_job_nr.ctrl.new \ 229 >/dev/null || \ 230 echo "class: $postrun_job_class" >> $uniq_job_nr.ctrl.new 231 # 232 # FIXME: add the user name to the control file 233 # 234 235 # Use a new job id so that the job moves to the end of the queue. 236 # Need to do this such a whay that if this process is interrupted at 237 # any stage, the job is not lost and is not in the queue twice: 238 239 # Step 1: copy the job to the new id: 240 cp $uniq_job_nr.cmd $job_seq.cmd 241 242 # Step 2: move the original job ctrl file to the new id: 243 mv $uniq_job_nr.ctrl $job_seq.ctrl 244 245 # Step 3: replace the original job ctrl file with the updated one: 246 mv $uniq_job_nr.ctrl.new $job_seq.ctrl 247 248 # Step 4: delete the original cmd file 249 rm -f $uniq_job_nr.cmd 250 else 251 postrun_debug "spooling command as job #${job_seq}" 252 user_name=${EMAIL:-root} 253 ctrl_file="$SPOOLDIR/$job_seq.ctrl" 254 cmd_file="$SPOOLDIR/$job_seq.cmd" 255 cat $postrun_command_file > $cmd_file 256 cat /dev/null > $ctrl_file 257 echo "pkginst: $PKGINST" >> $ctrl_file 258 echo "submit_time: `date +%Y.%m.%d.%H.%M.%S`" >> $ctrl_file 259 echo "uniq_command: $postrun_is_uniq" >> $ctrl_file 260 echo "uniq_time: `date +%Y.%m.%d.%H.%M.%S`" >> $ctrl_file 261 echo "uniq_timeout: $postrun_uniq_timeout" >> $ctrl_file 262 echo "background: $postrun_bg_job" >> $ctrl_file 263 echo "user: $user_name" >> $ctrl_file 264 echo "class: $postrun_job_class" >> $ctrl_file 265 fi 266 postrun_unlock 267 268 return $new_job 269 } 270 271 postrun_run_command() { 272 cmdout=`mktemp /tmp/postrun.out.XXXX` 273 # create a background jobs script that executes the commands 274 # then locks the spool/log file and appends the output to the 275 # log file and finally unlocks 276 cmdfile=`mktemp /tmp/postrun.job.XXXX` 277 cat /dev/null > $cmdfile 278 cat /dev/null > $cmdout 279 echo '#!/bin/ksh' >> $cmdfile 280 # copy the postrun_lock and postrun_unlock commands from 281 # this script to the background job script 282 echo "LOCKFILE=$LOCKFILE" >> $cmdfile 283 sed -e '1,/#LOCK_UNLOCK_FUNCTIONS_START/d' \ 284 -e '/#LOCK_UNLOCK_FUNCTIONS_END/,$d' $0 >> $cmdfile 285 # save the stdout file description 286 echo 'exec 3<&1' >> $cmdfile 287 echo "exec >> $cmdout 2>&1" >> $cmdfile 288 echo 'PATH=/usr/bin; export PATH' >> $cmdfile 289 echo 'echo Starting postrun job at `LC_ALL=C date`' >> $cmdfile 290 if [ "x$postrun_submit_time" != x ]; then 291 if [ $postrun_bg_job = yes ]; then 292 echo "echo 'This is a spooled background job (#${postrun_job_number})'" >> $cmdfile 293 else 294 echo "echo 'This is a spooled foreground job (#${postrun_job_number})'" >> $cmdfile 295 fi 296 echo "echo Job submitted by $postrun_pkginst at $postrun_submit_time" \ 297 >> $cmdfile 298 else 299 if [ $postrun_bg_job = yes ]; then 300 echo 'echo This is an immediate background job' >> $cmdfile 301 else 302 echo 'echo This is an immediate foreground job' >> $cmdfile 303 fi 304 echo "echo Job submitted by $postrun_pkginst"\ 305 >> $cmdfile 306 fi 307 echo 'echo Running commands:' >> $cmdfile 308 echo "echo '>>>' commands follow:" >> $cmdfile 309 cat $postrun_command_file | \ 310 sed -e "s/'/'\"'\"'/g" | \ 311 sed -e "s/^/echo '/" \ 312 -e "s/\$/'/" >> $cmdfile 313 echo "echo '<<<' commands end" >> $cmdfile 314 echo "echo '>>>' Command output follows:" >> $cmdfile 315 echo "chmod 700 $postrun_command_file" >> $cmdfile 316 echo "$postrun_command_file" >> $cmdfile 317 318 # 319 # FIXME: send email to $postrun_user if the command failed 320 # 321 322 echo "echo '<<<' Command completed with exit status \$?" \ 323 >> $cmdfile 324 echo 'echo Job finished at `LC_ALL=C date`' >> $cmdfile 325 echo 'echo --' >> $cmdfile 326 # restore PATH in case the command changed it 327 echo 'PATH=/usr/bin; export PATH' >> $cmdfile 328 # restore stdout 329 echo 'exec 1<&3' >> $cmdfile 330 # close file descriptor 3 331 echo 'exec 3<&-' >> $cmdfile 332 echo 'exec 2>&1' >> $cmdfile 333 # append the messages to the real log file 334 # need to lock the log file to avoid 2 postrun commands 335 # writing at the same time and messing up the log 336 echo 'postrun_lock log' >> $cmdfile 337 echo "cat $cmdout >> $LOGFILE" >> $cmdfile 338 echo 'postrun_unlock log' >> $cmdfile 339 echo "rm -f $cmdout" >> $cmdfile 340 echo "rm -f $cmdfile" >> $cmdfile 341 echo "rm -f $postrun_command_file" >> $cmdfile 342 chmod 700 $cmdfile 343 if [ $postrun_bg_job = yes ]; then 344 $cmdfile & 345 else 346 $cmdfile 347 fi 348 exitval=$? 349 } 350 351 username=${EMAIL:-root} 352 353 postrun_defaults() { 354 # default settings 355 postrun_pkginst="$PKGINST" 356 postrun_submit_time='' 357 postrun_uniq_time='' 358 postrun_is_uniq=no 359 postrun_uniq_timeout=5 360 postrun_bg_job=no 361 postrun_command_file='' 362 postrun_user=${username} 363 postrun_job_number='???' 364 postrun_alt_root_okay=no 365 postrun_job_class=other 366 postrun_no_spool=no 367 } 368 369 # usage: is_leap_year yyyy 370 is_leap_year() { 371 cal 02 $1 | egrep -s 29 && return 0 372 return 1 373 } 374 375 # get_abstime yy mm dd hh mm ss 376 # 377 # prints the elapsed time in seconds since 1970.01.01.00.00.00 378 #Length of the months: 379 # JA FE MA AP MY JN JL AU SE OC NO DE 380 set -A MONTH 0 31 28 31 30 31 30 31 31 30 31 30 31 381 get_abstime() { 382 # the absolute time since 1970... 383 t=0 384 385 # number of years 386 t=$(($t + ($1 - 1970) * 31536000)) 387 388 # add 1 day for each leap year 389 y=1972 390 end_y=$1 391 if [ $2 -lt 2 ]; then 392 end_y=$(($1 - 1)) 393 fi 394 while [ $y -le $end_y ]; do 395 is_leap_year $y && t=$(($t + 86400)) 396 y=$(($y + 4)) 397 done 398 399 # number of months 400 m=1 401 while [ $m -lt $2 ]; do 402 t=$(($t + ${MONTH[$m]} * 86400)) 403 m=$(($m + 1)) 404 done 405 406 # number of days, hours, minutes and seconds: 407 echo $(($t + ($3 - 1) * 86400 + $4 * 3600 + $5 * 60 + $6)) 408 } 409 410 # get_timediff: prints the difference in seconds between 2 time strings 411 # the time strings should be of the following format: 412 # YYYY.MM.DD.HH.MM.SS as printed by date +%Y.%m.%d.%H.%M.%S 413 # 414 # Works for dates after 1970.01.01.00.00.00 415 # 416 get_timediff() { 417 year1=$(expr "$1" : "^\([^.]*\)\..*") 418 month1=$(expr "$1" : "^[^.]*\.\([^.]*\)\..*") 419 day1=$(expr "$1" : "^[^.]*\.[^.]*\.\([^.]*\)\..*") 420 hour1=$(expr "$1" : "^[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*") 421 min1=$(expr "$1" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*") 422 sec1=$(expr "$1" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)") 423 424 year2=$(expr "$2" : "^\([^.]*\)\..*") 425 month2=$(expr "$2" : "^[^.]*\.\([^.]*\)\..*") 426 day2=$(expr "$2" : "^[^.]*\.[^.]*\.\([^.]*\)\..*") 427 hour2=$(expr "$2" : "^[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*") 428 min2=$(expr "$2" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)\..*") 429 sec2=$(expr "$2" : "^[^.]*\.[^.]*\.[^.]*\.[^.]*\.[^.]*\.\([^.]*\)") 430 431 # calculate seconds since 1970.01.01.00.00.00 432 t1=`get_abstime $year1 $month1 $day1 $hour1 $min1 $sec1` 433 t2=`get_abstime $year2 $month2 $day2 $hour2 $min2 $sec2` 434 435 # print difference 436 expr $t1 - $t2 437 } 438 439 postrun_runq() { 440 cd $SPOOLDIR 441 IFS=' 442 ' 443 timeleft=0 444 postrun_lock 445 all_jobs=`/bin/ls -1 *.ctrl | /bin/sort -n` 446 for job in $all_jobs; do 447 test -f "$job" || continue 448 postrun_defaults 449 while read var val; do 450 case "$var" in 451 pkginst: ) 452 postrun_pkginst="$val" 453 ;; 454 submit_time: ) 455 postrun_submit_time="$val" 456 ;; 457 resubmit_time: ) 458 ;; 459 uniq_command: ) 460 postrun_is_uniq="$val" 461 ;; 462 uniq_time: ) 463 postrun_uniq_time="$val" 464 ;; 465 uniq_timeout: ) 466 postrun_uniq_timeout="$val" 467 ;; 468 background: ) 469 postrun_bg_job="$val" 470 ;; 471 user: ) 472 postrun_user="$val" 473 ;; 474 class: ) 475 postrun_job_class="$val" 476 ;; 477 * ) 478 echo "postrun: WARNING: invalid setting in $job: $var" 479 ;; 480 esac 481 done < $job 482 postrun_command_file=$SPOOLDIR/`basename $job .ctrl`.cmd 483 postrun_job_number=`basename $job .ctrl` 484 if [ $postrun_ignore_timeout = no ]; then 485 # if it's a uniq job, check if it timed out 486 if [ "x$postrun_is_uniq" = xyes ]; then 487 # calculate time difference (seconds) 488 tdiff=$(get_timediff $(date +%Y.%m.%d.%H.%M.%S) \ 489 $postrun_uniq_time) 490 timeout_sec=$((postrun_uniq_timeout * 60)) 491 if [ $tdiff -ge $timeout_sec ]; then 492 postrun_run_command 493 rm -f $job 494 else 495 # try again in at least $tdiff sec time 496 tl=$(($tdiff / 60 + 1)) 497 if [ $tl -gt $timeleft ]; then 498 timeleft=$tl 499 fi 500 fi 501 else 502 postrun_run_command 503 rm -f $job 504 fi 505 else 506 # ignore timeout, just run the job 507 postrun_run_command 508 rm -f $job 509 fi 510 done 511 if [ $timeleft -gt 0 ]; then 512 echo "$MYDIR/postrun -q" | 513 at now "+${timeleft}minutes" \ 514 > /dev/null 2>&1 515 fi 516 postrun_unlock 517 exit 0 518 } 519 520 postrun_defaults 521 exitval=0 522 523 postrun_ignore_timeout=no 524 if [ $# = 1 -a "x$1" = 'x-qf' ]; then 525 # postrun-runq mode (ignore timeout for uniq jobs, since this is 526 # expected to be run at system boot) 527 postrun_ignore_timeout=yes 528 postrun_runq 529 exit 1 530 fi 531 532 if [ $# = 1 -a "x$1" = 'x-q' ]; then 533 # postrun-runq mode, to be run from at(1) 534 postrun_runq 535 exit 1 536 fi 537 538 # process the command line 539 while [ $# -gt 0 ]; do 540 case "$1" in 541 -h|-\?|--help) 542 usage 543 ;; 544 -u|--uniq) 545 postrun_is_uniq=yes 546 ;; 547 -b|--bg) 548 postrun_bg_job=yes 549 ;; 550 -t|--timeout) 551 opt="$1" 552 if [ $# == 0 ]; then 553 echo "postrun: error: argument expected after $opt" 554 exit 1 555 fi 556 shift 557 timeout=$1 558 if ! is_number "$timeout"; then 559 echo "postrun: error: interger number expected after $opt (found \"$timeout\")" 560 exit 1 561 fi 562 postrun_uniq_timeout=$timeout 563 ;; 564 -i|--ignore) 565 postrun_no_spool=yes 566 ;; 567 -f) 568 opt="$1" 569 if [ $# == 0 ]; then 570 echo "postrun: error: argument expected after $opt" 571 exit 1 572 fi 573 shift 574 postrun_command_file="$1" 575 ;; 576 -c) 577 opt="$1" 578 if [ $# == 0 ]; then 579 echo "postrun: error: argument expected after $opt" 580 exit 1 581 fi 582 shift 583 postrun_job_class="$1" 584 ;; 585 -a) 586 postrun_alt_root_okay=yes 587 ;; 588 --) 589 break 590 ;; 591 *) 592 echo "postrun: error: invalid argument: $1" 593 exit 1 594 ;; 595 esac 596 shift 597 done 598 599 check_alt_root_okay () { 600 if [ "x$PKG_INSTALL_ROOT" = x -o "x$PKG_INSTALL_ROOT" = x/ \ 601 -o "x$postrun_alt_root_okay" = xno ]; then 602 return 1 603 fi 604 # need to verify if the architecture and Solaris minor version 605 # of / is equal to that of $PKG_INSTALL_ROOT, otherwise 606 # running the script is not okay 607 pkginfo -q SUNWsolnm || return 1 608 609 this_solnm_pkginfo="`pkginfo -R / -l SUNWsolnm 2>/dev/null`" 610 alt_root_solnm_pkginfo="`pkginfo -R $PKG_INSTALL_ROOT -l SUNWsolnm 2>/dev/null`" 611 612 this_sol_minor=`echo "$this_solnm_pkginfo" |grep VERSION| sed -e 's/^.*VERSION: *\([0-9]*\),REV=.*/\1/'` 613 alt_root_sol_minor=`echo "$alt_root_solnm_pkginfo" |grep VERSION| sed -e 's/^.*VERSION: *\([0-9]*\),REV=.*/\1/'` 614 if [ "x$this_sol_minor" != "x$alt_root_sol_minor" ]; then 615 postrun_debug "/ is Solaris $this_sol_minor, $PKG_INSTALL_ROOT is Solaris $alt_root_sol_minor" 616 return 1 617 fi 618 this_sol_arch=`echo "$this_solnm_pkginfo" |grep ARCH|sed -e 's/^.*ARCH: *\([a-z0-9]*\).*/\1/'` 619 alt_root_sol_arch=`echo "$alt_root_solnm_pkginfo" |grep ARCH|sed -e 's/^.*ARCH: *\([a-z0-9]*\).*/\1/'` 620 if [ "x$this_sol_arch" != "x$alt_root_sol_arch" ]; then 621 postrun_debug "/ is $this_sol_arch, $PKG_INSTALL_ROOT is $alt_root_sol_arch" 622 return 1 623 fi 624 return 0 625 } 626 627 check_alt_root_okay || postrun_alt_root_okay=no 628 629 if [ "x$postrun_command_file" = x ]; then 630 # save the standard input in a temporary file 631 tmp_cmd_file=`postrun_mktemp /tmp/postrun.cmd.XXXX` 632 cat > $tmp_cmd_file 633 postrun_command_file=$tmp_cmd_file 634 fi 635 636 if [ "$LUBIN" != "" ]; then 637 # 638 # Live Upgrade. Unsafe to run the command now. 639 # Put into spool and defer to next boot. 640 # 641 postrun_spool_command "${@}" 642 elif [ "$PKG_INSTALL_ROOT" != "" -a "$PKG_INSTALL_ROOT" != "/" -a \ 643 "x$postrun_alt_root_okay" != xyes ]; then 644 # 645 # Installation to an alternate root directory 646 # Put command into spool and defer to next boot. 647 # 648 postrun_spool_command "${@}" 649 else 650 # 651 # Local package install. Everything's shiny happy, 652 # safe to run the command right now 653 # 654 # Note: for alt_root_okay jobs, -u only applies to the case 655 # when we have to spool the job 656 if [ x$postrun_is_uniq = xyes -a x$postrun_alt_root_okay != xyes ]; then 657 # don't run the command yet in case the same command is requested 658 # within the next postrun_uniq_timeout minutes 659 postrun_spool_command "${@}" && { 660 echo "$MYDIR/postrun -q" | \ 661 at now "+${postrun_uniq_timeout}minutes" > /dev/null 2>&1 662 } 663 else 664 postrun_debug "Executing commands immediately" 665 postrun_run_command "${@}" 666 # do not delete the tmp_cmd_file because it's the only copy of the 667 # commands (since the job is not spooled) 668 tmp_cmd_file='' 669 fi 670 fi 671 672 if [ "x$tmp_cmd_file" != x ]; then 673 rm -f $tmp_cmd_file 674 fi 675 676 exit $exitval 677