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# 63unset CDPATH 64 65INSTALL=`basename $0` 66DOT=`pwd` 67 68TRAILER="Install.$LOGNAME" 69INSTALL_STATE=${INSTALL_STATE-$HOME/.Install.state} 70export INSTALL_STATE 71INSTALL_DIR=${INSTALL_DIR-/tmp/$TRAILER} 72if [ "`basename $INSTALL_DIR`" != "$TRAILER" ]; then 73 INSTALL_DIR="$INSTALL_DIR/$TRAILER" 74fi 75export INSTALL_DIR 76INSTALL_LIB=${INSTALL_LIB-$HOME/LibInstall} 77export INSTALL_LIB 78INSTALL_RC=${INSTALL_RC-$HOME/.Installrc} 79export INSTALL_RC 80INSTALL_CP=${INSTALL_CP-"cp -p"} 81export INSTALL_CP 82INSTALL_RCP=${INSTALL_RCP-"rcp -p"} 83export INSTALL_RCP 84 85STATE=0 86 87DEFAULT_OPTIONS="-naq" 88GLOM=no 89GLOMNAME=kernel 90IMPL="default" 91WANT32="yes" 92WANT64="yes" 93 94modlist=/tmp/modlist$$ 95# dummy directory for make state files. 96modstatedir=/tmp/modstate$$ 97 98trap 'fail "User Interrupt" "You can resume by typing \"$INSTALL -R\""' 1 2 3 15 99 100function usage { 101 echo "" 102 echo $1 103 echo ' 104Usage: 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 135For 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 146function save_state { 147 rm -f $INSTALL_STATE 148 (echo "# State of previous Install 149TARGET=$TARGET 150ENV_PATH=$ENV_PATH 151ENV_NAME=$ENV_NAME 152KARCH=$KARCH 153UTS=$UTS 154INSTALL_DIR=$INSTALL_DIR 155INSTALL_LIB=$INSTALL_LIB 156IMODE=$IMODE 157LIBCREATE=$LIBCREATE 158LIBSRC=$LIBSRC 159VERBOSE=$VERBOSE 160CLEANUP=$CLEANUP 161GLOM=$GLOM 162GLOMNAME=$GLOMNAME 163KMDB=$KMDB 164files='$files' 165STATE=$STATE" >$INSTALL_STATE) || verbose "Warning: cannot save state" 166} 167 168# 169# Restore the previous state of Install 170# 171 172function 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 181function 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 204function verbose { 205 test "$VERBOSE" != "q" && echo $1 206} 207 208# 209# hack for tmpfs bug -- remove files gradually 210# 211 212function 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 228function 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 237function 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 272function 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# 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($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# 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 srcdir module targdir size impl; 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# 414 415function copymod { 416 case $1 in 417 MOD) 418 targdir=$INSTALL_FILES/$4 419 tstmkdir $targdir 420 target=$targdir/$3 421 verbose "$INSTALL_CP $2/${OBJD}$5/$3 $target" 422 $INSTALL_CP $2/${OBJD}$5/$3 $target || \ 423 fail "can't create $target" 424 ;; 425 SYMLINK) 426 targdir=$INSTALL_FILES/$4 427 tstmkdir $targdir 428 target=$targdir/$5 429 rm -f $target 430 verbose "ln -s $3 $target" 431 ln -s $3 $target || fail "can't create $target" 432 ;; 433 LINK) 434 targdir=$INSTALL_FILES/$5 435 tstmkdir $targdir 436 target=$targdir/$6 437 rm -f $target 438 verbose "ln $INSTALL_FILES/$3/$4 $target" 439 ln $INSTALL_FILES/$3/$4 $target || fail "can't create $target" 440 ;; 441 CONF) 442 target=$INSTALL_FILES/$3 443 tstmkdir `dirname $target` 444 conffile=`basename $3` 445 verbose "$INSTALL_CP $4/$conffile $target" 446 $INSTALL_CP $4/$conffile $target 447 ;; 448 *) 449 fail "unrecognized modlist entry: $*" 450 ;; 451 esac 452} 453 454# Sanity-check the given module list. 455function check_modlist { 456 nawk ' 457 BEGIN { 458 nfields["MOD"] = 6 459 nfields["CONF"] = 6 460 nfields["LINK"] = 7 461 nfields["SYMLINK"] = 7 462 } 463 { 464 # This also catches unknown tags. 465 if (nfields[$1] != NF) { 466 print "error: invalid modlist record:" 467 print $0 468 print "expected", nfields[$1], "fields, found", NF 469 status=1 470 } 471 } 472 END { 473 exit status 474 } 475 ' $1 || fail "Errors in kernel module list" 476} 477 478# 479# Copy kernel modules to $INSTALL_DIR 480# 481 482function copy_kernel { 483 484 case $KARCH in 485 sun4*) ISA=sparc; MACH=sparc ;; 486 i86*) ISA=intel; MACH=i386 ;; 487 *) fail "${KARCH}: invalid kernel architecture";; 488 esac 489 export MACH 490 491 if [ "$GLOM" = "no" ]; then 492 verbose "Source = $UTS, ISA = $ISA, kernel = $KARCH" 493 else 494 verbose "Source = $UTS, ISA = $ISA, kernel = $KARCH, impl = $IMPL" 495 fi 496 497 test -d $KARCH || fail "${KARCH}: invalid kernel architecture" 498 test -d $ISA || fail "${ISA}: invalid instruction set architecture" 499 500 tstmkdir $INSTALL_FILES 501 rm -rf $modstatedir 502 tstmkdir $modstatedir 503 export MODSTATE=$modstatedir/state 504 505 # 506 # Figure out which "make" to use. dmake is faster than serial 507 # make, but dmake 7.3 has a bug that causes it to lose log 508 # output, which means the modlist might be incomplete. 509 # 510 make=dmake 511 dmvers=`$make -version` 512 if [ $? -ne 0 ]; then 513 make=/usr/ccs/bin/make 514 elif [[ $dmvers = *Distributed?Make?7.3* ]]; then 515 unset make 516 searchpath="/ws/onnv-tools/SUNWspro/SOS10/bin 517 /opt/SUNWspro/SOS10/bin 518 /opt/SUNWspro/bin" 519 for dmpath in $searchpath; do 520 verbose "Trying $dmpath/dmake" 521 if [ -x $dmpath/dmake ]; then 522 dmvers=`$dmpath/dmake -version` 523 if [[ $dmvers != *Distributed?Make?7.3* ]]; then 524 make="$dmpath/dmake" 525 break; 526 fi 527 fi 528 done 529 if [ -z $make ]; then 530 make=/usr/ccs/bin/make 531 echo "Warning: dmake 7.3 doesn't work with Install;" \ 532 "using $make" 533 fi 534 fi 535 536 # 537 # Get a list of all modules, configuration files, and links 538 # that we might want to install. 539 # 540 verbose "Building module list..." 541 (cd $KARCH; MAKEFLAGS=e $make -K $MODSTATE modlist.karch) | \ 542 egrep "^MOD|^CONF|^LINK|^SYMLINK" > $modlist 543 [ "$VERBOSE" = "V" ] && cat $modlist 544 check_modlist $modlist 545 if [ -n "$ON_CRYPTO_BINS" ]; then 546 cryptotar="$ON_CRYPTO_BINS" 547 if [ "$OBJD" = obj ]; then 548 isa=$(uname -p) 549 cryptotar=$(echo "$ON_CRYPTO_BINS" | 550 sed -e s/.$isa.tar.bz2/-nd.$isa.tar.bz2/) 551 fi 552 [ -f "$cryptotar" ] || fail "crypto ($cryptotar) doesn't exist" 553 cryptotree=$(mktemp -d /tmp/crypto.XXXXXX) 554 [ -n "$cryptotree" ] || fail "can't create tree for crypto" 555 unpack_crypto "$cryptotar" "$cryptotree" 556 # 557 # fixcrypto must come before fixglom, because 558 # fixcrypto uses the unglommed path to find things in 559 # the unpacked crypto. 560 # 561 fixcrypto $modlist "$cryptotree" 562 fi 563 if [ "$GLOM" = "yes" ]; then 564 fixglom $modlist $GLOMNAME 565 filtimpl $modlist $IMPL 566 fi 567 if [[ -n "$files" && "$files" != All ]]; then 568 filtmod $modlist "$files" 569 fi 570 571 # 572 # Copy modules and create links. For architectures with both 573 # 32- and 64-bit modules, we'll likely have duplicate 574 # configuration files, so do those after filtering out the 575 # duplicates. 576 # 577 verbose "Copying files to ${INSTALL_FILES}..." 578 579 # 580 # The IFS is reset to the newline character so we can buffer the 581 # output of grep without piping it directly to copymod, otherwise 582 # if fail() is called, then it will deadlock in fail()'s wait call 583 # 584 OIFS="$IFS" 585 IFS=" 586 " 587 set -- `grep -v "^CONF" $modlist`; 588 IFS="$OIFS" 589 for onemod in "$@"; do 590 copymod $onemod 591 done 592 593 OIFS="$IFS" 594 IFS=" 595 " 596 set -- `grep "^CONF" $modlist | sort | uniq`; 597 IFS="$OIFS" 598 for onemod in "$@"; do 599 copymod $onemod 600 done 601 602 # 603 # Add the glommed kernel name to the root archive 604 # 605 if [[ $GLOM == "yes" ]]; 606 then 607 filelist="$INSTALL_FILES/etc/boot/solaris/filelist.ramdisk" 608 mkdir -p `dirname $filelist` 609 echo "platform/$KARCH/$GLOMNAME" >$filelist 610 fi 611 612 STATE=1 # all kernel modules copied correctly 613 save_state 614} 615 616function kmdb_copy { 617 typeset src="$1" 618 typeset destdir="$2" 619 620 if [[ ! -d $dest ]] ; then 621 [[ "$VERBOSE" != "q" ]] && echo "mkdir -p $destdir" 622 623 mkdir -p $destdir || fail "failed to create $destdir" 624 fi 625 626 [[ "$VERBOSE" != "q" ]] && echo "cp $src $destdir" 627 628 cp $src $destdir || fail "failed to copy $src to $destdir" 629} 630 631function kmdb_copy_machkmods { 632 typeset modbase="$1" 633 typeset destdir="$2" 634 typeset dir= 635 typeset kmod= 636 637 [[ ! -d $modbase ]] && return 638 639 for dir in $(find $modbase -name kmod) ; do 640 set -- $(echo $dir |tr '/' ' ') 641 642 [[ $# -lt 2 ]] && fail "invalid mach kmod dir $dir" 643 644 shift $(($# - 2)) 645 kmod=$1 646 647 [[ ! -f $dir/$kmod ]] && continue 648 649 kmdb_copy $dir/$kmod $destdir 650 done 651} 652 653function kmdb_copy_karchkmods { 654 typeset modbase="$1" 655 typeset destdir="$2" 656 typeset bitdir="$3" 657 typeset dir= 658 typeset kmod= 659 typeset karch= 660 661 [[ ! -d $modbase ]] && return 662 663 for dir in $(find $modbase -name kmod) ; do 664 set -- $(echo $dir | tr '/' ' ') 665 666 [[ $# -lt 3 ]] && fail "invalid karch kmod dir $dir" 667 668 shift $(($# - 3)) 669 kmod=$1 670 bdir=$2 671 672 [[ $bdir != $bitdir ]] && continue 673 [[ ! -f $dir/$1 ]] && continue 674 675 kmdb_copy $dir/$kmod $destdir 676 done 677} 678 679function kmdb_copy_kmdbmod { 680 typeset kmdbpath="$1" 681 typeset destdir="$2" 682 683 [[ ! -f $kmdbpath ]] && return 1 684 685 kmdb_copy $kmdbpath $destdir 686 687 return 0 688} 689 690function copy_kmdb { 691 typeset kmdbtgtdir=$INSTALL_FILES/platform/$KARCH/$GLOMNAME/misc 692 typeset bitdirs= 693 typeset isadir= 694 typeset b64srcdir= 695 typeset b64tgtdir= 696 typeset b32srcdir= 697 typeset b32tgtdir= 698 typeset machdir= 699 typeset platdir= 700 701 if [[ $KMDB = "no" || ! -d $SRC/cmd/mdb ]] ; then 702 # The kmdb copy was suppressed or the workspace doesn't contain 703 # the mdb subtree. Either way, there's nothing to do. 704 STATE=2 705 save_state 706 return 707 fi 708 709 if [[ $(mach) = "i386" ]] ; then 710 isadir="intel" 711 b64srcdir="amd64" 712 b64tgtdir="amd64" 713 b32srcdir="ia32" 714 b32tgtdir="." 715 else 716 isadir="sparc" 717 b64srcdir="v9" 718 b64tgtdir="sparcv9" 719 b32srcdir="v7" 720 b32tgtdir="." 721 fi 722 723 typeset foundkmdb=no 724 typeset kmdbpath= 725 typeset destdir= 726 727 platdir=$INSTALL_FILES/platform/$KARCH/$GLOMNAME 728 if [[ $GLOM = "yes" ]] ; then 729 machdir=$platdir 730 else 731 machdir=$INSTALL_FILES/kernel 732 fi 733 734 srctrees=$SRC 735 if [[ -d $SRC/../closed && "$CLOSED_IS_PRESENT" != no ]]; then 736 srctrees="$srctrees $SRC/../closed" 737 else 738 if [ -z "$ON_CRYPTO_BINS" ]; then 739 echo "Warning: ON_CRYPTO_BINS not set; pre-signed" \ 740 "crypto not provided." 741 fi 742 fi 743 if [[ $WANT64 = "yes" ]] ; then 744 # kmdbmod for sparc and x86 are built and installed 745 # in different places 746 if [[ $(mach) = "i386" ]] ; then 747 kmdbpath=$SRC/cmd/mdb/$isadir/$b64srcdir/kmdb/kmdbmod 748 destdir=$machdir/misc/$b64tgtdir 749 else 750 kmdbpath=$SRC/cmd/mdb/$KARCH/$b64srcdir/kmdb/kmdbmod 751 destdir=$platdir/misc/$b64tgtdir 752 fi 753 754 if kmdb_copy_kmdbmod $kmdbpath $destdir ; then 755 foundkmdb="yes" 756 757 for tree in $srctrees; do 758 kmdb_copy_machkmods \ 759 $tree/cmd/mdb/$isadir/$b64srcdir \ 760 $machdir/kmdb/$b64tgtdir 761 kmdb_copy_karchkmods $tree/cmd/mdb/$KARCH \ 762 $platdir/kmdb/$b64tgtdir $b64srcdir 763 done 764 fi 765 fi 766 767 if [[ $WANT32 = "yes" ]] ; then 768 kmdbpath=$SRC/cmd/mdb/$isadir/$b32srcdir/kmdb/kmdbmod 769 destdir=$machdir/misc/$b32tgtdir 770 771 if kmdb_copy_kmdbmod $kmdbpath $destdir ; then 772 foundkmdb="yes" 773 774 for tree in $srctrees; do 775 kmdb_copy_machkmods \ 776 $tree/cmd/mdb/$isadir/$b32srcdir \ 777 $machdir/kmdb/$b32tgtdir 778 kmdb_copy_karchkmods $tree/cmd/mdb/$KARCH \ 779 $platdir/kmdb/$b32tgtdir $b32srcdir 780 done 781 fi 782 fi 783 784 # A kmdb-less workspace isn't fatal, but it is potentially problematic, 785 # as the changes made to uts may have altered something upon which kmdb 786 # depends. We will therefore remind the user that they haven't built it 787 # yet. 788 if [[ $foundkmdb != "yes" ]] ; then 789 echo "WARNING: kmdb isn't built, and won't be included" 790 fi 791 792 STATE=2 793 save_state 794 return 795} 796 797# 798# Make tarfile 799# 800 801function make_tarfile { 802 echo "Creating tarfile $TARFILE" 803 test -d $INSTALL_FILES || fail "Can't find $INSTALL_FILES" 804 cd $INSTALL_FILES 805 rm -f $TARFILE files 806 807 # We don't want to change the permissions or ownership of pre-existing 808 # directories on the target machine, so we're going to take care to 809 # avoid including directories in the tarfile. On extraction, tar won't 810 # modify pre-existing directories, and will create non-existent ones as 811 # the user doing the extraction. 812 find . ! -type d -print |fgrep -vx './files' >files 813 tar cf $TARFILE -I files || fail "Couldn't create tarfile $TARFILE" 814 STATE=3 815} 816 817# 818# Routines to copy files to the target machine 819# 820 821function remote_fail { 822 fail "" "$1" "" \ 823 "Make sure that $TARGET_MACHINE is up." \ 824"Check .rhosts in the home directory of user $TARGET_USER on $TARGET_MACHINE." \ 825 "Check /etc/hosts.equiv, /etc/passwd, and /etc/shadow." \ 826 "Change permissions on $TARGET_MACHINE as necessary." \ 827 "Then, use \"$INSTALL -R\" to resume the install." "" 828} 829 830function remote_install { 831 if [ "$IMODE" = "n" ]; then 832 STATE=4 833 return 0 834 fi 835 test -s $TARFILE || fail "$TARFILE missing or empty" 836 verbose "Installing system on $TARGET" 837 test -d $INSTALL_DIR || fail "Can't find $INSTALL_DIR" 838 cd $INSTALL_DIR 839 rm -f errors fatal nonfatal 840 if [ "$IMODE" = "T" ]; then 841 EMESG="Can't rcp to $TARGET" 842 touch errors 843 sh -e${SHV}c "$INSTALL_RCP $TARFILE $TARGET/Install.tar" 844 else 845 EMESG="Can't rsh to $TARGET_MACHINE" 846 rsh -l $TARGET_USER $TARGET_MACHINE \ 847 "(cd $TARGET_DIR; /usr/bin/tar x${V}f -)" \ 848 <$TARFILE 2>errors 849 fi 850 test $? -ne 0 && remote_fail "$EMESG" 851 cd $INSTALL_DIR 852 egrep "set time|warning|blocksize" errors >nonfatal 853 egrep -v "set time|warning|blocksize" errors >fatal 854 if [ -s fatal ]; then 855 echo "Fatal errors from rsh:" 856 cat fatal 857 remote_fail "Can't install on $TARGET_MACHINE" 858 fi 859 if [ -s nonfatal -a "$VERBOSE" != "q" ]; then 860 echo "Non-fatal errors from rsh:" 861 cat nonfatal 862 fi 863 rm -f fatal nonfatal errors 864 test "$IMODE" = "T" && echo "Files can be extracted on \ 865$TARGET_MACHINE using 'tar xvf $TARGET_DIR/Install.tar'" 866 STATE=4 867} 868 869function okexit { 870 cd /tmp 871 test "$CLEANUP" = c && remove_dir $INSTALL_DIR 872 save_state 873 rm -rf $modstatedir 874 rm -f $modlist 875 [ -n "$cryptotree" ] && rm -rf "$cryptotree" 876 verbose "Install complete" 877 exit 0 878} 879 880# 881# Process options 882# 883 884RCOPTS="" 885LIBCREATE="no" 886LIBSRC="" 887ENV_PATH=$CODEMGR_WS 888OBJD="debug" 889KMDB="yes" 890 891test -s $INSTALL_RC && RCOPTS=`cat $INSTALL_RC` 892set $INSTALL $DEFAULT_OPTIONS $RCOPTS $* 893shift 894 895while getopts acd:D:G:hi:k:Kl:Lmno:pPqRs:t:T:uvVw:xX36 opt 896do 897 case $opt in 898 w) ENV_PATH="$OPTARG"; SRC="$ENV_PATH/usr/src";; 899 s) UTS="$OPTARG";; 900 k) KARCH="$OPTARG";; 901 t|T) TARGET="$OPTARG"; IMODE=$opt; CLEANUP="c";; 902 n) TARGET=""; IMODE="n"; CLEANUP="p";; 903 u) files="unix genunix";; 904 m) files="Modules";; 905 a) files="All";; 906 v|V|q) VERBOSE=$opt;; 907 c|p) CLEANUP=$opt;; 908 L) LIBCREATE="yes"; CLEANUP="c";; 909 l) LIBSRC="$OPTARG";; 910 D) INSTALL_LIB="$OPTARG";; 911 d) INSTALL_DIR="$OPTARG/$TRAILER";; 912 G) GLOM=yes; GLOMNAME="$OPTARG";; 913 P|X|x) echo "-$opt is obsolete; ignored";; 914 h) usage "${INSTALL}: installs unix and modules";; 915 R) x=$OPTIND; restore_state; OPTIND=$x;; 916 i) IMPL="$OPTARG";; 917 o) OBJD="$OPTARG";; 918 K) KMDB="no";; 919 3) WANT64="no";; 920 6) WANT32="no";; 921 \?) usage "Illegal option";; 922 esac 923done 924shift `expr $OPTIND - 1` 925 926ENV_NAME=`basename $ENV_PATH` 927 928# 929# The rest of the command line is a list of individual files to copy. 930# If non-null, this list overrides the -uma options. 931# 932 933if [[ $# -gt 0 ]] ; then 934 files="$*" 935 KMDB="no" 936fi 937 938case "$VERBOSE" in 939 v) V="v"; SHV="x";; 940 V) V="v"; SHV="x"; set -x;; 941 q) V=""; SHV="";; 942esac 943 944# 945# Create temp directory for Install's files 946# 947 948tstmkdir $INSTALL_DIR 949 950TARFILE=$INSTALL_DIR/Install.${KARCH}.tar 951INSTALL_FILES=$INSTALL_DIR/$KARCH 952 953# 954# Extract the target machine and target directory from a target of the 955# form [user@]machine:/dir . 956# 957 958if [ "$IMODE" != "n" ]; then 959 eval `echo $TARGET | nawk -F':' '{ 960 if (NF != 2 || !length($1) || !length($2)) 961 print "usage \"Invalid target\"" 962 m = $1; d = $2 963 if ($1 ~ /@/) { 964 k = split($1, f, "@"); 965 if (k != 2 || !length(f[1]) || !length (f[2])) 966 print "usage \"Invalid target\"" 967 u = f[1]; m = f[2] 968 } 969 print "TARGET_USER=" u ";" 970 print "TARGET_MACHINE=" m ";" 971 print "TARGET_DIR=" d ";" 972 }'` 973 if [ -z "$TARGET_USER" ]; then 974 TARGET_USER=$LOGNAME 975 fi 976fi 977 978# 979# Allow the use of library source or target for the install 980# 981 982if [ -n "$LIBSRC" ]; then 983 LIBSRC="`basename $LIBSRC .tar`.tar" 984 TARFILE=$INSTALL_LIB/$LIBSRC 985 test -s $TARFILE || fail "Can't find tarfile $TARFILE" 986 verbose "Installing from library tarfile $TARFILE" 987 STATE=3 988elif [ "$LIBCREATE" = "yes" ]; then 989 tstmkdir $INSTALL_LIB 990 TARFILE="$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar" 991fi 992 993# 994# The next few lines allow recovery and activation with -R, 995# and library installs with -l. 996# 997 998[[ $STATE -eq 1 ]] && copy_kmdb 999[[ $STATE -eq 2 ]] && make_tarfile 1000[[ $STATE -eq 3 ]] && remote_install 1001[[ $STATE -eq 4 ]] && okexit 1002 1003save_state 1004 1005cd $DOT 1006DOTDOT=`cd ..; pwd` 1007 1008# 1009# Try to be smart: if DOTDOT ends in uts, then infer UTS and KARCH from DOT 1010# Otherwise, if SRC is set, infer UTS = $SRC/uts. 1011# 1012 1013if [ "`basename $DOTDOT`" = "uts" ]; then 1014 UTS=$DOTDOT 1015 KARCH=`basename $DOT` 1016 if [ ! -n "$SRC" ]; then 1017 SRC=`dirname $DOTDOT` 1018 verbose "Setting SRC to $SRC" 1019 fi 1020 export SRC 1021fi 1022 1023if [ -z "$UTS" -a -n "$SRC" ]; then 1024 UTS="${SRC}/uts" 1025 test -n "$KARCH" || fail "no karch specified (e.g. -k sun4u)" 1026fi 1027 1028if [ "$LIBCREATE" = "yes" ]; then 1029 TARFILE=$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar 1030else 1031 TARFILE=$INSTALL_DIR/Install.${KARCH}.tar 1032fi 1033INSTALL_FILES=$INSTALL_DIR/$KARCH 1034save_state 1035 1036cd $DOT 1037test -z "$UTS" && fail 'Cannot find kernel sources -- $SRC not set' 1038test -d "$UTS" || fail "${UTS}: no such directory" 1039 1040# 1041# Convert UTS into an absolute path. 1042# 1043 1044cd $UTS 1045UTS=`pwd` 1046 1047test "`basename $UTS`" = "uts" || \ 1048 verbose "Warning: source path $UTS doesn't end in 'uts'" 1049 1050remove_dir $INSTALL_DIR/$KARCH 1051rm -f $TARFILE 1052 1053copy_kernel # sets STATE=1 if successful 1054copy_kmdb # sets STATE=2 if successful 1055make_tarfile # sets STATE=3 if successful 1056remote_install # sets STATE=4 if successful 1057 1058okexit 1059