1 #!/bin/ksh 2 # 3 # CDDL HEADER START 4 # 5 # The contents of this file are subject to the terms of the 6 # Common Development and Distribution License (the "License"). 7 # You may not use this file except in compliance with the License. 8 # 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 # or http://www.opensolaris.org/os/licensing. 11 # See the License for the specific language governing permissions 12 # and limitations under the License. 13 # 14 # When distributing Covered Code, include this CDDL HEADER in each 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 # If applicable, add the following below this CDDL HEADER, with the 17 # fields enclosed by brackets "[]" replaced with your own identifying 18 # information: Portions Copyright [yyyy] [name of copyright owner] 19 # 20 # CDDL HEADER END 21 # 22 # 23 # Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. 24 # 25 # Author: Jeff Bonwick 26 # 27 # Please report any bugs to bonwick@eng. 28 # 29 # How Install works: 30 # 31 # Install performs the following steps: 32 # 33 # 1. Get the list of modules, configuration files, and links 34 # that are desired. 35 # 36 # 2. Create the requested subset of /kernel in Install's temp space 37 # (/tmp/Install.username by default.) 38 # 39 # 3. Create a tar file (/tmp/Install.username/Install.tar) based on (3). 40 # 41 # 4. If -n was specified, exit. If a target was specified using -T, 42 # rcp the tarfile to the target and exit. If a target was specified 43 # using -t, rsh to the target machine and untar the tarfile in the 44 # target directory. 45 # 46 # If any of these steps fail, Install will give you an error message and, 47 # in most cases, suggest corrective measures. Then, you can recover the 48 # install with "Install -R". (This is not required; it's just faster than 49 # starting from scratch.) 50 # 51 # One final comment: Unfortunately, tar and I disagree on what 52 # constitutes a fatal error. (tar -x will exit 0 even if it can't write 53 # anything in the current directory.) Thus, I am reduced to grepping stderr 54 # for (what I consider) fatal and nonfatal error messages. If you run into 55 # a situation where this doesn't behave the way you think it should (either 56 # an "Install failed" message after a successful install, or an "Install 57 # complete" message after it bombs), please let me know. 58 59 # 60 # The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout 61 # under certain circumstances, which can really screw things up; unset it. 62 # 63 unset CDPATH 64 65 INSTALL=`basename $0` 66 DOT=`pwd` 67 68 TRAILER="Install.$LOGNAME" 69 INSTALL_STATE=${INSTALL_STATE-$HOME/.Install.state} 70 export INSTALL_STATE 71 INSTALL_DIR=${INSTALL_DIR-/tmp/$TRAILER} 72 if [ "`basename $INSTALL_DIR`" != "$TRAILER" ]; then 73 INSTALL_DIR="$INSTALL_DIR/$TRAILER" 74 fi 75 export INSTALL_DIR 76 INSTALL_LIB=${INSTALL_LIB-$HOME/LibInstall} 77 export INSTALL_LIB 78 INSTALL_RC=${INSTALL_RC-$HOME/.Installrc} 79 export INSTALL_RC 80 INSTALL_CP=${INSTALL_CP-"cp -p"} 81 export INSTALL_CP 82 INSTALL_RCP=${INSTALL_RCP-"rcp -p"} 83 export INSTALL_RCP 84 85 STATE=0 86 87 DEFAULT_OPTIONS="-naq" 88 GLOM=no 89 GLOMNAME=kernel 90 IMPL="default" 91 WANT32="yes" 92 WANT64="yes" 93 94 modlist=/tmp/modlist$$ 95 # dummy directory for make state files. 96 modstatedir=/tmp/modstate$$ 97 98 trap 'fail "User Interrupt" "You can resume by typing \"$INSTALL -R\""' 1 2 3 15 99 100 function usage { 101 echo "" 102 echo $1 103 echo ' 104 Usage: Install [ -w workspace ] 105 [ -s srcdir (default: usr/src/uts) ] 106 [ -k karch (e.g. sun4u; required if not deducible from pwd) ] 107 [ -t target (extract tar file on target, e.g. user@machine:/) ] 108 [ -T target (copy tar file to target, e.g. user@machine:/tmp) ] 109 [ -n (no target, just create tar file in /tmp (default)) ] 110 [ -u (install unix only) ] 111 [ -m (install modules only) ] 112 [ -a (install everything, i.e. unix + modules (default)) ] 113 [ -v (verbose output) ] 114 [ -V (REALLY verbose output) ] 115 [ -q (quiet (default)) ] 116 [ -c (clean up (remove temp files) when done (default) ] 117 [ -p (preserve temp files -- useful for debugging) ] 118 [ -L (library create: put tarfile in $INSTALL_LIB/env.karch) ] 119 [ -l lib (library extract: use $INSTALL_LIB/lib as source) ] 120 [ -D libdir (default: $HOME/LibInstall) ] 121 [ -d tempdir (Install work area (default: /tmp)) ] 122 [ -G glomname (put all files under platform/karch/glomname) ] 123 [ -i impl (e.g. sunfire; recommended with -G) ] 124 [ -x (update /etc/name_to_major et al) ] 125 [ -X (do not update /etc/name_to_major et al (default)) ] 126 [ -P (update /etc/path_to_inst -- generally not advisable) ] 127 [ -h (help -- prints this message) ] 128 [ -R (recover a previous Install) ] 129 [ -o objdir (object directory - either obj or debug (the default)) ] 130 [ -K (do not copy kmdb) ] 131 [ -3 32-bit modules only ] 132 [ -6 64-bit modules only ] 133 [ list of modules to install ] 134 135 For full details: 136 137 man -M /ws/on297-gate/public/docs Install 138 ' 139 exit 1 140 } 141 142 # 143 # Save the current state of Install 144 # 145 146 function save_state { 147 rm -f $INSTALL_STATE 148 (echo "# State of previous Install 149 TARGET=$TARGET 150 ENV_PATH=$ENV_PATH 151 ENV_NAME=$ENV_NAME 152 KARCH=$KARCH 153 UTS=$UTS 154 INSTALL_DIR=$INSTALL_DIR 155 INSTALL_LIB=$INSTALL_LIB 156 IMODE=$IMODE 157 LIBCREATE=$LIBCREATE 158 LIBSRC=$LIBSRC 159 VERBOSE=$VERBOSE 160 CLEANUP=$CLEANUP 161 GLOM=$GLOM 162 GLOMNAME=$GLOMNAME 163 KMDB=$KMDB 164 files='$files' 165 STATE=$STATE" >$INSTALL_STATE) || verbose "Warning: cannot save state" 166 } 167 168 # 169 # Restore the previous state of Install 170 # 171 172 function restore_state { 173 test -s $INSTALL_STATE || fail "Can't find $INSTALL_STATE" 174 eval "`cat $INSTALL_STATE`" 175 } 176 177 # 178 # Install failed -- print error messages and exit 2 179 # 180 181 function fail { 182 save_state 183 # 184 # We might have gotten here via a trap. So wait for any 185 # children (especially "make modlist") to exit before giving 186 # the error message or cleaning up. 187 # 188 wait 189 while [ $# -gt 0 ] 190 do 191 echo $1 192 shift 193 done 194 rm -rf $modstatedir 195 rm -f $modlist 196 echo "Install failed" 197 exit 2 198 } 199 200 # 201 # Echo a string in verbose mode only 202 # 203 204 function verbose { 205 test "$VERBOSE" != "q" && echo $1 206 } 207 208 # 209 # hack for tmpfs bug -- remove files gradually 210 # 211 212 function remove_dir { 213 test -d $1 || return 214 local_dot=`pwd` 215 cd $1 216 touch foo 217 rm -f `find . -type f -print` 218 cd $local_dot 219 rm -rf $1 220 } 221 222 # 223 # Create a directory if it doesn't already exist. 224 # mkdir will provide an error message, so don't provide an additional 225 # message. 226 # 227 228 function tstmkdir { 229 [ -d $1 ] || mkdir -p $1 || fail 230 } 231 232 # 233 # Patch up target directories for glommed kernel. 234 # usage: fixglom listfile glomname 235 # 236 237 function fixglom { 238 nawk \ 239 -v glomname=$2 \ 240 -v karch=$KARCH ' 241 $1 == "MOD" || $1 == "SYMLINK" { 242 sub(/^platform.*kernel/, "platform/" karch "/" glomname, $4) 243 sub(/^kernel/, "platform/" karch "/" glomname, $4) 244 sub(/^usr.kernel/, "platform/" karch "/" glomname, $4) 245 print 246 } 247 $1 == "LINK" { 248 sub(/^platform.*kernel/, "platform/" karch "/" glomname, $3) 249 sub(/^kernel/, "platform/" karch "/" glomname, $3) 250 sub(/^usr.kernel/, "platform/" karch "/" glomname, $3) 251 sub(/^platform.*kernel/, "platform/" karch "/" glomname, $5) 252 sub(/^kernel/, "platform/" karch "/" glomname, $5) 253 sub(/^usr.kernel/, "platform/" karch "/" glomname, $5) 254 print 255 } 256 $1 == "CONF" { 257 sub(/^platform.*kernel/, "platform/" karch "/" glomname, $3) 258 sub(/^kernel/, "platform/" karch "/" glomname, $3) 259 sub(/^usr.kernel/, "platform/" karch "/" glomname, $3) 260 print 261 } 262 ' $1 > $1.new 263 mv $1.new $1 264 } 265 266 # 267 # Filter out implementation-specific modules, unless that 268 # implementation was requested by the user. 269 # usage: filtimpl listfile implname 270 # 271 272 function filtimpl { 273 nawk \ 274 -v impl=$2 ' 275 $1 == "MOD" || $1 == "SYMLINK" { 276 if ($6 == "all" || $6 == impl) 277 print 278 } 279 $1 == "CONF" { 280 if ($5 == "all" || $5 == impl) 281 print 282 } 283 $1 == "LINK" { 284 if ($7 == "all" || $7 == impl) 285 print 286 } 287 ' $1 > $1.new 288 mv $1.new $1 289 } 290 291 # 292 # Filter the module list to match the user's request. 293 # Usage: filtmod listfile modules 294 # 295 function filtmod { 296 nawk -v reqstring="$2" ' 297 function modmatch(modname) { 298 if (reqstring == "All") { 299 return (1) 300 } else if (reqstring == "Modules") { 301 if (modname != "unix" && modname != "genunix") 302 return (1) 303 } else { 304 if (modname in reqmods) 305 return (1) 306 } 307 return (0) 308 } 309 BEGIN { 310 # 311 # The split call creates indexes 1, 2, 3, ... We want 312 # the module names as indexes. 313 # 314 split(reqstring, tmpmods) 315 for (i in tmpmods) 316 reqmods[tmpmods[i]] = 1 317 } 318 $1 == "MOD" { 319 if (modmatch($3)) 320 print 321 } 322 $1 == "CONF" { 323 if (modmatch($6)) 324 print 325 } 326 $1 == "SYMLINK" { 327 if (modmatch($7)) 328 print 329 } 330 $1 == "LINK" { 331 if (modmatch($4)) 332 print 333 } 334 ' $1 > $1.new 335 mv $1.new $1 336 } 337 338 # 339 # Copy a module, or create a link, as needed. 340 # 341 342 function copymod { 343 case $1 in 344 MOD) 345 targdir=$INSTALL_FILES/$4 346 tstmkdir $targdir 347 target=$targdir/$3 348 verbose "$INSTALL_CP $2/${OBJD}$5/$3 $target" 349 $INSTALL_CP $2/${OBJD}$5/$3 $target || \ 350 fail "can't create $target" 351 ;; 352 SYMLINK) 353 targdir=$INSTALL_FILES/$4 354 tstmkdir $targdir 355 target=$targdir/$5 356 rm -f $target 357 verbose "ln -s $3 $target" 358 ln -s $3 $target || fail "can't create $target" 359 ;; 360 LINK) 361 targdir=$INSTALL_FILES/$5 362 tstmkdir $targdir 363 target=$targdir/$6 364 rm -f $target 365 verbose "ln $INSTALL_FILES/$3/$4 $target" 366 ln $INSTALL_FILES/$3/$4 $target || fail "can't create $target" 367 ;; 368 CONF) 369 target=$INSTALL_FILES/$3 370 tstmkdir `dirname $target` 371 conffile=`basename $3` 372 verbose "$INSTALL_CP $4/$conffile $target" 373 $INSTALL_CP $4/$conffile $target 374 ;; 375 *) 376 fail "unrecognized modlist entry: $*" 377 ;; 378 esac 379 } 380 381 # Sanity-check the given module list. 382 function check_modlist { 383 nawk ' 384 BEGIN { 385 nfields["MOD"] = 6 386 nfields["CONF"] = 6 387 nfields["LINK"] = 7 388 nfields["SYMLINK"] = 7 389 } 390 { 391 # This also catches unknown tags. 392 if (nfields[$1] != NF) { 393 print "error: invalid modlist record:" 394 print $0 395 print "expected", nfields[$1], "fields, found", NF 396 status=1 397 } 398 } 399 END { 400 exit status 401 } 402 ' $1 || fail "Errors in kernel module list" 403 } 404 405 # 406 # Copy kernel modules to $INSTALL_DIR 407 # 408 409 function copy_kernel { 410 411 case $KARCH in 412 sun4*) ISA=sparc; MACH=sparc ;; 413 i86*) ISA=intel; MACH=i386 ;; 414 *) fail "${KARCH}: invalid kernel architecture";; 415 esac 416 export MACH 417 418 if [ "$GLOM" = "no" ]; then 419 verbose "Source = $UTS, ISA = $ISA, kernel = $KARCH" 420 else 421 verbose "Source = $UTS, ISA = $ISA, kernel = $KARCH, impl = $IMPL" 422 fi 423 424 test -d $KARCH || fail "${KARCH}: invalid kernel architecture" 425 test -d $ISA || fail "${ISA}: invalid instruction set architecture" 426 427 tstmkdir $INSTALL_FILES 428 rm -rf $modstatedir 429 tstmkdir $modstatedir 430 export MODSTATE=$modstatedir/state 431 432 # 433 # Figure out which "make" to use. dmake is faster than serial 434 # make, but dmake 7.3 has a bug that causes it to lose log 435 # output, which means the modlist might be incomplete. 436 # 437 make=dmake 438 dmvers=`$make -version` 439 if [ $? -ne 0 ]; then 440 make=/usr/ccs/bin/make 441 elif [[ $dmvers = *Distributed?Make?7.3* ]]; then 442 unset make 443 searchpath="/ws/onnv-tools/SUNWspro/SOS10/bin 444 /opt/SUNWspro/SOS10/bin 445 /opt/SUNWspro/bin" 446 for dmpath in $searchpath; do 447 verbose "Trying $dmpath/dmake" 448 if [ -x $dmpath/dmake ]; then 449 dmvers=`$dmpath/dmake -version` 450 if [[ $dmvers != *Distributed?Make?7.3* ]]; then 451 make="$dmpath/dmake" 452 break; 453 fi 454 fi 455 done 456 if [ -z $make ]; then 457 make=/usr/ccs/bin/make 458 echo "Warning: dmake 7.3 doesn't work with Install;" \ 459 "using $make" 460 fi 461 fi 462 463 # 464 # Get a list of all modules, configuration files, and links 465 # that we might want to install. 466 # 467 verbose "Building module list..." 468 (cd $KARCH; MAKEFLAGS=e $make -K $MODSTATE modlist.karch) | \ 469 egrep "^MOD|^CONF|^LINK|^SYMLINK" > $modlist 470 [ "$VERBOSE" = "V" ] && cat $modlist 471 check_modlist $modlist 472 if [ "$GLOM" = "yes" ]; then 473 fixglom $modlist $GLOMNAME 474 filtimpl $modlist $IMPL 475 fi 476 if [[ -n "$files" && "$files" != All ]]; then 477 filtmod $modlist "$files" 478 fi 479 480 # 481 # Copy modules and create links. For architectures with both 482 # 32- and 64-bit modules, we'll likely have duplicate 483 # configuration files, so do those after filtering out the 484 # duplicates. 485 # 486 verbose "Copying files to ${INSTALL_FILES}..." 487 488 # 489 # The IFS is reset to the newline character so we can buffer the 490 # output of grep without piping it directly to copymod, otherwise 491 # if fail() is called, then it will deadlock in fail()'s wait call 492 # 493 OIFS="$IFS" 494 IFS=" 495 " 496 set -- `grep -v "^CONF" $modlist`; 497 IFS="$OIFS" 498 for onemod in "$@"; do 499 copymod $onemod 500 done 501 502 OIFS="$IFS" 503 IFS=" 504 " 505 set -- `grep "^CONF" $modlist | sort | uniq`; 506 IFS="$OIFS" 507 for onemod in "$@"; do 508 copymod $onemod 509 done 510 511 # 512 # Add the glommed kernel name to the root archive 513 # 514 if [[ $GLOM == "yes" ]]; 515 then 516 filelist="$INSTALL_FILES/etc/boot/solaris/filelist.ramdisk" 517 mkdir -p `dirname $filelist` 518 echo "platform/$KARCH/$GLOMNAME" >$filelist 519 fi 520 521 STATE=1 # all kernel modules copied correctly 522 save_state 523 } 524 525 function kmdb_copy { 526 typeset src="$1" 527 typeset destdir="$2" 528 529 if [[ ! -d $dest ]] ; then 530 [[ "$VERBOSE" != "q" ]] && echo "mkdir -p $destdir" 531 532 mkdir -p $destdir || fail "failed to create $destdir" 533 fi 534 535 [[ "$VERBOSE" != "q" ]] && echo "cp $src $destdir" 536 537 cp $src $destdir || fail "failed to copy $src to $destdir" 538 } 539 540 function kmdb_copy_machkmods { 541 typeset modbase="$1" 542 typeset destdir="$2" 543 typeset dir= 544 typeset kmod= 545 546 [[ ! -d $modbase ]] && return 547 548 for dir in $(find $modbase -name kmod) ; do 549 set -- $(echo $dir |tr '/' ' ') 550 551 [[ $# -lt 2 ]] && fail "invalid mach kmod dir $dir" 552 553 shift $(($# - 2)) 554 kmod=$1 555 556 [[ ! -f $dir/$kmod ]] && continue 557 558 kmdb_copy $dir/$kmod $destdir 559 done 560 } 561 562 function kmdb_copy_karchkmods { 563 typeset modbase="$1" 564 typeset destdir="$2" 565 typeset bitdir="$3" 566 typeset dir= 567 typeset kmod= 568 typeset karch= 569 570 [[ ! -d $modbase ]] && return 571 572 for dir in $(find $modbase -name kmod) ; do 573 set -- $(echo $dir | tr '/' ' ') 574 575 [[ $# -lt 3 ]] && fail "invalid karch kmod dir $dir" 576 577 shift $(($# - 3)) 578 kmod=$1 579 bdir=$2 580 581 [[ $bdir != $bitdir ]] && continue 582 [[ ! -f $dir/$1 ]] && continue 583 584 kmdb_copy $dir/$kmod $destdir 585 done 586 } 587 588 function kmdb_copy_kmdbmod { 589 typeset kmdbpath="$1" 590 typeset destdir="$2" 591 592 [[ ! -f $kmdbpath ]] && return 1 593 594 kmdb_copy $kmdbpath $destdir 595 596 return 0 597 } 598 599 function copy_kmdb { 600 typeset kmdbtgtdir=$INSTALL_FILES/platform/$KARCH/$GLOMNAME/misc 601 typeset bitdirs= 602 typeset isadir= 603 typeset b64srcdir= 604 typeset b64tgtdir= 605 typeset b32srcdir= 606 typeset b32tgtdir= 607 typeset machdir= 608 typeset platdir= 609 610 if [[ $KMDB = "no" || ! -d $SRC/cmd/mdb ]] ; then 611 # The kmdb copy was suppressed or the workspace doesn't contain 612 # the mdb subtree. Either way, there's nothing to do. 613 STATE=2 614 save_state 615 return 616 fi 617 618 if [[ $(mach) = "i386" ]] ; then 619 isadir="intel" 620 b64srcdir="amd64" 621 b64tgtdir="amd64" 622 b32srcdir="ia32" 623 b32tgtdir="." 624 else 625 isadir="sparc" 626 b64srcdir="v9" 627 b64tgtdir="sparcv9" 628 b32srcdir="v7" 629 b32tgtdir="." 630 fi 631 632 typeset foundkmdb=no 633 typeset kmdbpath= 634 typeset destdir= 635 636 platdir=$INSTALL_FILES/platform/$KARCH/$GLOMNAME 637 if [[ $GLOM = "yes" ]] ; then 638 machdir=$platdir 639 else 640 machdir=$INSTALL_FILES/kernel 641 fi 642 643 srctrees=$SRC 644 if [[ -d $SRC/../closed && "$CLOSED_IS_PRESENT" != no ]]; then 645 srctrees="$srctrees $SRC/../closed" 646 fi 647 if [[ $WANT64 = "yes" ]] ; then 648 # kmdbmod for sparc and x86 are built and installed 649 # in different places 650 if [[ $(mach) = "i386" ]] ; then 651 kmdbpath=$SRC/cmd/mdb/$isadir/$b64srcdir/kmdb/kmdbmod 652 destdir=$machdir/misc/$b64tgtdir 653 else 654 kmdbpath=$SRC/cmd/mdb/$KARCH/$b64srcdir/kmdb/kmdbmod 655 destdir=$platdir/misc/$b64tgtdir 656 fi 657 658 if kmdb_copy_kmdbmod $kmdbpath $destdir ; then 659 foundkmdb="yes" 660 661 for tree in $srctrees; do 662 kmdb_copy_machkmods \ 663 $tree/cmd/mdb/$isadir/$b64srcdir \ 664 $machdir/kmdb/$b64tgtdir 665 kmdb_copy_karchkmods $tree/cmd/mdb/$KARCH \ 666 $platdir/kmdb/$b64tgtdir $b64srcdir 667 done 668 fi 669 fi 670 671 if [[ $WANT32 = "yes" ]] ; then 672 kmdbpath=$SRC/cmd/mdb/$isadir/$b32srcdir/kmdb/kmdbmod 673 destdir=$machdir/misc/$b32tgtdir 674 675 if kmdb_copy_kmdbmod $kmdbpath $destdir ; then 676 foundkmdb="yes" 677 678 for tree in $srctrees; do 679 kmdb_copy_machkmods \ 680 $tree/cmd/mdb/$isadir/$b32srcdir \ 681 $machdir/kmdb/$b32tgtdir 682 kmdb_copy_karchkmods $tree/cmd/mdb/$KARCH \ 683 $platdir/kmdb/$b32tgtdir $b32srcdir 684 done 685 fi 686 fi 687 688 # A kmdb-less workspace isn't fatal, but it is potentially problematic, 689 # as the changes made to uts may have altered something upon which kmdb 690 # depends. We will therefore remind the user that they haven't built it 691 # yet. 692 if [[ $foundkmdb != "yes" ]] ; then 693 echo "WARNING: kmdb isn't built, and won't be included" 694 fi 695 696 STATE=2 697 save_state 698 return 699 } 700 701 # 702 # Make tarfile 703 # 704 705 function make_tarfile { 706 echo "Creating tarfile $TARFILE" 707 test -d $INSTALL_FILES || fail "Can't find $INSTALL_FILES" 708 cd $INSTALL_FILES 709 rm -f $TARFILE files 710 711 # We don't want to change the permissions or ownership of pre-existing 712 # directories on the target machine, so we're going to take care to 713 # avoid including directories in the tarfile. On extraction, tar won't 714 # modify pre-existing directories, and will create non-existent ones as 715 # the user doing the extraction. 716 find . ! -type d -print |fgrep -vx './files' >files 717 tar cf $TARFILE -I files || fail "Couldn't create tarfile $TARFILE" 718 STATE=3 719 } 720 721 # 722 # Routines to copy files to the target machine 723 # 724 725 function remote_fail { 726 fail "" "$1" "" \ 727 "Make sure that $TARGET_MACHINE is up." \ 728 "Check .rhosts in the home directory of user $TARGET_USER on $TARGET_MACHINE." \ 729 "Check /etc/hosts.equiv, /etc/passwd, and /etc/shadow." \ 730 "Change permissions on $TARGET_MACHINE as necessary." \ 731 "Then, use \"$INSTALL -R\" to resume the install." "" 732 } 733 734 function remote_install { 735 if [ "$IMODE" = "n" ]; then 736 STATE=4 737 return 0 738 fi 739 test -s $TARFILE || fail "$TARFILE missing or empty" 740 verbose "Installing system on $TARGET" 741 test -d $INSTALL_DIR || fail "Can't find $INSTALL_DIR" 742 cd $INSTALL_DIR 743 rm -f errors fatal nonfatal 744 if [ "$IMODE" = "T" ]; then 745 EMESG="Can't rcp to $TARGET" 746 touch errors 747 sh -e${SHV}c "$INSTALL_RCP $TARFILE $TARGET/Install.tar" 748 else 749 EMESG="Can't rsh to $TARGET_MACHINE" 750 rsh -l $TARGET_USER $TARGET_MACHINE \ 751 "(cd $TARGET_DIR; /usr/bin/tar x${V}f -)" \ 752 <$TARFILE 2>errors 753 fi 754 test $? -ne 0 && remote_fail "$EMESG" 755 cd $INSTALL_DIR 756 egrep "set time|warning|blocksize" errors >nonfatal 757 egrep -v "set time|warning|blocksize" errors >fatal 758 if [ -s fatal ]; then 759 echo "Fatal errors from rsh:" 760 cat fatal 761 remote_fail "Can't install on $TARGET_MACHINE" 762 fi 763 if [ -s nonfatal -a "$VERBOSE" != "q" ]; then 764 echo "Non-fatal errors from rsh:" 765 cat nonfatal 766 fi 767 rm -f fatal nonfatal errors 768 test "$IMODE" = "T" && echo "Files can be extracted on \ 769 $TARGET_MACHINE using 'tar xvf $TARGET_DIR/Install.tar'" 770 STATE=4 771 } 772 773 function okexit { 774 cd /tmp 775 test "$CLEANUP" = c && remove_dir $INSTALL_DIR 776 save_state 777 rm -rf $modstatedir 778 rm -f $modlist 779 verbose "Install complete" 780 exit 0 781 } 782 783 # 784 # Process options 785 # 786 787 RCOPTS="" 788 LIBCREATE="no" 789 LIBSRC="" 790 ENV_PATH=$CODEMGR_WS 791 OBJD="debug" 792 KMDB="yes" 793 794 test -s $INSTALL_RC && RCOPTS=`cat $INSTALL_RC` 795 set $INSTALL $DEFAULT_OPTIONS $RCOPTS $* 796 shift 797 798 while getopts acd:D:G:hi:k:Kl:Lmno:pPqRs:t:T:uvVw:xX36 opt 799 do 800 case $opt in 801 w) ENV_PATH="$OPTARG"; SRC="$ENV_PATH/usr/src";; 802 s) UTS="$OPTARG";; 803 k) KARCH="$OPTARG";; 804 t|T) TARGET="$OPTARG"; IMODE=$opt; CLEANUP="c";; 805 n) TARGET=""; IMODE="n"; CLEANUP="p";; 806 u) files="unix genunix";; 807 m) files="Modules";; 808 a) files="All";; 809 v|V|q) VERBOSE=$opt;; 810 c|p) CLEANUP=$opt;; 811 L) LIBCREATE="yes"; CLEANUP="c";; 812 l) LIBSRC="$OPTARG";; 813 D) INSTALL_LIB="$OPTARG";; 814 d) INSTALL_DIR="$OPTARG/$TRAILER";; 815 G) GLOM=yes; GLOMNAME="$OPTARG";; 816 P|X|x) echo "-$opt is obsolete; ignored";; 817 h) usage "${INSTALL}: installs unix and modules";; 818 R) x=$OPTIND; restore_state; OPTIND=$x;; 819 i) IMPL="$OPTARG";; 820 o) OBJD="$OPTARG";; 821 K) KMDB="no";; 822 3) WANT64="no";; 823 6) WANT32="no";; 824 \?) usage "Illegal option";; 825 esac 826 done 827 shift `expr $OPTIND - 1` 828 829 ENV_NAME=`basename $ENV_PATH` 830 831 # 832 # The rest of the command line is a list of individual files to copy. 833 # If non-null, this list overrides the -uma options. 834 # 835 836 if [[ $# -gt 0 ]] ; then 837 files="$*" 838 KMDB="no" 839 fi 840 841 case "$VERBOSE" in 842 v) V="v"; SHV="x";; 843 V) V="v"; SHV="x"; set -x;; 844 q) V=""; SHV="";; 845 esac 846 847 # 848 # Create temp directory for Install's files 849 # 850 851 tstmkdir $INSTALL_DIR 852 853 TARFILE=$INSTALL_DIR/Install.${KARCH}.tar 854 INSTALL_FILES=$INSTALL_DIR/$KARCH 855 856 # 857 # Extract the target machine and target directory from a target of the 858 # form [user@]machine:/dir . 859 # 860 861 if [ "$IMODE" != "n" ]; then 862 eval `echo $TARGET | nawk -F':' '{ 863 if (NF != 2 || !length($1) || !length($2)) 864 print "usage \"Invalid target\"" 865 m = $1; d = $2 866 if ($1 ~ /@/) { 867 k = split($1, f, "@"); 868 if (k != 2 || !length(f[1]) || !length (f[2])) 869 print "usage \"Invalid target\"" 870 u = f[1]; m = f[2] 871 } 872 print "TARGET_USER=" u ";" 873 print "TARGET_MACHINE=" m ";" 874 print "TARGET_DIR=" d ";" 875 }'` 876 if [ -z "$TARGET_USER" ]; then 877 TARGET_USER=$LOGNAME 878 fi 879 fi 880 881 # 882 # Allow the use of library source or target for the install 883 # 884 885 if [ -n "$LIBSRC" ]; then 886 LIBSRC="`basename $LIBSRC .tar`.tar" 887 TARFILE=$INSTALL_LIB/$LIBSRC 888 test -s $TARFILE || fail "Can't find tarfile $TARFILE" 889 verbose "Installing from library tarfile $TARFILE" 890 STATE=3 891 elif [ "$LIBCREATE" = "yes" ]; then 892 tstmkdir $INSTALL_LIB 893 TARFILE="$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar" 894 fi 895 896 # 897 # The next few lines allow recovery and activation with -R, 898 # and library installs with -l. 899 # 900 901 [[ $STATE -eq 1 ]] && copy_kmdb 902 [[ $STATE -eq 2 ]] && make_tarfile 903 [[ $STATE -eq 3 ]] && remote_install 904 [[ $STATE -eq 4 ]] && okexit 905 906 save_state 907 908 cd $DOT 909 DOTDOT=`cd ..; pwd` 910 911 # 912 # Try to be smart: if DOTDOT ends in uts, then infer UTS and KARCH from DOT 913 # Otherwise, if SRC is set, infer UTS = $SRC/uts. 914 # 915 916 if [ "`basename $DOTDOT`" = "uts" ]; then 917 UTS=$DOTDOT 918 KARCH=`basename $DOT` 919 if [ ! -n "$SRC" ]; then 920 SRC=`dirname $DOTDOT` 921 verbose "Setting SRC to $SRC" 922 fi 923 export SRC 924 fi 925 926 if [ -z "$UTS" -a -n "$SRC" ]; then 927 UTS="${SRC}/uts" 928 test -n "$KARCH" || fail "no karch specified (e.g. -k sun4u)" 929 fi 930 931 if [ "$LIBCREATE" = "yes" ]; then 932 TARFILE=$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar 933 else 934 TARFILE=$INSTALL_DIR/Install.${KARCH}.tar 935 fi 936 INSTALL_FILES=$INSTALL_DIR/$KARCH 937 save_state 938 939 cd $DOT 940 test -z "$UTS" && fail 'Cannot find kernel sources -- $SRC not set' 941 test -d "$UTS" || fail "${UTS}: no such directory" 942 943 # 944 # Convert UTS into an absolute path. 945 # 946 947 cd $UTS 948 UTS=`pwd` 949 950 test "`basename $UTS`" = "uts" || \ 951 verbose "Warning: source path $UTS doesn't end in 'uts'" 952 953 remove_dir $INSTALL_DIR/$KARCH 954 rm -f $TARFILE 955 956 copy_kernel # sets STATE=1 if successful 957 copy_kmdb # sets STATE=2 if successful 958 make_tarfile # sets STATE=3 if successful 959 remote_install # sets STATE=4 if successful 960 961 okexit