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, Version 1.0 only 7# (the "License"). You may not use this file except in compliance 8# with the License. 9# 10# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11# or http://www.opensolaris.org/os/licensing. 12# See the License for the specific language governing permissions 13# and limitations under the License. 14# 15# When distributing Covered Code, include this CDDL HEADER in each 16# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17# If applicable, add the following below this CDDL HEADER, with the 18# fields enclosed by brackets "[]" replaced with your own identifying 19# information: Portions Copyright [yyyy] [name of copyright owner] 20# 21# CDDL HEADER END 22# 23# 24# Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27#From: "@(#)Install 1.56 96/10/11 SMI" 28#ident "%Z%%M% %I% %E% SMI" 29# 30# Author: Jeff Bonwick 31# 32# Please report any bugs to bonwick@eng. 33# 34# How Install works: 35# 36# Install performs the following steps: 37# 38# 1. Figure out how to construct /kernel by looking at Makefile.uts, 39# Makefile.$ISA (sparc default), Makefile.$KARCH and the Makefiles 40# in the module directories (uts/arch/*/Makefile). 41# 42# 2. Create the requested subset of /kernel in Install's temp space 43# (/tmp/Install.username by default.) 44# 45# 3. Create a tar file (/tmp/Install.username/Install.tar) based on (3). 46# 47# 4. If -n was specified, exit. If a target was specified using -T, 48# rcp the tarfile to the target and exit. If a target was specified 49# using -t, rsh to the target machine and untar the tarfile in the 50# target directory. 51# 52# If any of these steps fail, Install will give you an error message and, 53# in most cases, suggest corrective measures. Then, you can recover the 54# install with "Install -R". (This is not required; it's just faster than 55# starting from scratch.) 56# 57# One final comment: Unfortunately, tar and I disagree on what 58# constitutes a fatal error. (tar -x will exit 0 even if it can't write 59# anything in the current directory.) Thus, I am reduced to grepping stderr 60# for (what I consider) fatal and nonfatal error messages. If you run into 61# a situation where this doesn't behave the way you think it should (either 62# an "Install failed" message after a successful install, or an "Install 63# complete" message after it bombs), please let me know. 64 65# 66# The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout 67# under certain circumstances, which can really screw things up; unset it. 68# 69unset CDPATH 70 71INSTALL=`basename $0` 72DOT=`pwd` 73 74TRAILER="Install.$LOGNAME" 75INSTALL_STATE=${INSTALL_STATE-$HOME/.Install.state} 76export INSTALL_STATE 77INSTALL_DIR=${INSTALL_DIR-/tmp/$TRAILER} 78if [ "`basename $INSTALL_DIR`" != "$TRAILER" ]; then 79 INSTALL_DIR="$INSTALL_DIR/$TRAILER" 80fi 81export INSTALL_DIR 82INSTALL_LIB=${INSTALL_LIB-$HOME/LibInstall} 83export INSTALL_LIB 84INSTALL_RC=${INSTALL_RC-$HOME/.Installrc} 85export INSTALL_RC 86INSTALL_CP=${INSTALL_CP-"cp -p"} 87export INSTALL_CP 88INSTALL_RCP=${INSTALL_RCP-"rcp -p"} 89export INSTALL_RCP 90 91STATE=0 92 93DEFAULT_OPTIONS="-naqX" 94GLOM=no 95GLOMNAME=kernel 96IMPL="default" 97WANT32="yes" 98WANT64="yes" 99 100trap 'fail "User Interrupt" "You can resume by typing \"$INSTALL -R\""' 1 2 3 15 101 102usage() { 103 echo "" 104 echo $1 105 echo ' 106Usage: Install [ -w workspace ] 107 [ -s srcdir (default: usr/src/uts) ] 108 [ -k karch (e.g. sun4u; required if not deducible from pwd) ] 109 [ -t target (extract tar file on target, e.g. user@machine:/) ] 110 [ -T target (copy tar file to target, e.g. user@machine:/tmp) ] 111 [ -n (no target, just create tar file in /tmp (default)) ] 112 [ -u (install unix only) ] 113 [ -m (install modules only) ] 114 [ -a (install everything, i.e. unix + modules (default)) ] 115 [ -v (verbose output) ] 116 [ -V (REALLY verbose output) ] 117 [ -q (quiet (default)) ] 118 [ -c (clean up (remove temp files) when done (default) ] 119 [ -p (preserve temp files -- useful for debugging) ] 120 [ -L (library create: put tarfile in $INSTALL_LIB/env.karch) ] 121 [ -l lib (library extract: use $INSTALL_LIB/lib as source) ] 122 [ -D libdir (default: $HOME/LibInstall) ] 123 [ -d tempdir (Install work area (default: /tmp)) ] 124 [ -G glomname (put all files under platform/karch/glomname) ] 125 [ -i impl (e.g. sunfire; recommended with -G) ] 126 [ -x (update /etc/name_to_major et al) ] 127 [ -X (do not update /etc/name_to_major et al (default)) ] 128 [ -P (update /etc/path_to_inst -- generally not advisable) ] 129 [ -h (help -- prints this message) ] 130 [ -R (recover a previous Install) ] 131 [ -o objdir (object directory - either obj or debug (the default)) ] 132 [ -K (do not copy kmdb) ] 133 [ -3 32-bit modules only ] 134 [ -6 64-bit modules only ] 135 [ list of modules to install ] 136 137For full details: 138 139 man -M /ws/on297-gate/public/docs Install 140' 141 exit 1 142} 143 144# 145# Save the current state of Install 146# 147 148save_state() { 149 rm -f $INSTALL_STATE 150 (echo "# State of previous Install 151TARGET=$TARGET 152ENV_PATH=$ENV_PATH 153ENV_NAME=$ENV_NAME 154KARCH=$KARCH 155UTS=$UTS 156INSTALL_DIR=$INSTALL_DIR 157INSTALL_LIB=$INSTALL_LIB 158IMODE=$IMODE 159LIBCREATE=$LIBCREATE 160LIBSRC=$LIBSRC 161VERBOSE=$VERBOSE 162CLEANUP=$CLEANUP 163GLOM=$GLOM 164GLOMNAME=$GLOMNAME 165KMDB=$KMDB 166XFLAG=$XFLAG 167files='$files' 168STATE=$STATE" >$INSTALL_STATE) || verbose "Warning: cannot save state" 169} 170 171# 172# Restore the previous state of Install 173# 174 175restore_state() { 176 test -s $INSTALL_STATE || fail "Can't find $INSTALL_STATE" 177 eval "`cat $INSTALL_STATE`" 178} 179 180# 181# Install failed -- print error messages and exit 2 182# 183 184fail() { 185 save_state 186 while [ $# -gt 0 ] 187 do 188 echo $1 189 shift 190 done 191 echo "Install failed" 192 exit 2 193} 194 195# 196# Echo a string in verbose mode only 197# 198 199verbose() { 200 test "$VERBOSE" != "q" && echo $1 201} 202 203# 204# hack for tmpfs bug -- remove files gradually 205# 206 207remove_dir() { 208 test -d $1 || return 209 local_dot=`pwd` 210 cd $1 211 touch foo 212 rm -f `find . -type f -print` 213 cd $local_dot 214 rm -rf $1 215} 216 217# 218# Copy kernel modules to $INSTALL_DIR 219# 220 221copy_kernel() { 222 # The awk script below looks in Makefile.uts to find out what module 223 # subdirectories to make. It then looks in Makefile.$KARCH (for root 224 # modules) and Makefile.$ISA (for usr modules) to create a list of 225 # all possible modules. Finally, it looks at each module's Makefile 226 # to determine where it belongs and what links are required. 227 # This script makes three assumptions: 228 # 229 # 1) Module subdirectories are specified in Makefile.uts by lines of the 230 # form: 231 # 232 # ROOT_FOO_DIR = $(ROOT_MOD_DIR)/foo 233 # USR_BAR_DIR = $(USR_MOD_DIR)/bar 234 # 235 # 2) The corresponding lists of modules appear in Makefile.$KARCH and 236 # Makefile.$ISA on one or more lines of the form: 237 # 238 # FOO_KMODS = foo bar 239 # FOO_KMODS += red white blue 240 # 241 # 3) Each module directory has a Makefile with lines of the form: 242 # 243 # ROOTMODULE = $(ROOT_FOO_DIR)/$(MODULE) 244 # USRMODULE = $(USR_FOO_DIR)/$(MODULE) 245 # ROOTLINK* = $(ROOT_BAR_DIR)/something 246 # USRLINK* = $(USR_BAR_DIR)/something 247 # 248 # If the structure of Makefile.{$KARCH,uts,$ISA} changes in a way that 249 # invalidates these assumptions, you'll need to pick up a new version of 250 # Install. 251 252 case $KARCH in 253 sun4*) ISA=sparc; MACH=sparc; SUBISA_MAKE=;; 254 i86pc) ISA=intel; MACH=i386; SUBISA_MAKE=$ISA/ia32/Makefile.ia32;; 255 *) fail "${KARCH}: invalid kernel architecture";; 256 esac 257 258 if [ "$GLOM" = "no" ]; then 259 verbose "Source = $UTS, ISA = $ISA, kernel = $KARCH" 260 else 261 verbose "Source = $UTS, ISA = $ISA, kernel = $KARCH, impl = $IMPL" 262 fi 263 264 UTS_MAKE=Makefile.uts 265 ISA_MAKE=$ISA/Makefile.$ISA 266 KARCH_MAKE=$KARCH/Makefile.$KARCH 267 PSM_MAKE=$UTS/../Makefile.psm 268 269 test -d $KARCH || fail "${KARCH}: invalid kernel architecture" 270 test -d $ISA || fail "${ISA}: invalid instruction set architecture" 271 test -s $UTS_MAKE || fail "Can't find $UTS_MAKE" 272 test -s $ISA_MAKE || fail "Can't find $ISA_MAKE" 273 test -s $KARCH_MAKE || fail "Can't find $KARCH_MAKE" 274 test -s $PSM_MAKE || fail "Can't find $PSM_MAKE" 275 276 # 277 # For 5.8 and 5.9 we used to build a few x86 things in an ia32 subdirectory 278 # 279 [[ -n "$SUBISA_MAKE" && -s "$SUBISA_MAKE" ]] || SUBISA_MAKE=; 280 281 if [ $GLOM = "yes" ]; then 282 if [ -f $KARCH/$IMPL/Makefile.$IMPL ]; then 283 IMPL_MAKE="$KARCH/$IMPL/Makefile.$IMPL" 284 fi 285 else 286 IMPL_MAKE=`nawk -v karch="$KARCH" ' 287 $1 == "IMPLEMENTATIONS" { 288 for (i = 3; i <= NF; i++) 289 if ($i != ".WAIT") 290 printf("%s ", karch "/" $i "/Makefile." $i) 291 }' $KARCH_MAKE` 292 fi 293 294 DEVFS="./$ISA/devfs/Makefile" 295 296 verbose "Copying files to ${INSTALL_FILES}..." 297 test -d $INSTALL_FILES || mkdir -p $INSTALL_FILES 298 299 nawk \ 300 -v isa="$ISA" \ 301 -v mach="$MACH" \ 302 -v insd="$INSTALL_FILES" \ 303 -v files="$files" \ 304 -v verbose=$VERBOSE \ 305 -v karch=$KARCH \ 306 -v copy="$INSTALL_CP" \ 307 -v devfs=$DEVFS \ 308 -v auxfiles=$XFLAG \ 309 -v ptiflag=$PFLAG \ 310 -v glom=$GLOM \ 311 -v glomname=$GLOMNAME \ 312 -v impl=$IMPL \ 313 -v objd=$OBJD \ 314 -v want32=$WANT32 \ 315 -v want64=$WANT64 \ 316 ' 317 function run(s) { 318 if (verbose != "q") 319 print s 320 if (system(s)) 321 exit 1 322 } 323 function cpf(f1,f2) { 324 if (verbose != "q") 325 print copy " " f1 " " f2 326 if (system(copy " " f1 " " f2)) 327 print "WARNING: copy of " f1 " failed" 328 } 329 function mkdir(dir) { 330 if (!touched[dir]) { 331 run("test -d " dir " || mkdir -p " dir) 332 touched[dir]=1 333 } 334 return dir 335 } 336 function vprint(s) { 337 if (verbose == "V") 338 print s 339 } 340 function try_run(s) { 341 if (verbose != "q") 342 print s 343 if (system(s)) 344 return 1 345 return 0 346 } 347 function exist(s) { 348 if (verbose != "q") 349 print "test -f " s 350 return !system("test -f " s) 351 } 352 353 function copymod(src, targ, om) { 354 if (om) { 355 run("if [ -f " src " ] ; then " \ 356 copy " " src " " targ " ; fi") 357 } else { 358 run(copy " " src " " targ) 359 } 360 } 361 362 function copymod32(idx, modtarg) { 363 modsrc = modsrcd[idx] "/" objd32 "/" modname[idx] 364 365 if (!exist(modsrc)) 366 return (0) 367 368 copymod(modsrc, modtarg, optmod[idx]) 369 return (1) 370 } 371 372 function copymod64(idx, modtarg) { 373 modsrc = modsrcd[idx] "/" objd64 "/" modname[idx] 374 375 if (!exist(modsrc)) 376 return (0) 377 378 copymod(modsrc, modtarg subdir64, optmod[idx]) 379 return (1) 380 } 381 382 function linkmod(lmod, idx, modtarg, did32, did64) { 383 if (lmod ~ /^...MODULE.$/) 384 lmod = "/" modname[idx] 385 386 if (did32 == "yes") { 387 m = modtarg "/" modname[i] 388 run("rm -f " dir lmod "; ln " m " " dir lmod) 389 } 390 391 if (did64 == "yes") { 392 m = modtarg subdir64 "/" modname[i] 393 run("rm -f " dir subdir64 lmod "; ln " m " " \ 394 dir subdir64 lmod) 395 } 396 } 397 398 function slinkmod(slinktarg, idx, modtarg, did32, did64) { 399 if (did32 == "yes") { 400 slink = modtarg "/" slinktarg 401 run("rm -f " slink "; ln -s " modname[i] " " slink) 402 } 403 404 if (did64 == "yes") { 405 slink = modtarg subdir64 "/" slinktarg 406 run("rm -f " slink "; ln -s " modname[i] " " slink) 407 } 408 } 409 410 BEGIN { 411 # If you do NOT want the SVVS modules, set svvs to 0. 412 svvs=1 413 # If you do NOT want the excluded modules, set xmods to 0. 414 xmods=1 415 416 machkernel = "/platform/" karch "/" glomname 417 418 nmods=0 419 do32="no" 420 do64="no" 421 objd32=objd "32" 422 objd64=objd "64" 423 build64and32="no" 424 } 425 426 $1 == "SUBDIR64_" mach { 427 vprint($0) 428 subdir64="/" $3 429 subdir64_relative=$3 430 } 431 432 FILENAME == "Makefile.uts" && $1 == "ALL_BUILDS64" { 433 vprint($0) 434 if ($0 ~ /32/) 435 build64and32="yes" 436 } 437 438 FILENAME == karch "/Makefile." karch && $1 == "ALL_BUILDS" { 439 vprint($0) 440 if ($3 ~ /32/) 441 do32=want32 442 if ($4 ~ /32/) 443 build64and32="yes" 444 if ($3 ~ /ALL_BUILDS64/ && build64and32 == "yes") 445 do32=want32 446 if ($3 ~ /64/ && want64) 447 do64=want64 448 } 449 450 $1 ~ /^(ROOT|USR)_.+_DIR(_32)?$/ { 451 vprint($0) 452 if ($3 ~ /_..CLASS..$/) 453 next 454 slash=index($3,"/") 455 sub(/_32$/,"",$1) 456 if (!slash) 457 slash=length($3)+1 458 parent=substr($3,3,slash-4) 459 subdir=substr($3,slash) 460 if (parent == "ROOT") 461 child=subdir 462 else if (moddirs[parent]) { 463 if ($3 ~ /..PLATFORM.$/) 464 child=moddirs[parent] "/" karch 465 else 466 child=moddirs[parent] subdir 467 } else { 468 print "missing mod dir " parent 469 exit 1 470 } 471 moddirs[$1]=child 472 sub(/^.*kernel/,machkernel,child) 473 glomdirs[$1]=child 474 n=split($1,foo,"_") 475 if (n == 4 && foo[2] != "PSM") 476 notdef[$1]=tolower(foo[2]) 477 } 478 479 FILENAME != isa "/Makefile." isa && $1 ~ /^(GENLIB|UNIX)_DIR$/ { 480 vprint($0) 481 n=split($3,foo,"/") 482 slash=index($3,"/") 483 dir="." substr($3,slash) 484 sub(/..PLATFORM./,karch,dir) 485 nmods++ 486 modsrcd[nmods]=dir 487 modname[nmods]=foo[n] 488 unixmod[nmods]=1 489 } 490 491 FILENAME != "Makefile.uts" && $1 ~ /KMODS|XMODS/ && 492 $1 != "GENUNIX_KMODS" { 493 dir = FILENAME; 494 sub(/\/Makefile.*$/, "", dir); 495 if ($1 ~ "^SVVS_") 496 if (svvs == 0) 497 next 498 else 499 dir = dir "/svvs" 500 if ($1 ~ "XMODS" && xmods == 0) 501 next 502 if ($0 !~ /\$/) { 503 vprint($0) 504 for (i = 3; i <= NF; i++) { 505 if ($i ~ /^(ramdisk|wsdrv|vdi)$/) 506 continue; 507 nmods++ 508 modname[nmods]=$i 509 modsrcd[nmods]="./" dir "/" $i 510 if ($1 ~ "^MPSAS_") 511 optmod[nmods] = 1 512 } 513 } 514 } 515 516 FILENAME == karch "/Makefile." karch && $1 == "PLATFORMS" && 517 $3 !~ /\(/ { 518 for (i = 3; i <= NF; i++) 519 mkdir(insd "/platform/" $i) 520 } 521 522 FILENAME == karch "/Makefile." karch && ($1 == "IMPLEMENTED_PLATFORM" || 523 $1 == "LINKED_PLATFORMS") { 524 for (i = 3; i <= NF; i++) 525 mkdir(insd "/platform/" $i) 526 } 527 528 FILENAME != "Makefile.uts" && $1 == "CONFS" { 529 for (i = 3; i <= NF; i++) { 530 kbi_brain_damage[$i] = "yes" 531 } 532 } 533 534 END { 535 split(files, modlist) 536 for (m in modlist) { 537 mm = modlist[m] 538 if (mm == "modules") { 539 for (i = 1; i <= nmods; i++) 540 if (unixmod[i] == 0) 541 modcopy[i]=1 542 continue 543 } 544 nomodfound = 1 545 for (i = 1; i <= nmods; i++) { 546 if (modname[i] == mm) { 547 modcopy[i]=1 548 nomodfound = 0 549 } 550 } 551 if (nomodfound) { 552 print mm ": invalid module" 553 exit 1 554 } 555 } 556 557 for(i = 1; i <= nmods; i++) { 558 if (!modcopy[i]) 559 continue 560 561 confsrc = "" 562 drvfiles[1] = "" 563 classfile = "" 564 ptifile = "" 565 did32=do32 566 did64=do64 567 no_builds="false" 568 modmake=modsrcd[i] "/Makefile" 569 570 while (getline <modmake > 0) { 571 if ($1 == "NO_BUILDS") { 572 vprint($0) 573 no_builds="true" 574 } 575 576 if ($1 == "ALL_BUILDS" && $3 ~ /64/) { 577 vprint($0) 578 did32="ok" 579 } 580 581 if ($1 == "ALL_BUILDS" && $3 ~ /32/) { 582 vprint($0) 583 did64="ok" 584 } 585 586 if ($1 ~ /^(MODULE|UNIX)$/) { 587 vprint($0) 588 modname[i] = $3 589 } 590 591 if ($1 ~ /^(ROOT|USR)(LINK|MODULE$)/) { 592 vprint($0) 593 slash=index($3,"/") 594 parent=substr($3,3,slash-4) 595 596 if (notdef[parent] && 597 notdef[parent] != impl && 598 glom == "yes") { 599 confsrc = "" 600 break 601 } 602 603 dir = (glom == "no") ? \ 604 moddirs[parent] : glomdirs[parent] 605 if (!dir) { 606 print "no parent for " modname[i] 607 exit 1 608 } 609 610 dir=insd dir 611 mkdir(dir) 612 613 if (do64 == "yes") 614 mkdir(dir subdir64) 615 616 if ($1 ~ /^(ROOT|USR)MODULE$/) { 617 modtarg=dir 618 conftarg=dir 619 if (modname[i] in \ 620 kbi_brain_damage) { 621 confsrc = "./" karch \ 622 "/io" 623 conftarg = insd \ 624 machkernel "/drv" 625 626 mkdir(conftarg) 627 628 if (do64 == "yes") { 629 mkdir(conftarg \ 630 subdir64) 631 } 632 } 633 634 if (do32 == "yes" && 635 !copymod32(i, modtarg)) 636 did32="no" 637 638 if (do64 == "yes" && 639 !copymod64(i, modtarg)) 640 did64="no" 641 642 } else { 643 linkmod(substr($3, slash), 644 i, modtarg, did32, did64) 645 } 646 } 647 648 if ($1 == "SOFTLINKS") { 649 vprint($0) 650 for (j = 3; j <= NF; j++) { 651 slinkmod($j, i, modtarg, did32, 652 did64) 653 } 654 } 655 656 if ($1 == "CONF_SRCDIR") { 657 vprint($0) 658 slash = index($3, "/") 659 confsrc = "." substr($3, slash) 660 } 661 } 662 663 if (do32 == "yes" && did32 == "no" && 664 no_builds == "false") { 665 print "missing 32b file " confsrc "/" modname[i] 666 exit 1 667 } 668 669 if (do64 == "yes" && did64 == "no" && 670 no_builds == "false") { 671 print "missing 64b file " confsrc "/" modname[i] 672 exit 1 673 } 674 675 if (confsrc != "") { 676 conffile = confsrc "/" modname[i] ".conf" 677 cpf(conffile, conftarg) 678 } 679 680 close(modmake) 681 } 682 683 # 684 # Make symlinks for KBI for different root node names for a 685 # given platform 686 # 687 km = "./" karch "/Makefile" 688 while (getline <km > 0) { 689 if ($1 == "PLAT_LINKS") { 690 for (i = 3; i <= NF; i++) { 691 mkdir(insd "/platform") 692 run("ln -s " karch " " insd \ 693 "/platform/" $i) 694 } 695 } 696 } 697 close(km) 698 699 if (did64 == "yes" && build64and32 == "no" && 700 (try_run("test -f " insd "/platform/" karch "/" \ 701 glomname "/" subdir64_relative "/unix") == 0)) 702 { 703 run("ln -s " subdir64_relative "/unix " insd \ 704 "/platform/" karch "/" glomname "/unix") 705 706 if (isa == "sparc" && glom == "no" && 707 (try_run("test -f " insd \ 708 "/platform/SUNW,Ultra-Enterprise-10000/" glomname \ 709 "/" subdir64_relative "/unix") == 0)) { 710 run("ln -s " subdir64_relative "/unix " insd \ 711 "/platform/SUNW,Ultra-Enterprise-10000/" \ 712 glomname "/unix") 713 } 714 } 715 716 while (getline <devfs > 0) { 717 if ($1 == "SRCDIR") 718 configdir = "." substr($3, index($3, "/")) "/" 719 if ($1 == "CLASSFILE") 720 classfile = $3 721 if ($1 == "PTIFILE") 722 ptifile = $3 723 if ($1 == "DRVFILES") 724 split(substr($0, index($0, $3)), drvfiles) 725 } 726 close(devfs) 727 728 if (classfile != "" && auxfiles == 1) { 729 dir = mkdir(targ["ROOT_DRV"]) 730 cpf(configdir classfile, dir) 731 } 732 733 if (ptifile != "" && ptiflag == 1) { 734 dir = mkdir(insd "/etc") 735 cpf(configdir ptifile, dir) 736 } 737 738 if (drvfiles[1] != "" && auxfiles == 1) { 739 dir = mkdir(insd "/etc") 740 for (file in drvfiles) 741 cpf(configdir drvfiles[file], dir) 742 } 743 }' $UTS_MAKE $PSM_MAKE $ISA_MAKE $SUBISA_MAKE $KARCH_MAKE $IMPL_MAKE 744 [[ $? -ne 0 ]] && fail "Files missing in environment" 745 746 # 747 # on x86, add the glommed kernel name to the root archive 748 # 749 if [[ $KARCH = "i86pc" && $GLOM == "yes" ]]; then 750 filelist="$INSTALL_FILES/etc/boot/solaris/filelist.ramdisk" 751 mkdir -p `dirname $filelist` 752 echo "platform/$KARCH/$GLOMNAME" >$filelist 753 fi 754 755 STATE=1 # all kernel modules copied correctly 756 save_state 757} 758 759kmdb_copy() { 760 typeset src="$1" 761 typeset destdir="$2" 762 763 if [[ ! -d $dest ]] ; then 764 [[ $VERBOSE != "q" ]] && echo "mkdir -p $destdir" 765 766 mkdir -p $destdir || fail "failed to create $destdir" 767 fi 768 769 [[ $VERBOSE != "q" ]] && echo "cp $src $destdir" 770 771 cp $src $destdir || fail "failed to copy $src to $destdir" 772} 773 774kmdb_copy_machkmods() { 775 typeset modbase="$1" 776 typeset destdir="$2" 777 typeset dir= 778 typeset kmod= 779 780 [[ ! -d $modbase ]] && return 781 782 for dir in $(find $modbase -name kmod) ; do 783 set -- $(echo $dir |tr '/' ' ') 784 785 [[ $# -lt 2 ]] && fail "invalid mach kmod dir $dir" 786 787 shift $(($# - 2)) 788 kmod=$1 789 790 [[ ! -f $dir/$kmod ]] && continue 791 792 kmdb_copy $dir/$kmod $destdir 793 done 794} 795 796kmdb_copy_karchkmods() { 797 typeset modbase="$1" 798 typeset destdir="$2" 799 typeset bitdir="$3" 800 typeset dir= 801 typeset kmod= 802 typeset karch= 803 804 [[ ! -d $modbase ]] && return 805 806 for dir in $(find $modbase -name kmod) ; do 807 set -- $(echo $dir | tr '/' ' ') 808 809 [[ $# -lt 3 ]] && fail "invalid karch kmod dir $dir" 810 811 shift $(($# - 3)) 812 kmod=$1 813 bdir=$2 814 815 [[ $bdir != $bitdir ]] && continue 816 [[ ! -f $dir/$1 ]] && continue 817 818 kmdb_copy $dir/$kmod $destdir 819 done 820} 821 822kmdb_copy_kmdbmod() { 823 typeset kmdbpath="$1" 824 typeset destdir="$2" 825 826 [[ ! -f $kmdbpath ]] && return 1 827 828 kmdb_copy $kmdbpath $destdir 829 830 return 0 831} 832 833copy_kmdb() { 834 typeset kmdbtgtdir=$INSTALL_FILES/platform/$KARCH/$GLOMNAME/misc 835 typeset bitdirs= 836 typeset isadir= 837 typeset b64srcdir= 838 typeset b64tgtdir= 839 typeset b32srcdir= 840 typeset b32tgtdir= 841 typeset machdir= 842 typeset platdir= 843 844 if [[ $KMDB = "no" || ! -d $SRC/cmd/mdb ]] ; then 845 # The kmdb copy was suppressed or the workspace doesn't contain 846 # the mdb subtree. Either way, there's nothing to do. 847 STATE=2 848 save_state 849 return 850 fi 851 852 if [[ $(mach) = "i386" ]] ; then 853 isadir="intel" 854 b64srcdir="amd64" 855 b64tgtdir="amd64" 856 b32srcdir="ia32" 857 b32tgtdir="." 858 else 859 isadir="sparc" 860 b64srcdir="v9" 861 b64tgtdir="sparcv9" 862 b32srcdir="v7" 863 b32tgtdir="." 864 fi 865 866 typeset foundkmdb=no 867 typeset kmdbpath= 868 869 platdir=$INSTALL_FILES/platform/$KARCH/$GLOMNAME 870 if [[ $GLOM = "yes" ]] ; then 871 machdir=$platdir 872 else 873 machdir=$INSTALL_FILES/kernel 874 fi 875 876 kmdbpath=$SRC/cmd/mdb/$KARCH/$b64srcdir/kmdb/kmdbmod 877 if [[ $WANT64 = "yes" ]] ; then 878 if kmdb_copy_kmdbmod $kmdbpath $platdir/misc/$b64tgtdir ; then 879 foundkmdb="yes" 880 881 kmdb_copy_machkmods $SRC/cmd/mdb/$isadir/$b64srcdir \ 882 $machdir/kmdb/$b64tgtdir 883 kmdb_copy_karchkmods $SRC/cmd/mdb/$KARCH \ 884 $platdir/kmdb/$b64tgtdir $b64srcdir 885 fi 886 fi 887 888 kmdbpath=$SRC/cmd/mdb/$isadir/$b32srcdir/kmdb/kmdbmod 889 if [[ $WANT32 = "yes" ]] ; then 890 if kmdb_copy_kmdbmod $kmdbpath $machdir/misc/$b32tgtdir ; then 891 foundkmdb="yes" 892 893 kmdb_copy_machkmods $SRC/cmd/mdb/$isadir/$b32srcdir \ 894 $machdir/kmdb/$b32tgtdir 895 kmdb_copy_karchkmods $SRC/cmd/mdb/$KARCH \ 896 $platdir/kmdb/$b32tgtdir $b32srcdir 897 fi 898 fi 899 900 # A kmdb-less workspace isn't fatal, but it is potentially problematic, 901 # as the changes made to uts may have altered something upon which kmdb 902 # depends. We will therefore remind the user that they haven't built it 903 # yet. 904 if [[ $foundkmdb != "yes" ]] ; then 905 echo "WARNING: kmdb isn't built, and won't be included" 906 fi 907 908 STATE=2 909 save_state 910 return 911} 912 913# 914# Make tarfile 915# 916 917make_tarfile() { 918 echo "Creating tarfile $TARFILE" 919 test -d $INSTALL_FILES || fail "Can't find $INSTALL_FILES" 920 cd $INSTALL_FILES 921 rm -f $TARFILE files 922 923 # We don't want to change the permissions or ownership of pre-existing 924 # directories on the target machine, so we're going to take care to 925 # avoid including directories in the tarfile. On extraction, tar won't 926 # modify pre-existing directories, and will create non-existent ones as 927 # the user doing the extraction. 928 find . ! -type d -print |fgrep -vx './files' >files 929 tar cf $TARFILE -I files || fail "Couldn't create tarfile $TARFILE" 930 STATE=3 931} 932 933# 934# Routines to copy files to the target machine 935# 936 937remote_fail() { 938 fail "" "$1" "" \ 939 "Make sure that $TARGET_MACHINE is up." \ 940"Check .rhosts in the home directory of user $TARGET_USER on $TARGET_MACHINE." \ 941 "Check /etc/hosts.equiv, /etc/passwd, and /etc/shadow." \ 942 "Change permissions on $TARGET_MACHINE as necessary." \ 943 "Then, use \"$INSTALL -R\" to resume the install." "" 944} 945 946remote_install() { 947 if [ "$IMODE" = "n" ]; then 948 STATE=4 949 return 0 950 fi 951 test -s $TARFILE || fail "$TARFILE missing or empty" 952 verbose "Installing system on $TARGET" 953 test -d $INSTALL_DIR || fail "Can't find $INSTALL_DIR" 954 cd $INSTALL_DIR 955 rm -f errors fatal nonfatal 956 if [ "$IMODE" = "T" ]; then 957 EMESG="Can't rcp to $TARGET" 958 touch errors 959 sh -e${SHV}c "$INSTALL_RCP $TARFILE $TARGET/Install.tar" 960 else 961 EMESG="Can't rsh to $TARGET_MACHINE" 962 rsh -l $TARGET_USER $TARGET_MACHINE \ 963 "(cd $TARGET_DIR; /usr/bin/tar x${V}f -)" \ 964 <$TARFILE 2>errors 965 fi 966 test $? -ne 0 && remote_fail "$EMESG" 967 cd $INSTALL_DIR 968 egrep "set time|warning|blocksize" errors >nonfatal 969 egrep -v "set time|warning|blocksize" errors >fatal 970 if [ -s fatal ]; then 971 echo "Fatal errors from rsh:" 972 cat fatal 973 remote_fail "Can't install on $TARGET_MACHINE" 974 fi 975 if [ -s nonfatal -a "$VERBOSE" != "q" ]; then 976 echo "Non-fatal errors from rsh:" 977 cat nonfatal 978 fi 979 rm -f fatal nonfatal errors 980 test "$IMODE" = "T" && echo "Files can be extracted on \ 981$TARGET_MACHINE using 'tar xvf $TARGET_DIR/Install.tar'" 982 STATE=4 983} 984 985okexit() { 986 cd /tmp 987 test "$CLEANUP" = c && remove_dir $INSTALL_DIR 988 save_state 989 verbose "Install complete" 990 exit 0 991} 992 993# 994# Process options 995# 996 997RCOPTS="" 998LIBCREATE="no" 999LIBSRC="" 1000PFLAG=0 1001ENV_PATH=$CODEMGR_WS 1002OBJD="debug" 1003KMDB="yes" 1004 1005test -s $INSTALL_RC && RCOPTS=`cat $INSTALL_RC` 1006set $INSTALL $DEFAULT_OPTIONS $RCOPTS $* 1007shift 1008 1009while getopts acd:D:G:hi:k:Kl:Lmno:pPqRs:t:T:uvVw:xX36 opt 1010do 1011 case $opt in 1012 w) ENV_PATH="$OPTARG"; SRC="$ENV_PATH/usr/src";; 1013 s) UTS="$OPTARG";; 1014 k) KARCH="$OPTARG";; 1015 t|T) TARGET="$OPTARG"; IMODE=$opt; CLEANUP="c";; 1016 n) TARGET=""; IMODE="n"; CLEANUP="p";; 1017 u) files="unix genunix";; 1018 m) files="modules";; 1019 a) files="unix genunix modules";; 1020 v|V|q) VERBOSE=$opt;; 1021 c|p) CLEANUP=$opt;; 1022 L) LIBCREATE="yes"; CLEANUP="c";; 1023 l) LIBSRC="$OPTARG";; 1024 D) INSTALL_LIB="$OPTARG";; 1025 d) INSTALL_DIR="$OPTARG/$TRAILER";; 1026 G) GLOM=yes; GLOMNAME="$OPTARG";; 1027 x) XFLAG=1;; 1028 X) XFLAG=0;; 1029 P) PFLAG=1;; 1030 h) usage "${INSTALL}: installs unix and modules";; 1031 R) x=$OPTIND; restore_state; OPTIND=$x;; 1032 i) IMPL="$OPTARG";; 1033 o) OBJD="$OPTARG";; 1034 K) KMDB="no";; 1035 3) WANT64="no";; 1036 6) WANT32="no";; 1037 \?) usage "Illegal option";; 1038 esac 1039done 1040shift `expr $OPTIND - 1` 1041 1042ENV_NAME=`basename $ENV_PATH` 1043 1044# 1045# The rest of the command line is a list of individual files to copy. 1046# If non-null, this list overrides the -uma options. 1047# 1048 1049if [[ $# -gt 0 ]] ; then 1050 files="$*" 1051 KMDB="no" 1052fi 1053 1054case $VERBOSE in 1055 v) V="v"; SHV="x";; 1056 V) V="v"; SHV="x"; set -x;; 1057 q) V=""; SHV="";; 1058esac 1059 1060# 1061# Create temp directory for Install's files 1062# 1063 1064test -d $INSTALL_DIR || mkdir -p $INSTALL_DIR || fail "Can't mkdir $INSTALL_DIR" 1065 1066TARFILE=$INSTALL_DIR/Install.${KARCH}.tar 1067INSTALL_FILES=$INSTALL_DIR/$KARCH 1068 1069# 1070# Extract the target machine and target directory from a target of the 1071# form [user@]machine:/dir . 1072# 1073 1074if [ "$IMODE" != "n" ]; then 1075 eval `echo $TARGET | nawk -F':' '{ 1076 if (NF != 2 || !length($1) || !length($2)) 1077 print "usage \"Invalid target\"" 1078 m = $1; d = $2 1079 if ($1 ~ /@/) { 1080 k = split($1, f, "@"); 1081 if (k != 2 || !length(f[1]) || !length (f[2])) 1082 print "usage \"Invalid target\"" 1083 u = f[1]; m = f[2] 1084 } 1085 print "TARGET_USER=" u ";" 1086 print "TARGET_MACHINE=" m ";" 1087 print "TARGET_DIR=" d ";" 1088 }'` 1089 if [ -z "$TARGET_USER" ]; then 1090 TARGET_USER=$LOGNAME 1091 fi 1092fi 1093 1094# 1095# Allow the use of library source or target for the install 1096# 1097 1098if [ -n "$LIBSRC" ]; then 1099 LIBSRC="`basename $LIBSRC .tar`.tar" 1100 TARFILE=$INSTALL_LIB/$LIBSRC 1101 test -s $TARFILE || fail "Can't find tarfile $TARFILE" 1102 verbose "Installing from library tarfile $TARFILE" 1103 STATE=3 1104elif [ "$LIBCREATE" = "yes" ]; then 1105 test -d $INSTALL_LIB \ 1106 || mkdir -p $INSTALL_LIB \ 1107 || fail "Can't mkdir $INSTALL_LIB" 1108 TARFILE="$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar" 1109fi 1110 1111# 1112# The next three lines allow recovery and activation with -R, 1113# and library installs with -l. 1114# 1115 1116[[ $STATE -eq 1 ]] && copy_kmdb 1117[[ $STATE -eq 2 ]] && make_tarfile 1118[[ $STATE -eq 3 ]] && remote_install 1119[[ $STATE -eq 4 ]] && okexit 1120 1121save_state 1122 1123cd $DOT 1124DOTDOT=`cd ..; pwd` 1125 1126# 1127# Try to be smart: if DOTDOT ends in uts, then infer UTS and KARCH from DOT 1128# Otherwise, if SRC is set, infer UTS = $SRC/uts. 1129# 1130 1131if [ "`basename $DOTDOT`" = "uts" ]; then 1132 UTS=$DOTDOT 1133 KARCH=`basename $DOT` 1134fi 1135 1136if [ -z "$UTS" -a -n "$SRC" ]; then 1137 UTS="${SRC}/uts" 1138 test -n "$KARCH" || fail "no karch specified (e.g. -k sun4u)" 1139fi 1140 1141if [ "$LIBCREATE" = "yes" ]; then 1142 TARFILE=$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar 1143else 1144 TARFILE=$INSTALL_DIR/Install.${KARCH}.tar 1145fi 1146INSTALL_FILES=$INSTALL_DIR/$KARCH 1147save_state 1148 1149cd $DOT 1150test -z "$UTS" && fail 'Cannot find kernel sources -- $SRC not set' 1151test -d "$UTS" || fail "${UTS}: no such directory" 1152 1153# 1154# Convert UTS into an absolute path. 1155# 1156 1157cd $UTS 1158UTS=`pwd` 1159 1160test "`basename $UTS`" = "uts" || \ 1161 verbose "Warning: source path $UTS doesn't end in 'uts'" 1162 1163remove_dir $INSTALL_DIR/$KARCH 1164rm -f $TARFILE 1165 1166copy_kernel # sets STATE=1 if successful 1167copy_kmdb # sets STATE=2 if successful 1168make_tarfile # sets STATE=3 if successful 1169remote_install # sets STATE=4 if successful 1170 1171okexit 1172