#!/bin/ksh # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. # # Author: Jeff Bonwick # # Please report any bugs to bonwick@eng. # # How Install works: # # Install performs the following steps: # # 1. Get the list of modules, configuration files, and links # that are desired. # # 2. Create the requested subset of /kernel in Install's temp space # (/tmp/Install.username by default.) # # 3. Create a tar file (/tmp/Install.username/Install.tar) based on (3). # # 4. If -n was specified, exit. If a target was specified using -T, # rcp the tarfile to the target and exit. If a target was specified # using -t, rsh to the target machine and untar the tarfile in the # target directory. # # If any of these steps fail, Install will give you an error message and, # in most cases, suggest corrective measures. Then, you can recover the # install with "Install -R". (This is not required; it's just faster than # starting from scratch.) # # One final comment: Unfortunately, tar and I disagree on what # constitutes a fatal error. (tar -x will exit 0 even if it can't write # anything in the current directory.) Thus, I am reduced to grepping stderr # for (what I consider) fatal and nonfatal error messages. If you run into # a situation where this doesn't behave the way you think it should (either # an "Install failed" message after a successful install, or an "Install # complete" message after it bombs), please let me know. # # The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout # under certain circumstances, which can really screw things up; unset it. # unset CDPATH setvar INSTALL = $(basename $0) setvar DOT = $(pwd) setvar TRAILER = ""Install.$LOGNAME"" setvar INSTALL_STATE = ${INSTALL_STATE-$HOME/.Install.state} export INSTALL_STATE setvar INSTALL_DIR = ${INSTALL_DIR-/tmp/$TRAILER} if test $(basename $INSTALL_DIR) != $TRAILER { setvar INSTALL_DIR = ""$INSTALL_DIR/$TRAILER"" } export INSTALL_DIR setvar INSTALL_LIB = ${INSTALL_LIB-$HOME/LibInstall} export INSTALL_LIB setvar INSTALL_RC = ${INSTALL_RC-$HOME/.Installrc} export INSTALL_RC setvar INSTALL_CP = ${INSTALL_CP-"cp -p"} export INSTALL_CP setvar INSTALL_RCP = ${INSTALL_RCP-"rcp -p"} export INSTALL_RCP setvar STATE = '0' setvar DEFAULT_OPTIONS = ""-naq"" setvar GLOM = 'no' setvar GLOMNAME = 'kernel' setvar IMPL = ""default"" setvar WANT32 = ""yes"" setvar WANT64 = ""yes"" setvar modlist = "/tmp/modlist$Pid" # dummy directory for make state files. setvar modstatedir = "/tmp/modstate$Pid" trap 'fail "User Interrupt" "You can resume by typing \"$INSTALL -R\""' 1 2 3 15 proc usage { echo "" echo $1 echo ' Usage: Install [ -w workspace ] [ -s srcdir (default: usr/src/uts) ] [ -k karch (e.g. sun4u; required if not deducible from pwd) ] [ -t target (extract tar file on target, e.g. user@machine:/) ] [ -T target (copy tar file to target, e.g. user@machine:/tmp) ] [ -n (no target, just create tar file in /tmp (default)) ] [ -u (install unix only) ] [ -m (install modules only) ] [ -a (install everything, i.e. unix + modules (default)) ] [ -v (verbose output) ] [ -V (REALLY verbose output) ] [ -q (quiet (default)) ] [ -c (clean up (remove temp files) when done (default) ] [ -p (preserve temp files -- useful for debugging) ] [ -L (library create: put tarfile in $INSTALL_LIB/env.karch) ] [ -l lib (library extract: use $INSTALL_LIB/lib as source) ] [ -D libdir (default: $HOME/LibInstall) ] [ -d tempdir (Install work area (default: /tmp)) ] [ -G glomname (put all files under platform/karch/glomname) ] [ -i impl (e.g. sunfire; recommended with -G) ] [ -x (update /etc/name_to_major et al) ] [ -X (do not update /etc/name_to_major et al (default)) ] [ -P (update /etc/path_to_inst -- generally not advisable) ] [ -h (help -- prints this message) ] [ -R (recover a previous Install) ] [ -o objdir (object directory - either obj or debug (the default)) ] [ -K (do not copy kmdb) ] [ -3 32-bit modules only ] [ -6 64-bit modules only ] [ list of modules to install ] For full details: man -M /ws/on297-gate/public/docs Install ' exit 1 } # # Save the current state of Install # proc save_state { rm -f $INSTALL_STATE shell {echo "# State of previous Install TARGET=$TARGET ENV_PATH=$ENV_PATH ENV_NAME=$ENV_NAME KARCH=$KARCH UTS=$UTS INSTALL_DIR=$INSTALL_DIR INSTALL_LIB=$INSTALL_LIB IMODE=$IMODE LIBCREATE=$LIBCREATE LIBSRC=$LIBSRC VERBOSE=$VERBOSE CLEANUP=$CLEANUP GLOM=$GLOM GLOMNAME=$GLOMNAME KMDB=$KMDB files='$files' STATE=$STATE" >$INSTALL_STATE} || verbose "Warning: cannot save state" } # # Restore the previous state of Install # proc restore_state { test -s $INSTALL_STATE || fail "Can't find $INSTALL_STATE" eval $(cat $INSTALL_STATE) } # # Install failed -- print error messages and exit 2 # proc fail { save_state # # We might have gotten here via a trap. So wait for any # children (especially "make modlist") to exit before giving # the error message or cleaning up. # wait while [ $# -gt 0 ] { echo $1 shift } rm -rf $modstatedir rm -f $modlist echo "Install failed" exit 2 } # # Echo a string in verbose mode only # proc verbose { test $VERBOSE != "q" && echo $1 } # # hack for tmpfs bug -- remove files gradually # proc remove_dir { test -d $1 || return setvar local_dot = $(pwd) cd $1 touch foo rm -f $(find . -type f -print) cd $local_dot rm -rf $1 } # # Create a directory if it doesn't already exist. # mkdir will provide an error message, so don't provide an additional # message. # proc tstmkdir { test -d $1 || mkdir -p $1 || fail } # # Patch up target directories for glommed kernel. # usage: fixglom listfile glomname # proc fixglom { nawk \ -v glomname=$2 \ -v karch=$KARCH ' $1 == "MOD" || $1 == "SYMLINK" { sub(/^platform.*kernel/, "platform/" karch "/" glomname, $4) sub(/^kernel/, "platform/" karch "/" glomname, $4) sub(/^usr.kernel/, "platform/" karch "/" glomname, $4) print } $1 == "LINK" { sub(/^platform.*kernel/, "platform/" karch "/" glomname, $3) sub(/^kernel/, "platform/" karch "/" glomname, $3) sub(/^usr.kernel/, "platform/" karch "/" glomname, $3) sub(/^platform.*kernel/, "platform/" karch "/" glomname, $5) sub(/^kernel/, "platform/" karch "/" glomname, $5) sub(/^usr.kernel/, "platform/" karch "/" glomname, $5) print } $1 == "CONF" { sub(/^platform.*kernel/, "platform/" karch "/" glomname, $3) sub(/^kernel/, "platform/" karch "/" glomname, $3) sub(/^usr.kernel/, "platform/" karch "/" glomname, $3) print } ' $1 > $1.new mv $1.new $1 } # # Filter out implementation-specific modules, unless that # implementation was requested by the user. # usage: filtimpl listfile implname # proc filtimpl { nawk \ -v impl=$2 ' $1 == "MOD" || $1 == "SYMLINK" { if ($6 == "all" || $6 == impl) print } $1 == "CONF" { if ($5 == "all" || $5 == impl) print } $1 == "LINK" { if ($7 == "all" || $7 == impl) print } ' $1 > $1.new mv $1.new $1 } # # Filter the module list to match the user's request. # Usage: filtmod listfile modules # proc filtmod { nawk -v reqstring="$2" ' function modmatch(modname) { if (reqstring == "All") { return (1) } else if (reqstring == "Modules") { if (modname != "unix" && modname != "genunix") return (1) } else { if (modname in reqmods) return (1) } return (0) } BEGIN { # # The split call creates indexes 1, 2, 3, ... We want # the module names as indexes. # split(reqstring, tmpmods) for (i in tmpmods) reqmods[tmpmods[i]] = 1 } $1 == "MOD" { if (modmatch($3)) print } $1 == "CONF" { if (modmatch($6)) print } $1 == "SYMLINK" { if (modmatch($7)) print } $1 == "LINK" { if (modmatch($4)) print } ' $1 > $1.new mv $1.new $1 } # # Unpack the crypto tarball into the given tree, then massage the # tree so that the binaries are all in objNN or debugNN directories. # proc unpack_crypto { typeset tarfile=$1 typeset ctop=$2 test -d $ctop || fail "Can't create tree for crypto modules." test $VERBOSE = "V" && echo "unpacking crypto tarball into $ctop..." bzcat $tarfile | shell {cd $ctop; tar xf -} typeset root="$ctop/proto/root_$MACH" test $OBJD = obj && setvar root = ""$ctop/proto/root_$MACH-nd"" test -d $root || fail "Can't unpack crypto tarball." shell {cd $root; for d in [platform kernel usr/kernel] { test ! -d $d && continue find $d -type f -print }} | while read file { typeset dir=$(dirname "$file") typeset base=$(basename "$file") typeset type=$(basename "$dir") if test $type = amd64 { setvar newdir = ""$dir/${OBJD}64"" } elif test $type = sparcv9 { setvar newdir = ""$dir/${OBJD}64"" } else { setvar newdir = ""$dir/${OBJD}32"" } mkdir -p "$root/$newdir" test $VERBOSE = "V" && echo "mv $file $newdir" mv "$root/$file" "$root/$newdir" } } # # Copy a module, or create a link, as needed. # proc copymod { match $1 { with MOD setvar targdir = "$INSTALL_FILES/$4" tstmkdir $targdir setvar target = "$targdir/$3" verbose "$INSTALL_CP $2/${OBJD}$5/$3 $target" $INSTALL_CP $2/${OBJD}$5/$3 $target || \ fail "can't create $target" with SYMLINK setvar targdir = "$INSTALL_FILES/$4" tstmkdir $targdir setvar target = "$targdir/$5" rm -f $target verbose "ln -s $3 $target" ln -s $3 $target || fail "can't create $target" with LINK setvar targdir = "$INSTALL_FILES/$5" tstmkdir $targdir setvar target = "$targdir/$6" rm -f $target verbose "ln $INSTALL_FILES/$3/$4 $target" ln $INSTALL_FILES/$3/$4 $target || fail "can't create $target" with CONF setvar target = "$INSTALL_FILES/$3" tstmkdir $(dirname $target) setvar conffile = $(basename $3) verbose "$INSTALL_CP $4/$conffile $target" $INSTALL_CP $4/$conffile $target with * fail "unrecognized modlist entry: $ifsjoin(ARGV)" } } # Sanity-check the given module list. proc check_modlist { nawk ' BEGIN { nfields["MOD"] = 6 nfields["CONF"] = 6 nfields["LINK"] = 7 nfields["SYMLINK"] = 7 } { # This also catches unknown tags. if (nfields[$1] != NF) { print "error: invalid modlist record:" print $0 print "expected", nfields[$1], "fields, found", NF status=1 } } END { exit status } ' $1 || fail "Errors in kernel module list" } # # Copy kernel modules to $INSTALL_DIR # proc copy_kernel { match $KARCH { with sun4* setvar ISA = 'sparc'; setvar MACH = 'sparc' with i86* setvar ISA = 'intel'; setvar MACH = 'i386' with * fail "${KARCH}: invalid kernel architecture" } export MACH if test $GLOM = "no" { verbose "Source = $UTS, ISA = $ISA, kernel = $KARCH" } else { verbose "Source = $UTS, ISA = $ISA, kernel = $KARCH, impl = $IMPL" } test -d $KARCH || fail "${KARCH}: invalid kernel architecture" test -d $ISA || fail "${ISA}: invalid instruction set architecture" tstmkdir $INSTALL_FILES rm -rf $modstatedir tstmkdir $modstatedir export MODSTATE=$modstatedir/state # # Figure out which "make" to use. dmake is faster than serial # make, but dmake 7.3 has a bug that causes it to lose log # output, which means the modlist might be incomplete. # setvar make = 'dmake' setvar dmvers = $($make -version) if test $Status -ne 0 { setvar make = '/usr/ccs/bin/make' } elif [[ $dmvers = *Distributed?Make?7.3* ]] { unset make setvar searchpath = ""/ws/onnv-tools/SUNWspro/SOS10/bin /opt/SUNWspro/SOS10/bin /opt/SUNWspro/bin"" for dmpath in [$searchpath] { verbose "Trying $dmpath/dmake" if test -x $dmpath/dmake { setvar dmvers = $($dmpath/dmake -version) if [[ $dmvers != *Distributed?Make?7.3* ]] { setvar make = ""$dmpath/dmake"" break; } } } if test -z $make { setvar make = '/usr/ccs/bin/make' echo "Warning: dmake 7.3 doesn't work with Install;" \ "using $make" } } # # Get a list of all modules, configuration files, and links # that we might want to install. # verbose "Building module list..." shell {cd $KARCH'; MAKEFLAGS=e' $make -K $MODSTATE modlist.karch} | \ egrep "^MOD|^CONF|^LINK|^SYMLINK" > $modlist test $VERBOSE = "V" && cat $modlist check_modlist $modlist if test $GLOM = "yes" { fixglom $modlist $GLOMNAME filtimpl $modlist $IMPL } if [[ -n "$files" && "$files" != All ]] { filtmod $modlist $files } # # Copy modules and create links. For architectures with both # 32- and 64-bit modules, we'll likely have duplicate # configuration files, so do those after filtering out the # duplicates. # verbose "Copying files to ${INSTALL_FILES}..." # # The IFS is reset to the newline character so we can buffer the # output of grep without piping it directly to copymod, otherwise # if fail() is called, then it will deadlock in fail()'s wait call # setvar OIFS = "$IFS" setvar IFS = "" "" set -- $(grep -v "^CONF" $modlist); setvar IFS = "$OIFS" for onemod in [@ARGV] { copymod $onemod } setvar OIFS = "$IFS" setvar IFS = "" "" set -- $(grep "^CONF" $modlist | sort | uniq); setvar IFS = "$OIFS" for onemod in [@ARGV] { copymod $onemod } # # Add the glommed kernel name to the root archive # if [[ $GLOM == "yes" ]] { setvar filelist = ""$INSTALL_FILES/etc/boot/solaris/filelist.ramdisk"" mkdir -p $(dirname $filelist) echo "platform/$KARCH/$GLOMNAME" >$filelist } setvar STATE = '1' # all kernel modules copied correctly save_state } proc kmdb_copy { typeset src="$1" typeset destdir="$2" if [[ ! -d $dest ]] { [[ "$VERBOSE" != "q" ]] && echo "mkdir -p $destdir" mkdir -p $destdir || fail "failed to create $destdir" } [[ "$VERBOSE" != "q" ]] && echo "cp $src $destdir" cp $src $destdir || fail "failed to copy $src to $destdir" } proc kmdb_copy_machkmods { typeset modbase="$1" typeset destdir="$2" typeset dir= typeset kmod= [[ ! -d $modbase ]] && return for dir in [$(find $modbase -name kmod)] { set -- $(echo $dir |tr '/' ' ') [[ $# -lt 2 ]] && fail "invalid mach kmod dir $dir" shift $(($# - 2)) setvar kmod = "$1" [[ ! -f $dir/$kmod ]] && continue kmdb_copy $dir/$kmod $destdir } } proc kmdb_copy_karchkmods { typeset modbase="$1" typeset destdir="$2" typeset bitdir="$3" typeset dir= typeset kmod= typeset karch= [[ ! -d $modbase ]] && return for dir in [$(find $modbase -name kmod)] { set -- $(echo $dir | tr '/' ' ') [[ $# -lt 3 ]] && fail "invalid karch kmod dir $dir" shift $(($# - 3)) setvar kmod = "$1" setvar bdir = "$2" [[ $bdir != $bitdir ]] && continue [[ ! -f $dir/$1 ]] && continue kmdb_copy $dir/$kmod $destdir } } proc kmdb_copy_kmdbmod { typeset kmdbpath="$1" typeset destdir="$2" [[ ! -f $kmdbpath ]] && return 1 kmdb_copy $kmdbpath $destdir return 0 } proc copy_kmdb { typeset kmdbtgtdir=$INSTALL_FILES/platform/$KARCH/$GLOMNAME/misc typeset bitdirs= typeset isadir= typeset b64srcdir= typeset b64tgtdir= typeset b32srcdir= typeset b32tgtdir= typeset machdir= typeset platdir= if [[ $KMDB = "no" || ! -d $SRC/cmd/mdb ]] { # The kmdb copy was suppressed or the workspace doesn't contain # the mdb subtree. Either way, there's nothing to do. setvar STATE = '2' save_state return } if [[ $(mach) = "i386" ]] { setvar isadir = ""intel"" setvar b64srcdir = ""amd64"" setvar b64tgtdir = ""amd64"" setvar b32srcdir = ""ia32"" setvar b32tgtdir = ""."" } else { setvar isadir = ""sparc"" setvar b64srcdir = ""v9"" setvar b64tgtdir = ""sparcv9"" setvar b32srcdir = ""v7"" setvar b32tgtdir = ""."" } typeset foundkmdb=no typeset kmdbpath= typeset destdir= setvar platdir = "$INSTALL_FILES/platform/$KARCH/$GLOMNAME" if [[ $GLOM = "yes" ]] { setvar machdir = "$platdir" } else { setvar machdir = "$INSTALL_FILES/kernel" } setvar srctrees = "$SRC" if [[ $WANT64 = "yes" ]] { # kmdbmod for sparc and x86 are built and installed # in different places if [[ $(mach) = "i386" ]] { setvar kmdbpath = "$SRC/cmd/mdb/$isadir/$b64srcdir/kmdb/kmdbmod" setvar destdir = "$machdir/misc/$b64tgtdir" } else { setvar kmdbpath = "$SRC/cmd/mdb/$KARCH/$b64srcdir/kmdb/kmdbmod" setvar destdir = "$platdir/misc/$b64tgtdir" } if kmdb_copy_kmdbmod $kmdbpath $destdir { setvar foundkmdb = ""yes"" for tree in [$srctrees] { kmdb_copy_machkmods \ $tree/cmd/mdb/$isadir/$b64srcdir \ $machdir/kmdb/$b64tgtdir kmdb_copy_karchkmods $tree/cmd/mdb/$KARCH \ $platdir/kmdb/$b64tgtdir $b64srcdir } } } if [[ $WANT32 = "yes" ]] { setvar kmdbpath = "$SRC/cmd/mdb/$isadir/$b32srcdir/kmdb/kmdbmod" setvar destdir = "$machdir/misc/$b32tgtdir" if kmdb_copy_kmdbmod $kmdbpath $destdir { setvar foundkmdb = ""yes"" for tree in [$srctrees] { kmdb_copy_machkmods \ $tree/cmd/mdb/$isadir/$b32srcdir \ $machdir/kmdb/$b32tgtdir kmdb_copy_karchkmods $tree/cmd/mdb/$KARCH \ $platdir/kmdb/$b32tgtdir $b32srcdir } } } # A kmdb-less workspace isn't fatal, but it is potentially problematic, # as the changes made to uts may have altered something upon which kmdb # depends. We will therefore remind the user that they haven't built it # yet. if [[ $foundkmdb != "yes" ]] { echo "WARNING: kmdb isn't built, and won't be included" } setvar STATE = '2' save_state return } # # Make tarfile # proc make_tarfile { echo "Creating tarfile $TARFILE" test -d $INSTALL_FILES || fail "Can't find $INSTALL_FILES" cd $INSTALL_FILES rm -f $TARFILE files # We don't want to change the permissions or ownership of pre-existing # directories on the target machine, so we're going to take care to # avoid including directories in the tarfile. On extraction, tar won't # modify pre-existing directories, and will create non-existent ones as # the user doing the extraction. find . ! -type d -print |fgrep -vx './files' >files tar cf $TARFILE -I files || fail "Couldn't create tarfile $TARFILE" setvar STATE = '3' } # # Routines to copy files to the target machine # proc remote_fail { fail "" $1 "" \ "Make sure that $TARGET_MACHINE is up." \ "Check .rhosts in the home directory of user $TARGET_USER on $TARGET_MACHINE." \ "Check /etc/hosts.equiv, /etc/passwd, and /etc/shadow." \ "Change permissions on $TARGET_MACHINE as necessary." \ "Then, use \"$INSTALL -R\" to resume the install." "" } proc remote_install { if test $IMODE = "n" { setvar STATE = '4' return 0 } test -s $TARFILE || fail "$TARFILE missing or empty" verbose "Installing system on $TARGET" test -d $INSTALL_DIR || fail "Can't find $INSTALL_DIR" cd $INSTALL_DIR rm -f errors fatal nonfatal if test $IMODE = "T" { setvar EMESG = ""Can't rcp to $TARGET"" touch errors sh -e${SHV}c "$INSTALL_RCP $TARFILE $TARGET/Install.tar" } else { setvar EMESG = ""Can't rsh to $TARGET_MACHINE"" rsh -l $TARGET_USER $TARGET_MACHINE \ "(cd $TARGET_DIR; /usr/bin/tar x${V}f -)" \ <$TARFILE 2>errors } test $Status -ne 0 && remote_fail $EMESG cd $INSTALL_DIR egrep "set time|warning|blocksize" errors >nonfatal egrep -v "set time|warning|blocksize" errors >fatal if test -s fatal { echo "Fatal errors from rsh:" cat fatal remote_fail "Can't install on $TARGET_MACHINE" } if test -s nonfatal -a $VERBOSE != "q" { echo "Non-fatal errors from rsh:" cat nonfatal } rm -f fatal nonfatal errors test $IMODE = "T" && echo "Files can be extracted on \ $TARGET_MACHINE using 'tar xvf $TARGET_DIR/Install.tar'" setvar STATE = '4' } proc okexit { cd /tmp test $CLEANUP = c && remove_dir $INSTALL_DIR save_state rm -rf $modstatedir rm -f $modlist test -n $cryptotree && rm -rf $cryptotree verbose "Install complete" exit 0 } # # Process options # setvar RCOPTS = """" setvar LIBCREATE = ""no"" setvar LIBSRC = """" setvar ENV_PATH = "$CODEMGR_WS" setvar OBJD = ""debug"" setvar KMDB = ""yes"" test -s $INSTALL_RC && setvar RCOPTS = $(cat $INSTALL_RC) set $INSTALL $DEFAULT_OPTIONS $RCOPTS $ifsjoin(ARGV) shift while getopts acd:D:G:hi:k:Kl:Lmno:pPqRs:t:T:uvVw:xX36 opt { match $opt { with w setvar ENV_PATH = "$OPTARG"; setvar SRC = ""$ENV_PATH/usr/src"" with s setvar UTS = "$OPTARG" with k setvar KARCH = "$OPTARG" with t|T setvar TARGET = "$OPTARG"; setvar IMODE = "$opt"; setvar CLEANUP = ""c"" with n setvar TARGET = """"; setvar IMODE = ""n""; setvar CLEANUP = ""p"" with u setvar files = ""unix genunix"" with m setvar files = ""Modules"" with a setvar files = ""All"" with v|V|q setvar VERBOSE = "$opt" with c|p setvar CLEANUP = "$opt" with L setvar LIBCREATE = ""yes""; setvar CLEANUP = ""c"" with l setvar LIBSRC = "$OPTARG" with D setvar INSTALL_LIB = "$OPTARG" with d setvar INSTALL_DIR = ""$OPTARG/$TRAILER"" with G setvar GLOM = 'yes'; setvar GLOMNAME = "$OPTARG" with P|X|x echo "-$opt is obsolete; ignored" with h usage "${INSTALL}: installs unix and modules" with R setvar x = "$OPTIND"; restore_state; setvar OPTIND = "$x" with i setvar IMPL = "$OPTARG" with o setvar OBJD = "$OPTARG" with K setvar KMDB = ""no"" with 3 setvar WANT64 = ""no"" with 6 setvar WANT32 = ""no"" with \? usage "Illegal option" } } shift $(expr $OPTIND - 1) setvar ENV_NAME = $(basename $ENV_PATH) # # The rest of the command line is a list of individual files to copy. # If non-null, this list overrides the -uma options. # if [[ $# -gt 0 ]] { setvar files = ""$ifsjoin(ARGV)"" setvar KMDB = ""no"" } match $VERBOSE { with v setvar V = ""v""; setvar SHV = ""x"" with V setvar V = ""v""; setvar SHV = ""x""; set -x with q setvar V = """"; setvar SHV = """" } # # Create temp directory for Install's files # tstmkdir $INSTALL_DIR setvar TARFILE = "$INSTALL_DIR/Install.${KARCH}.tar" setvar INSTALL_FILES = "$INSTALL_DIR/$KARCH" # # Extract the target machine and target directory from a target of the # form [user@]machine:/dir . # if test $IMODE != "n" { eval $(echo $TARGET | nawk -F':' '{ if (NF != 2 || !length($1) || !length($2)) print "usage \"Invalid target\"" m = $1; d = $2 if ($1 ~ /@/) { k = split($1, f, "@"); if (k != 2 || !length(f[1]) || !length (f[2])) print "usage \"Invalid target\"" u = f[1]; m = f[2] } print "TARGET_USER=" u ";" print "TARGET_MACHINE=" m ";" print "TARGET_DIR=" d ";" }) if test -z $TARGET_USER { setvar TARGET_USER = "$LOGNAME" } } # # Allow the use of library source or target for the install # if test -n $LIBSRC { setvar LIBSRC = ""$(basename $LIBSRC .tar).tar"" setvar TARFILE = "$INSTALL_LIB/$LIBSRC" test -s $TARFILE || fail "Can't find tarfile $TARFILE" verbose "Installing from library tarfile $TARFILE" setvar STATE = '3' } elif test $LIBCREATE = "yes" { tstmkdir $INSTALL_LIB setvar TARFILE = ""$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar"" } # # The next few lines allow recovery and activation with -R, # and library installs with -l. # [[ $STATE -eq 1 ]] && copy_kmdb [[ $STATE -eq 2 ]] && make_tarfile [[ $STATE -eq 3 ]] && remote_install [[ $STATE -eq 4 ]] && okexit save_state cd $DOT setvar DOTDOT = $(cd ..; pwd) # # Try to be smart: if DOTDOT ends in uts, then infer UTS and KARCH from DOT # Otherwise, if SRC is set, infer UTS = $SRC/uts. # if test $(basename $DOTDOT) = "uts" { setvar UTS = "$DOTDOT" setvar KARCH = $(basename $DOT) if test ! -n $SRC { setvar SRC = $(dirname $DOTDOT) verbose "Setting SRC to $SRC" } export SRC } if test -z $UTS -a -n $SRC { setvar UTS = ""${SRC}/uts"" test -n $KARCH || fail "no karch specified (e.g. -k sun4u)" } if test $LIBCREATE = "yes" { setvar TARFILE = "$INSTALL_LIB/${ENV_NAME}.${KARCH}.tar" } else { setvar TARFILE = "$INSTALL_DIR/Install.${KARCH}.tar" } setvar INSTALL_FILES = "$INSTALL_DIR/$KARCH" save_state cd $DOT test -z $UTS && fail 'Cannot find kernel sources -- $SRC not set' test -d $UTS || fail "${UTS}: no such directory" # # Convert UTS into an absolute path. # cd $UTS setvar UTS = $(pwd) test $(basename $UTS) = "uts" || \ verbose "Warning: source path $UTS doesn't end in 'uts'" remove_dir $INSTALL_DIR/$KARCH rm -f $TARFILE copy_kernel # sets STATE=1 if successful copy_kmdb # sets STATE=2 if successful make_tarfile # sets STATE=3 if successful remote_install # sets STATE=4 if successful okexit