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