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 typeset destdir= 869 870 platdir=$INSTALL_FILES/platform/$KARCH/$GLOMNAME 871 if [[ $GLOM = "yes" ]] ; then 872 machdir=$platdir 873 else 874 machdir=$INSTALL_FILES/kernel 875 fi 876 877 if [[ $WANT64 = "yes" ]] ; then 878 # kmdbmod for sparc and x86 are built and installed 879 # in different places 880 if [[ $(mach) = "i386" ]] ; then 881 kmdbpath=$SRC/cmd/mdb/$isadir/$b64srcdir/kmdb/kmdbmod 882 destdir=$machdir/misc/$b64tgtdir 883 else 884 kmdbpath=$SRC/cmd/mdb/$KARCH/$b64srcdir/kmdb/kmdbmod 885 destdir=$platdir/misc/$b64tgtdir 886 fi 887 888 if kmdb_copy_kmdbmod $kmdbpath $destdir ; then 889 foundkmdb="yes" 890 891 kmdb_copy_machkmods $SRC/cmd/mdb/$isadir/$b64srcdir \ 892 $machdir/kmdb/$b64tgtdir 893 kmdb_copy_karchkmods $SRC/cmd/mdb/$KARCH \ 894 $platdir/kmdb/$b64tgtdir $b64srcdir 895 fi 896 fi 897 898 if [[ $WANT32 = "yes" ]] ; then 899 kmdbpath=$SRC/cmd/mdb/$isadir/$b32srcdir/kmdb/kmdbmod 900 destdir=$machdir/misc/$b32tgtdir 901 902 if kmdb_copy_kmdbmod $kmdbpath $destdir ; then 903 foundkmdb="yes" 904 905 kmdb_copy_machkmods $SRC/cmd/mdb/$isadir/$b32srcdir \ 906 $machdir/kmdb/$b32tgtdir 907 kmdb_copy_karchkmods $SRC/cmd/mdb/$KARCH \ 908 $platdir/kmdb/$b32tgtdir $b32srcdir 909 fi 910 fi 911 912 # A kmdb-less workspace isn't fatal, but it is potentially problematic, 913 # as the changes made to uts may have altered something upon which kmdb 914 # depends. We will therefore remind the user that they haven't built it 915 # yet. 916 if [[ $foundkmdb != "yes" ]] ; then 917 echo "WARNING: kmdb isn't built, and won't be included" 918 fi 919 920 STATE=2 921 save_state 922 return 923} 924 925# 926# Make tarfile 927# 928 929make_tarfile() { 930 echo "Creating tarfile $TARFILE" 931 test -d $INSTALL_FILES || fail "Can't find $INSTALL_FILES" 932 cd $INSTALL_FILES 933 rm -f $TARFILE files 934 935 # We don't want to change the permissions or ownership of pre-existing 936 # directories on the target machine, so we're going to take care to 937 # avoid including directories in the tarfile. On extraction, tar won't 938 # modify pre-existing directories, and will create non-existent ones as 939 # the user doing the extraction. 940 find . ! -type d -print |fgrep -vx './files' >files 941 tar cf $TARFILE -I files || fail "Couldn't create tarfile $TARFILE" 942 STATE=3 943} 944 945# 946# Routines to copy files to the target machine 947# 948 949remote_fail() { 950 fail "" "$1" "" \ 951 "Make sure that $TARGET_MACHINE is up." \ 952"Check .rhosts in the home directory of user $TARGET_USER on $TARGET_MACHINE." \ 953 "Check /etc/hosts.equiv, /etc/passwd, and /etc/shadow." \ 954 "Change permissions on $TARGET_MACHINE as necessary." \ 955 "Then, use \"$INSTALL -R\" to resume the install." "" 956} 957 958remote_install() { 959 if [ "$IMODE" = "n" ]; then 960 STATE=4 961 return 0 962 fi 963 test -s $TARFILE || fail "$TARFILE missing or empty" 964 verbose "Installing system on $TARGET" 965 test -d $INSTALL_DIR || fail "Can't find $INSTALL_DIR" 966 cd $INSTALL_DIR 967 rm -f errors fatal nonfatal 968 if [ "$IMODE" = "T" ]; then 969 EMESG="Can't rcp to $TARGET" 970 touch errors 971 sh -e${SHV}c "$INSTALL_RCP $TARFILE $TARGET/Install.tar" 972 else 973 EMESG="Can't rsh to $TARGET_MACHINE" 974 rsh -l $TARGET_USER $TARGET_MACHINE \ 975 "(cd $TARGET_DIR; /usr/bin/tar x${V}f -)" \ 976 <$TARFILE 2>errors 977 fi 978 test $? -ne 0 && remote_fail "$EMESG" 979 cd $INSTALL_DIR 980 egrep "set time|warning|blocksize" errors >nonfatal 981 egrep -v "set time|warning|blocksize" errors >fatal 982 if [ -s fatal ]; then 983 echo "Fatal errors from rsh:" 984 cat fatal 985 remote_fail "Can't install on $TARGET_MACHINE" 986 fi 987 if [ -s nonfatal -a "$VERBOSE" != "q" ]; then 988 echo "Non-fatal errors from rsh:" 989 cat nonfatal 990 fi 991 rm -f fatal nonfatal errors 992 test "$IMODE" = "T" && echo "Files can be extracted on \ 993$TARGET_MACHINE using 'tar xvf $TARGET_DIR/Install.tar'" 994 STATE=4 995} 996 997okexit() { 998 cd /tmp 999 test "$CLEANUP" = c && remove_dir $INSTALL_DIR 1000 save_state 1001 verbose "Install complete" 1002 exit 0 1003} 1004 1005# 1006# Process options 1007# 1008 1009RCOPTS="" 1010LIBCREATE="no" 1011LIBSRC="" 1012PFLAG=0 1013ENV_PATH=$CODEMGR_WS 1014OBJD="debug" 1015KMDB="yes" 1016 1017test -s $INSTALL_RC && RCOPTS=`cat $INSTALL_RC` 1018set $INSTALL $DEFAULT_OPTIONS $RCOPTS $* 1019shift 1020 1021while getopts acd:D:G:hi:k:Kl:Lmno:pPqRs:t:T:uvVw:xX36 opt 1022do 1023 case $opt in 1024 w) ENV_PATH="$OPTARG"; SRC="$ENV_PATH/usr/src";; 1025 s) UTS="$OPTARG";; 1026 k) KARCH="$OPTARG";; 1027 t|T) TARGET="$OPTARG"; IMODE=$opt; CLEANUP="c";; 1028 n) TARGET=""; IMODE="n"; CLEANUP="p";; 1029 u) files="unix genunix";; 1030 m) files="modules";; 1031 a) files="unix genunix modules";; 1032 v|V|q) VERBOSE=$opt;; 1033 c|p) CLEANUP=$opt;; 1034 L) LIBCREATE="yes"; CLEANUP="c";; 1035 l) LIBSRC="$OPTARG";; 1036 D) INSTALL_LIB="$OPTARG";; 1037 d) INSTALL_DIR="$OPTARG/$TRAILER";; 1038 G) GLOM=yes; GLOMNAME="$OPTARG";; 1039 x) XFLAG=1;; 1040 X) XFLAG=0;; 1041 P) PFLAG=1;; 1042 h) usage "${INSTALL}: installs unix and modules";; 1043 R) x=$OPTIND; restore_state; OPTIND=$x;; 1044 i) IMPL="$OPTARG";; 1045 o) OBJD="$OPTARG";; 1046 K) KMDB="no";; 1047 3) WANT64="no";; 1048 6) WANT32="no";; 1049 \?) usage "Illegal option";; 1050 esac 1051done 1052shift `expr $OPTIND - 1` 1053 1054ENV_NAME=`basename $ENV_PATH` 1055 1056# 1057# The rest of the command line is a list of individual files to copy. 1058# If non-null, this list overrides the -uma options. 1059# 1060 1061if [[ $# -gt 0 ]] ; then 1062 files="$*" 1063 KMDB="no" 1064fi 1065 1066case $VERBOSE in 1067 v) V="v"; SHV="x";; 1068 V) V="v"; SHV="x"; set -x;; 1069 q) V=""; SHV="";; 1070esac 1071 1072# 1073# Create temp directory for Install's files 1074# 1075 1076test -d $INSTALL_DIR || mkdir -p $INSTALL_DIR || fail "Can't mkdir $INSTALL_DIR" 1077 1078TARFILE=$INSTALL_DIR/Install.${KARCH}.tar 1079INSTALL_FILES=$INSTALL_DIR/$KARCH 1080 1081# 1082# Extract the target machine and target directory from a target of the 1083# form [user@]machine:/dir . 1084# 1085 1086if [ "$IMODE" != "n" ]; then 1087 eval `echo $TARGET | nawk -F':' '{ 1088 if (NF != 2 || !length($1) || !length($2)) 1089 print "usage \"Invalid target\"" 1090 m = $1; d = $2 1091 if ($1 ~ /@/) { 1092 k = split($1, f, "@"); 1093 if (k != 2 || !length(f[1]) || !length (f[2])) 1094 print "usage \"Invalid target\"" 1095 u = f[1]; m = f[2] 1096 } 1097 print "TARGET_USER=" u ";" 1098 print "TARGET_MACHINE=" m ";" 1099 print "TARGET_DIR=" d ";" 1100 }'` 1101 if [ -z "$TARGET_USER" ]; then 1102 TARGET_USER=$LOGNAME 1103 fi 1104fi 1105 1106# 1107# Allow the use of library source or target for the install 1108# 1109 1110if [ -n "$LIBSRC" ]; then 1111 LIBSRC="`basename $LIBSRC .tar`.tar" 1112 TARFILE=$INSTALL_LIB/$LIBSRC 1113 test -s $TARFILE || fail "Can't find tarfile $TARFILE" 1114 verbose "Installing from library tarfile $TARFILE" 1115 STATE=3 1116elif [ "$LIBCREATE" = "yes" ]; then 1117 test -d $INSTALL_LIB \ 1118 || mkdir -p $INSTALL_LIB \ 1119 || fail "Can't mkdir $INSTALL_LIB" 1120 TARFILE="$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar" 1121fi 1122 1123# 1124# The next three lines allow recovery and activation with -R, 1125# and library installs with -l. 1126# 1127 1128[[ $STATE -eq 1 ]] && copy_kmdb 1129[[ $STATE -eq 2 ]] && make_tarfile 1130[[ $STATE -eq 3 ]] && remote_install 1131[[ $STATE -eq 4 ]] && okexit 1132 1133save_state 1134 1135cd $DOT 1136DOTDOT=`cd ..; pwd` 1137 1138# 1139# Try to be smart: if DOTDOT ends in uts, then infer UTS and KARCH from DOT 1140# Otherwise, if SRC is set, infer UTS = $SRC/uts. 1141# 1142 1143if [ "`basename $DOTDOT`" = "uts" ]; then 1144 UTS=$DOTDOT 1145 KARCH=`basename $DOT` 1146fi 1147 1148if [ -z "$UTS" -a -n "$SRC" ]; then 1149 UTS="${SRC}/uts" 1150 test -n "$KARCH" || fail "no karch specified (e.g. -k sun4u)" 1151fi 1152 1153if [ "$LIBCREATE" = "yes" ]; then 1154 TARFILE=$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar 1155else 1156 TARFILE=$INSTALL_DIR/Install.${KARCH}.tar 1157fi 1158INSTALL_FILES=$INSTALL_DIR/$KARCH 1159save_state 1160 1161cd $DOT 1162test -z "$UTS" && fail 'Cannot find kernel sources -- $SRC not set' 1163test -d "$UTS" || fail "${UTS}: no such directory" 1164 1165# 1166# Convert UTS into an absolute path. 1167# 1168 1169cd $UTS 1170UTS=`pwd` 1171 1172test "`basename $UTS`" = "uts" || \ 1173 verbose "Warning: source path $UTS doesn't end in 'uts'" 1174 1175remove_dir $INSTALL_DIR/$KARCH 1176rm -f $TARFILE 1177 1178copy_kernel # sets STATE=1 if successful 1179copy_kmdb # sets STATE=2 if successful 1180make_tarfile # sets STATE=3 if successful 1181remote_install # sets STATE=4 if successful 1182 1183okexit 1184