Mercurial > illumos > illumos-gate
changeset 10840:7df556caf412
PSARC 2009/253 S10C
6666646 Solaris 10 zones on OpenSolaris binary (supported) distributions
line wrap: on
line diff
--- a/usr/src/Makefile.lint Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/Makefile.lint Thu Oct 22 11:21:27 2009 -0700 @@ -329,6 +329,7 @@ lib/auditd_plugins \ lib/brand/native \ lib/brand/sn1 \ + lib/brand/solaris10 \ lib/cfgadm_plugins/sdcard \ lib/crypt_modules \ lib/extendedFILE \
--- a/usr/src/Targetdirs Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/Targetdirs Thu Oct 22 11:21:27 2009 -0700 @@ -88,6 +88,7 @@ /etc \ /etc/brand \ /etc/brand/native \ + /etc/brand/solaris10 \ /etc/certs \ /etc/cron.d \ /etc/crypto \ @@ -209,6 +210,7 @@ /usr/lib/brand/native \ /usr/lib/brand/shared \ /usr/lib/brand/sn1 \ + /usr/lib/brand/solaris10 \ /usr/lib/class \ /usr/lib/class/FSS \ /usr/lib/class/FX \ @@ -408,6 +410,7 @@ /usr/lib/$(MACH64) \ /usr/lib/$(MACH64)/gss \ /usr/lib/brand/sn1/$(MACH64) \ + /usr/lib/brand/solaris10/$(MACH64) \ /usr/lib/elfedit/$(MACH64) \ /usr/lib/fm/$(MACH64) \ /usr/lib/fs/nfs/$(MACH64) \ @@ -481,6 +484,7 @@ /lib/secure/64 \ /usr/lib/64 \ /usr/lib/brand/sn1/64 \ + /usr/lib/brand/solaris10/64 \ /usr/lib/elfedit/64 \ /usr/lib/libp/64 \ /usr/lib/link_audit/64 \ @@ -589,6 +593,7 @@ $(BUILD64) $(ROOT)/usr/lib/elfedit/64:= LINKDEST=$(MACH64) $(BUILD64) $(ROOT)/usr/lib/brand/lx/64:= LINKDEST=$(MACH64) $(BUILD64) $(ROOT)/usr/lib/brand/sn1/64:= LINKDEST=$(MACH64) +$(BUILD64) $(ROOT)/usr/lib/brand/solaris10/64:= LINKDEST=$(MACH64) $(BUILD64) $(ROOT)/usr/lib/libp/64:= LINKDEST=$(MACH64) $(BUILD64) $(ROOT)/usr/lib/lwp/64:= LINKDEST=$(MACH64) $(BUILD64) $(ROOT)/usr/lib/link_audit/64:= LINKDEST=$(MACH64)
--- a/usr/src/lib/brand/Makefile Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/lib/brand/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -34,8 +34,8 @@ i386_SUBDIRS= lx i386_MSGSUBDIRS= lx -SUBDIRS= sn1 native $($(MACH)_SUBDIRS) -MSGSUBDIRS= native $($(MACH)_MSGSUBDIRS) +SUBDIRS= sn1 solaris10 native $($(MACH)_SUBDIRS) +MSGSUBDIRS= solaris10 native $($(MACH)_MSGSUBDIRS) all := TARGET= all install := TARGET= install
--- a/usr/src/lib/brand/Makefile.brand Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/lib/brand/Makefile.brand Thu Oct 22 11:21:27 2009 -0700 @@ -30,11 +30,13 @@ ROOTBRANDDIR= $(ROOTDIR)/$(BRAND) ROOTBRANDDIR64= $(ROOTDIR)/$(BRAND)/$(MACH64) ROOTSHAREDDIR= $(ROOTDIR)/shared +ETCBRANDDIR= $(ROOT)/etc/brand/$(BRAND) ROOTPROGS= $(PROGS:%=$(ROOTBRANDDIR)/%) ROOTTXTS= $(TXTS:%=$(ROOTBRANDDIR)/%) ROOTXMLDOCS= $(XMLDOCS:%=$(ROOTBRANDDIR)/%) ROOTSHARED= $(SHARED:%=$(ROOTSHAREDDIR)/%) +ETCUSER= $(USERFILES:%=$(ETCBRANDDIR)/%) ROOTTEMPLATES= $(TEMPLATES:%=$(ROOTTEMPLATEDIR)/%) @@ -42,7 +44,7 @@ $(ROOTXMLDOCS) := FILEMODE = 444 -$(ROOTSHARED) := FILEMODE = 444 +$(ROOTSHARED) := FILEMODE = 755 $(ROOTTEMPLATEDIR) := FILEMODE = 755 @@ -52,9 +54,13 @@ $(ROOTPROGS) := FILEMODE = 755 -$(ROOTBRANDDIR)/% $(ROOTBRANDDIR64)/% $(ROOTTEMPLATEDIR)/% $(ROOTSHAREDDIR)/%: % +$(ROOTBRANDDIR)/% $(ROOTBRANDDIR64)/% $(ROOTTEMPLATEDIR)/% $(ROOTSHAREDDIR)/% $(ETCBRANDDIR)/%: % $(INS.file) +$(ETCUSER) := FILEMODE = 644 +$(ETCUSER) := OWNER = root +$(ETCUSER) := GROUP = sys + .SUFFIXES: .ksh .ksh:
--- a/usr/src/lib/brand/lx/lx_support/Makefile Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/lib/brand/lx/lx_support/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -19,10 +19,9 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" PROG = lx_support PROGS = $(PROG) @@ -31,13 +30,13 @@ all: $(PROG) include ../Makefile.lx -include ../../../../cmd/Makefile.cmd +include $(SRC)/cmd/Makefile.cmd # override the install directory ROOTBIN = $(ROOTBRANDDIR) CLOBBERFILES = $(OBJS) $(ROOTPROGS) -UTSBASE = ../../../../uts +UTSBASE = $(SRC)/uts CFLAGS += $(CCVERBOSE) CPPFLAGS += -D_REENTRANT -I$(UTSBASE)/common/brand/lx @@ -52,4 +51,4 @@ lint: lint_PROG -include ../../../../cmd/Makefile.targ +include $(SRC)/cmd/Makefile.targ
--- a/usr/src/lib/brand/native/zone/Makefile Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/lib/brand/native/zone/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -24,19 +24,12 @@ # Use is subject to license terms. # -ETCBRANDDIR= $(ROOT)/etc/brand/native -ETCUSER= $(USERFILES:%=$(ETCBRANDDIR)/%) -$(ETCUSER) := FILEMODE = 644 - -$(ETCBRANDDIR)/%: % - $(INS.file) - PROG= sw_support BRAND= native PROGS= attach_update image_install p2v $(PROG) XMLDOCS= config.xml platform.xml smf_disable.lst pkgrm.lst USERFILES= smf_disable.conf pkgrm.conf -SHARED= common.ksh +SHARED= common.ksh query uninstall.ksh TEMPLATES= SUNWdefault.xml SUNWblank.xml CLOBBERFILES= $(ROOTPROGS) $(ROOTXMLDOCS) $(ROOTTEMPLATES) $(ROOTSHARED) \ $(ETCUSER) @@ -46,10 +39,13 @@ include $(SRC)/cmd/Makefile.cmd include ../../Makefile.brand +$(ROOTSHAREDDIR)/common.ksh := FILEMODE = 444 +$(ROOTSHAREDDIR)/uninstall.ksh := FILEMODE = 444 + CPPFLAGS += -I/usr/include/libxml2 -D_REENTRANT LDLIBS += -lzonecfg -luutil -POFILES= $(PROGS:%=%.po) common.po +POFILES= $(PROGS:%=%.po) common.po query.po uninstall.po POFILE= native_zone.po $(POFILE): $(POFILES)
--- a/usr/src/lib/brand/native/zone/common.ksh Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/lib/brand/native/zone/common.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -43,6 +43,13 @@ exit $EXIT_CODE } +fail_fatal() { + printf "ERROR: " + printf "$@" + printf "\n" + exit $ZONE_SUBPROC_FATAL +} + # # Send the provided printf()-style arguments to the screen and to the logfile. # @@ -68,7 +75,24 @@ [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2 } +# # Validate that the directory is safe. +# +# It is possible for a malicious zone root user to modify a zone's filesystem +# so that modifications made to the zone's filesystem by administrators in the +# global zone modify the global zone's filesystem. We can prevent this by +# ensuring that all components of paths accessed by scripts are real (i.e., +# non-symlink) directories. +# +# NOTE: The specified path should be an absolute path as would be seen from +# within the zone. Also, this function does not check parent directories. +# If, for example, you need to ensure that every component of the path +# '/foo/bar/baz' is a directory and not a symlink, then do the following: +# +# safe_dir /foo +# safe_dir /foo/bar +# safe_dir /foo/bar/baz +# safe_dir() { typeset dir="$1" @@ -78,6 +102,18 @@ fi } +# Like safe_dir except the dir doesn't have to exist. +safe_opt_dir() +{ + typeset dir="$1" + + [[ ! -e $ZONEROOT/$dir ]] && return + + if [[ -h $ZONEROOT/$dir || ! -d $ZONEROOT/$dir ]]; then + fatal "$e_baddir" "$dir" + fi +} + # Only make a copy if we haven't already done so. safe_backup() { @@ -111,6 +147,64 @@ fi } +safe_rm() +{ + if [[ ! -h $ZONEROOT/$1 && -f $ZONEROOT/$1 ]]; then + rm -f "$ZONEROOT/$1" + fi +} + +# +# Replace the file with a wrapper pointing to the native brand code. +# However, we only do the replacement if the file hasn't already been +# replaced with our wrapper. This function expects the cwd to be the +# location of the file we're replacing. +# +# Some of the files we're replacing are hardlinks to isaexec so we need to 'rm' +# the file before we setup the wrapper while others are hardlinks to rc scripts +# that we need to maintain. +# +safe_replace() +{ + typeset filename="$1" + typeset runname="$2" + typeset mode="$3" + typeset own="$4" + typeset rem="$5" + + if [ -h $filename -o ! -f $filename ]; then + return + fi + + egrep -s "Solaris Brand Replacement" $filename + if [ $? -eq 0 ]; then + return + fi + + safe_backup $filename $filename.pre_p2v + if [ $rem = "remove" ]; then + rm -f $filename + fi + + cat <<-END >$filename || exit 1 + #!/bin/sh + # + # Solaris Brand Replacement + # + # Attention. This file has been replaced with a new version for + # use in a virtualized environment. Modification of this script is not + # supported and all changes will be lost upon reboot. The + # {name}.pre_p2v version of this file is a backup copy of the + # original and should not be deleted. + # + END + + echo ". $runname \"\$@\"" >>$filename || exit 1 + + chmod $mode $filename + chown $own $filename +} + # # Read zonecfg ipd and fs entries and save the relevant data, one entry per # line. @@ -218,6 +312,19 @@ }' >>$LOGFILE } +# Find the dataset mounted on the zonepath. +get_zonepath_ds() { + ZONEPATH_DS=`/usr/sbin/zfs list -H -t filesystem -o name,mountpoint | \ + /usr/bin/nawk -v zonepath=$1 '{ + if ($2 == zonepath) + print $1 + }'` + + if [ -z "$ZONEPATH_DS" ]; then + fail_fatal "$f_no_ds" + fi +} + # # Perform any cleanup in the zoneroot after unpacking the archive. # @@ -893,6 +1000,9 @@ e_mismatch_archive=$(gettext "Error: the archive top-level directory (%s) does not match the zonepath (%s).") e_tmpfile=$(gettext "Unable to create temporary file") e_root_full=$(gettext "Zonepath root %s exists and contains data; remove or move aside prior to install.") +f_mkdir=$(gettext "Unable to create directory %s.") +f_chmod=$(gettext "Unable to chmod directory %s.") +f_chown=$(gettext "Unable to chown directory %s.") m_analyse_archive=$(gettext "Analysing the archive")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/native/zone/query.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,47 @@ +#!/bin/ksh -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PATH=/usr/bin:/usr/sbin +export PATH + +. /usr/lib/brand/shared/common.ksh + +zonename=$1 +zonepath=$2 +cmd=$3 + +if [ $3 == "datasets" ]; then + get_zonepath_ds $zonepath + + DS=`/usr/sbin/zfs list -H -t filesystem -o name $ZONEPATH_DS/ROOT` + if [ ! -z "$DS" ]; then + echo "$DS\c" + else + fail_fatal "$f_no_ds" + fi +fi + +exit $ZONE_SUBPROC_OK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/native/zone/uninstall.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,721 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# get script name (bname) +# +bname=`basename $0` + +# +# common shell script functions +# +. /usr/lib/brand/shared/common.ksh + +# +# error messages +# +m_usage=$(gettext "Usage: %s: [-hFn]") + +m_1_zfs_promote=$(gettext "promoting '%s'.") +m_1_zfs_destroy=$(gettext "destroying '%s'.") +m_2_zfs_rename=$(gettext "renaming '%s' to '%s'.") +m_3_zfs_set=$(gettext "setting property %s='%s' for '%s'.") +m_rm_r=$(gettext "recursively deleting '%s'.") +m_rm=$(gettext "deleting '%s'.") + +w_no_ds=$(gettext "Warning: no zonepath dataset found.") + +f_usage_err=$(gettext "Error: invalid usage") +f_abort=$(gettext "Error: internal error detected, aborting.") +f_1_zfs_promote=$(gettext "Error: promoting ZFS dataset '%s'.") +f_2_zfs_rename=$(gettext "Error: renaming ZFS dataset '%s' to '%s'.") +f_3_zfs_set=$(gettext "Error: setting ZFS propery %s='%s' for '%s'.") +f_1_zfs_destroy=$(gettext "Error: destroying ZFS dataset.") +f_2_zfs_get=$(gettext "Error: reading ZFS dataset property '%s' from '%s'.") +f_user_snap=$(gettext "Error: user snapshot(s) detected.") +f_stray_snap=$(gettext "Error: uncloned snapshot(s) detected.") +f_stray_clone=$(gettext "Error: cloned zone datasets found outsize of zone.") +f_rm_snap=$(gettext "Error: please delete snapshot(s) and retry uninstall.") +f_rm_clone=$(gettext "Error: please delete clone(s) and retry uninstall.") +f_iu_clone=$(gettext "Error: cloned zone dataset(s) in use.") +f_dis_clone=$(gettext "Error: please stop using clone(s) and retry uninstall.") + +# +# functions +# +print_array() +{ + typeset -n pa_array=$1 + + (( pa_i = 0 )) + while (( $pa_i < ${#pa_array[@]} )); do + printf "\t${pa_array[$pa_i]}\n" + (( pa_i = $pa_i + 1 )) + done +} + +usage() +{ + printf "$m_usage\n" "$bname" + exit $ZONE_SUBPROC_USAGE +} + +usage_err() +{ + printf "$f_usage_err\n" >&2 + usage >&2 +} + +rm_zonepath() +{ + # cleanup stuff we know about and leave any user data alone + + [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && + printf "$m_rm\n" "$zonepath/SUNWattached.xml" + $nop /bin/rm -f "$zonepath/SUNWattached.xml" + + [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && + printf "$m_rm_r\n" "$zonepath/lu" + $nop /bin/rm -rf "$zonepath/lu" + + [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && + printf "$m_rm_r\n" "$zonepath/dev" + $nop /bin/rm -rf "$zonepath/dev" + + [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && + printf "$m_rm_r\n" "$zonepath/root" + $nop /bin/rm -rf "$zonepath/root" + + [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && + printf "$m_rm\n" "$zonepath" + $nop /bin/rmdir "$zonepath" 2>/dev/null +} + +zfs_destroy() +{ + zd_fs1="$1" + + # first figure out if the target fs has an origin snapshot + zd_origin=`/sbin/zfs get -H -o value origin "$zd_fs1"` + if [[ $? != 0 ]]; then + printf "$f_2_zfs_get\n" origin "$zd_fs1" >&2 + exit $ZONE_SUBPROC_FATAL + fi + + [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && + printf "$m_1_zfs_destroy\n" "$zd_fs1" + + # + # note that we specify the '-r' flag so that we destroy any + # descendants (filesystems and snapshot) of the specified + # filesystem. + # + $nop /sbin/zfs destroy -r "$zd_fs1" + if [[ $? != 0 ]]; then + printf "$f_1_zfs_destroy\n" "$zd_fs1" >&2 + exit $ZONE_SUBPROC_FATAL + fi + + [[ "$zd_origin" == "-" ]] && return + + [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && + printf "$m_1_zfs_destroy\n" "$zd_origin" + + $nop /sbin/zfs destroy "$zd_origin" 2>/dev/null + # + # we ignore errors while trying to destroy the origin since + # the origin could have been used as the source for other + # clones + # +} + +zfs_promote() +{ + zp_fs1="$1" + + [[ -z "$opt_n" ]] && + printf "$m_1_zfs_promote\n" "$zp_fs1" + + $nop /sbin/zfs promote "$zp_fs1" + if [[ $? != 0 ]]; then + printf "$f_1_zfs_promote\n" "$zp_fs1" >&2 + exit $ZONE_SUBPROC_FATAL + fi +} + +zfs_rename() +{ + zr_fs1="$1" + zr_fs2="$2" + + [[ -z "$opt_n" ]] && + printf "$m_2_zfs_rename\n" "$zr_fs1" "$zr_fs2" + + $nop /sbin/zfs rename "$zr_fs1" "$zr_fs2" + if [[ $? != 0 ]]; then + printf "$f_2_zfs_rename\n" "$zr_fs1" "$zr_fs2" >&2 + return 1 + fi + return 0 +} + +zfs_set() +{ + zs_prop=$1 + zs_value=$2 + zs_fs1=$3 + + [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && + printf "$m_3_zfs_set\n" "$zs_prop" "$zs_value" "$zs_fs1" + + $nop /sbin/zfs set "$zs_prop"="$zs_value" "$zs_fs1" + if [[ $? != 0 ]]; then + printf "$f_3_zfs_set\n" "$zs_prop" "$zs_value" "$zs_fs1" + return 1 + fi + return 0 +} + +zfs_set_array() +{ + zsa_prop=$1 + zsa_value=$2 + typeset -n zsa_array=$3 + zsa_ignore_errors=$4 + + (( zsa_i = 0 )) + while (( $zsa_i < ${#zsa_array[@]} )); do + zfs_set "$zsa_prop" "$zsa_value" "${zsa_array[$zsa_i]}" + [[ $? != 0 ]] && [[ -z "$zsa_ignore_errors" ]] && + return 1 + (( zsa_i = $zsa_i + 1 )) + done + return 0 +} + + +(( snap_rename_zbe_i = 1 )) +(( snap_rename_snap_i = 1 )) +snap_rename_init() +{ + (( snap_rename_zbe_i = 1 )) + (( snap_rename_snap_i = 1 )) +} + +snap_rename() +{ + eval sr_fs=\${$1} + eval sr_snap=\${$2} + + if [[ "$sr_snap" == ~(Elr)(zbe-[0-9][0-9]*) ]]; then + sr_snap="zbe-$snap_rename_zbe_i" + (( snap_rename_zbe_i = $snap_rename_zbe_i + 1 )) + elif [[ "$sr_snap" == ~(Er)(_snap[0-9]*) ]]; then + sr_snap=${sr_snap##~(Er)([0-9]*)} + sr_snap="${sr_snap}${snap_rename_snap_i}" + (( snap_rename_snap_i = $snap_rename_snap_i + 1 )) + else + printf "$f_user_snap\n" >&2 + printf "\t$sr_fs@$sr_snap\n" >&2 + printf "$f_rm_snap\n" >&2 + exit $ZONE_SUBPROC_FATAL + fi + + eval $2="$sr_snap" +} + +# find the dataset associated with $zonepath +uninstall_get_zonepath_ds() +{ + ZONEPATH_DS=`/sbin/zfs list -t filesystem -o name,mountpoint | \ + /bin/nawk -v zonepath=$zonepath '{ + if ($2 == zonepath) + print $1 + }'` + + if [ -z "$ZONEPATH_DS" ]; then + # there is no $zonepath dataset + rm_zonepath + exit $ZONE_SUBPROC_OK + fi +} + +# find the dataset associated with $ZONEPATH_DS/ROOT +uninstall_get_zonepath_root_ds() +{ + ZONEPATH_RDS=`/sbin/zfs list -H -t filesystem -o name \ + $ZONEPATH_DS/ROOT 2>/dev/null` + + if [ -z "$ZONEPATH_RDS" ]; then + # there is no $ZONEPATH_DS/ROOT dataset + c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_DS | wc -l` + if [ $c = 1 ]; then + # $zonepath dataset has no descendents + zfs_destroy "$ZONEPATH_DS" + fi + rm_zonepath + exit $ZONE_SUBPROC_OK + fi +} + +destroy_zone_dataset() +{ + fs=$1 + + pool=${fs%%/*} + + # Fastpath. if there are no snapshots of $fs then just delete it. + c=`/sbin/zfs list -H -t snapshot -o name -r $fs | grep "^$fs@" | + LC_ALL=C LANG=C wc -l` + if (( $c == 0 )) ; then + zfs_destroy "$fs" + return + fi + + # + # This zone BE has snapshots. This can happen if a zone has + # multiple BEs (in which case we have snapshots named "zbe-XXX"), + # if this zone has been used as the source for a clone of + # another zone (in which case we have snapshots named + # "XXX_snap"), or if an administrator has been doing manual + # snapshotting. + # + # To be able to destroy this dataset (which we'll call the + # origin) we need to get rid of all it's snapshots. The "easiest" + # way to do this is to: + # + # - delete any uncloned origin snapshots + # - find the oldest clone of the youngest origin snapshot (which + # we'll call the oldest clone) + # - check if there are any snapshots naming conflicts between + # the origin and the oldest clone. + # - if so, find any clones of those conflicting origin snapshots + # - make sure that those clones are not zoned an in-use. + # - if any of those clones are zoned, unzone them. + # - rename origin snapshots to eliminate naming conflicts + # - for any clones that we unzoned, rezone them. + # - promote the oldest clone + # - destroy the origin and all it's descendants + # + + # + # Get a list of all the cloned datasets within the zpool + # containing the origin filesystem. Filter out any filesystems + # that are descendants of origin because we are planning to + # destroy them anyway. + # + unset clones clones_origin + (( clones_c = 0 )) + pool=${fs%%/*} + LANG=C LC_ALL=C /sbin/zfs list -H -t filesystem -s creation \ + -o name,origin -r "$pool" | + while IFS=" " read name origin; do + + # skip non-clone filesystems + [[ "$origin" == "-" ]] && + continue + + # skip desendents of the origin we plan to destroy + [[ "$name" == ~()(${fs}/*) ]] && + continue + + # record this clone and it's origin + clones[$clones_c]="$name" + clones_origin[$clones_c]="$origin" + (( clones_c = $clones_c + 1 )) + done + + # + # Now do a sanity check. Search for clones of a child datasets + # of the dataset we want to destroy, that are not themselves + # children of the dataset we're going to destroy). This should + # really never happen unless the global zone admin has cloned a + # snapshot of a zone filesystem to a location outside of that + # zone. bad admin... + # + unset stray_clones + (( stray_clones_c = 0 )) + (( j = 0 )) + while (( $j < $clones_c )); do + # is the clone origin a descendant of $fs? + if [[ "${clones_origin[$j]}" != ~()(${fs}/*) ]]; then + # we don't care. + (( j = $j + 1 )) + continue + fi + stray_clones[$stray_clones_c]=${clones[$j]} + (( stray_clones_c = $stray_clones_c + 1 )) + (( j = $j + 1 )) + done + if (( stray_clones_c > 0 )); then + # + # sigh. the admin has done something strange. + # tell them to clean it up and retry. + # + printf "$f_stray_clone\n" >&2 + print_array stray_clones >&2 + printf "$f_rm_clone\n" >&2 + exit $ZONE_SUBPROC_FATAL + fi + + # Find all the snapshots of the origin filesystem. + unset s_origin + (( s_origin_c = 0 )) + /sbin/zfs list -H -t snapshot -s creation -o name -r $fs | + grep "^$fs@" | while read name; do + s_origin[$s_origin_c]=$name + (( s_origin_c = $s_origin_c + 1 )) + done + + # + # Now go through the origin snapshots and find those which don't + # have clones. We're going to explicity delete these snapshots + # before we do the promotion. + # + unset s_delete + (( s_delete_c = 0 )) + (( j = 0 )) + while (( $j < $s_origin_c )); do + (( k = 0 )) + while (( $k < $clones_c )); do + # if we have a match then break out of this loop + [[ "${s_origin[$j]}" == "${clones_origin[$k]}" ]] && + break + (( k = $k + 1 )) + done + if (( $k != $clones_c )); then + # this snapshot has a clone, move on to the next one + (( j = $j + 1 )) + continue + fi + + # snapshot has no clones so add it to our delete list + s_delete[$s_delete_c]=${s_origin[$j]} + (( s_delete_c = $s_delete_c + 1 )) + # remove it from the origin snapshot list + (( k = $j + 1 )) + while (( $k < $s_origin_c )); do + s_origin[(( $k - 1 ))]=${s_origin[$k]} + (( k = $k + 1 )) + done + (( s_origin_c = $s_origin_c - 1 )) + done + + # + # Fastpath. If there are no remaining snapshots then just + # delete the origin filesystem (and all it's descendents) and + # move onto the next zone BE. + # + if (( $s_origin_c == 0 )); then + zfs_destroy "$fs" + return + fi + + # find the youngest snapshot of $fs + s_youngest=${s_origin[(( $s_origin_c - 1 ))]} + + # Find the oldest clone of the youngest snapshot of $fs + unset s_clone + (( j = $clones_c - 1 )) + while (( $j >= 0 )); do + if [[ "$s_youngest" == "${clones_origin[$j]}" ]]; then + s_clone=${clones[$j]} + break + fi + (( j = $j - 1 )) + done + if [[ -z "$s_clone" ]]; then + # uh oh. something has gone wrong. bail. + printf "$f_stray_snap\n" >&2 + printf "\t$s_youngest\n" >&2 + printf "$f_rm_snap\n" >&2 + exit $ZONE_SUBPROC_FATAL + fi + + # create an array of clone snapshot names + unset s_clone_s + (( s_clone_s_c = 0 )) + /sbin/zfs list -H -t snapshot -s creation -o name -r $s_clone | + grep "^$s_clone@" | while read name; do + s_clone_s[$s_clone_s_c]=${name##*@} + (( s_clone_s_c = $s_clone_s_c + 1 )) + done + + # create an arrays of possible origin snapshot renames + unset s_origin_snap + unset s_rename + (( j = 0 )) + while (( $j < $s_origin_c )); do + s_origin_snap[$j]=${s_origin[$j]##*@} + s_rename[$j]=${s_origin[$j]##*@} + (( j = $j + 1 )) + done + + # + # Search for snapshot name collisions between the origin and + # oldest clone. If we find one, generate a new name for the + # origin snapshot and re-do the collision check. + # + snap_rename_init + (( j = 0 )) + while (( $j < $s_origin_c )); do + (( k = 0 )) + while (( $k < $s_clone_s_c )); do + + # if there's no naming conflict continue + if [[ "${s_rename[$j]}" != "${s_clone_s[$k]}" ]]; then + (( k = $k + 1 )) + continue + fi + + # + # The origin snapshot conflicts with a clone + # snapshot. Choose a new name and then restart + # then check that against clone snapshot names. + # + snap_rename fs "s_rename[$j]" + (( k = 0 )) + continue; + done + + # if we didn't rename this snapshot then continue + if [[ "${s_rename[$j]}" == "${s_origin_snap[$j]}" ]]; then + (( j = $j + 1 )) + continue + fi + + # + # We need to rename this origin snapshot because it + # conflicts with a clone snapshot name. So above we + # chose a name that didn't conflict with any other clone + # snapshot names. But we also have to avoid naming + # conflicts with any other origin snapshot names. So + # check for that now. + # + (( k = 0 )) + while (( $k < $s_origin_c )); do + + # don't compare against ourself + if (( $j == $k )); then + (( k = $k + 1 )) + continue + fi + + # if there's no naming conflict continue + if [[ "${s_rename[$j]}" != "${s_rename[$k]}" ]]; then + (( k = $k + 1 )) + continue + fi + + # + # The new origin snapshot name conflicts with + # another origin snapshot name. Choose a new + # name and then go back to check the new name + # for uniqueness against all the clone snapshot + # names. + # + snap_rename fs "s_rename[$j]" + continue 2; + done + + # + # A new unique name has been chosen. Move on to the + # next origin snapshot. + # + (( j = $j + 1 )) + snap_rename_init + done + + # + # So now we know what snapshots need to be renamed before the + # promotion. But there's an additional problem. If any of the + # filesystems cloned from these snapshots have the "zoned" + # attribute set (which is highly likely) or if they are in use + # (and can't be unmounted and re-mounted) then the snapshot + # rename will fail. So now we'll search for all the clones of + # snapshots we plan to rename and look for ones that are zoned. + # + # We'll ignore any snapshot clones that may be in use but are + # not zoned. If these clones are in-use, the rename will fail + # and we'll abort, there's not much else we can do about it. + # But if they are not in use the snapshot rename will unmount + # and remount the clone. This is ok because when the zoned + # attribute is off, we know that the clone was originally + # mounted from the global zone. (So unmounting and remounting + # it from the global zone is ok.) + # + # But we'll abort this whole operation if we find any clones + # that that are zoned and in use. (This can happen if another + # zone has been cloned from this one and is now booted.) The + # reason we do this is because those zoned filesystems could + # have originally mounted from within the zone. So if we + # cleared the zone attribute and did the rename, we'd be + # remounting the filesystem from the global zone. This would + # result in the zone losing the ability to unmount the + # filesystem, which would be bad. + # + unset zoned_clones zoned_iu_clones + (( zoned_clones_c = 0 )) + (( zoned_iu_clones_c = 0 )) + (( j = 0 )) + # walk through all the clones + while (( $j < $clones_c )); do + # walk through all the origin snapshots + (( k = 0 )) + while (( $k < $s_origin_c )); do + # + # check if this clone originated from a snapshot that + # we need to rename. + # + [[ "${clones_origin[$j]}" == "${s_origin[$k]}" ]] && + [[ "${s_origin_snap[$k]}" != "${s_rename[$k]}" ]] && + break + (( k = $k + 1 )) + continue + done + if (( $k == $s_origin_c )); then + # This isn't a clone of a snapshot we want to rename. + (( j = $j + 1 )) + continue; + fi + + # get the zoned attr for this clone. + zoned=`LC_ALL=C LANG=C \ + /sbin/zfs get -H -o value zoned ${clones[$j]}` + if [[ "$zoned" != on ]]; then + # This clone isn't zoned so ignore it. + (( j = $j + 1 )) + continue + fi + + # remember this clone so we can muck with it's zoned attr. + zoned_clones[$zoned_clones_c]=${clones[$j]} + (( zoned_clones_c = $zoned_clones_c + 1 )) + + # check if it's in use + mounted=`LC_ALL=C LANG=C \ + /sbin/zfs get -H -o value mounted ${clones[$j]}` + if [[ "$mounted" != yes ]]; then + # Good news. This clone isn't in use. + (( j = $j + 1 )) + continue + fi + + # Sigh. This clone is in use so we're destined to fail. + zoned_iu_clones[$zoned_iu_clones_c]=${clones[$j]} + (( zoned_iu_clones_c = $zoned_iu_clones_c + 1 )) + + # keep looking for errors so we can report them all at once. + (( j = $j + 1 )) + done + if (( zoned_iu_clones_c > 0 )); then + # + # Tell the admin + # + printf "$f_iu_clone\n" >&2 + print_array zoned_iu_clones >&2 + printf "$f_dis_clone\n" >&2 + exit $ZONE_SUBPROC_FATAL + fi + + # + # Ok. So we're finally done with planning and we can do some + # damage. We're going to: + # - destroy unused snapshots + # - unzone clones which originate from snapshots we need to rename + # - rename conflicting snapshots + # - rezone any clones which we unzoned + # - promote the oldest clone of the youngest snapshot + # - finally destroy the origin filesystem. + # + + # delete any unsed snapshot + (( j = 0 )) + while (( $j < $s_delete_c )); do + zfs_destroy "${s_delete[$j]}" + (( j = $j + 1 )) + done + + # unzone clones + zfs_set_array zoned off zoned_clones || + zfs_set_array zoned on zoned_clones 1 + + # rename conflicting snapshots + (( j = 0 )) + while (( $j < $s_origin_c )); do + if [[ "${s_origin_snap[$j]}" != "${s_rename[$j]}" ]]; then + zfs_rename "${s_origin[$j]}" "$fs@${s_rename[$j]}" + if [[ $? != 0 ]]; then + # re-zone the clones before aborting + zfs_set_array zoned on zoned_clones 1 + exit $ZONE_SUBPROC_FATAL + fi + fi + (( j = $j + 1 )) + done + + # re-zone the clones + zfs_set_array zoned on zoned_clones 1 + + # promote the youngest clone of the oldest snapshot + zfs_promote "$s_clone" + + # destroy the origin filesystem and it's descendants + zfs_destroy "$fs" +} + +# +# This function expects an array named fs_all to exist which is initialized +# with the zone's ZFS datasets that should be destroyed. fs_all_c is the +# count of the number of elements in the array. ZONEPATH_RDS is the +# zonepath/root dataset and ZONEPATH_DS is the zonepath dataset. +# +destroy_zone_datasets() +{ + # Destroy the zone BEs datasets one by one. + (( i = 0 )) + while (( $i < $fs_all_c )); do + fs=${fs_all[$i]} + + destroy_zone_dataset "$fs" + (( i = $i + 1 )) + done + + # + # Check if there are any other datasets left. There may be datasets + # associated with other GZ BEs, so we need to leave things alone in + # that case. + # + c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_RDS | wc -l` + if [ $c = 1 ]; then + zfs_destroy "$ZONEPATH_RDS" + fi + c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_DS | wc -l` + if [ $c = 1 ]; then + zfs_destroy "$ZONEPATH_DS" + fi + + rm_zonepath +}
--- a/usr/src/lib/brand/sn1/librtld_db/Makefile.com Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/lib/brand/sn1/librtld_db/Makefile.com Thu Oct 22 11:21:27 2009 -0700 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -52,9 +52,9 @@ LDLIBS += -lc -lrtld_db CFLAGS += $(CCVERBOSE) CPPFLAGS += -D_REENTRANT -I../ -I$(UTSBASE)/common/brand/sn1 \ - -I../../../../../cmd/sgs/librtld_db/common \ - -I../../../../../cmd/sgs/include \ - -I../../../../../cmd/sgs/include/$(MACH) + -I$(SRC)/cmd/sgs/librtld_db/common \ + -I$(SRC)/cmd/sgs/include \ + -I$(SRC)/cmd/sgs/include/$(MACH) ROOTLIBDIR = $(ROOT)/usr/lib/brand/sn1 ROOTLIBDIR64 = $(ROOT)/usr/lib/brand/sn1/$(MACH64)
--- a/usr/src/lib/brand/sn1/sn1_brand/Makefile Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/lib/brand/sn1/sn1_brand/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -19,15 +19,15 @@ # CDDL HEADER END # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -include ../../../Makefile.lib +include $(SRC)/lib/Makefile.lib default: all -SUBDIRS = $(MACH) $(VARIANT_SUBDIRS) +SUBDIRS = $(MACH) $(BUILD64)SUBDIRS += $(MACH64) all := TARGET= all @@ -39,9 +39,7 @@ .KEEP_STATE: -all install clean clobber _msg: $(SUBDIRS) - -lint: $(SUBDIRS) +all install clean clobber lint _msg: $(SUBDIRS) $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET)
--- a/usr/src/lib/brand/sn1/zone/config.xml Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/lib/brand/sn1/zone/config.xml Thu Oct 22 11:21:27 2009 -0700 @@ -59,6 +59,7 @@ <privilege set="default" name="net_bindmlp" /> <privilege set="default" name="net_icmpaccess" /> <privilege set="default" name="net_mac_aware" /> + <privilege set="default" name="net_observability" /> <privilege set="default" name="net_privaddr" /> <privilege set="default" name="net_rawaccess" ip-type="exclusive" /> <privilege set="default" name="proc_chroot" />
--- a/usr/src/lib/brand/sn1/zone/platform.xml Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/lib/brand/sn1/zone/platform.xml Thu Oct 22 11:21:27 2009 -0700 @@ -49,6 +49,7 @@ <!-- Devices to create under /dev --> <device match="arp" /> + <device match="bpf" /> <device match="conslog" /> <device match="cpu/self/cpuid" /> <device match="crypto" /> @@ -62,6 +63,7 @@ <device match="lo0" /> <device match="log" /> <device match="logindmux" /> + <device match="nsmb" /> <device match="net/*" /> <device match="null" /> <device match="openprom" arch="sparc" /> @@ -120,7 +122,7 @@ <device match="spdsock" ip-type="exclusive" /> <device match="sppp" ip-type="exclusive" /> <device match="sppptun" ip-type="exclusive" /> - + <!-- Renamed devices to create under /dev --> <device match="zcons/%z/zoneconsole" name="zconsole" />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,52 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +default: all + +include Makefile.s10 + +# Build everything in parallel; use .WAIT for dependencies +.PARALLEL: + +SUBDIRS = librtld_db s10_npreload s10_brand s10_support zone cmd +MSGSUBDIRS = s10_support zone + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint +_msg := TARGET= _msg + +.KEEP_STATE: + +all install clean clobber lint: $(SUBDIRS) + +_msg: $(MSGSUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/Makefile.s10 Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,30 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# include global definitions + +BRAND = solaris10 + +include $(SRC)/lib/brand/Makefile.brand +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/cmd/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,46 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROGS = s10_native s10_isaexec_wrapper s10_automount s10_automountd + +include $(SRC)/cmd/Makefile.cmd +include ../Makefile.s10 + +# override the install directory +ROOTBIN = $(ROOTBRANDDIR) +CLOBBERFILES = $(ROOTPROGS) + +.KEEP_STATE: + +all: $(PROGS) + +lint: + +install: all $(ROOTPROGS) + +clean: + $(RM) $(PROGS) + +include $(SRC)/cmd/Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/cmd/s10_automount.sh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,42 @@ +#!/bin/sh +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# All native executables must be run using the native linker. +# By default, the kernel loads the linker at /lib/ld.so.1, which +# in an s10 zone is the s10 linker. Hence when we run the native +# executable below, we explicitly specify /.SUNWnative/lib/ld.so.1 as our +# linker. For convience we define "n" to be the native path prefix. +# +n=/.SUNWnative +LD_NOCONFIG=1 +LD_LIBRARY_PATH_32=$n/lib:$n/usr/lib:$n/usr/lib/mps +LD_LIBRARY_PATH_64=$n/lib/64:$n/usr/lib/64:$n/usr/lib/mps/64 +LD_PRELOAD_32=s10_npreload.so.1 +LD_PRELOAD_64=s10_npreload.so.1 +export LD_NOCONFIG +export LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 LD_PRELOAD_32 LD_PRELOAD_64 +exec /.SUNWnative/usr/lib/brand/solaris10/s10_native \ + /.SUNWnative/lib/ld.so.1 /.SUNWnative/usr/lib/fs/autofs/automount "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/cmd/s10_automountd.sh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,42 @@ +#!/bin/sh +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# All native executables must be run using the native linker. +# By default, the kernel loads the linker at /lib/ld.so.1, which +# in an s10 zone is the s10 linker. Hence when we run the native +# executable below, we explicitly specify /.SUNWnative/lib/ld.so.1 as our +# linker. For convience we define "n" to be the native path prefix. +# +n=/.SUNWnative +LD_NOCONFIG=1 +LD_LIBRARY_PATH_32=$n/lib:$n/usr/lib:$n/usr/lib/mps +LD_LIBRARY_PATH_64=$n/lib/64:$n/usr/lib/64:$n/usr/lib/mps/64 +LD_PRELOAD_32=s10_npreload.so.1 +LD_PRELOAD_64=s10_npreload.so.1 +export LD_NOCONFIG +export LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 LD_PRELOAD_32 LD_PRELOAD_64 +exec /.SUNWnative/usr/lib/brand/solaris10/s10_native \ + /.SUNWnative/lib/ld.so.1 /.SUNWnative/usr/lib/autofs/automountd "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/cmd/s10_isaexec_wrapper.sh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,56 @@ +#!/bin/sh +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# This script is invoked by isaexec-governed executable wrappers from within +# s10-branded zones. It circumvents the native isaexec so that native wrappers +# will function correctly. +# +# All native executables must be run using the native linker. +# By default, the kernel loads the linker at /lib/ld.so.1, which +# in an s10 zone is the s10 linker. Hence when we run the native +# executable below, we explicitly specify /.SUNWnative/lib/ld.so.1 as our 32- +# bit linker and /.SUNWnative/lib/64/ld.so.1 as our 64-bit linker. +# For convience we define "n" to be the native path prefix. +# +bname=`/usr/bin/basename $0` +dname=`/usr/bin/dirname $0` +echo $dname | /usr/bin/grep "^/" >/dev/null || dname=`/bin/pwd`/$dname +dname=`(cd $dname 2>/dev/null && /bin/pwd 2>/dev/null)` +arch64=/ +LC_ALL=C /usr/bin/file /.SUNWnative/$dname/$bname | /usr/bin/grep "64-bit" \ + >/dev/null && arch64=/64/ +n=/.SUNWnative + +LD_NOCONFIG=1 +LD_LIBRARY_PATH_32=$n/lib:$n/usr/lib:$n/usr/lib/mps +LD_LIBRARY_PATH_64=$n/lib/64:$n/usr/lib/64:$n/usr/lib/mps/64 +LD_PRELOAD_32=s10_npreload.so.1 +LD_PRELOAD_64=s10_npreload.so.1 +export LD_NOCONFIG +export LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 LD_PRELOAD_32 LD_PRELOAD_64 +exec /.SUNWnative/usr/lib/brand/solaris10/s10_native \ + /.SUNWnative/lib${arch64}ld.so.1 /.SUNWnative$dname/$bname "$@" +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/cmd/s10_native.sh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,26 @@ +#!/bin/sh +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/librtld_db/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,51 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +default: all + +include $(SRC)/lib/Makefile.lib + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +LINT_SUBDIRS= $(MACH) +$(BUILD64)LINT_SUBDIRS += $(MACH64) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint + +.KEEP_STATE: + +all install clean clobber: $(SUBDIRS) + +lint: $(LINT_SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/librtld_db/Makefile.com Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,80 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +LIBRARY = solaris10_librtld_db.a +VERS = .1 +COBJS = solaris10_librtld_db.o +OBJECTS = $(COBJS) $(COBJS64) + +include $(SRC)/lib/Makefile.lib +include ../../Makefile.s10 + +CSRCS = $(COBJS:%o=../common/%c) +SRCS = $(CSRCS) + +SRCDIR = ../common +UTSBASE = $(SRC)/uts + +# +# ATTENTION: +# Librtl_db brand plugin libraries should NOT directly invoke any +# libproc.so interfaces or be linked against libproc. If a librtl_db +# brand plugin library uses libproc.so interfaces then it may break +# any other librtld_db consumers (like mdb) that tries to attach +# to a branded process. The only safe interfaces that the a librtld_db +# brand plugin library can use to access a target process are the +# proc_service(3PROC) apis. +# +DYNFLAGS += $(VERSREF) -M../common/mapfile-vers +LIBS = $(DYNLIB) +LDLIBS += -lc -lrtld_db +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -D_REENTRANT -I../ -I$(UTSBASE)/common/brand/solaris10 \ + -I$(SRC)/cmd/sgs/librtld_db/common \ + -I$(SRC)/cmd/sgs/include \ + -I$(SRC)/cmd/sgs/include/$(MACH) + +ROOTLIBDIR = $(ROOT)/usr/lib/brand/solaris10 +ROOTLIBDIR64 = $(ROOT)/usr/lib/brand/solaris10/$(MACH64) + +# +# The top level Makefiles define define TEXT_DOMAIN. But librtld_db.so.1 +# isn't internationalized and this library won't be either. The only +# messages that this library can generate are messages used for debugging +# the operation of the library itself. +# +DTEXTDOM = + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +pics/%64.o: ../common/%.c + $(COMPILE.c) -D_ELF64 $(PICFLAGS) -o $@ $< + $(POST_PROCESS_O) + +include $(SRC)/lib/Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/librtld_db/amd64/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,34 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +COBJS64 = solaris10_librtld_db64.o + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +CLOBBERFILES = $(ROOTLIBDIR64)/$(DYNLIB) +DYNFLAGS += -M../common/mapfile-vers.64 + +install: all $(ROOTLIBS64)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/librtld_db/common/mapfile-vers Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,57 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +SUNWprivate_1.1 { + global: + rtld_db_brand_ops32; + local: + *; +}; + +#Externally defined symbols +{ + global: + ps_pauxv = NODIRECT PARENT; + ps_pdmodel = NODIRECT PARENT; + ps_pglobal_lookup = NODIRECT PARENT; + ps_pglobal_sym = NODIRECT PARENT; + ps_plog = NODIRECT PARENT; + ps_pread = NODIRECT PARENT; + ps_pwrite = NODIRECT PARENT; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/librtld_db/common/mapfile-vers.64 Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,43 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +SUNWprivate_1.1 { + global: + rtld_db_brand_ops64; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/librtld_db/common/solaris10_librtld_db.c Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,299 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <libproc.h> +#include <proc_service.h> +#include <synch.h> +#include <sys/types.h> +#include <sys/link.h> +#include <rtld_db.h> + +#include <s10_brand.h> + +/* + * ATTENTION: + * Librtl_db brand plugin libraries should NOT directly invoke any + * libproc.so interfaces or be linked against libproc. If a librtl_db + * brand plugin library uses libproc.so interfaces then it may break + * any other librtld_db consumers (like mdb) that tries to attach + * to a branded process. The only safe interfaces that the a librtld_db + * brand plugin library can use to access a target process are the + * proc_service(3PROC) apis. + */ + +/* + * M_DATA comes from some streams header file but is also redifined in + * _rtld_db.h, so nuke the old streams definition here. + */ +#ifdef M_DATA +#undef M_DATA +#endif /* M_DATA */ + +/* + * For 32-bit versions of this library, this file get's compiled once. + * For 64-bit versions of this library, this file get's compiled twice, + * once with _ELF64 defined and once without. The expectation is that + * the 64-bit version of the library can properly deal with both 32-bit + * and 64-bit elf files, hence in the 64-bit library there are two copies + * of all the interfaces in this file, one set named *32 and one named *64. + * + * This also means that we need to be careful when declaring local pointers + * that point to objects in another processes address space, since these + * pointers may not match the current processes pointer width. Basically, + * we should not use any objects that change size between 32 and 64 bit + * modes like: long, void *, uintprt_t, caddr_t, psaddr_t, size_t, etc. + * Instead we should declare all pointers as uint32_t. Then when we + * are compiled to deal with 64-bit targets we'll re-define uing32_t + * to be a uint64_t. + */ +#ifdef _LP64 +#ifdef _ELF64 +#define uint32_t uint64_t +#define Elf32_Dyn Elf64_Dyn +#define validate_rdebug32 validate_rdebug64 +#define _rd_loadobj_iter32 _rd_loadobj_iter64 +#define _rd_get_dyns32 _rd_get_dyns64 +#define dummy_ldb32 dummy_ldb64 +#define dummy_ldb_init32 dummy_ldb_init64 +#define dummy_ldb_fini32 dummy_ldb_fini64 +#define dummy_ldb_loadobj_iter32 dummy_ldb_loadobj_iter64 +#define dummy_ldb_get_dyns32 dummy_ldb_get_dyns64 +#define s10_ldb_init32 s10_ldb_init64 +#define s10_ldb_fini32 s10_ldb_fini64 +#define s10_ldb_loadobj_iter32 s10_ldb_loadobj_iter64 +#define s10_ldb_get_dyns32 s10_ldb_get_dyns64 +#endif /* _ELF64 */ +#endif /* _LP64 */ + +/* Included from usr/src/cmd/sgs/librtld_db/common */ +#include <_rtld_db.h> + +/*ARGSUSED*/ +static rd_helper_data_t +dummy_ldb_init32(rd_agent_t *rap, struct ps_prochandle *php) +{ + return (NULL); +} + +/*ARGSUSED*/ +static void +dummy_ldb_fini32(rd_helper_data_t rhd) +{ +} + +/*ARGSUSED*/ +static int +dummy_ldb_loadobj_iter32(rd_helper_data_t rhd, rl_iter_f *cb, void *client_data) +{ + return (RD_OK); +} + +/*ARGSUSED*/ +static rd_err_e +dummy_ldb_get_dyns32(rd_helper_data_t rhd, + psaddr_t addr, void **dynpp, size_t *dynpp_sz) +{ + *dynpp = NULL; + *dynpp_sz = 0; + return (RD_OK); +} + +static rd_helper_ops_t dummy_ldb32 = { + LM_ID_BRAND, + dummy_ldb_init32, + dummy_ldb_fini32, + dummy_ldb_loadobj_iter32, + dummy_ldb_get_dyns32 +}; + +static uint32_t +s10_ldb_getauxval32(struct ps_prochandle *php, int type) +{ + const auxv_t *auxvp = NULL; + + if (ps_pauxv(php, &auxvp) != PS_OK) + return ((uint32_t)-1); + + while (auxvp->a_type != AT_NULL) { + if (auxvp->a_type == type) + return ((uint32_t)(uintptr_t)auxvp->a_un.a_ptr); + auxvp++; + } + return ((uint32_t)-1); +} + +/* + * Normally, the native Solaris librtldb_db plugin uses a bunch of different + * methods to try and find the rdebug structure associated with the target + * process we're debugging. For details on the different methods see + * _rd_reset32(). Thankfully our job is easier. We know that the brand + * library is always linked against the native linker, and when the + * process was first executed we saved off a pointer to the brand linkers + * rdebug structure in one of our brand specific aux vectors, + * AT_SUN_BRAND_S10_LDDATA. So we'll just look that up here. + */ +/*ARGSUSED*/ +static rd_helper_data_t +s10_ldb_init32(rd_agent_t *rap, struct ps_prochandle *php) +{ + struct rd_agent *rap_new; + uint32_t lddata_addr; + int rd_dmodel; + + if (ps_pdmodel(php, &rd_dmodel) != PS_OK) { + ps_plog("s10_ldb_init: lookup of data model failed"); + return (NULL); + } +#ifdef _ELF64 + assert(rd_dmodel == PR_MODEL_LP64); +#else /* !_ELF64 */ + assert(rd_dmodel == PR_MODEL_ILP32); +#endif /* !_ELF64 */ + + lddata_addr = s10_ldb_getauxval32(php, AT_SUN_BRAND_S10_LDDATA); + if (lddata_addr == (uint32_t)-1) { + ps_plog("s10_ldb_init: no LDDATA found in aux vector"); + return (NULL); + } + ps_plog("s10_ldb_init: found LDDATA auxv ld.so.1 data seg " + "at: 0x%p", lddata_addr); + + /* + * Ok. So this is kinda ugly. Basically we know that we're going to + * be parsing data from link maps that are generated by a Solaris + * linker. As it turns out, that's exactly what the default + * Solaris librtld_db library is designed to do. So rather than + * duplicate all that link map parsing code here we'll simply + * invoke the native librtld_db that normally does this, and when + * we do we'll point them at our emulation libraries link map. + * + * Of course these interfacess aren't really public interfaces + * and they take a "struct rd_agent" as a parameter. So here + * we'll allocate and initialize a new "struct rd_agent", point + * it at our emulation libraries link map, and initialize just + * enough of the structure to make the librtld_db interfaces + * that we want to use happy. + */ + if ((rap_new = calloc(sizeof (*rap_new), 1)) == NULL) { + ps_plog("s10_ldb_init: can't allocate memory"); + return (NULL); + } + rap_new->rd_dmodel = rd_dmodel; + rap_new->rd_psp = php; + rap_new->rd_rdebug = lddata_addr; + (void) mutex_init(&rap_new->rd_mutex, USYNC_THREAD, 0); + + /* + * When we get invoked from librtld_db, and we call back into it, + * librtld_db will once again check if there is a plugin and + * invoke it. Since we don't want to enter a recursive loop + * we're going to specify a different plugin interface for + * our linkmap, and these new plugin interfaces won't actually + * do anything other than return. + */ + rap_new->rd_helper.rh_ops = &dummy_ldb32; + + /* + * validate_rdebug32() requires the following "struct rd_agent" + * members to be initialized: + * rd_psp, rd_rdebug + * + * validate_rdebug32() initializes the following "struct rd_agent" + * members: + * rd_flags, rd_rdebugvers, rd_rtlddbpriv + */ + if (validate_rdebug32(rap_new) != RD_OK) { + ps_plog("s10_ldb_init: can't find valid r_debug data"); + free(rap_new); + return (NULL); + } + + ps_plog("s10_ldb_init: finished, helper_data=0x%p", rap_new); + return ((rd_helper_data_t)rap_new); +} + +static void +s10_ldb_fini32(rd_helper_data_t rhd) +{ + struct rd_agent *rap = (struct rd_agent *)rhd; + ps_plog("s10_ldb_fini: cleaning up s10 helper"); + free(rap); +} + +/*ARGSUSED*/ +static int +s10_ldb_loadobj_iter32(rd_helper_data_t rhd, rl_iter_f *cb, void *client_data) +{ + struct rd_agent *rap = (struct rd_agent *)rhd; + int err; + + ps_plog("s10_ldb_loadobj_iter(helper_data=0x%p)", rhd); + assert(rap->rd_psp == php); + RDAGLOCK(rap); + /* + * _rd_loadobj_iter32() requires the following "struct rd_agent" + * members to be initialized: + * rd_rtlddbpriv, rd_rdebugvers, rd_flags, + * rd_helper.rh_ops, rd_dmodel + */ + err = _rd_loadobj_iter32(rap, cb, client_data); + RDAGUNLOCK(rap); + ps_plog("s10_ldb_loadobj_iter: finished, err = %d", err); + return (err); +} + +/*ARGSUSED*/ +static rd_err_e +s10_ldb_get_dyns32(rd_helper_data_t rhd, + psaddr_t addr, void **dynpp, size_t *dynpp_sz) +{ + struct rd_agent *rap = (struct rd_agent *)rhd; + int err; + + ps_plog("s10_ldb_get_dyns(helper_data=0x%p)", rhd); + err = _rd_get_dyns32(rap, addr, (Elf32_Dyn **)dynpp, dynpp_sz); + ps_plog("s10_ldb_get_dyns: finished, err = %d", err); + return (err); +} + +/* + * Librtld_db plugin linkage struct. + * + * When we get loaded by librtld_db, it will look for the symbol below + * to find our plugin entry points. + */ +rd_helper_ops_t RTLD_DB_BRAND_OPS = { + LM_ID_NONE, + s10_ldb_init32, + s10_ldb_fini32, + s10_ldb_loadobj_iter32, + s10_ldb_get_dyns32 +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/librtld_db/i386/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,30 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +CLOBBERFILES = $(ROOTLIBDIR)/$(DYNLIB) + +install: all $(ROOTLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/librtld_db/sparc/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,30 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +CLOBBERFILES = $(ROOTLIBDIR)/$(DYNLIB) + +install: all $(ROOTLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/librtld_db/sparcv9/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,34 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +COBJS64 = solaris10_librtld_db64.o + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +CLOBBERFILES = $(ROOTLIBDIR64)/$(DYNLIB) +DYNFLAGS += -M../common/mapfile-vers.64 + +install: all $(ROOTLIBS64)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,47 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include $(SRC)/lib/Makefile.lib + +default: all + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint +_msg := TARGET= _msg + +.KEEP_STATE: + +all install clean clobber lint _msg: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/Makefile.com Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,119 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +LIBRARY = s10_brand.a +VERS = .1 +COBJS = s10_brand.o +ASOBJS = s10_crt.o s10_handler.o s10_runexe.o +OFFSETS_SRC = ../common/offsets.in +OFFSETS_H = assym.h +OBJECTS = $(COBJS) $(ASOBJS) +CLOBBERFILES += $(OFFSETS_H) + +include ../../Makefile.s10 +include $(SRC)/lib/Makefile.lib + +SRCDIR = ../common +UTSBASE = $(SRC)/uts + +LIBS = $(DYNLIB) +CSRCS = $(COBJS:%o=../common/%c) +ASSRCS = $(ASOBJS:%o=$(ISASRCDIR)/%s) +SRCS = $(CSRCS) $(ASSRCS) + +# +# Ugh, this is a gross hack. Our assembly routines uses lots of defines +# to simplify variable access. All these defines work fine for amd64 +# compiles because when compiling for amd64 we use the GNU assembler, +# gas. For 32-bit code we use the Sun assembler, as. Unfortunatly +# as does not handle certian constructs that gas does. So rather than +# make our code less readable, we'll just use gas to compile our 32-bit +# code as well. +# +i386_AS = $(amd64_AS) + +# +# Note that the architecture specific makefiles MUST update DYNFLAGS to +# explicitly specify an interpreter for the brand emulation library so that we +# use /lib/ld.so.1 or /lib/64/ld.so.1, which in a s10 zone is the Solaris 10 +# linker. This is different from some other brands where the linker that is +# used is the native system linker (/.SUNWnative/.../ld.so.1). We have to do +# this because the linker has a very incestuous relationship with libc and we +# don't want to use the native linker with the s10 version of libc. (This may +# come as a surprise to the reader, but when our library is loaded it get's +# linked against the s10 version of libc.) Although the linker interfaces are +# normally stable, there are examples, such as with the solaris8 brand, where +# we could not combine the brand's libc with the native linker. Since we want +# to run in a known configuration, we use the S10 libc/linker combination. +# +# There is one more non-obvious side effect of using the s10 linker that +# should be mentioned. Since the linker is used to setup processes before +# libc is loaded, it makes system calls directly (ie avoiding libc), and +# it makes these system calls before our library has been initialized. +# Since our library hasn't been initialized yet, there's no way for us +# to intercept and emulate any of those system calls. So if any of those +# system calls ever change in the native code such that they break the s10 +# linker then we're kinda screwed and will need to re-visit the current +# solution. (The likely solution then will probably be to start using the +# native linker with our brand emulation library.) +# +# Note that we make sure to link our brand emulation library +# libmapmalloc. This is required because in most cases there will be two +# copies of libc in the same process and we don't want them to fight over +# the heap. So for our brand library we link against libmapmalloc so that +# if we (our or copy of libc) try to allocate any memory it will be done +# via mmap() instead of brk(). +# +CPPFLAGS += -D_REENTRANT -U_ASM \ + -I. -I../sys -I$(UTSBASE)/common/brand/solaris10 \ + -I$(SRC)/uts/common/fs/zfs +CFLAGS += $(CCVERBOSE) +# Needed to handle zfs include files +C99MODE= -xc99=%all +C99LMODE= -Xc99=%all +ASFLAGS = -P $(ASFLAGS_$(CURTYPE)) -D_ASM -I. -I../sys +DYNFLAGS += $(DYNFLAGS_$(CLASS)) +DYNFLAGS += $(BLOCAL) $(ZNOVERSION) -Wl,-e_start +LDLIBS += -lc -lmapmalloc + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +# +# build the offset header before trying to compile any files. (it's included +# by s10_misc.h, so it's needed for all objects, not just assembly ones.) +# +$(OBJECTS:%=pics/%): $(OFFSETS_H) +$(OFFSETS_H): $(OFFSETS_SRC) + $(OFFSETS_CREATE) $(CTF_FLAGS) < $(OFFSETS_SRC) >$@ + +pics/%.o: $(ISASRCDIR)/%.s + $(COMPILE.s) -o $@ $< + $(POST_PROCESS_O) + +include $(SRC)/lib/Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/amd64/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,41 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +ISASRCDIR = . + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +# +# see ../Makefile.com for why we MUST explicity make ld.so.1 our interpreter +# +# S10 linker +DYNFLAGS += -Wl,-I/lib/64/ld.so.1 +CPPFLAGS += -D_SYSCALL32 + +CLEANFILES += $(DYNLIB) +CLOBBERFILES += $(ROOTLIBS64) + +install: all $(ROOTLIBS64)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/amd64/s10_crt.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,73 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/asm_linkage.h> + +#if defined(lint) + +void +_start(void) +{ +} + +#else /* lint */ + /* + * Initial entry point for the brand emulation library. + * + * This platform specific assembly entry point exists just to invoke + * the common brand library startup routine. That routine expects to + * be called with the following arguments: + * s10_init(int argc, char *argv[], char *envp[]) + * + * There are no arguments explicitly passed to this entry point, + * routine, but we do know how our initial stack has been setup by + * the kernel. The stack format is documented in: + * usr/src/cmd/sgs/rtld/amd64/boot.s + * + * So this routine will troll through the stack to setup the argument + * values for the common brand library startup routine and then invoke + * it. This routine is modeled after the default crt1.s`_start() + * routines. + */ + ENTRY_NP(_start) + + /* Make stack traces look pretty, build a fake stack frame. */ + pushq $0 / Build a stack frame. retpc = NULL + pushq $0 / fp = NULL + movq %rsp, %rbp / first stack frame + + /* + * Calculate the location of the envp array by adding the size of + * the argv array to the start of the argv array. + */ + movq 16(%rbp), %rdi / argc in %rax (1st param) + leaq 24(%rbp), %rsi / &argv[0] in %rbx (2nd param) + leaq 32(%rbp,%rdi,8), %rdx / envp in %rcx (3rd param) + call s10_init + + /*NOTREACHED*/ + SET_SIZE(_start) +#endif /* lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/amd64/s10_handler.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,182 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <s10_misc.h> + +#if defined(lint) + +void +s10_handler(void) +{ +} + +#else /* lint */ + /* + * %rax - syscall number + * stack contains: + * -------------------------------------- + * | 16 | syscall arguments | + * v 8 | syscall wrapper return address | + * %rsp+0 | syscall return address | + * -------------------------------------- + */ + ENTRY_NP(s10_handler) + pushq %rbp /* allocate stack frame */ + movq %rsp, %rbp + + /* Save registers at the time of the syscall. */ + movq $0, EH_LOCALS_GREG(REG_TRAPNO)(%rbp) + movq $0, EH_LOCALS_GREG(REG_ERR)(%rbp) + movq %r15, EH_LOCALS_GREG(REG_R15)(%rbp) + movq %r14, EH_LOCALS_GREG(REG_R14)(%rbp) + movq %r13, EH_LOCALS_GREG(REG_R13)(%rbp) + movq %r12, EH_LOCALS_GREG(REG_R12)(%rbp) + movq %r11, EH_LOCALS_GREG(REG_R11)(%rbp) + movq %r10, EH_LOCALS_GREG(REG_R10)(%rbp) + movq %r9, EH_LOCALS_GREG(REG_R9)(%rbp) + movq %r8, EH_LOCALS_GREG(REG_R8)(%rbp) + movq %rdi, EH_LOCALS_GREG(REG_RDI)(%rbp) + movq %rsi, EH_LOCALS_GREG(REG_RSI)(%rbp) + movq %rax, EH_LOCALS_GREG(REG_RAX)(%rbp) + movq %rbx, EH_LOCALS_GREG(REG_RBX)(%rbp) + movq %rcx, EH_LOCALS_GREG(REG_RCX)(%rbp) + movq %rdx, EH_LOCALS_GREG(REG_RDX)(%rbp) + xorq %rcx, %rcx + movw %cs, %cx + movq %rcx, EH_LOCALS_GREG(REG_CS)(%rbp) + movw %ds, %cx + movq %rcx, EH_LOCALS_GREG(REG_DS)(%rbp) + movw %es, %cx + movq %rcx, EH_LOCALS_GREG(REG_ES)(%rbp) + movw %fs, %cx + movq %rcx, EH_LOCALS_GREG(REG_FS)(%rbp) + movw %gs, %cx + movq %rcx, EH_LOCALS_GREG(REG_GS)(%rbp) + movw %ss, %cx + movq %rcx, EH_LOCALS_GREG(REG_SS)(%rbp) + pushfq /* save syscall flags */ + popq %r12 + movq %r12, EH_LOCALS_GREG(REG_RFL)(%rbp) + movq EH_ARGS_OFFSET(0)(%rbp), %r12 /* save syscall rbp */ + movq %r12, EH_LOCALS_GREG(REG_RBP)(%rbp) + movq %rbp, %r12 /* save syscall rsp */ + addq $CPTRSIZE, %r12 + movq %r12, EH_LOCALS_GREG(REG_RSP)(%rbp) + movq EH_ARGS_OFFSET(1)(%rbp), %r12 /* save syscall ret address */ + movq %r12, EH_LOCALS_GREG(REG_RIP)(%rbp) + movq %fs:0, %r12 /* save syscall fsbase */ + movq %r12, EH_LOCALS_GREG(REG_FSBASE)(%rbp) + movq $0, EH_LOCALS_GREG(REG_GSBASE)(%rbp) + + /* + * Finish setting up our stack frame. We would normally do this + * upon entry to this function, but in this case we delayed it + * because a "sub" operation can modify flags and we wanted to + * save the flags into the gregset_t above before they get modified. + * + * Our stack frame format is documented in s10_misc.h. + */ + subq $EH_LOCALS_SIZE, %rsp + + /* Look up the system call's entry in the sysent table */ + movq s10_sysent_table@GOTPCREL(%rip), %r11 /* %r11 = sysent_table */ + shlq $4, %rax /* each entry is 16 bytes */ + addq %rax, %r11 /* %r11 = sysent entry address */ + + /* + * Get the return value flag and the number of arguments from the + * sysent table. + */ + movq CPTRSIZE(%r11), %r12 /* number of args + rv flag */ + andq $RV_MASK, %r12 /* strip out number of args */ + movq %r12, EH_LOCALS_RVFLAG(%rbp) /* save rv flag */ + + /* + * Setup arguments for our emulation call. Our input arguments, + * 0 to N, will become emulation call arguments 1 to N+1. + * + * Note: Syscall argument passing is different from function call + * argument passing on amd64. For function calls, the fourth arg + * is passed via %rcx, but for system calls the 4th argument is + * passed via %r10. This is because in amd64, the syscall + * instruction puts lower 32 bit of %rflags in %r11 and puts the + * %rip value to %rcx. + */ + movq EH_ARGS_OFFSET(4)(%rbp), %r12 /* copy 8th arg */ + movq %r12, EH_ARGS_OFFSET(2)(%rsp) + movq EH_ARGS_OFFSET(3)(%rbp), %r12 /* copy 7th arg */ + movq %r12, EH_ARGS_OFFSET(1)(%rsp) + movq %r9, EH_ARGS_OFFSET(0)(%rsp) + movq %r8, %r9 + movq %r10, %r8 + movq %rdx, %rcx + movq %rsi, %rdx + movq %rdi, %rsi + + /* + * The first parameter to the emulation callback function is a + * pointer to a sysret_t structure. + */ + movq %rbp, %rdi + addq $EH_LOCALS_SYSRET, %rdi /* arg0 == sysret_t ptr */ + + /* invoke the emulation routine */ + ALTENTRY(s10_handler_savepc) + call *(%r11) + + /* restore scratch and parameter registers */ + movq EH_LOCALS_GREG(REG_R12)(%rbp), %r12 /* restore %r12 */ + movq EH_LOCALS_GREG(REG_R11)(%rbp), %r11 /* restore %r11 */ + movq EH_LOCALS_GREG(REG_R10)(%rbp), %r10 /* restore %r10 */ + movq EH_LOCALS_GREG(REG_R9)(%rbp), %r9 /* restore %r9 */ + movq EH_LOCALS_GREG(REG_R8)(%rbp), %r8 /* restore %r8 */ + movq EH_LOCALS_GREG(REG_RCX)(%rbp), %rcx /* restore %rcx */ + movq EH_LOCALS_GREG(REG_RDX)(%rbp), %rdx /* restore %rdx */ + movq EH_LOCALS_GREG(REG_RSI)(%rbp), %rsi /* restore %rsi */ + movq EH_LOCALS_GREG(REG_RDI)(%rbp), %rdi /* restore %rdi */ + + /* Check for syscall emulation success or failure */ + cmpq $0, %rax + je success + stc /* failure, set carry flag */ + jmp return /* return, %rax == errno */ + +success: + /* There is always at least one return value. */ + movq EH_LOCALS_SYSRET1(%rbp), %rax /* %rax == sys_rval1 */ + cmpq $RV_DEFAULT, EH_LOCALS_RVFLAG(%rbp) /* check rv flag */ + je clear_carry + mov EH_LOCALS_SYSRET2(%rbp), %rdx /* %rdx == sys_rval2 */ +clear_carry: + clc /* success, clear carry flag */ + +return: + movq %rbp, %rsp /* restore stack */ + popq %rbp + ret /* ret to instr after syscall */ + SET_SIZE(s10_handler) + + +#endif /* lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/amd64/s10_runexe.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,80 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/asm_linkage.h> +#include <s10_misc.h> + +#if defined(lint) + +/*ARGSUSED*/ +void +s10_runexe(void *argv, ulong_t entry) +{ +} + +#else /* lint */ + /* + * Prepare to jump to the target program we actually want to run. + * If this program is dynamically linked then we'll be jumping to + * another copy of the linker. If it's a statically linked program + * we'll be jumping directy to it's main entry point. In any case, + * we need to reset our current state stack and register state to + * something similar to the initial process state setup by the kernel + * and documented at: + * usr/src/cmd/sgs/rtld/i386/boot.s + * usr/src/cmd/sgs/rtld/sparcv9/boot.s + * + * Of course this is the same stack format as when this executable + * was first started, so here we'll just roll back the stack and + * frame pointers to their values when this processes first started + * execution. + */ + ENTRY_NP(s10_runexe) + + movq %rdi, %rax / %rax = &argv[0] + movq %rsi, %rbx / Brand app entry point in %rbx + subq $8, %rax / Top of stack - must point at argc + movq %rax, %rsp / Set %rsp to what linkers expect + + /* + * We also have to make sure to clear %rdx since nornally ld.so.1 will + * set that to non-zero if there is an exit function that should be + * invoked when the process is terminating. This isn't actually + * necessary if the target program we're jumping to is a dynamically + * linked program since in that case we're actually jumping to another + * copy of ld.so.1 and it will just reset %rdx, but if the target + * program we're jumping to is a statically linked binary that uses + * the standard sun compiler supplied crt1.o`_start(), it will check + * to see if %g1 is set. + */ + movq $0, %rdx + + jmp *%rbx / And away we go... + /* + * target will never return. + */ + SET_SIZE(s10_runexe) +#endif /* lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/common/mapfile-vers Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,47 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +# +# Scope everything local -- our .init section is our only public interface. +# +{ + local: + *; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/common/offsets.in Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,35 @@ +\ +\ Copyright 2009 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ 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 +\ + + +#include <sys/types.h> +#include <sys/regset.h> +#include <sys/ucontext.h> +#include <sys/syscall.h> + +greg_t SIZEOF_GREG_T + +gregset_t SIZEOF_GREGSET_T + +sysret_t SIZEOF_SYSRET_T
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,1828 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> +#include <thread.h> +#include <sys/auxv.h> +#include <sys/bitmap.h> +#include <sys/brand.h> +#include <sys/inttypes.h> +#include <sys/lwp.h> +#include <sys/syscall.h> +#include <sys/systm.h> +#include <sys/utsname.h> +#include <sys/systeminfo.h> +#include <sys/zone.h> +#include <sys/stat.h> +#include <sys/mntent.h> +#include <sys/ctfs.h> +#include <sys/priv.h> +#include <sys/acctctl.h> +#include <libgen.h> +#include <bsm/audit.h> +#include <sys/crypto/ioctl.h> +#include <sys/fs/zfs.h> +#include <sys/zfs_ioctl.h> +#include <sys/ucontext.h> + +#include <s10_brand.h> +#include <s10_misc.h> + +/* + * Principles of emulation 101. + * + * + * *** Setting errno + * + * Just don't do it. This emulation library is loaded onto a + * seperate link map from the application who's address space we're + * running in. We have our own private copy of libc, so there for, + * the errno value accessible from here is is also private and changing + * it will not affect any errno value that the processes who's address + * space we are running in will see. To return an error condition we + * should return the negated errno value we'd like the system to return. + * For more information about this see the comment in s10_handler(). + * Basically, when we return to the caller that initiated the system + * call it's their responsibility to set errno. + * + * + * *** Recursion Considerations + * + * When emulating system calls we need to be very careful about what + * library calls we invoke. Library calls should be kept to a minimum. + * One issue is that library calls can invoke system calls, so if we're + * emulating a system call and we invoke a library call that depends on + * that system call we will probably enter a recursive loop, which would + * be bad. + * + * + * *** Return Values. + * + * When declaring new syscall emulation functions, it is very important + * to to set the proper RV_* flags in the s10_sysent_table. Upon failure, + * syscall emulation fuctions should return an errno value. Upon success + * syscall emulation functions should return 0 and set the sysret_t return + * value parameters accordingly. + * + * There are five possible syscall macro wrappers used in the kernel's system + * call sysent table. These turn into the following return values: + * SYSENT_CL -> SYSENT_C or SYSENT_CI + * SYSENT_C SE_64RVAL RV_DEFAULT + * SYSENT_CI SE_32RVAL1 RV_DEFAULT + * SYSENT_2CI SE_32RVAL1|SE_32RVAL2 RV_32RVAL2 + * SYSENT_AP SE_64RVAL RV_64RVAL + * + * + * *** Agent lwp considerations + * + * It is currently impossible to do any emulation for these system call + * when they are being invoked on behalf of an agent lwp. To understand why + * it's impossible you have to understand how agent lwp syscalls work. + * + * The agent lwp syscall process works as follows: + * 1 The controlling process stops the target. + * 2 The controlling process injects an agent lwp which is also stopped. + * This agent lwp assumes the userland stack and register values + * of another stopped lwp in the current process. + * 3 The controlling process configures the agent lwp to start + * executing the requested system call. + * 4 The controlling process configure /proc to stop the agent lwp when + * it enters the requested system call. + * 5 The controlling processes allows the agent lwp to start executing. + * 6 The agent lwp traps into the kernel to perform the requested system + * call and immediately stop. + * 7 The controlling process copies all the arguments for the requested + * system call onto the agent lwp's stack. + * 8 The controlling process configures /proc to stop the agent lwp + * when it completes the requested system call. + * 9 The controlling processes allows the agent lwp to start executing. + * 10 The agent lwp executes the system call and then stop before returning + * to userland. + * 11 The controlling process copies the return value and return arguments + * back from the agent lwps stack. + * 12 The controlling process destroys the agent lwp and restarts + * the target process. + * + * The fundamental problem is that when the agent executes the request + * system call in step 5, if we're emulating that system call then the + * lwp is redirected back to our emulation layer without blocking + * in the kernel. But our emulation layer can't access the arguments + * for the system call because they haven't been copied to the stack + * yet and they still only exist in the controlling processes address + * space. This prevents us from being able to do any emulation of + * agent lwp system calls. Hence, currently our brand trap interposition + * callback (s10_brand_syscall_callback_common) will detect if a system + * call is being made by an agent lwp, and if this is the case it will + * never redirect the system call to this emulation library. + * + * In the future, if this proves to be a problem the the easiest solution + * would probably be to replace the branded versions of these application + * with their native counterparts. Ie, truss, plimit, and pfiles could be + * replace with wrapper scripts that execute the native versions of these + * applications. In the case of plimit and pfiles this should be pretty + * strait forward. Truss would probably be more tricky since it can + * execute applications which would be branded applications, so in that + * case it might be necessary to create a loadable library which could + * be LD_PRELOADed into truss and this library would interpose on the + * exec() system call to allow truss to correctly execute branded + * processes. It should be pointed out that this solution could work + * because "native agent lwps" (ie, agent lwps created by native + * processes) can be treated differently from "branded aged lwps" (ie, + * agent lwps created by branded processes), since native agent lwps + * would presumably be making native system calls and hence not need + * any interposition. + * + */ + +static zoneid_t zoneid; +static boolean_t emul_global_zone = B_FALSE; +static int emul_vers; +pid_t zone_init_pid; + +#define EMULATE(cb, args) { (sysent_cb_t)(cb), (args) } +#define NOSYS EMULATE(s10_unimpl, (0 | RV_DEFAULT)) + +typedef long (*sysent_cb_t)(); +typedef struct s10_sysent_table { + sysent_cb_t st_callc; + uintptr_t st_args; +} s10_sysent_table_t; +s10_sysent_table_t s10_sysent_table[]; + +#define S10_UTS_RELEASE "5.10" +#define S10_UTS_VERSION "Generic_Virtual" + +/*LINTED: static unused*/ +static volatile int s10_abort_err; +/*LINTED: static unused*/ +static volatile const char *s10_abort_msg; +/*LINTED: static unused*/ +static volatile const char *s10_abort_file; +/*LINTED: static unused*/ +static volatile int s10_abort_line; + +extern int errno; + +/*ARGSUSED*/ +void +_s10_abort(int err, const char *msg, const char *file, int line) +{ + sysret_t rval; + + /* Save the error message into convenient globals */ + s10_abort_err = err; + s10_abort_msg = msg; + s10_abort_file = file; + s10_abort_line = line; + + /* kill ourselves */ + abort(); + + /* If abort() didn't work, try something stronger. */ + (void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGKILL); +} + +static int +s10_uucopy(const void *from, void *to, size_t size) +{ + sysret_t rval; + + if (__systemcall(&rval, SYS_uucopy + 1024, from, to, size) != 0) + return (EFAULT); + return (0); +} + +/* + * ATTENTION: uucopystr() does NOT ensure that string are null terminated! + */ +static int +s10_uucopystr(const void *from, void *to, size_t size) +{ + sysret_t rval; + + if (__systemcall(&rval, SYS_uucopystr + 1024, from, to, size) != 0) + return (EFAULT); + return (0); +} + +/* + * Figures out the PID of init for the zone. Also returns a boolean + * indicating whether this process currently has that pid: if so, + * then at this moment, we are init. + */ +static boolean_t +get_initpid_info(void) +{ + pid_t pid; + sysret_t rval; + int err; + + /* + * Determine the current process PID and the PID of the zone's init. + * We use care not to call getpid() here, because we're not supposed + * to call getpid() until after the program is fully linked-- the + * first call to getpid() is a signal from the linker to debuggers + * that linking has been completed. + */ + if ((err = __systemcall(&rval, SYS_brand, + B_S10_PIDINFO, &pid, &zone_init_pid)) != 0) { + s10_abort(err, "Failed to get init's pid"); + } + + /* + * Note that we need to be cautious with the pid we get back-- + * it should not be stashed and used in place of getpid(), since + * we might fork(2). So we keep zone_init_pid and toss the pid + * we otherwise got. + */ + if (pid == zone_init_pid) + return (B_TRUE); + + return (B_FALSE); +} + +/* + * This function is defined to be NOSYS but it won't be called from the + * the kernel since the NOSYS system calls are not enabled in the kernel. + * Thus, the only time this function is called is directly from within the + * indirect system call path. + */ +/*ARGSUSED*/ +static long +s10_unimpl(sysret_t *rv, uintptr_t p1) +{ + sysret_t rval; + + /* + * We'd like to print out some kind of error message here like + * "unsupported syscall", but we can't because it's not safe to + * assume that stderr or STDERR_FILENO actually points to something + * that is a terminal, and if we wrote to those files we could + * inadvertantly write to some applications open files, which would + * be bad. + * + * Normally, if an application calls an invalid system call + * it get a SIGSYS sent to it. So we'll just go ahead and send + * ourselves a signal here. Note that this is far from ideal since + * if the application has registered a signal handler, that signal + * handler may recieve a ucontext_t as the third parameter to + * indicate the context of the process when the signal was + * generated, and in this case that context will not be what the + * application is expecting. Hence, we should probably create a + * brandsys() kernel function that can deliver the signal to us + * with the correct ucontext_t. + */ + (void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGSYS); + return (ENOSYS); +} + +#if defined(__sparc) && !defined(__sparcv9) +/* + * Yuck. For 32-bit sparc applications, handle indirect system calls. + * Note that we declare this interface to use the maximum number of + * system call arguments. If we recieve a system call that uses less + * arguments, then the additional arguments will be garbage, but they + * will also be ignored so that should be ok. + */ +static long +s10_indir(sysret_t *rv, int code, + uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, + uintptr_t a5, uintptr_t a6, uintptr_t a7) +{ + s10_sysent_table_t *sst = &(s10_sysent_table[code]); + + s10_assert(code < NSYSCALL); + switch (sst->st_args & NARGS_MASK) { + case 0: + return ((sst->st_callc)(rv)); + case 1: + return ((sst->st_callc)(rv, a0)); + case 2: + return ((sst->st_callc)(rv, a0, a1)); + case 3: + return ((sst->st_callc)(rv, a0, a1, a2)); + case 4: + return ((sst->st_callc)(rv, a0, a1, a2, a3)); + case 5: + return ((sst->st_callc)(rv, a0, a1, a2, a3, a4)); + case 6: + return ((sst->st_callc)(rv, rv, a0, a1, a2, a3, a4, a5)); + case 7: + return ((sst->st_callc)(rv, a0, a1, a2, a3, a4, a5, a6)); + case 8: + return ((sst->st_callc)(rv, a0, a1, a2, a3, a4, a5, a6, a7)); + } + s10_abort(0, "invalid entry in s10_sysent_table"); + return (EINVAL); +} +#endif /* __sparc && !__sparcv9 */ + +/* + * Assign the structure member value from the s (source) structure to the + * d (dest) structure. + */ +#define struct_assign(d, s, val) (((d).val) = ((s).val)) + +/* + * The CRYPTO_GET_FUNCTION_LIST parameter structure crypto_function_list_t + * changed between S10 and Nevada, so we have to emulate the old S10 + * crypto_function_list_t structure when interposing on the ioctl syscall. + */ +typedef struct s10_crypto_function_list { + boolean_t fl_digest_init; + boolean_t fl_digest; + boolean_t fl_digest_update; + boolean_t fl_digest_key; + boolean_t fl_digest_final; + + boolean_t fl_encrypt_init; + boolean_t fl_encrypt; + boolean_t fl_encrypt_update; + boolean_t fl_encrypt_final; + + boolean_t fl_decrypt_init; + boolean_t fl_decrypt; + boolean_t fl_decrypt_update; + boolean_t fl_decrypt_final; + + boolean_t fl_mac_init; + boolean_t fl_mac; + boolean_t fl_mac_update; + boolean_t fl_mac_final; + + boolean_t fl_sign_init; + boolean_t fl_sign; + boolean_t fl_sign_update; + boolean_t fl_sign_final; + boolean_t fl_sign_recover_init; + boolean_t fl_sign_recover; + + boolean_t fl_verify_init; + boolean_t fl_verify; + boolean_t fl_verify_update; + boolean_t fl_verify_final; + boolean_t fl_verify_recover_init; + boolean_t fl_verify_recover; + + boolean_t fl_digest_encrypt_update; + boolean_t fl_decrypt_digest_update; + boolean_t fl_sign_encrypt_update; + boolean_t fl_decrypt_verify_update; + + boolean_t fl_seed_random; + boolean_t fl_generate_random; + + boolean_t fl_session_open; + boolean_t fl_session_close; + boolean_t fl_session_login; + boolean_t fl_session_logout; + + boolean_t fl_object_create; + boolean_t fl_object_copy; + boolean_t fl_object_destroy; + boolean_t fl_object_get_size; + boolean_t fl_object_get_attribute_value; + boolean_t fl_object_set_attribute_value; + boolean_t fl_object_find_init; + boolean_t fl_object_find; + boolean_t fl_object_find_final; + + boolean_t fl_key_generate; + boolean_t fl_key_generate_pair; + boolean_t fl_key_wrap; + boolean_t fl_key_unwrap; + boolean_t fl_key_derive; + + boolean_t fl_init_token; + boolean_t fl_init_pin; + boolean_t fl_set_pin; + + boolean_t prov_is_limited; + uint32_t prov_hash_threshold; + uint32_t prov_hash_limit; +} s10_crypto_function_list_t; + +typedef struct s10_crypto_get_function_list { + uint_t fl_return_value; + crypto_provider_id_t fl_provider_id; + s10_crypto_function_list_t fl_list; +} s10_crypto_get_function_list_t; + +/* + * The structure returned by the CRYPTO_GET_FUNCTION_LIST ioctl on /dev/crypto + * increased in size due to: + * 6482533 Threshold for HW offload via PKCS11 interface + * between S10 and Nevada. This is a relatively simple process of filling + * in the S10 structure fields with the Nevada data. + * + * We stat the device to make sure that the ioctl is meant for /dev/crypto. + * + */ +static int +crypto_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg) +{ + int err; + s10_crypto_get_function_list_t s10_param; + crypto_get_function_list_t native_param; + static dev_t crypto_dev = (dev_t)-1; + struct stat sbuf; + + if (crypto_dev == (dev_t)-1) { + if ((err = __systemcall(rval, SYS_stat + 1024, "/dev/crypto", + &sbuf)) != 0) + goto nonemuioctl; + crypto_dev = major(sbuf.st_rdev); + } + if ((err = __systemcall(rval, SYS_fstat + 1024, fdes, &sbuf)) != 0) + return (err); + /* Each open fd of /dev/crypto gets a new minor device. */ + if (major(sbuf.st_rdev) != crypto_dev) + goto nonemuioctl; + + if (s10_uucopy((const void *)arg, &s10_param, sizeof (s10_param)) != 0) + return (EFAULT); + struct_assign(native_param, s10_param, fl_provider_id); + if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, + &native_param)) != 0) + return (err); + + struct_assign(s10_param, native_param, fl_return_value); + struct_assign(s10_param, native_param, fl_provider_id); + + struct_assign(s10_param, native_param, fl_list.fl_digest_init); + struct_assign(s10_param, native_param, fl_list.fl_digest); + struct_assign(s10_param, native_param, fl_list.fl_digest_update); + struct_assign(s10_param, native_param, fl_list.fl_digest_key); + struct_assign(s10_param, native_param, fl_list.fl_digest_final); + + struct_assign(s10_param, native_param, fl_list.fl_encrypt_init); + struct_assign(s10_param, native_param, fl_list.fl_encrypt); + struct_assign(s10_param, native_param, fl_list.fl_encrypt_update); + struct_assign(s10_param, native_param, fl_list.fl_encrypt_final); + + struct_assign(s10_param, native_param, fl_list.fl_decrypt_init); + struct_assign(s10_param, native_param, fl_list.fl_decrypt); + struct_assign(s10_param, native_param, fl_list.fl_decrypt_update); + struct_assign(s10_param, native_param, fl_list.fl_decrypt_final); + + struct_assign(s10_param, native_param, fl_list.fl_mac_init); + struct_assign(s10_param, native_param, fl_list.fl_mac); + struct_assign(s10_param, native_param, fl_list.fl_mac_update); + struct_assign(s10_param, native_param, fl_list.fl_mac_final); + + struct_assign(s10_param, native_param, fl_list.fl_sign_init); + struct_assign(s10_param, native_param, fl_list.fl_sign); + struct_assign(s10_param, native_param, fl_list.fl_sign_update); + struct_assign(s10_param, native_param, fl_list.fl_sign_final); + struct_assign(s10_param, native_param, fl_list.fl_sign_recover_init); + struct_assign(s10_param, native_param, fl_list.fl_sign_recover); + + struct_assign(s10_param, native_param, fl_list.fl_verify_init); + struct_assign(s10_param, native_param, fl_list.fl_verify); + struct_assign(s10_param, native_param, fl_list.fl_verify_update); + struct_assign(s10_param, native_param, fl_list.fl_verify_final); + struct_assign(s10_param, native_param, fl_list.fl_verify_recover_init); + struct_assign(s10_param, native_param, fl_list.fl_verify_recover); + + struct_assign(s10_param, native_param, + fl_list.fl_digest_encrypt_update); + struct_assign(s10_param, native_param, + fl_list.fl_decrypt_digest_update); + struct_assign(s10_param, native_param, fl_list.fl_sign_encrypt_update); + struct_assign(s10_param, native_param, + fl_list.fl_decrypt_verify_update); + + struct_assign(s10_param, native_param, fl_list.fl_seed_random); + struct_assign(s10_param, native_param, fl_list.fl_generate_random); + + struct_assign(s10_param, native_param, fl_list.fl_session_open); + struct_assign(s10_param, native_param, fl_list.fl_session_close); + struct_assign(s10_param, native_param, fl_list.fl_session_login); + struct_assign(s10_param, native_param, fl_list.fl_session_logout); + + struct_assign(s10_param, native_param, fl_list.fl_object_create); + struct_assign(s10_param, native_param, fl_list.fl_object_copy); + struct_assign(s10_param, native_param, fl_list.fl_object_destroy); + struct_assign(s10_param, native_param, fl_list.fl_object_get_size); + struct_assign(s10_param, native_param, + fl_list.fl_object_get_attribute_value); + struct_assign(s10_param, native_param, + fl_list.fl_object_set_attribute_value); + struct_assign(s10_param, native_param, fl_list.fl_object_find_init); + struct_assign(s10_param, native_param, fl_list.fl_object_find); + struct_assign(s10_param, native_param, fl_list.fl_object_find_final); + + struct_assign(s10_param, native_param, fl_list.fl_key_generate); + struct_assign(s10_param, native_param, fl_list.fl_key_generate_pair); + struct_assign(s10_param, native_param, fl_list.fl_key_wrap); + struct_assign(s10_param, native_param, fl_list.fl_key_unwrap); + struct_assign(s10_param, native_param, fl_list.fl_key_derive); + + struct_assign(s10_param, native_param, fl_list.fl_init_token); + struct_assign(s10_param, native_param, fl_list.fl_init_pin); + struct_assign(s10_param, native_param, fl_list.fl_set_pin); + + struct_assign(s10_param, native_param, fl_list.prov_is_limited); + struct_assign(s10_param, native_param, fl_list.prov_hash_threshold); + struct_assign(s10_param, native_param, fl_list.prov_hash_limit); + + return (s10_uucopy(&s10_param, (void *)arg, sizeof (s10_param))); + +nonemuioctl: + return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg)); +} + +/* + * The process contract CT_TGET and CT_TSET parameter structure ct_param_t + * changed between S10 and Nevada, so we have to emulate the old S10 + * ct_param_t structure when interposing on the ioctl syscall. + */ +typedef struct s10_ct_param { + uint32_t ctpm_id; + uint32_t ctpm_pad; + uint64_t ctpm_value; +} s10_ct_param_t; + +/* + * We have to emulate process contract ioctls for init(1M) because the + * ioctl parameter structure changed between S10 and Nevada. This is + * a relatively simple process of filling Nevada structure fields, + * shuffling values, and initiating a native system call. + * + * For now, we'll assume that all consumers of CT_TGET and CT_TSET will + * need emulation. We'll issue a stat to make sure that the ioctl + * is meant for the contract file system. + * + */ +static int +ctfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg) +{ + int err; + s10_ct_param_t s10param; + ct_param_t param; + struct stat statbuf; + + if ((err = __systemcall(rval, SYS_fstat + 1024, fdes, &statbuf)) != 0) + return (err); + if (strcmp(statbuf.st_fstype, MNTTYPE_CTFS) != 0) + return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg)); + + if (s10_uucopy((const void *)arg, &s10param, sizeof (s10param)) != 0) + return (EFAULT); + param.ctpm_id = s10param.ctpm_id; + param.ctpm_size = sizeof (uint64_t); + param.ctpm_value = &s10param.ctpm_value; + if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, ¶m)) + != 0) + return (err); + + if (cmd == CT_TGET) + return (s10_uucopy(&s10param, (void *)arg, sizeof (s10param))); + + return (0); +} + +typedef struct s10_zfs_cmd { + char zc_name[MAXPATHLEN]; + char zc_value[MAXPATHLEN * 2]; + char zc_string[MAXNAMELEN]; + uint64_t zc_guid; + uint64_t zc_nvlist_conf; /* really (char *) */ + uint64_t zc_nvlist_conf_size; + uint64_t zc_nvlist_src; /* really (char *) */ + uint64_t zc_nvlist_src_size; + uint64_t zc_nvlist_dst; /* really (char *) */ + uint64_t zc_nvlist_dst_size; + uint64_t zc_cookie; + uint64_t zc_objset_type; + uint64_t zc_perm_action; + uint64_t zc_history; /* really (char *) */ + uint64_t zc_history_len; + uint64_t zc_history_offset; + uint64_t zc_obj; + /* Solaris Next added zc_iflags member here */ + zfs_share_t zc_share; + dmu_objset_stats_t zc_objset_stats; + struct drr_begin zc_begin_record; + zinject_record_t zc_inject_record; +} s10_zfs_cmd_t; + +/* + * There is a difference in the zfs_cmd_t ioctl parameter between S10 and + * Solaris Next so we need to translate between the two structures when + * making ZFS ioctls. + */ +static int +zfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg) +{ + int err; + s10_zfs_cmd_t s10_param; + zfs_cmd_t native_param; + static dev_t zfs_dev = (dev_t)-1; + struct stat sbuf; + + if (zfs_dev == (dev_t)-1) { + if ((err = __systemcall(rval, SYS_stat + 1024, "/dev/zfs", + &sbuf)) != 0) + goto nonemuioctl; + zfs_dev = major(sbuf.st_rdev); + } + if ((err = __systemcall(rval, SYS_fstat + 1024, fdes, &sbuf)) != 0) + return (err); + if (major(sbuf.st_rdev) != zfs_dev) + goto nonemuioctl; + + if (s10_uucopy((const void *)arg, &s10_param, sizeof (s10_param)) != 0) + return (EFAULT); + + bcopy((const void *)s10_param.zc_name, (void *)native_param.zc_name, + sizeof (s10_param.zc_name)); + bcopy((const void *)s10_param.zc_value, (void *)native_param.zc_value, + sizeof (s10_param.zc_value)); + bcopy((const void *)s10_param.zc_string, (void *)native_param.zc_string, + sizeof (s10_param.zc_string)); + struct_assign(native_param, s10_param, zc_guid); + struct_assign(native_param, s10_param, zc_nvlist_conf); + struct_assign(native_param, s10_param, zc_nvlist_conf_size); + struct_assign(native_param, s10_param, zc_nvlist_src); + struct_assign(native_param, s10_param, zc_nvlist_src_size); + struct_assign(native_param, s10_param, zc_nvlist_dst); + struct_assign(native_param, s10_param, zc_nvlist_dst_size); + struct_assign(native_param, s10_param, zc_cookie); + struct_assign(native_param, s10_param, zc_objset_type); + struct_assign(native_param, s10_param, zc_perm_action); + struct_assign(native_param, s10_param, zc_history); + struct_assign(native_param, s10_param, zc_history_len); + struct_assign(native_param, s10_param, zc_history_offset); + struct_assign(native_param, s10_param, zc_obj); + native_param.zc_iflags = 0; + struct_assign(native_param, s10_param, zc_share); + struct_assign(native_param, s10_param, zc_objset_stats); + struct_assign(native_param, s10_param, zc_begin_record); + struct_assign(native_param, s10_param, zc_inject_record); + + err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, &native_param); + + bcopy((const void *)native_param.zc_name, (void *)s10_param.zc_name, + sizeof (s10_param.zc_name)); + bcopy((const void *)native_param.zc_value, (void *)s10_param.zc_value, + sizeof (s10_param.zc_value)); + bcopy((const void *)native_param.zc_string, (void *)s10_param.zc_string, + sizeof (s10_param.zc_string)); + struct_assign(s10_param, native_param, zc_guid); + struct_assign(s10_param, native_param, zc_nvlist_conf); + struct_assign(s10_param, native_param, zc_nvlist_conf_size); + struct_assign(s10_param, native_param, zc_nvlist_src); + struct_assign(s10_param, native_param, zc_nvlist_src_size); + struct_assign(s10_param, native_param, zc_nvlist_dst); + struct_assign(s10_param, native_param, zc_nvlist_dst_size); + struct_assign(s10_param, native_param, zc_cookie); + struct_assign(s10_param, native_param, zc_objset_type); + struct_assign(s10_param, native_param, zc_perm_action); + struct_assign(s10_param, native_param, zc_history); + struct_assign(s10_param, native_param, zc_history_len); + struct_assign(s10_param, native_param, zc_history_offset); + struct_assign(s10_param, native_param, zc_obj); + struct_assign(s10_param, native_param, zc_share); + struct_assign(s10_param, native_param, zc_objset_stats); + struct_assign(s10_param, native_param, zc_begin_record); + struct_assign(s10_param, native_param, zc_inject_record); + + (void) s10_uucopy(&s10_param, (void *)arg, sizeof (s10_param)); + return (err); + +nonemuioctl: + return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg)); +} + +int +s10_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg) +{ + switch (cmd) { + case CRYPTO_GET_FUNCTION_LIST: + return (crypto_ioctl(rval, fdes, cmd, arg)); + case CT_TGET: + /*FALLTHRU*/ + case CT_TSET: + return (ctfs_ioctl(rval, fdes, cmd, arg)); + } + + if ((cmd & 0xff00) == ZFS_IOC) + return (zfs_ioctl(rval, fdes, cmd, arg)); + + return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg)); +} + +/* + * Unfortunately, pwrite()'s behavior differs between S10 and Nevada when + * applied to files opened with O_APPEND. The offset argument is ignored and + * the buffer is appended to the target file in S10, whereas the current file + * position is ignored in Nevada (i.e., pwrite() acts as though the target file + * wasn't opened with O_APPEND). This is a result of the fix for CR 6655660 + * (pwrite() must ignore the O_APPEND/FAPPEND flag). + * + * We emulate the old S10 pwrite() behavior by checking whether the target file + * was opened with O_APPEND. If it was, then invoke the write() system call + * instead of pwrite(); otherwise, invoke the pwrite() system call as usual. + */ +static int +s10_pwrite(sysret_t *rval, int fd, const void *bufferp, size_t num_bytes, + off_t offset) +{ + int err; + + if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0) + return (err); + if (rval->sys_rval1 & O_APPEND) + return (__systemcall(rval, SYS_write + 1024, fd, bufferp, + num_bytes)); + return (__systemcall(rval, SYS_pwrite + 1024, fd, bufferp, num_bytes, + offset)); +} + +#ifndef _LP64 +/* + * This is the large file version of the pwrite() system call for 32-bit + * processes. This exists for the same reason that s10_pwrite() exists; see + * the comment above s10_pwrite(). + */ +static int +s10_pwrite64(sysret_t *rval, int fd, const void *bufferp, size32_t num_bytes, + uint32_t offset_1, uint32_t offset_2) +{ + int err; + + if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0) + return (err); + if (rval->sys_rval1 & O_APPEND) + return (__systemcall(rval, SYS_write + 1024, fd, bufferp, + num_bytes)); + return (__systemcall(rval, SYS_pwrite64 + 1024, fd, bufferp, + num_bytes, offset_1, offset_2)); +} +#endif /* !_LP64 */ + +#define S10_AC_PROC (0x1 << 28) +#define S10_AC_TASK (0x2 << 28) +#define S10_AC_FLOW (0x4 << 28) +#define S10_AC_MODE(x) ((x) & 0xf0000000) +#define S10_AC_OPTION(x) ((x) & 0x0fffffff) + +/* + * The mode shift, mode mask and option mask for acctctl have changed. The + * mode is currently the top full byte and the option is the lower 3 full bytes. + */ +int +s10_acctctl(sysret_t *rval, int cmd, void *buf, size_t bufsz) +{ + int mode = S10_AC_MODE(cmd); + int option = S10_AC_OPTION(cmd); + + switch (mode) { + case S10_AC_PROC: + mode = AC_PROC; + break; + case S10_AC_TASK: + mode = AC_TASK; + break; + case S10_AC_FLOW: + mode = AC_FLOW; + break; + default: + return (S10_TRUSS_POINT_3(rval, SYS_acctctl, EINVAL, cmd, buf, + bufsz)); + } + + return (__systemcall(rval, SYS_acctctl + 1024, mode | option, buf, + bufsz)); +} + +/* + * The Audit Policy parameters have changed due to: + * 6466722 audituser and AUDIT_USER are defined, unused, undocumented and + * should be removed. + * + * In S10 we had the following flag: + * #define AUDIT_USER 0x0040 + * which doesn't exist in Solaris Next where the subsequent flags are shifted + * down. For example, in S10 we had: + * #define AUDIT_GROUP 0x0080 + * but on Solaris Next we have: + * #define AUDIT_GROUP 0x0040 + * AUDIT_GROUP has the value AUDIT_USER had in S10 and all of the subsequent + * bits are also shifted one place. + * + * When we're getting or setting the Audit Policy parameters we need to + * shift the outgoing or incoming bits into their proper positions. Since + * S10_AUDIT_USER was always unused, we always clear that bit on A_GETPOLICY. + * + * The command we care about, BSM_AUDITCTL, passes the most parameters (3), + * so declare this function to take up to 4 args and just pass them on. + * The number of parameters for s10_auditsys needs to be equal to the BSM_* + * subcommand that has the most parameters, since we want to pass all + * parameters through, regardless of which subcommands we interpose on. + * + * Note that the auditsys system call uses the SYSENT_AP macro wrapper instead + * of the more common SYSENT_CI macro. This means the return value is a + * SE_64RVAL so the syscall table uses RV_64RVAL. + */ + +#define S10_AUDIT_HMASK 0xffffffc0 +#define S10_AUDIT_LMASK 0x3f + +int +s10_auditsys(sysret_t *rval, int bsmcmd, intptr_t a0, intptr_t a1, intptr_t a2) +{ + int err; + uint_t m; + + if (bsmcmd != BSM_AUDITCTL) + return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, a1, + a2)); + + if ((int)a0 == A_GETPOLICY) { + if ((err = __systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, + &m, a2)) != 0) + return (err); + m = ((m & S10_AUDIT_HMASK) << 1) | (m & S10_AUDIT_LMASK); + if (s10_uucopy(&m, (void *)a1, sizeof (m)) != 0) + return (EFAULT); + return (0); + + } else if ((int)a0 == A_SETPOLICY) { + if (s10_uucopy((const void *)a1, &m, sizeof (m)) != 0) + return (EFAULT); + m = ((m >> 1) & S10_AUDIT_HMASK) | (m & S10_AUDIT_LMASK); + return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, &m, + a2)); + } + + return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, a1, a2)); +} + +/* + * Determine whether the executable passed to SYS_exec or SYS_execve is a + * native executable. The s10_npreload.so invokes the B_S10_NATIVE brand + * operation which patches up the processes exec info to eliminate any trace + * of the wrapper. That will make pgrep and other commands that examine + * process' executable names and command-line parameters work properly. + */ +static int +s10_exec_native(sysret_t *rval, const char *fname, const char **argp, + const char **envp) +{ + const char *filename = fname; + char path[64]; + int err; + + /* Get a copy of the executable we're trying to run */ + path[0] = '\0'; + (void) s10_uucopystr(filename, path, sizeof (path)); + + /* Check if we're trying to run a native binary */ + if (strncmp(path, "/.SUNWnative/usr/lib/brand/solaris10/s10_native", + sizeof (path)) != 0) + return (0); + + /* Skip the first element in the argv array */ + argp++; + + /* + * The the path of the dynamic linker is the second parameter + * of s10_native_exec(). + */ + if (s10_uucopy(argp, &filename, sizeof (char *)) != 0) + return (EFAULT); + + /* If an exec call succeeds, it never returns */ + err = __systemcall(rval, SYS_brand + 1024, B_EXEC_NATIVE, filename, + argp, envp, NULL, NULL, NULL); + s10_assert(err != 0); + return (err); +} + +/* + * Interpose on the SYS_exec syscall to detect native wrappers. + */ +int +s10_exec(sysret_t *rval, const char *fname, const char **argp) +{ + int err; + + if ((err = s10_exec_native(rval, fname, argp, NULL)) != 0) + return (err); + + /* If an exec call succeeds, it never returns */ + err = __systemcall(rval, SYS_exec + 1024, fname, argp); + s10_assert(err != 0); + return (err); +} + +/* + * Interpose on the SYS_execve syscall to detect native wrappers. + */ +int +s10_execve(sysret_t *rval, const char *fname, const char **argp, + const char **envp) +{ + int err; + + if ((err = s10_exec_native(rval, fname, argp, envp)) != 0) + return (err); + + /* If an exec call succeeds, it never returns */ + err = __systemcall(rval, SYS_execve + 1024, fname, argp, envp); + s10_assert(err != 0); + return (err); +} + +/* + * S10's issetugid() syscall is now a subcode to privsys(). + */ +static int +s10_issetugid(sysret_t *rval) +{ + return (__systemcall(rval, SYS_privsys + 1024, PRIVSYS_ISSETUGID, + 0, 0, 0, 0, 0)); +} + +/* + * New last arg "block" flag should be zero. The block flag is used by + * the Opensolaris AIO implementation, which is now part of libc. + */ +static int +s10_sigqueue(sysret_t *rval, pid_t pid, int signo, void *value, int si_code) +{ + return (__systemcall(rval, SYS_sigqueue + 1024, pid, signo, value, + si_code, 0)); +} + +static long +s10_uname(sysret_t *rv, uintptr_t p1) +{ + struct utsname un, *unp = (struct utsname *)p1; + int rev, err; + + if ((err = __systemcall(rv, SYS_uname + 1024, &un)) != 0) + return (err); + + rev = atoi(&un.release[2]); + s10_assert(rev >= 11); + bzero(un.release, _SYS_NMLN); + (void) strlcpy(un.release, S10_UTS_RELEASE, _SYS_NMLN); + bzero(un.version, _SYS_NMLN); + (void) strlcpy(un.version, S10_UTS_VERSION, _SYS_NMLN); + + /* copy out the modified uname info */ + return (s10_uucopy(&un, unp, sizeof (un))); +} + +int +s10_sysinfo(sysret_t *rv, int command, char *buf, long count) +{ + char *value; + int len; + + /* + * We must interpose on the sysinfo(2) commands SI_RELEASE and + * SI_VERSION; all others get passed to the native sysinfo(2) + * command. + */ + switch (command) { + case SI_RELEASE: + value = S10_UTS_RELEASE; + break; + + case SI_VERSION: + value = S10_UTS_VERSION; + break; + + default: + /* + * The default action is to pass the command to the + * native sysinfo(2) syscall. + */ + return (__systemcall(rv, SYS_systeminfo + 1024, + command, buf, count)); + } + + len = strlen(value) + 1; + if (count > 0) { + if (s10_uucopystr(value, buf, count) != 0) + return (EFAULT); + + /* Assure NULL termination of buf as s10_uucopystr() doesn't. */ + if (len > count && s10_uucopy("\0", buf + (count - 1), 1) != 0) + return (EFAULT); + } + + /* + * On success, sysinfo(2) returns the size of buffer required to hold + * the complete value plus its terminating NULL byte. + */ + (void) S10_TRUSS_POINT_3(rv, SYS_systeminfo, 0, command, buf, count); + rv->sys_rval1 = len; + rv->sys_rval2 = 0; + return (0); +} + +#ifdef __x86 +#ifdef __amd64 +/* + * 64-bit x86 LWPs created by SYS_lwp_create start here if they need to set + * their %fs registers to the legacy Solaris 10 selector value. + * + * This function does three things: + * + * 1. Trap to the kernel so that it can set %fs to the legacy Solaris 10 + * selector value. + * 2. Read the LWP's true entry point (the entry point supplied by libc + * when SYS_lwp_create was invoked) from %r14. + * 3. Eliminate this function's stack frame and pass control to the LWP's + * true entry point. + * + * See the comment above s10_lwp_create_correct_fs() (see below) for the reason + * why this function exists. + */ +/*ARGSUSED*/ +static void +s10_lwp_create_entry_point(void *ulwp_structp) +{ + sysret_t rval; + + /* + * The new LWP's %fs register is initially zero, but libc won't + * function correctly when %fs is zero. Change the LWP's %fs register + * via SYS_brand. + */ + (void) __systemcall(&rval, SYS_brand + 1024, B_S10_FSREGCORRECTION); + + /* + * Jump to the true entry point, which is stored in %r14. + * Remove our stack frame before jumping so that + * s10_lwp_create_entry_point() won't be seen in stack traces. + * + * NOTE: s10_lwp_create_entry_point() pushes %r12 onto its stack frame + * so that it can use it as a temporary register. We don't restore %r12 + * in this assembly block because we don't care about its value (and + * neither does _lwp_start()). Besides, the System V ABI AMD64 + * Actirecture Processor Supplement doesn't specify that %r12 should + * have a special value when LWPs start, so we can ignore its value when + * we jump to the true entry point. Furthermore, %r12 is a callee-saved + * register, so the true entry point should push %r12 onto its stack + * before using the register. We ignore %r14 after we read it for + * similar reasons. + * + * NOTE: The compiler will generate a function epilogue for this + * function despite the fact that the LWP will never execute it. + * We could hand-code this entire function in assembly to eliminate + * the epilogue, but the epilogue is only three or four instructions, + * so we wouldn't save much space. Besides, why would we want + * to create yet another ugly, hard-to-maintain assembly function when + * we could write most of it in C? + */ + __asm__ __volatile__( + "movq %0, %%rdi\n\t" /* pass ulwp_structp as arg1 */ + "movq %%rbp, %%rsp\n\t" /* eliminate the stack frame */ + "popq %%rbp\n\t" + "jmp *%%r14\n\t" /* jump to the true entry point */ + : : "r" (ulwp_structp)); + /*NOTREACHED*/ +} + +/* + * The S10 libc expects that %fs will be nonzero for new 64-bit x86 LWPs but the + * Nevada kernel clears %fs for such LWPs. Unforunately, new LWPs do not issue + * SYS_lwp_private (see s10_lwp_private() below) after they are created, so + * we must ensure that new LWPs invoke a brand operation that sets %fs to a + * nonzero value immediately after their creation. + * + * The easiest way to do this is to make new LWPs start at a special function, + * s10_lwp_create_entry_point() (see its definition above), that invokes the + * brand operation that corrects %fs. We'll store the entry points of new LWPs + * in their %r14 registers so that s10_lwp_create_entry_point() can find and + * call them after invoking the special brand operation. %r14 is a callee-saved + * register; therefore, any functions invoked by s10_lwp_create_entry_point() + * and all functions dealing with signals (e.g., sigacthandler()) will preserve + * %r14 for s10_lwp_create_entry_point(). + * + * The Nevada kernel can safely work with nonzero %fs values because the kernel + * configures per-thread %fs segment descriptors so that the legacy %fs selector + * value will still work. See the comment in lwp_load() regarding %fs and + * %fsbase in 64-bit x86 processes. + * + * This emulation exists thanks to CRs 6467491 and 6501650. + */ +static int +s10_lwp_create_correct_fs(sysret_t *rval, ucontext_t *ucp, int flags, + id_t *new_lwp) +{ + ucontext_t s10_uc; + + /* + * Copy the supplied ucontext_t structure to the local stack + * frame and store the new LWP's entry point (the value of %rip + * stored in the ucontext_t) in the new LWP's %r14 register. + * Then make s10_lwp_create_entry_point() the new LWP's entry + * point. + */ + if (s10_uucopy(ucp, &s10_uc, sizeof (s10_uc)) != 0) + return (EFAULT); + s10_uc.uc_mcontext.gregs[REG_R14] = s10_uc.uc_mcontext.gregs[REG_RIP]; + s10_uc.uc_mcontext.gregs[REG_RIP] = (greg_t)s10_lwp_create_entry_point; + + /* + * Issue SYS_lwp_create to create the new LWP. We pass the + * modified ucontext_t to make sure that the new LWP starts at + * s10_lwp_create_entry_point(). + */ + return (__systemcall(rval, SYS_lwp_create + 1024, &s10_uc, + flags, new_lwp)); +} +#endif /* __amd64 */ + +/* + * This function is invoked on x86 systems when SYS_lwp_create is issued but no + * %fs register correction is necessary. + * + * See the comment above s10_lwp_create_correct_fs() above for more details. + */ +static int +s10_lwp_create(sysret_t *rval, ucontext_t *ucp, int flags, id_t *new_lwp) +{ + return (__systemcall(rval, SYS_lwp_create + 1024, ucp, flags, new_lwp)); +} + +/* + * SYS_lwp_private is issued by libc_init() to set %fsbase in 64-bit x86 + * processes. The Nevada kernel sets %fs to zero but the S10 libc expects + * %fs to be nonzero. We'll pass the issued system call to the kernel untouched + * and invoke a brand operation to set %fs to the legacy S10 selector value. + * + * This emulation exists thanks to CRs 6467491 and 6501650. + */ +static int +s10_lwp_private(sysret_t *rval, int cmd, int which, uintptr_t base) +{ +#ifdef __amd64 + int err; + + /* + * The current LWP's %fs register should be zero. Determine whether the + * Solaris 10 libc with which we're working functions correctly when %fs + * is zero by calling thr_main() after issuing the SYS_lwp_private + * syscall. If thr_main() barfs (returns -1), then change the LWP's %fs + * register via SYS_brand and patch s10_sysent_table so that issuing + * SYS_lwp_create executes s10_lwp_create_correct_fs() rather than the + * default s10_lwp_create(). s10_lwp_create_correct_fs() will + * guarantee that new LWPs will have correct %fs values. + */ + if ((err = __systemcall(rval, SYS_lwp_private + 1024, cmd, which, + base)) != 0) + return (err); + if (thr_main() == -1) { + /* + * SYS_lwp_private is only issued by libc_init(), which is + * executed when libc is first loaded by ld.so.1. Thus we + * are guaranteed to be single-threaded at this point. Even + * if we were multithreaded at this point, writing a 64-bit + * value to the st_callc field of a s10_sysent_table + * entry is guaranteed to be atomic on 64-bit x86 chips + * as long as the field is not split across cache lines + * (It shouldn't be.). See chapter 8, section 1.1 of + * "The Intel 64 and IA32 Architectures Software Developer's + * Manual," Volume 3A for more details. + */ + s10_sysent_table[SYS_lwp_create].st_callc = + (sysent_cb_t)s10_lwp_create_correct_fs; + return (__systemcall(rval, SYS_brand + 1024, + B_S10_FSREGCORRECTION)); + } + return (0); +#else /* !__amd64 */ + return (__systemcall(rval, SYS_lwp_private + 1024, cmd, which, base)); +#endif /* !__amd64 */ +} +#endif /* __x86 */ + +/* + * If the emul_global_zone flag is set then emulate some aspects of the + * zone system call. In particular, emulate the global zone ID on the + * ZONE_LOOKUP subcommand and emulate some of the global zone attributes + * on the ZONE_GETATTR subcommand. If the flag is not set or we're performing + * some other operation, simply pass the calls through. + */ +int +s10_zone(sysret_t *rval, int cmd, void *arg1, void *arg2, void *arg3, + void *arg4) +{ + char *aval; + int len; + zoneid_t zid; + int attr; + char *buf; + size_t bufsize; + + /* + * We only emulate the zone syscall for a subset of specific commands, + * otherwise we just pass the call through. + */ + if (!emul_global_zone) + return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2, + arg3, arg4)); + + switch (cmd) { + case ZONE_LOOKUP: + (void) S10_TRUSS_POINT_1(rval, SYS_zone, 0, cmd); + rval->sys_rval1 = GLOBAL_ZONEID; + rval->sys_rval2 = 0; + return (0); + + case ZONE_GETATTR: + zid = (zoneid_t)(uintptr_t)arg1; + attr = (int)(uintptr_t)arg2; + buf = (char *)arg3; + bufsize = (size_t)arg4; + + /* + * If the request is for the global zone then we're emulating + * that, otherwise pass this thru. + */ + if (zid != GLOBAL_ZONEID) + goto passthru; + + switch (attr) { + case ZONE_ATTR_NAME: + aval = GLOBAL_ZONENAME; + break; + + case ZONE_ATTR_BRAND: + aval = NATIVE_BRAND_NAME; + break; + default: + /* + * We only emulate a subset of the attrs, use the + * real zone id to pass thru the rest. + */ + arg1 = (void *)(uintptr_t)zoneid; + goto passthru; + } + + (void) S10_TRUSS_POINT_5(rval, SYS_zone, 0, cmd, zid, attr, + buf, bufsize); + + len = strlen(aval) + 1; + if (len > bufsize) + return (ENAMETOOLONG); + + if (buf != NULL) { + if (len == 1) { + if (s10_uucopy("\0", buf, 1) != 0) + return (EFAULT); + } else { + if (s10_uucopystr(aval, buf, len) != 0) + return (EFAULT); + + /* + * Assure NULL termination of "buf" as + * s10_uucopystr() does NOT. + */ + if (s10_uucopy("\0", buf + (len - 1), 1) != 0) + return (EFAULT); + } + } + + rval->sys_rval1 = len; + rval->sys_rval2 = 0; + return (0); + + default: + break; + } + +passthru: + return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2, arg3, + arg4)); +} + +/* + * Close a libc file handle, but don't actually close the underlying + * file descriptor. + */ +static void +s10_close_fh(FILE *file) +{ + int fd, fd_new; + + if (file == NULL) + return; + + if ((fd = fileno(file)) < 0) + return; + + fd_new = dup(fd); + if (fd_new == -1) + return; + + (void) fclose(file); + (void) dup2(fd_new, fd); + (void) close(fd_new); +} + +/*ARGSUSED*/ +int +s10_init(int argc, char *argv[], char *envp[]) +{ + sysret_t rval; + s10_brand_reg_t reg; + s10_elf_data_t sed; + auxv_t *ap; + uintptr_t *p; + int i, err; + char *bname; + + /* Sanity check our translation table return value codes */ + for (i = 0; i < NSYSCALL; i++) { + s10_sysent_table_t *est = &(s10_sysent_table[i]); + s10_assert(BIT_ONLYONESET(est->st_args & RV_MASK)); + } + + /* + * We need to shutdown all libc stdio. libc stdio normally goes to + * file descriptors, but since we're actually part of a another + * process we don't own these file descriptors and we can't make + * any assumptions about their state. + */ + s10_close_fh(stdin); + s10_close_fh(stdout); + s10_close_fh(stderr); + + /* + * Cache the pid of the zone's init process and determine if + * we're init(1m) for the zone. Remember: we might be init + * now, but as soon as we fork(2) we won't be. + */ + (void) get_initpid_info(); + + /* get the current zoneid */ + err = __systemcall(&rval, SYS_zone, ZONE_LOOKUP, NULL); + s10_assert(err == 0); + zoneid = (zoneid_t)rval.sys_rval1; + + /* Get the emulation version number. */ + if ((err = __systemcall(&rval, SYS_zone, ZONE_GETATTR, zoneid, + S10_EMUL_VERSION_NUM, &emul_vers, sizeof (emul_vers))) != 0 || + emul_vers != 0) { + s10_abort(err, "The zone's patch level is unsupported"); + /*NOTREACHED*/ + } + + bname = basename(argv[0]); + + /* + * In general we want the S10 commands that are zone-aware to continue + * to behave as they normally do within a zone. Since these commands + * are zone-aware, they should continue to "do the right thing". + * However, some zone-aware commands aren't going to work the way + * we expect them to inside the branded zone. In particular, the pkg + * and patch commands will not properly manage all pkgs/patches + * unless the commands think they are running in the global zone. For + * these commands we want to emulate the global zone. + * + * We don't do any emulation for pkgcond since it is typically used + * in pkg/patch postinstall scripts and we want those scripts to do + * the right thing inside a zone. + * + * One issue is the handling of hollow pkgs. Since the pkgs are + * hollow, they won't use pkgcond in their postinstall scripts. These + * pkgs typically are installing drivers so we handle that by + * replacing add_drv and rem_drv in the s10_boot script. + */ + if (strcmp("pkgadd", bname) == 0 || strcmp("pkgrm", bname) == 0 || + strcmp("patchadd", bname) == 0 || strcmp("patchrm", bname) == 0) + emul_global_zone = B_TRUE; + + /* + * Register our syscall emulation table with the kernel. + * Note that we don't have to do invoke (syscall_number + 1024) + * until we've actually establised a syscall emulation callback + * handler address, which is what we're doing with this brand + * syscall. + */ + reg.sbr_version = S10_VERSION; + reg.sbr_handler = (caddr_t)s10_handler; + if ((err = __systemcall(&rval, SYS_brand, B_REGISTER, ®)) != 0) { + s10_abort(err, "Failed to brand current process"); + /*NOTREACHED*/ + } + + /* Get data about the executable we're running from the kernel. */ + if ((err = __systemcall(&rval, SYS_brand + 1024, + B_ELFDATA, (void *)&sed)) != 0) { + s10_abort(err, + "Failed to get required brand ELF data from the kernel"); + /*NOTREACHED*/ + } + + /* + * Find the aux vector on the stack. + */ + p = (uintptr_t *)envp; + while (*p != NULL) + p++; + + /* + * p is now pointing at the 0 word after the environ pointers. + * After that is the aux vectors. + * + * The aux vectors are currently pointing to the brand emulation + * library and associated linker. We're going to change them to + * point to the brand executable and associated linker (or to no + * linker for static binaries). This matches the process data + * stored within the kernel and visible from /proc, which was + * all setup in s10_elfexec(). We do this so that when a debugger + * attaches to the process it sees the process as a normal solaris + * process, this brand emulation library and everything on it's + * link map will not be visible, unless our librtld_db plugin + * is used. Note that this is very different from how Linux + * branded processes are implemented within lx branded zones. + * In that situation, the primary linkmap of the process is the + * brand emulation libraries linkmap, not the Linux applications + * linkmap. + * + * We also need to clear the AF_SUN_NOPLM flag from the AT_SUN_AUXFLAGS + * aux vector. This flag told our linker that we don't have a + * primary link map. Now that our linker is done initializing, we + * want to clear this flag before we transfer control to the + * applications copy of the linker, since we want that linker to have + * a primary link map which will be the link map for the application + * we're running. + */ + p++; + for (ap = (auxv_t *)p; ap->a_type != AT_NULL; ap++) { + switch (ap->a_type) { + case AT_BASE: + /* Hide AT_BASE if static binary */ + if (sed.sed_base == NULL) { + ap->a_type = AT_IGNORE; + ap->a_un.a_val = NULL; + } else { + ap->a_un.a_val = sed.sed_base; + } + break; + case AT_ENTRY: + ap->a_un.a_val = sed.sed_entry; + break; + case AT_PHDR: + ap->a_un.a_val = sed.sed_phdr; + break; + case AT_PHENT: + ap->a_un.a_val = sed.sed_phent; + break; + case AT_PHNUM: + ap->a_un.a_val = sed.sed_phnum; + break; + case AT_SUN_AUXFLAGS: + ap->a_un.a_val &= ~AF_SUN_NOPLM; + break; + case AT_SUN_EMULATOR: + /* + * ld.so.1 inspects AT_SUN_EMULATOR to see if + * if it is the linker for the brand emulation + * library. Hide AT_SUN_EMULATOR, as the + * linker we are about to jump to is the linker + * for the binary. + */ + ap->a_type = AT_IGNORE; + ap->a_un.a_val = NULL; + break; + case AT_SUN_LDDATA: + /* Hide AT_SUN_LDDATA if static binary */ + if (sed.sed_lddata == NULL) { + ap->a_type = AT_IGNORE; + ap->a_un.a_val = NULL; + } else { + ap->a_un.a_val = sed.sed_lddata; + } + break; + default: + break; + } + } + + s10_runexe(argv, sed.sed_ldentry); + /*NOTREACHED*/ + s10_abort(0, "s10_runexe() returned"); + return (-1); +} + +/* + * This table must have at least NSYSCALL entries in it. + * + * The second parameter of each entry in the s10_sysent_table + * contains the number of parameters and flags that describe the + * syscall return value encoding. See the block comments at the + * top of this file for more information about the syscall return + * value flags and when they should be used. + */ +s10_sysent_table_t s10_sysent_table[] = { +#if defined(__sparc) && !defined(__sparcv9) + EMULATE(s10_indir, 9 | RV_64RVAL), /* 0 */ +#else /* !__sparc || __sparcv9 */ + NOSYS, /* 0 */ +#endif /* !__sparc || __sparcv9 */ + NOSYS, /* 1 */ + NOSYS, /* 2 */ + NOSYS, /* 3 */ + NOSYS, /* 4 */ + NOSYS, /* 5 */ + NOSYS, /* 6 */ + NOSYS, /* 7 */ + NOSYS, /* 8 */ + NOSYS, /* 9 */ + NOSYS, /* 10 */ + EMULATE(s10_exec, 2 | RV_DEFAULT), /* 11 */ + NOSYS, /* 12 */ + NOSYS, /* 13 */ + NOSYS, /* 14 */ + NOSYS, /* 15 */ + NOSYS, /* 16 */ + NOSYS, /* 17 */ + NOSYS, /* 18 */ + NOSYS, /* 19 */ + NOSYS, /* 20 */ + NOSYS, /* 21 */ + NOSYS, /* 22 */ + NOSYS, /* 23 */ + NOSYS, /* 24 */ + NOSYS, /* 25 */ + NOSYS, /* 26 */ + NOSYS, /* 27 */ + NOSYS, /* 28 */ + NOSYS, /* 29 */ + NOSYS, /* 30 */ + NOSYS, /* 31 */ + NOSYS, /* 32 */ + NOSYS, /* 33 */ + NOSYS, /* 34 */ + NOSYS, /* 35 */ + NOSYS, /* 36 */ + NOSYS, /* 37 */ + NOSYS, /* 38 */ + NOSYS, /* 39 */ + NOSYS, /* 40 */ + NOSYS, /* 41 */ + NOSYS, /* 42 */ + NOSYS, /* 43 */ + NOSYS, /* 44 */ + NOSYS, /* 45 */ + NOSYS, /* 46 */ + NOSYS, /* 47 */ + NOSYS, /* 48 */ + NOSYS, /* 49 */ + NOSYS, /* 50 */ + NOSYS, /* 51 */ + NOSYS, /* 52 */ + NOSYS, /* 53 */ + EMULATE(s10_ioctl, 3 | RV_DEFAULT), /* 54 */ + NOSYS, /* 55 */ + NOSYS, /* 56 */ + NOSYS, /* 57 */ + NOSYS, /* 58 */ + EMULATE(s10_execve, 3 | RV_DEFAULT), /* 59 */ + NOSYS, /* 60 */ + NOSYS, /* 61 */ + NOSYS, /* 62 */ + NOSYS, /* 63 */ + NOSYS, /* 64 */ + NOSYS, /* 65 */ + NOSYS, /* 66 */ + NOSYS, /* 67 */ + NOSYS, /* 68 */ + NOSYS, /* 69 */ + NOSYS, /* 70 */ + EMULATE(s10_acctctl, 3 | RV_DEFAULT), /* 71 */ + NOSYS, /* 72 */ + NOSYS, /* 73 */ + NOSYS, /* 74 */ + EMULATE(s10_issetugid, 0 | RV_DEFAULT), /* 75 */ + NOSYS, /* 76 */ + NOSYS, /* 77 */ + NOSYS, /* 78 */ + NOSYS, /* 79 */ + NOSYS, /* 80 */ + NOSYS, /* 81 */ + NOSYS, /* 82 */ + NOSYS, /* 83 */ + NOSYS, /* 84 */ + NOSYS, /* 85 */ + NOSYS, /* 86 */ + NOSYS, /* 87 */ + NOSYS, /* 88 */ + NOSYS, /* 89 */ + NOSYS, /* 90 */ + NOSYS, /* 91 */ + NOSYS, /* 92 */ + NOSYS, /* 93 */ + NOSYS, /* 94 */ + NOSYS, /* 95 */ + NOSYS, /* 96 */ + NOSYS, /* 97 */ + NOSYS, /* 98 */ + NOSYS, /* 99 */ + NOSYS, /* 100 */ + NOSYS, /* 101 */ + NOSYS, /* 102 */ + NOSYS, /* 103 */ + NOSYS, /* 104 */ + NOSYS, /* 105 */ + NOSYS, /* 106 */ + NOSYS, /* 107 */ + NOSYS, /* 108 */ + NOSYS, /* 109 */ + NOSYS, /* 110 */ + NOSYS, /* 111 */ + NOSYS, /* 112 */ + NOSYS, /* 113 */ + NOSYS, /* 114 */ + NOSYS, /* 115 */ + NOSYS, /* 116 */ + NOSYS, /* 117 */ + NOSYS, /* 118 */ + NOSYS, /* 119 */ + NOSYS, /* 120 */ + NOSYS, /* 121 */ + NOSYS, /* 122 */ + NOSYS, /* 123 */ + NOSYS, /* 124 */ + NOSYS, /* 125 */ + NOSYS, /* 126 */ + NOSYS, /* 127 */ + NOSYS, /* 128 */ + NOSYS, /* 129 */ + NOSYS, /* 130 */ + NOSYS, /* 131 */ + NOSYS, /* 132 */ + NOSYS, /* 133 */ + NOSYS, /* 134 */ + EMULATE(s10_uname, 1 | RV_DEFAULT), /* 135 */ + NOSYS, /* 136 */ + NOSYS, /* 137 */ + NOSYS, /* 138 */ + EMULATE(s10_sysinfo, 3 | RV_DEFAULT), /* 139 */ + NOSYS, /* 140 */ + NOSYS, /* 141 */ + NOSYS, /* 142 */ + NOSYS, /* 143 */ + NOSYS, /* 144 */ + NOSYS, /* 145 */ + NOSYS, /* 146 */ + NOSYS, /* 147 */ + NOSYS, /* 148 */ + NOSYS, /* 149 */ + NOSYS, /* 150 */ + NOSYS, /* 151 */ + NOSYS, /* 152 */ + NOSYS, /* 153 */ + NOSYS, /* 154 */ + NOSYS, /* 155 */ + NOSYS, /* 156 */ + NOSYS, /* 157 */ + NOSYS, /* 158 */ +#ifdef __x86 + EMULATE(s10_lwp_create, 3 | RV_DEFAULT), /* 159 */ +#else /* !__x86 */ + NOSYS, /* 159 */ +#endif /* !__x86 */ + NOSYS, /* 160 */ + NOSYS, /* 161 */ + NOSYS, /* 162 */ + NOSYS, /* 163 */ + NOSYS, /* 164 */ + NOSYS, /* 165 */ +#ifdef __x86 + EMULATE(s10_lwp_private, 3 | RV_DEFAULT), /* 166 */ +#else /* !__x86 */ + NOSYS, /* 166 */ +#endif /* !__x86 */ + NOSYS, /* 167 */ + NOSYS, /* 168 */ + NOSYS, /* 169 */ + NOSYS, /* 170 */ + NOSYS, /* 171 */ + NOSYS, /* 172 */ + NOSYS, /* 173 */ + EMULATE(s10_pwrite, 4 | RV_DEFAULT), /* 174 */ + NOSYS, /* 175 */ + NOSYS, /* 176 */ + NOSYS, /* 177 */ + NOSYS, /* 178 */ + NOSYS, /* 179 */ + NOSYS, /* 180 */ + NOSYS, /* 181 */ + NOSYS, /* 182 */ + NOSYS, /* 183 */ + NOSYS, /* 184 */ + NOSYS, /* 185 */ + EMULATE(s10_auditsys, 4 | RV_64RVAL), /* 186 */ + NOSYS, /* 187 */ + NOSYS, /* 188 */ + NOSYS, /* 189 */ + EMULATE(s10_sigqueue, 4 | RV_DEFAULT), /* 190 */ + NOSYS, /* 191 */ + NOSYS, /* 192 */ + NOSYS, /* 193 */ + NOSYS, /* 194 */ + NOSYS, /* 195 */ + NOSYS, /* 196 */ + NOSYS, /* 197 */ + NOSYS, /* 198 */ + NOSYS, /* 199 */ + NOSYS, /* 200 */ + NOSYS, /* 201 */ + NOSYS, /* 202 */ + NOSYS, /* 203 */ + NOSYS, /* 204 */ + NOSYS, /* 205 */ + NOSYS, /* 206 */ + NOSYS, /* 207 */ + NOSYS, /* 208 */ + NOSYS, /* 209 */ + NOSYS, /* 210 */ + NOSYS, /* 211 */ + NOSYS, /* 212 */ + NOSYS, /* 213 */ + NOSYS, /* 214 */ + NOSYS, /* 215 */ + NOSYS, /* 216 */ + NOSYS, /* 217 */ + NOSYS, /* 218 */ + NOSYS, /* 219 */ + NOSYS, /* 220 */ + NOSYS, /* 221 */ + NOSYS, /* 222 */ +#ifdef _LP64 + NOSYS, /* 223 */ +#else /* !_LP64 */ + EMULATE(s10_pwrite64, 5 | RV_DEFAULT), /* 223 */ +#endif /* !_LP64 */ + NOSYS, /* 224 */ + NOSYS, /* 225 */ + NOSYS, /* 226 */ + EMULATE(s10_zone, 5 | RV_DEFAULT), /* 227 */ + NOSYS, /* 228 */ + NOSYS, /* 229 */ + NOSYS, /* 230 */ + NOSYS, /* 231 */ + NOSYS, /* 232 */ + NOSYS, /* 233 */ + NOSYS, /* 234 */ + NOSYS, /* 235 */ + NOSYS, /* 236 */ + NOSYS, /* 237 */ + NOSYS, /* 238 */ + NOSYS, /* 239 */ + NOSYS, /* 240 */ + NOSYS, /* 241 */ + NOSYS, /* 242 */ + NOSYS, /* 243 */ + NOSYS, /* 244 */ + NOSYS, /* 245 */ + NOSYS, /* 246 */ + NOSYS, /* 247 */ + NOSYS, /* 248 */ + NOSYS, /* 249 */ + NOSYS, /* 250 */ + NOSYS, /* 251 */ + NOSYS, /* 252 */ + NOSYS, /* 253 */ + NOSYS, /* 254 */ + NOSYS /* 255 */ +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/i386/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,39 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +ISASRCDIR = . + +include ../Makefile.com + +# +# see ../Makefile.com for why we explicity make ld.so.1 our interpreter +# +# S10 linker +DYNFLAGS += -Wl,-I/lib/ld.so.1 + +CLEANFILES += $(DYNLIB) +CLOBBERFILES += $(ROOTLIBS) + +install: all $(ROOTLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/i386/s10_crt.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,77 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/asm_linkage.h> + +#if defined(lint) + +void +_start(void) +{ +} + +#else /* lint */ + /* + * Initial entry point for the brand emulation library. + * + * This platform specific assembly entry point exists just to invoke + * the common brand library startup routine. That routine expects to + * be called with the following arguments: + * s10_init(int argc, char *argv[], char *envp[]) + * + * There are no arguments explicitly passed to this entry point, + * routine, but we do know how our initial stack has been setup by + * the kernel. The stack format is documented in: + * usr/src/cmd/sgs/rtld/i386/boot.s + * + * So this routine will troll through the stack to setup the argument + * values for the common brand library startup routine and then invoke + * it. This routine is modeled after the default crt1.s`_start() + * routines. + */ + ENTRY_NP(_start) + + /* Make stack traces look pretty, build a fake stack frame. */ + pushl $0 / retpc = NULL + pushl $0 / fp = NULL + movl %esp, %ebp / first stack frame + + /* + * Calculate the location of the envp array by adding the size of + * the argv array to the start of the argv array. + */ + movl 8(%ebp), %eax / argc in %eax + leal 12(%ebp), %ebx / &argv[0] in %ebx + leal 16(%ebp,%eax,4), %ecx / envp in %ecx + + pushl %ecx / push envp (3rd param) + pushl %ebx / push argv (2nd param) + pushl %eax / push argc (1st param) + call s10_init + + /*NOTREACHED*/ + SET_SIZE(_start) +#endif /* lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/i386/s10_handler.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,159 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <s10_misc.h> + +#if defined(lint) + +void +s10_handler(void) +{ +} + +#else /* lint */ + +#define PIC_SETUP(r) \ + call 9f; \ +9: \ + popl r; \ + addl $_GLOBAL_OFFSET_TABLE_ + [. - 9b], r + + /* + * %eax - syscall number + * stack contains: + * -------------------------------------- + * | 8 | syscall arguments | + * v 4 | syscall wrapper return address | + * %esp+0 | syscall return address | + * -------------------------------------- + */ + ENTRY_NP(s10_handler) + pushl %ebp /* allocate a stack frame */ + movl %esp, %ebp + + /* Save registers at the time of the syscall. */ + movl $0, EH_LOCALS_GREG(TRAPNO)(%ebp) + movl $0, EH_LOCALS_GREG(ERR)(%ebp) + movl %eax, EH_LOCALS_GREG(EAX)(%ebp) + movl %ebx, EH_LOCALS_GREG(EBX)(%ebp) + movl %ecx, EH_LOCALS_GREG(ECX)(%ebp) + movl %edx, EH_LOCALS_GREG(EDX)(%ebp) + movl %edi, EH_LOCALS_GREG(EDI)(%ebp) + movl %esi, EH_LOCALS_GREG(ESI)(%ebp) + mov %cs, EH_LOCALS_GREG(CS)(%ebp) + mov %ds, EH_LOCALS_GREG(DS)(%ebp) + mov %es, EH_LOCALS_GREG(ES)(%ebp) + mov %fs, EH_LOCALS_GREG(FS)(%ebp) + mov %gs, EH_LOCALS_GREG(GS)(%ebp) + pushfl /* save syscall flags */ + popl %ecx + movl %ecx, EH_LOCALS_GREG(EFL)(%ebp) + movl EH_ARGS_OFFSET(0)(%ebp), %ecx /* save syscall ebp */ + movl %ecx, EH_LOCALS_GREG(EBP)(%ebp) + movl %ebp, %ecx /* save syscall esp */ + addl $CPTRSIZE, %ecx + movl %ecx, EH_LOCALS_GREG(ESP)(%ebp) + movl EH_ARGS_OFFSET(1)(%ebp), %ecx /* save syscall ret address */ + movl %ecx, EH_LOCALS_GREG(EIP)(%ebp) + + /* + * Finish setting up our stack frame. We would normally do this + * upon entry to this function, but in this case we delayed it + * because a "sub" operation can modify flags and we wanted to + * save the flags into the gregset_t above before they get modified. + * + * Our stack frame format is documented in s10_misc.h. + */ + subl $EH_LOCALS_SIZE, %esp + + /* Look up the system call's entry in the sysent table */ + PIC_SETUP(%ecx) + movl s10_sysent_table@GOT(%ecx), %edx /* %edx = sysent_table */ + shll $3, %eax /* each entry is 8 bytes */ + add %eax, %edx /* %edx = sysent entry address */ + + /* + * Get the return value flag and the number of arguments from the + * sysent table. + */ + movl CPTRSIZE(%edx), %ecx /* number of args + rv flag */ + andl $RV_MASK, %ecx /* strip out number of args */ + movl %ecx, EH_LOCALS_RVFLAG(%ebp) /* save rv flag */ + movl CPTRSIZE(%edx), %ecx /* number of args + rv flag */ + andl $NARGS_MASK, %ecx /* strip out rv flag */ + + /* + * Setup arguments for our emulation call. Our input arguments, + * 0 to N, will become emulation call arguments 1 to N+1. + * %ecx == number of arguments. + */ + movl %ebp, %esi /* args are at 12(%ebp) */ + addl $EH_ARGS_OFFSET(3), %esi + movl %esp, %edi /* copy args to 4(%esp) */ + addl $EH_ARGS_OFFSET(1), %edi + rep; smovl /* copy: (%esi) -> (%edi) */ + /* copy: %ecx 32-bit words */ + movl EH_LOCALS_GREG(ESI)(%ebp), %esi /* restore %esi */ + movl EH_LOCALS_GREG(EDI)(%ebp), %edi /* restore %edi */ + + /* + * The first parameter to the emulation callback function is a + * pointer to a sysret_t structure. + */ + movl %ebp, %ecx + addl $EH_LOCALS_SYSRET, %ecx + movl %ecx, EH_ARGS_OFFSET(0)(%esp) /* arg0 == sysret_t ptr */ + + /* invoke the emulation routine */ + ALTENTRY(s10_handler_savepc) + call *(%edx) /* call emulation routine */ + + /* restore scratch registers */ + movl EH_LOCALS_GREG(ECX)(%ebp), %ecx /* restore %ecx */ + movl EH_LOCALS_GREG(EDX)(%ebp), %edx /* restore %edx */ + + /* Check for syscall emulation success or failure */ + cmpl $0, %eax /* check for an error */ + je success + stc /* failure, set carry flag */ + jmp return /* return, %rax == errno */ + +success: + /* There is always at least one return value. */ + movl EH_LOCALS_SYSRET1(%ebp), %eax /* %eax == sys_rval1 */ + cmpl $RV_DEFAULT, EH_LOCALS_RVFLAG(%ebp) /* check rv flag */ + je clear_carry + mov EH_LOCALS_SYSRET2(%ebp), %edx /* %edx == sys_rval2 */ +clear_carry: + clc /* success, clear carry flag */ + +return: + movl %ebp, %esp /* restore stack */ + popl %ebp + ret /* ret to instr after syscall */ + SET_SIZE(s10_handler) + + +#endif /* lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/i386/s10_runexe.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,80 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/asm_linkage.h> +#include <s10_misc.h> + +#if defined(lint) + +/*ARGSUSED*/ +void +s10_runexe(void *argv, ulong_t entry) +{ +} + +#else /* lint */ + /* + * Prepare to jump to the target program we actually want to run. + * If this program is dynamically linked then we'll be jumping to + * another copy of the linker. If it's a statically linked program + * we'll be jumping directy to it's main entry point. In any case, + * we need to reset our current state stack and register state to + * something similar to the initial process state setup by the kernel + * and documented at: + * usr/src/cmd/sgs/rtld/i386/boot.s + * usr/src/cmd/sgs/rtld/sparcv9/boot.s + * + * Of course this is the same stack format as when this executable + * was first started, so here we'll just roll back the stack and + * frame pointers to their values when this processes first started + * execution. + */ + ENTRY_NP(s10_runexe) + + movl 4(%esp), %eax / %eax = &argv[0] + movl 8(%esp), %ebx / Brand app entry point in %ebx + subl $4, %eax / Top of stack - must point at argc + movl %eax, %esp / Set %esp to what linkers expect + + /* + * We also have to make sure to clear %edx since nornally ld.so.1 will + * set that to non-zero if there is an exit function that should be + * invoked when the process is terminating. This isn't actually + * necessary if the target program we're jumping to is a dynamically + * linked program since in that case we're actually jumping to another + * copy of ld.so.1 and it will just reset %edx, but if the target + * program we're jumping to is a statically linked binary that uses + * the standard sun compiler supplied crt1.o`_start(), it will check + * to see if %g1 is set. + */ + movl $0, %edx + + jmp *%ebx / And away we go... + /* + * target will never return. + */ + SET_SIZE(s10_runexe) +#endif /* lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/sparc/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,40 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +ISASRCDIR = . + +include ../Makefile.com + +# +# see ../Makefile.com for why we MUST explicity make ld.so.1 our interpreter +# +# S10 linker +DYNFLAGS += -Wl,-I/lib/ld.so.1 +ASFLAGS += -xarch=v8plus ${AS_PICFLAGS} + +CLEANFILES += $(DYNLIB) +CLOBBERFILES += $(ROOTLIBS) + +install: all $(ROOTLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/sparc/s10_crt.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,80 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/asm_linkage.h> +#include <sys/link.h> + +#if defined(lint) + +void +_start(void) +{ +} + +#else /* lint */ + .section ".text" + /* + * Initial entry point for the brand emulation library. + * + * This platform specific assembly entry point exists just to invoke + * the common brand library startup routine. That routine expects to + * be called with the following arguments: + * s10_init(int argc, char *argv[], char *envp[]) + * + * There are no arguments explicitly passed to this entry point, + * routine, but we do know how our initial stack has been setup by + * the kernel. The stack format is documented in: + * usr/src/cmd/sgs/rtld/sparc/boot.s + * usr/src/cmd/sgs/rtld/sparcv9/boot.s + * + * So this routine will troll through the stack to setup the argument + * values for the common brand library startup routine and then invoke + * it. + */ + ENTRY_NP(_start) +#if defined (__sparcv9) + save %sp, -SA(MINFRAME + EB_MAX_SIZE64), %sp +#else /* !__sparcv9 */ + save %sp, -SA(MINFRAME + EB_MAX_SIZE32), %sp +#endif /* !__sparcv9 */ + + /* get argc */ + ldn [%fp + WINDOWSIZE + STACK_BIAS], %o0 + + /* get argv */ + add %fp, + WINDOWSIZE + CPTRSIZE + STACK_BIAS, %o1 + + /* get envp */ + add %o0, 1, %l0 ! add 1 to argc for last element of 0 + sll %l0, CPTRSHIFT, %l0 ! multiply argc by pointer size + add %o1, %l0, %o2 ! and add to argv to get first env ptr + + call s10_init + nop + + /*NOTREACHED*/ + SET_SIZE(_start) +#endif /* lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/sparc/s10_handler.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,225 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <s10_misc.h> + +#if defined(lint) + +void +s10_handler(void) +{ +} + +#else /* !lint */ + +#define PIC_SETUP(r) \ + mov %o7, %g1; \ +9: call 8f; \ + sethi %hi(_GLOBAL_OFFSET_TABLE_ - (9b - .)), r; \ +8: or r, %lo(_GLOBAL_OFFSET_TABLE_ - (9b - .)), r; \ + add r, %o7, r; \ + mov %g1, %o7 + +/* + * Translate a global symbol into an address. The resulting address + * is returned in the first register parameter. The second register + * is just for scratch space. + */ +#if defined(__sparcv9) +#define GET_SYM_ADDR(r1, r2, name) \ + PIC_SETUP(r1) ;\ + sethi %hi(name), r2 ;\ + or r2, %lo(name), r2 ;\ + ldn [r2 + r1], r1 +#else /* !__sparcv9 */ +#define GET_SYM_ADDR(r1, r2, name) \ + PIC_SETUP(r1); \ + ld [r1 + name], r1 +#endif /* !__sparcv9 */ + + .section ".text" + + /* + * When we get here, %g1 should contain the system call and + * %g5 should contain the address immediately after the trap + * instruction. + */ + ENTRY_NP(s10_handler) + + /* + * 64-bit sparc may need to save 3 parameters on the stack. + * 32-bit sparc may need to save 4 parameters on the stack. + * + * Our stack frame format is documented in s10_misc.h. + */ + save %sp, -SA(MINFRAME + EH_LOCALS_SIZE), %sp + + /* + * Save the current caller state into gregs and gwins. + * Note that this state isn't exact, %g1 and %g5 have been + * already been lost. Also, we've pushed a stack frame so + * the callers output registers are our input registers. + */ + stn %g0, [%sp + EH_LOCALS_GREG(REG_G1)] /* %g1 is lost */ + stn %g2, [%sp + EH_LOCALS_GREG(REG_G2)] + stn %g3, [%sp + EH_LOCALS_GREG(REG_G3)] + stn %g4, [%sp + EH_LOCALS_GREG(REG_G4)] + stn %g0, [%sp + EH_LOCALS_GREG(REG_G5)] /* %g5 is lost */ + stn %g6, [%sp + EH_LOCALS_GREG(REG_G6)] + stn %g7, [%sp + EH_LOCALS_GREG(REG_G7)] + stn %i0, [%sp + EH_LOCALS_GREG(REG_O0)] + stn %i1, [%sp + EH_LOCALS_GREG(REG_O1)] + stn %i2, [%sp + EH_LOCALS_GREG(REG_O2)] + stn %i3, [%sp + EH_LOCALS_GREG(REG_O3)] + stn %i4, [%sp + EH_LOCALS_GREG(REG_O4)] + stn %i5, [%sp + EH_LOCALS_GREG(REG_O5)] + stn %i6, [%sp + EH_LOCALS_GREG(REG_O6)] + stn %i7, [%sp + EH_LOCALS_GREG(REG_O7)] + sub %g5, 4, %o0 + stn %o0, [%sp + EH_LOCALS_GREG(REG_PC)] + stn %g5, [%sp + EH_LOCALS_GREG(REG_nPC)] + rd %y, %o0 + stn %o0, [%sp + EH_LOCALS_GREG(REG_Y)] +#if defined(__sparcv9) + stn %g0, [%sp + EH_LOCALS_GREG(REG_ASI)] + rd %fprs, %o0 + stn %o0, [%sp + EH_LOCALS_GREG(REG_FPRS)] +#endif /* __sparcv9 */ + + /* + * Look up the system call's entry in the sysent table + * and obtain the address of the proper emulation routine (%l2). + */ + mov %g1, %l5 /* save syscall number */ + GET_SYM_ADDR(%l1, %l2, s10_sysent_table) + mov %l5, %g1 /* restore syscall number */ + sll %g1, (1 + CLONGSHIFT), %l2 /* Each entry has 2 longs */ + add %l2, %l1, %l2 /* index to proper entry */ + ldn [%l2], %l2 /* emulation func address */ + + /* + * Look up the system call's entry in the sysent table, + * taking into account the posibility of indirect system calls, and + * obtain the number of arguments (%l4) and return value flag (%l3). + */ +#if defined(__sparcv9) + mov %g1, %l3 /* %g1 == syscall number */ +#else /* !__sparcv9 */ + /* + * Check for indirect system calls, in which case the real syscall + * number is the first parameter to the indirect system call. + */ + cmp %g1, %g0 /* saved syscall number */ + bne,a,pt %icc, no_indir /* indirect syscall? */ + mov %g1, %l3 /* %g1 == syscall number */ + mov %i0, %l3 /* %i0 == syscall number */ +no_indir: +#endif /* !__sparcv9 */ + sll %l3, (1 + CLONGSHIFT), %l3 /* Each entry has 2 longs */ + add %l3, %l1, %l3 /* index to proper entry */ + ldn [%l3 + CPTRSIZE], %l4 /* number of args + rv flag */ + sethi %hi(RV_MASK), %l5 + or %l5, %lo(RV_MASK), %l5 + andcc %l4, %l5, %l3 /* strip out number of args*/ + andcc %l4, NARGS_MASK, %l4 /* strip out rv flag */ + + /* + * Setup arguments for our emulation call. Our input arguments, + * 0 to N, will become emulation call arguments 1 to N+1. + * %l4 == number of arguments. + */ + mov %i0, %o1 + mov %i1, %o2 + mov %i2, %o3 + mov %i3, %o4 + mov %i4, %o5 + + /* 7th argument and above get passed on the stack */ + cmp %l4, 0x6 + bl,pt %ncc, args_copied + nop + stn %i5, [%sp + EH_ARGS_OFFSET(0)] /* copy 6th syscall arg */ + cmp %l4, 0x7 + bl,pt %ncc, args_copied + nop + ldn [%fp + EH_ARGS_OFFSET(0)], %l5 /* copy 7th syscall arg */ + stn %l5, [%sp + EH_ARGS_OFFSET(1)] + cmp %l4, 0x8 + bl,pt %ncc, args_copied + nop + ldn [%fp + EH_ARGS_OFFSET(1)], %l5 + stn %l5, [%sp + EH_ARGS_OFFSET(2)] /* copy 8th syscall arg */ +#if !defined(__sparcv9) + cmp %l4, 0x9 + bl,pt %ncc, args_copied + nop + ldn [%fp + EH_ARGS_OFFSET(2)], %l5 + stn %l5, [%sp + EH_ARGS_OFFSET(3)] /* copy 9th syscall arg */ +#endif /* !__sparcv9 */ + +args_copied: + /* + * The first parameter to the emulation callback function is a + * pointer to a sysret_t structure. + * + * invoke the emulation routine. + */ + ALTENTRY(s10_handler_savepc) + call %l2 + add %sp, EH_LOCALS_SYSRET, %o0 /* arg0 == sysret_t ptr */ + + /* Check for syscall emulation success or failure */ + cmp %g0, %o0 + be success + nop + subcc %g0, 1, %g0 /* failure, set carry flag */ + ba return + mov %o0, %i0 /* return, %o0 == errno */ + +success: + /* There is always at least one return value. */ + ldn [%sp + EH_LOCALS_SYSRET1], %i0 /* %i0 == sys_rval1 */ + cmp %l3, RV_DEFAULT /* check rv flag */ + be,a clear_carry + mov %g0, %i1 /* clear second rval */ + ldn [%sp + EH_LOCALS_SYSRET2], %i1 /* %i1 == sys_rval2 */ +clear_carry: + addcc %g0, %g0, %g0 /* success, clear carry flag */ + +return: + /* + * Our syscall emulation is complete. Return to the caller that + * originally invoked a system which needed emulation. Note that + * we have to load the return address that we saved earlier because + * it's possible that %g5 was overwritten by a nested call into + * this emulation library. + */ + ldn [%sp + EH_LOCALS_GREG(REG_nPC)], %g5 + jmp %g5 + restore /* delay slot */ + SET_SIZE(s10_handler) + + +#endif /* !lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/sparc/s10_runexe.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,82 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/asm_linkage.h> +#include <s10_misc.h> + +#if defined(lint) + +/*ARGSUSED*/ +void +s10_runexe(void *argv, ulong_t entry) +{ +} + +#else /* lint */ + .section ".text" + ENTRY_NP(s10_runexe) + /* + * Prepare to jump to the target program we actually want to run. + * If this program is dynamically linked then we'll be jumping to + * another copy of the linker. If it's a statically linked program + * we'll be jumping directy to it's main entry point. In any case, + * we need to reset our current state stack and register state to + * something similar to the initial process state setup by the kernel + * and documented at: + * usr/src/cmd/sgs/rtld/sparc/boot.s + * usr/src/cmd/sgs/rtld/sparcv9/boot.s + * + * Of course this is the same stack format as when this executable + * was first started, so here we'll just roll back the stack and + * frame pointers to their values when this processes first started + * execution. + * + * Our input parameters are stored in the %o? registers since we + * don't bother to allocate a new stack frame. + */ + sub %o0, CPTRSIZE + WINDOWSIZE + STACK_BIAS, %sp + clr %fp + + /* + * We also have to make sure to clear %g1 since nornally ld.so.1 will + * set that to non-zero if there is an exit function that should be + * invoked when the process is terminating. This isn't actually + * necessary if the target program we're jumping to is a dynamically + * linked program since in that case we're actually jumping to another + * copy of ld.so.1 and it will just reset %g1, but if the target + * program we're jumping to is a statically linked binary that uses + * the standard sun compiler supplied crt1.o`_start(), it will check + * to see if %g1 is set. + */ + clr %g1 + + jmp %o1 ! jump to the target processes entry point + nop + /* + * target will never return. + */ + SET_SIZE(s10_runexe) +#endif /* lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/sparcv9/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,41 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +ISASRCDIR = ../sparc + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +# +# see ../Makefile.com for why we explicity make ld.so.1 our interpreter +# +# S10 linker +DYNFLAGS += -Wl,-I/lib/64/ld.so.1 +ASFLAGS_$(CURTYPE) += ${AS_PICFLAGS} + +CLEANFILES += $(DYNLIB) +CLOBBERFILES += $(ROOTLIBS64) + +install: all $(ROOTLIBS64)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_brand/sys/s10_misc.h Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,199 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _S10_MISC_H +#define _S10_MISC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This header file must uses _ASM defines to allow it to be included + * in assmebly source files + */ +#include <sys/asm_linkage.h> +#include <sys/regset.h> +#include <sys/syscall.h> +#include "assym.h" + +/* + * Our syscall emulation callback handler adds one argument to each + * system call, so we'll need to allocate space for one more argument + * above the maximum number of arguments that a system call can normally + * take. Also, we assume that each syscall argument is a long, ie, we + * don't support long long syscall parameters. + */ +#if defined(__sparc) +/* + * 32-bit and 64-bit sparc syscalls can take up to 8 arguments. + * 32-bit sparc indirect syscalls can take up to 9 arguments. + * Arguments 1 - 6 are passed via %o0 - %o5. + * Additional arguments are passed on the stack. + * So make space for 4 arguments on the stack. + */ +#define EH_ARGS_COUNT 4 +#elif defined(__amd64) +/* + * amd64 syscalls can take up to 8 arguments. + * Arguments 1 - 6 are passed via: %rdi, %rsi, %rdx, %r10, %r8, %r9 + * Additional arguments are passed on the stack. + * So make space for 3 arguments on the stack. + */ +#define EH_ARGS_COUNT 3 +#else /* !__sparc && !__amd64 */ +/* + * ia32 syscalls can take up to 8 arguments. + * All arguments are passed on the stack. + * So make space for 9 arguments on the stack. + */ +#define EH_ARGS_COUNT 9 +#endif /* !__sparc && !__amd64 */ + + +#define EH_ARGS_SIZE (CPTRSIZE * EH_ARGS_COUNT) +#define EH_ARGS_OFFSET(x) (STACK_BIAS + MINFRAME + (CPTRSIZE * (x))) +#define EH_LOCALS_SIZE (EH_ARGS_SIZE + SIZEOF_GREGSET_T + \ + SIZEOF_SYSRET_T + CPTRSIZE) + +#if defined(__sparc) +/* + * On sparc, all emulation callback handler variable access is done + * relative to %sp, so access offsets are positive. + */ +#define EH_LOCALS_START (STACK_BIAS + MINFRAME + EH_ARGS_SIZE) +#define EH_LOCALS_END_TGT (STACK_BIAS + MINFRAME + EH_LOCALS_SIZE) +#else /* !__sparc */ +/* + * On x86, all emulation callback handler variable access is done + * relative to %ebp/%rbp, so access offsets are negative. + */ +#define EH_LOCALS_START (-(EH_LOCALS_SIZE - \ + (STACK_BIAS + MINFRAME + EH_ARGS_SIZE))) +#define EH_LOCALS_END_TGT 0 +#endif /* !__sparc */ + +/* + * In our emulation callback handler, our stack will look like: + * ------------------------------------------------- + * %bp | long rvflag | + * | | sysret_t sysret | + * v | gregset_t gregs | + * %sp | long callback args[EH_ARGS_COUNT] | + * ------------------------------------------------- + * For ia32, use %ebp and %esp instead of %bp and %sp. + * For amd64, use %rbp and %rsp instead of %bp and %sp. + * + * Our emulation callback handler always saves enough space to hold the + * maximum number of stack arguments to a system call. This is architecture + * specific and is defined via EH_ARGS_COUNT. + */ +#define EH_LOCALS_GREGS (EH_LOCALS_START) +#define EH_LOCALS_GREG(x) (EH_LOCALS_GREGS + (SIZEOF_GREG_T * (x))) +#define EH_LOCALS_SYSRET (EH_LOCALS_GREGS + SIZEOF_GREGSET_T) +#define EH_LOCALS_SYSRET1 (EH_LOCALS_SYSRET) +#define EH_LOCALS_SYSRET2 (EH_LOCALS_SYSRET + CPTRSIZE) +#define EH_LOCALS_RVFLAG (EH_LOCALS_SYSRET + SIZEOF_SYSRET_T) +#define EH_LOCALS_END (EH_LOCALS_RVFLAG + CPTRSIZE) + +#if (EH_LOCALS_END != EH_LOCALS_END_TGT) +#error "s10_misc.h EH_LOCALS_* macros don't add up" +#endif /* (EH_LOCALS_END != EH_LOCALS_END_TGT) */ + +/* + * The second parameter of each entry in the s10_sysent_table + * contains the number of parameters and flags that describe the + * syscall return value encoding. See the block comments at the + * top of ../common/s10_brand.c for more information about the + * syscall return value flags and when they should be used. + */ +#define NARGS_MASK 0x000000FF /* Mask for syscalls argument count */ +#define RV_MASK 0x0000FF00 /* Mask for return value flags */ +#define RV_DEFAULT 0x00000100 /* syscall returns "default" values */ +#define RV_32RVAL2 0x00000200 /* syscall returns two 32-bit values */ +#define RV_64RVAL 0x00000400 /* syscall returns a 64-bit value */ + +#if !defined(_ASM) + +/* + * We define our own version of assert because the default one will + * try to emit a localized message. That is bad because first, we can't + * emit messages to random file descriptors, and second localizing a message + * requires allocating memory and we can't do that either. + */ +#define s10_assert(ex) (void)((ex) || \ + (_s10_abort(0, #ex, __FILE__, __LINE__), 0)) +#define s10_abort(err, msg) _s10_abort((err), (msg), __FILE__, __LINE__) + +/* + * These macros invoke a brandsys subcommand, B_S10_TRUSS_POINT, used to expose + * a call to an interpositioned syscall that would have otherwise gone + * unnoticed by truss(1) because the interpositioned system call did not call + * any system calls before returning. + */ +#define S10_TRUSS_POINT_5(rval, syscall_num, err, a0, a1, a2, a3, a4) \ + __systemcall(rval, SYS_brand + 1024, \ + B_S10_TRUSS_POINT, (syscall_num), (err), (a0), (a1), (a2), (a3), \ + (a4)) + +#define S10_TRUSS_POINT_4(rval, syscall_num, err, a0, a1, a2, a3) \ + S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), (a2), (a3), 0) + +#define S10_TRUSS_POINT_3(rval, syscall_num, err, a0, a1, a2) \ + S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), (a2), 0, 0) + +#define S10_TRUSS_POINT_2(rval, syscall_num, err, a0, a1) \ + S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), 0, 0, 0) + +#define S10_TRUSS_POINT_1(rval, syscall_num, err, a0) \ + S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), 0, 0, 0, 0) + +#define S10_TRUSS_POINT_0(rval, syscall_num, err) \ + S10_TRUSS_POINT_5(rval, (syscall_num), (err), 0, 0, 0, 0, 0) + +/* + * From s10_runexe.s + */ +extern void s10_runexe(void *, ulong_t); + +/* + * From s10_handler.s + */ +extern void s10_handler(void); +extern void s10_error(void); +extern void s10_success(void); + +/* + * From s10_brand.c + */ +extern void _s10_abort(int, const char *, const char *, int); + +#endif /* !_ASM */ + +#ifdef __cplusplus +} +#endif + +#endif /* _S10_MISC_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_npreload/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,47 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include $(SRC)/lib/Makefile.lib + +default: all + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint +_msg := TARGET= _msg + +.KEEP_STATE: + +all install clean clobber lint _msg: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_npreload/Makefile.com Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,56 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +LIBRARY = s10_npreload.a +VERS = .1 +COBJS = s10_npreload.o + +OBJECTS = $(COBJS) + +UTSBASE = $(SRC)/uts + +include ../../Makefile.s10 +include $(SRC)/lib/Makefile.lib + +LIBS = $(DYNLIB) +CSRCS = $(COBJS:%o=../common/%c) +SRCS = $(CSRCS) +SRCDIR = ../common + +CPPFLAGS += -D_REENTRANT -U_ASM -I../sys \ + -I$(UTSBASE)/common/brand/solaris10 +CFLAGS += $(CCVERBOSE) +DYNFLAGS += $(BLOCAL) $(ZNOVERSION) +LDLIBS += -lc + +CLEANFILES += $(DYNLIB) + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include $(SRC)/lib/Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_npreload/amd64/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,31 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +CLOBBERFILES = $(ROOTLIBDIR64)/$(DYNLIB) $(ROOTLIBDIR64)/$(LINTLIB) + +install: all $(ROOTLIBS64)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_npreload/common/mapfile-vers Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,43 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +SUNWprivate_1.0 { + local: + *; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_npreload/common/s10_npreload.c Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,49 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma init(init) + +#include <s10_brand.h> +#include <sys/syscall.h> + +/* + * This is a library that is LD_PRELOADed into native binaries. + * All it does is one brand operation. B_S10_NATIVE. This brand + * operation checks that this is actually a native binary, and then + * if so changes the executable name so that it is no longer ld.sol.1. + * Instead it changes it to be the name of the real native executable + * that we're runnning. This allows things like pgrep to work as + * expected. Note, that this brand opration only changes the process + * name wrt the kernel. From the processes perspective, the first + * argument and AT_SUN_EXECNAME are still ld.so.1. + */ + +void +init(void) +{ + sysret_t rval; + (void) __systemcall(&rval, SYS_brand, B_S10_NATIVE); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_npreload/i386/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,30 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +CLOBBERFILES = $(ROOTLIBDIR)/$(DYNLIB) $(ROOTLIBDIR)/$(LINTLIB) + +install: all $(ROOTLIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_npreload/sparc/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,32 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +CLOBBERFILES += $(ROOTLIBS) + +install: all $(ROOTLIBS) + +include $(SRC)/Makefile.msg.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_npreload/sparcv9/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,33 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +CLOBBERFILES += $(ROOTLIBS64) + +install: all $(ROOTLIBS64) + +include $(SRC)/Makefile.msg.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_support/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,54 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROG = s10_support +PROGS = $(PROG) +OBJS = s10_support + +all: $(PROG) + +include ../Makefile.s10 +include $(SRC)/cmd/Makefile.cmd + +# override the install directory +ROOTBIN = $(ROOTBRANDDIR) +CLOBBERFILES = $(OBJS) $(ROOTPROGS) + +UTSBASE = $(SRC)/uts + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -D_REENTRANT -I$(UTSBASE)/common/brand/solaris10 +LDLIBS += -lzonecfg + +.KEEP_STATE: + +install: all $(ROOTPROGS) + +clean: + $(RM) $(PROG) $(OBJS) + +lint: lint_PROG + +include $(SRC)/cmd/Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/s10_support/s10_support.c Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,457 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * s10_support is a small cli utility used to perform some brand-specific + * tasks when verifying a zone. This utility is not intended to be called + * by users - it is intended to be invoked by the zones utilities. + */ + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <libgen.h> +#include <limits.h> +#include <s10_brand.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <stropts.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/utsname.h> +#include <sys/varargs.h> +#include <unistd.h> +#include <libintl.h> +#include <locale.h> +#include <dirent.h> +#include <sys/systeminfo.h> + +#include <libzonecfg.h> + +static void s10_err(char *msg, ...) __NORETURN; +static void usage(void) __NORETURN; + +/* + * XXX This is a temporary flag for the initial release to enable the + * use of features which are not yet tested or fully implemented. + */ +static boolean_t override = B_FALSE; + +static char *bname = NULL; + +#define PKGINFO_RD_LEN 128 +#define PATCHLIST "PATCHLIST=" + +#if !defined(TEXT_DOMAIN) /* should be defined by cc -D */ +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ +#endif + +/*PRINTFLIKE1*/ +static void +s10_err(char *msg, ...) +{ + char buf[1024]; + va_list ap; + + va_start(ap, msg); + (void) vsnprintf(buf, sizeof (buf), msg, ap); + va_end(ap); + + /* This needs go to stdout so the msgs show up through zoneadm. */ + (void) printf("Error: %s\n", buf); + + exit(1); + /*NOTREACHED*/ +} + +static int +s10_verify(char *xmlfile) +{ + zone_dochandle_t handle; + struct zone_fstab fstab; + struct zone_devtab devtab; + zone_iptype_t iptype; + struct zone_dstab dstab; + + if ((handle = zonecfg_init_handle()) == NULL) + s10_err(gettext("internal libzonecfg.so.1 error"), 0); + + if (zonecfg_get_xml_handle(xmlfile, handle) != Z_OK) { + zonecfg_fini_handle(handle); + s10_err(gettext("zonecfg provided an invalid XML file")); + } + + /* + * Check to see whether the zone has any inherit-pkg-dirs + * configured. + */ + if (zonecfg_setipdent(handle) != Z_OK) { + zonecfg_fini_handle(handle); + s10_err(gettext("zonecfg provided an invalid XML file")); + } + if (zonecfg_getipdent(handle, &fstab) == Z_OK) { + zonecfg_fini_handle(handle); + s10_err(gettext("solaris10 zones do not support " + "inherit-pkg-dirs")); + } + (void) zonecfg_endipdent(handle); + + /* + * Check to see whether the zone has any unsupported devices + * configured. + * + * The audio framework has changed in Solaris Next as compared to + * S10. Data indicates the less than 1/10 of 1 percent of zones + * are using /dev/sound. Given the low usage vs. the effort to + * provide emulation, /dev/sound is currently disallowed. We can + * revisit this if there is enough demand. + */ + if (zonecfg_setdevent(handle) != Z_OK) { + zonecfg_fini_handle(handle); + s10_err(gettext("zonecfg provided an invalid XML file")); + } + if (zonecfg_getdevent(handle, &devtab) == Z_OK) { + if (strncmp(devtab.zone_dev_match, "/dev/sound", 10) == 0 && + !override) { + zonecfg_fini_handle(handle); + s10_err(gettext("solaris10 zones do not currently " + "support /dev/sound")); + } + } + (void) zonecfg_enddevent(handle); + + /* + * Check to see whether the zone has any experimental features + * configured. + */ + if (zonecfg_get_iptype(handle, &iptype) == Z_OK && + iptype == ZS_EXCLUSIVE && !override) { + zonecfg_fini_handle(handle); + s10_err(gettext("solaris10 zones do not currently support " + "exclusive ip-type stacks")); + } + + if (zonecfg_setdsent(handle) != Z_OK) { + zonecfg_fini_handle(handle); + s10_err(gettext("zonecfg provided an invalid XML file")); + } + if (zonecfg_getdsent(handle, &dstab) == Z_OK && !override) { + zonecfg_fini_handle(handle); + s10_err(gettext("solaris10 zones do not currently support " + "delegated datasets")); + } + (void) zonecfg_enddsent(handle); + + zonecfg_fini_handle(handle); + return (0); +} + +/* + * Read an entry from a pkginfo file. Some of these lines can + * either be arbitrarily long or be continued by a backslash at the end of + * the line. This function coalesces lines that are longer than the read + * buffer, and lines that are continued, into one buffer which is returned. + * The caller must free this memory. NULL is returned when we hit EOF or + * if we run out of memory (errno is set to ENOMEM). + */ +static char * +read_pkg_data(FILE *fp) +{ + char *start; + char *inp; + char *p; + int char_cnt = 0; + + errno = 0; + if ((start = (char *)malloc(PKGINFO_RD_LEN)) == NULL) { + errno = ENOMEM; + return (NULL); + } + + inp = start; + while ((p = fgets(inp, PKGINFO_RD_LEN, fp)) != NULL) { + int len; + + len = strlen(inp); + if (inp[len - 1] == '\n' && + (len == 1 || inp[len - 2] != '\\')) { + char_cnt = len; + break; + } + + if (inp[len - 1] == '\n' && inp[len - 2] == '\\') + char_cnt += len - 2; + else + char_cnt += PKGINFO_RD_LEN - 1; + + if ((p = realloc(start, char_cnt + PKGINFO_RD_LEN)) == NULL) { + errno = ENOMEM; + break; + } + + start = p; + inp = start + char_cnt; + } + + if (errno == ENOMEM || (p == NULL && char_cnt == 0)) { + free(start); + start = NULL; + } + + return (start); +} + +/* + * Read the SUNWcakr pkginfo file and get the PATCHLIST for the pkg. + */ +static int +get_ku_patchlist(char *zonename, char **patchlist) +{ + char zonepath[MAXPATHLEN]; + char pkginfo[MAXPATHLEN]; + FILE *fp; + char *buf; + int err = 0; + + if (zone_get_zonepath(zonename, zonepath, sizeof (zonepath)) != Z_OK) + s10_err(gettext("error getting zone's path")); + + if (snprintf(pkginfo, sizeof (pkginfo), + "%s/root/var/sadm/pkg/SUNWcakr/pkginfo", zonepath) + >= sizeof (pkginfo)) + s10_err(gettext("error formating pkg path")); + + if ((fp = fopen(pkginfo, "r")) == NULL) + return (errno); + + while ((buf = read_pkg_data(fp)) != NULL) { + if (strncmp(buf, PATCHLIST, sizeof (PATCHLIST) - 1) == 0) { + int len; + + /* remove trailing newline */ + len = strlen(buf); + buf[len - 1] = '\0'; + + if ((*patchlist = + strdup(buf + sizeof (PATCHLIST) - 1)) == NULL) + err = ENOMEM; + + free(buf); + break; + } + + free(buf); + } + (void) fclose(fp); + + return (err); +} + +/* + * Verify that we have the minimum KU needed. + * Note that KU patches are accumulative so future KUs will still deliver + * 141444 or 141445. + */ +static boolean_t +have_valid_ku(char *zonename) +{ + char *p; + char *lastp; + char *pstr; + char *patchlist = NULL; + int i; + char *vers_table[] = { + "141444-09", + "141445-09", + NULL}; + + if (get_ku_patchlist(zonename, &patchlist) != 0 || patchlist == NULL) + return (B_FALSE); + + pstr = patchlist; + while ((p = strtok_r(pstr, " ", &lastp)) != NULL) { + for (i = 0; vers_table[i] != NULL; i++) + if (strcmp(p, vers_table[i]) == 0) + return (B_TRUE); + + pstr = NULL; + } + + return (B_FALSE); +} + +/* + * Get the emulation version from the /usr/lib/brand/solaris10/version file + * in either the global zone or the non-global zone. + */ +static int +get_emul_version_number(char *verspath) +{ + int vers = 0; + FILE *fp; + char buf[LINE_MAX]; + + /* If the file doesn't exist, assume version 0 */ + if ((fp = fopen(verspath, "r")) == NULL) + return (vers); + + while (fgets(buf, sizeof (buf), fp) != NULL) { + if (buf[0] == '#') + continue; + + errno = 0; + vers = strtol(buf, (char **)NULL, 10); + if (errno != 0) { + (void) fclose(fp); + s10_err(gettext("error reading minimum version")); + } + } + + (void) fclose(fp); + + return (vers); +} + +/* + * Get the current emulation version that is implemented. + */ +static int +get_current_emul_version() +{ + return (get_emul_version_number("/usr/lib/brand/solaris10/version")); +} + +/* + * Get the emulation version that the S10 image requires. This + * reads the optional /usr/lib/brand/solaris10/version file that might + * exist on Solaris 10. That file specifies the minimal solaris10 brand + * emulation version that the specific release of S10 requires. If no + * minimal version is specified, the initial emulation remains compatible. + * + * If a new KU patch is created which needs different handling by the + * emulation, then the S10 /usr/lib/brand/solaris10/version file should be + * updated to specify a new version. + */ +static int +get_image_emul_rqd_version(char *zonename) +{ + char zonepath[MAXPATHLEN]; + char verspath[MAXPATHLEN]; + + if (zone_get_zonepath(zonename, zonepath, sizeof (zonepath)) != Z_OK) + s10_err(gettext("error getting zone's path")); + + if (snprintf(verspath, sizeof (verspath), + "%s/root/usr/lib/brand/solaris10/version", + zonepath) >= sizeof (verspath)) + s10_err(gettext("error formating version path")); + + return (get_emul_version_number(verspath)); +} + +static void +fail_xvm() +{ + char buf[80]; + + if (sysinfo(SI_PLATFORM, buf, sizeof (buf)) != -1 && + strcmp(buf, "i86xpv") == 0 && !override) + s10_err(gettext("running the solaris10 brand " + "in a paravirtualized\ndomain is currently not supported")); +} + +static int +s10_boot(char *zonename) +{ + zoneid_t zoneid; + int emul_vers; + int rqd_emul_vers; + + if (!have_valid_ku(zonename)) + s10_err(gettext("The installed version of Solaris 10 is " + "not supported")); + + emul_vers = get_current_emul_version(); + rqd_emul_vers = get_image_emul_rqd_version(zonename); + + if (rqd_emul_vers > emul_vers) + s10_err(gettext("The zone's version of Solaris 10 is " + "incompatible with the current version of the solaris10 " + "brand.")); + + if ((zoneid = getzoneidbyname(zonename)) < 0) + s10_err(gettext("unable to get zoneid")); + + if (zone_setattr(zoneid, S10_EMUL_VERSION_NUM, &rqd_emul_vers, + sizeof (int)) == -1) + s10_err(gettext("error setting zone's emulation version " + "property")); + + fail_xvm(); + + return (0); +} + +static void +usage() +{ + (void) fprintf(stderr, gettext( + "usage:\t%s verify <xml file>\n" + "\t%s boot\n"), + bname, bname); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + (void) setlocale(LC_ALL, ""); + (void) textdomain(TEXT_DOMAIN); + + bname = basename(argv[0]); + + if (argc != 3) + usage(); + + /* + * XXX This is a temporary env variable for the initial release to + * enable the use of features which are not yet tested or fully + * implemented. + */ + if (getenv("S10BRAND_TEST") != NULL) + override = B_TRUE; + + if (strcmp(argv[1], "verify") == 0) + return (s10_verify(argv[2])); + + if (strcmp(argv[1], "boot") == 0) + return (s10_boot(argv[2])); + + usage(); + /*NOTREACHED*/ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,56 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROGS = attach clone detach image_install p2v poststate prestate \ + s10_boot uninstall +XMLDOCS= config.xml platform.xml smf_disable.lst pkgrm.lst common.ksh \ + version +USERFILES= smf_disable.conf pkgrm.conf +TEMPLATES = SUNWsolaris10.xml +CLOBBERFILES= $(ROOTPROGS) $(ROOTXMLDOCS) $(ROOTTEMPLATES) $(ETCUSER) + +include $(SRC)/cmd/Makefile.cmd +include ../Makefile.s10 + +.KEEP_STATE: + +all: $(PROGS) + +POFILES = $(PROGS:%=%.po) common.po +POFILE = s10_zone.po + +$(POFILE): $(POFILES) + $(RM) $@ + $(CAT) $(POFILES) > $@ + +install: $(PROGS) $(ROOTPROGS) $(ROOTXMLDOCS) $(ROOTTEMPLATES) $(ETCUSER) + +lint: + +clean: + -$(RM) $(PROGS) $(POFILES) $(POFILE) + +include $(SRC)/cmd/Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/SUNWsolaris10.xml Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,32 @@ +<?xml version="1.0"?> + +<!-- + Copyright 2009 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + 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 + + DO NOT EDIT THIS FILE. Use zonecfg(1M) instead. +--> + +<!DOCTYPE zone PUBLIC "-//Sun Microsystems Inc//DTD Zones//EN" "file:///usr/share/lib/xml/dtd/zonecfg.dtd.1"> + +<zone name="default" zonepath="" autoboot="false" brand="solaris10"> +</zone>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/attach.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,235 @@ +#!/bin/ksh -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +. /usr/lib/brand/solaris10/common.ksh + +m_attach_log=$(gettext "Log File: %s") +m_zfs=$(gettext "A ZFS file system was created for the zone.") +m_attaching=$(gettext "Attaching...") +m_usage=$(gettext "solaris10 brand usage:\n\tattach [-a archive | -d directory | -r recv_type]\n\tThe -a archive option specifies an archive name which can be a flar,\n\ttar, pax or cpio archive.\n\tThe -d directory option specifies an existing directory.\n\tThe -r recv_type option specifies the type of archive to be read from\n\tstdin.") +m_complete=$(gettext "Attach complete.") + +install_fail=$(gettext "*** Attach FAILED ***") + +f_n_unimpl=$(gettext "The -n option is not yet implemented.") +f_zfs=$(gettext "Error creating a ZFS file system (%s) for the zone.") +f_nodataset=$(gettext "Error: there is no ZFS file system for the zone.") +f_zfsdestroy=$(gettext "Error destroying ZFS file system %s.") + +f_sanity_notzone=$(gettext "Error: this is a system image and not a zone image.") + +f_baddir=$(gettext "Invalid '%s' directory within the zone") + +# Clean up on interrupt +trap_cleanup() +{ + msg=$(gettext "Installation cancelled due to interrupt.") + log "$msg" + + # umount any mounted file systems + umnt_fs + + trap_exit +} + +# If the attach failed then clean up the ZFS datasets we created. +trap_exit() +{ + if [[ $EXIT_CODE != $ZONE_SUBPROC_OK && "$install_media" != "-" ]]; then + /usr/lib/brand/solaris10/uninstall $ZONENAME $ZONEPATH -F + fi + + exit $EXIT_CODE +} + +EXIT_CODE=$ZONE_SUBPROC_USAGE +install_media="-" + +trap trap_cleanup INT +trap trap_exit EXIT + +# If we weren't passed at least two arguments, exit now. +(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE + +ZONENAME="$1" +ZONEPATH="$2" +# XXX shared/common script currently uses lower case zonename & zonepath +zonename="$ZONENAME" +zonepath="$ZONEPATH" + +shift; shift # remove ZONENAME and ZONEPATH from arguments array + +ZONEROOT="$ZONEPATH/root" +logdir="$ZONEROOT/var/log" + +noexecute=0 + +unset inst_type + +# Other brand attach options are invalid for this brand. +while getopts "a:d:nr:" opt; do + case $opt in + a) + if [[ -n "$inst_type" ]]; then + fatal "$incompat_options" "$m_usage" + fi + inst_type="archive" + install_media="$OPTARG" + ;; + d) + if [[ -n "$inst_type" ]]; then + fatal "$incompat_options" "$m_usage" + fi + inst_type="directory" + install_media="$OPTARG" + ;; + n) noexecute=1 ;; + r) + if [[ -n "$inst_type" ]]; then + fatal "$incompat_options" "$m_usage" + fi + inst_type="stdin" + install_media="$OPTARG" + ;; + ?) printf "$m_usage\n" + exit $ZONE_SUBPROC_USAGE;; + *) printf "$m_usage\n" + exit $ZONE_SUBPROC_USAGE;; + esac +done +shift $((OPTIND-1)) + +if [[ $noexecute == 1 && -n "$inst_type" ]]; then + fatal "$m_usage" +fi + +if [ $noexecute -eq 1 ]; then + # + # The zone doesn't have to exist when the -n option is used, so do + # this work early. + # + + # XXX do the sw validation for solaris10 minimal patch level to ensure + # everything will be ok. + EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE + fatal "$f_n_unimpl" +fi + +EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE + +if [[ -z "$inst_type" ]]; then + inst_type="directory" + +elif [[ "$install_media" != "-" ]]; then + # + # If we're not using a pre-existing zone directory layout then create + # the zone datasets and mount them. + # + unset DATASET + pdir=$(/usr/bin/dirname $ZONEPATH) + zds=$(/usr/sbin/zfs list -H -t filesystem -o name $pdir 2>/dev/null) + if (( $? == 0 )); then + pnm=$(/usr/bin/basename $ZONEPATH) + /usr/sbin/zfs create "$zds/$pnm" + if (( $? == 0 )); then + vlog "$m_zfs" + DATASET="$zds/$pnm" + else + log "$f_zfs" "$zds/$pnm" + fi + fi + + create_active_ds +fi + +# +# The zone's datasets are now in place, validate that things +# are setup correctly. +# + +get_zonepath_ds $zonepath + +/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1 +if (( $? != 0 )); then + fail_fatal "$f_no_active_ds" +else + /usr/sbin/zfs set mountpoint=legacy $ZONEPATH_DS/ROOT \ + >/dev/null 2>&1 + /usr/sbin/zfs set zoned=on $ZONEPATH_DS/ROOT \ + >/dev/null 2>&1 +fi + +BENAME=zbe-0 +/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT/$BENAME >/dev/null 2>&1 +if (( $? != 0 )); then + fail_fatal "$f_zfs_create" +else + /usr/sbin/zfs set $PROP_ACTIVE=on $ZONEPATH_DS/ROOT/$BENAME \ + >/dev/null 2>&1 + /usr/sbin/zfs set canmount=noauto $ZONEPATH_DS/ROOT/$BENAME \ + >/dev/null 2>&1 + /usr/sbin/zfs inherit mountpoint $ZONEPATH_DS/ROOT/$BENAME \ + >/dev/null 2>&1 + /usr/sbin/zfs inherit zoned $ZONEPATH_DS/ROOT/$BENAME \ + >/dev/null 2>&1 +fi + +LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp $zonename.attach_log.XXXXXX) +if [[ -z "$LOGFILE" ]]; then + fatal "$e_tmpfile" +fi +exec 2>>"$LOGFILE" +log "$m_attach_log" "$LOGFILE" + +log "$m_attaching" +install_image "$inst_type" "$install_media" + +mk_zone_dirs + +# +# Perform a final check that this is really a zone image and not an archive of +# a system image which would need p2v. Check for a well-known S10 SMF service +# that shouldn't exist in a zone. +# +if [[ -e $ZONEROOT/var/svc/manifest/system/sysevent.xml ]]; then + log "$f_sanity_notzone" + exit $ZONE_SUBPROC_NOTCOMPLETE +fi + +EXIT_CODE=$ZONE_SUBPROC_OK + +log "$m_complete" + +zone_logfile="${logdir}/$zonename.attach$$.log" + +safe_dir /var +safe_dir /var/log +safe_copy $LOGFILE $zone_logfile + +log "$m_attach_log" "$zone_logfile" +rm -f $LOGFILE + +exit $ZONE_SUBPROC_OK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/clone.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,137 @@ +#!/bin/ksh -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +. /usr/lib/brand/solaris10/common.ksh + +m_usage=$(gettext "solaris10 brand usage: clone {sourcezone}.") +f_nosource=$(gettext "Error: unable to determine source zone dataset.") +f_sysunconfig=$(gettext "Error: sys-unconfig failed.") + +# Set up ZFS dataset hierarchy for the zone. + +ROOT="rpool/ROOT" + +# Other brand clone options are invalid for this brand. +while getopts "R:z:" opt; do + case $opt in + R) ZONEPATH="$OPTARG" ;; + z) ZONENAME="$OPTARG" ;; + *) printf "$m_usage\n" + exit $ZONE_SUBPROC_USAGE;; + esac +done +shift $((OPTIND-1)) + +if [ $# -ne 1 ]; then + fail_usage "$0 {sourcezone}"; +fi + +sourcezone=$1 + +# Find the active source zone dataset to clone. +sourcezonepath=`/usr/sbin/zonecfg -z $sourcezone info zonepath | \ + /usr/bin/cut -f2 -d' '` +if [ -z "$sourcezonepath" ]; then + fail_fatal "$f_nosource" +fi + +get_zonepath_ds $sourcezonepath +get_active_ds $ZONEPATH_DS + +# +# Now set up the zone's datasets +# + +# +# First make the top-level dataset. +# + +pdir=`/usr/bin/dirname $ZONEPATH` +zpname=`/usr/bin/basename $ZONEPATH` + +get_zonepath_ds $pdir +zpds=$ZONEPATH_DS + +# Create the datasets. +/usr/sbin/zfs create $zpds/$zpname +if (( $? != 0 )); then + fail_fatal "$f_zfs_create" +fi + +/usr/sbin/zfs create -o mountpoint=legacy -o zoned=on $zpds/$zpname/ROOT +if (( $? != 0 )); then + fail_fatal "$f_zfs_create" +fi + +# make snapshot +SNAPNAME=${ZONENAME}_snap +SNAPNUM=0 +while [ $SNAPNUM -lt 100 ]; do + /usr/sbin/zfs snapshot $ACTIVE_DS@$SNAPNAME + if [ $? = 0 ]; then + break + fi + SNAPNUM=`expr $SNAPNUM + 1` + SNAPNAME="${ZONENAME}_snap$SNAPNUM" +done + +if [ $SNAPNUM -ge 100 ]; then + fail_fatal "$f_zfs_create" +fi + +# do clone +BENAME=zbe-0 +/usr/sbin/zfs clone -o $PROP_ACTIVE=on -o canmount=noauto \ + $ACTIVE_DS@$SNAPNAME $zpds/$zpname/ROOT/$BENAME +if (( $? != 0 )); then + fail_fatal "$f_zfs_create" +fi + +if [ ! -d $ZONEPATH/root ]; then + /usr/bin/mkdir -p $ZONEPATH/root || \ + fail_fatal "$f_mkdir" "$ZONEPATH/root" + /usr/bin/chmod 700 $ZONEPATH || \ + fail_fatal "$f_chmod" "$ZONEPATH" +fi + +# Don't re-sysunconfig if we've already done so +if [[ ! -f $ZONEROOT/etc/.UNCONFIGURED ]]; then + /usr/sbin/zoneadm -z $ZONENAME boot -f -- -m milestone=none + if (( $? != 0 )); then + error "$e_badboot" + fail_incomplete "$f_sysunconfig" + fi + + sysunconfig_zone + if (( $? != 0 )); then + /usr/sbin/zoneadm -z $ZONENAME halt + fail_incomplete "$f_sysunconfig" + fi + + /usr/sbin/zoneadm -z $ZONENAME halt +fi + +exit $ZONE_SUBPROC_OK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/common.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,333 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +unset LD_LIBRARY_PATH +PATH=/usr/bin:/usr/sbin +export PATH + +. /usr/lib/brand/shared/common.ksh + +# Use the ipkg-brand ZFS property for denoting the zone root's active dataset. +PROP_ACTIVE="org.opensolaris.libbe:active" + +f_sanity_detail=$(gettext "Missing %s at %s") +f_sanity_sparse=$(gettext "Is this a sparse zone image? The image must be whole-root.") +f_sanity_vers=$(gettext "The image release version must be 10 (got %s), the zone is not usable on this system.") +f_not_s10_image=$(gettext "%s doesn't look like a Solaris 10 image.") +f_sanity_nopatch=$(gettext "Unable to determine the image's patch level.") +f_sanity_downrev=$(gettext "The image patch level is downrev for running in a solaris10 branded zone.\n(patchlist %s)") +f_need_newer_emul=$(gettext "The image requires a newer version of the solaris10 brand emulation.") +f_zfs_create=$(gettext "Unable to create the zone's ZFS dataset.") +f_no_ds=$(gettext "No zonepath dataset; the zonepath must be a ZFS dataset.") +f_multiple_ds=$(gettext "Multiple active datasets.") +f_no_active_ds=$(gettext "No active dataset; the zone's ZFS root dataset must be configured as\n\ta zone boot environment.") +f_zfs_unmount=$(gettext "Unable to unmount the zone's root ZFS dataset (%s).\nIs there a global zone process inside the zone root?\nThe current zone boot environment will remain mounted.\n") +f_zfs_mount=$(gettext "Unable to mount the zone's ZFS dataset.") +incompat_options=$(gettext "mutually exclusive options.\n%s") + +sanity_ok=$(gettext " Sanity Check: Passed. Looks like a Solaris 10 image.") +sanity_fail=$(gettext " Sanity Check: FAILED (see log for details).") + +e_badboot=$(gettext "Zone boot failed") +e_nosingleuser=$(gettext "ERROR: zone did not finish booting to single-user.") +e_unconfig=$(gettext "sys-unconfig failed") +v_unconfig=$(gettext "Performing zone sys-unconfig") + +sanity_check() +{ + typeset dir="$1" + res=0 + + # + # Check for some required directories and make sure this isn't a + # sparse zone image. + # + checks="etc etc/svc var var/svc" + for x in $checks; do + if [[ ! -e $dir/$x ]]; then + log "$f_sanity_detail" "$x" "$dir" + res=1 + fi + done + # Files from SUNWcsr and SUNWcsu that are in sparse inherit-pkg-dirs. + checks="lib/svc sbin/zonename usr/bin/chmod" + for x in $checks; do + if [[ ! -e $dir/$x ]]; then + log "$f_sanity_detail" "$x" "$dir" + log "$f_sanity_sparse" + res=1 + fi + done + + # + # Check image release to be sure its S10. + # + image_vers="unknown" + if [[ -f $dir/var/sadm/system/admin/INST_RELEASE ]]; then + image_vers=$(nawk -F= '{if ($1 == "VERSION") print $2}' \ + $dir/var/sadm/system/admin/INST_RELEASE) + fi + + if [[ "$image_vers" != "10" ]]; then + log "$f_sanity_vers" "$image_vers" + res=1 + fi + + # + # Make sure we have the minimal KU patch we support. These are the + # KUs for S10u8. + # + if [[ $(uname -p) == "i386" ]]; then + req_patch="141445-09" + else + req_patch="141444-09" + fi + + for i in $dir/var/sadm/pkg/SUNWcakr* + do + if [[ ! -d $i || ! -f $i/pkginfo ]]; then + log "$f_sanity_nopatch" + res=1 + fi + done + + # + # Check the core kernel pkg for the required KU patch. + # + found=0 + for i in $dir/var/sadm/pkg/SUNWcakr*/pkginfo + do + patches=$(nawk -F= '{if ($1 == "PATCHLIST") print $2}' $i) + for patch in $patches + do + if [[ $patch == $req_patch ]]; then + found=1 + break + fi + done + + if (( $found == 1 )); then + break + fi + done + + if (( $found != 1 )); then + log "$f_sanity_downrev" "$patches" + res=1 + fi + + # + # Check the S10 image for a required version of the emulation. + # + VERS_FILE=/usr/lib/brand/solaris10/version + s10vers_needs=0 + if [[ -f $dir/$VERS_FILE ]]; then + s10vers_needs=$(/usr/bin/egrep -v "^#" $dir/$VERS_FILE) + fi + + # Now get the current emulation version. + emul_vers=$(/usr/bin/egrep -v "^#" $VERS_FILE) + + # Verify that the emulation can run this version of S10. + if (( $s10vers_needs > $emul_vers )); then + log "$f_need_newer_emul" + res=1 + fi + + if (( $res != 0 )); then + log "$sanity_fail" + fatal "$install_fail" "$ZONENAME" + fi + + vlog "$sanity_ok" +} + +# Find the active dataset under the zonepath dataset to mount on zonepath/root. +# $1 ZONEPATH_DS +get_active_ds() { + ACTIVE_DS=`/usr/sbin/zfs list -H -r -t filesystem \ + -o name,$PROP_ACTIVE $1/ROOT | \ + /usr/bin/nawk ' { + if ($1 ~ /ROOT\/[^\/]+$/ && $2 == "on") { + print $1 + if (found == 1) + exit 1 + found = 1 + } + }'` + + if [ $? -ne 0 ]; then + fail_fatal "$f_multiple_ds" + fi + + if [ -z "$ACTIVE_DS" ]; then + fail_fatal "$f_no_active_ds" + fi +} + +# +# Make sure the active dataset is mounted for the zone. There are several +# cases to consider: +# 1) First boot of the zone, nothing is mounted +# 2) Zone is halting, active dataset remains the same. +# 3) Zone is halting, there is a new active dataset to mount. +# +mount_active_ds() { + mount -p | cut -d' ' -f3 | egrep -s "^$zonepath/root$" + if (( $? == 0 )); then + # Umount current dataset on the root (it might be an old BE). + /usr/sbin/umount $zonepath/root + if (( $? != 0 )); then + # The umount failed, leave the old BE mounted. If + # there are zone processes (i.e. zsched) in the fs, + # then we're umounting because we failed validation + # during boot, otherwise, warn about gz process + # preventing umount. + nproc=`pgrep -z $zonename | wc -l` + if (( $nproc == 0 )); then + printf "$f_zfs_unmount" "$zonepath/root" + fi + return + fi + fi + + # Mount active dataset on the root. + get_zonepath_ds $zonepath + get_active_ds $ZONEPATH_DS + + /usr/sbin/mount -F zfs $ACTIVE_DS $zonepath/root || \ + fail_fatal "$f_zfs_mount" +} + +# +# Set up ZFS dataset hierarchy for the zone root dataset. +# +create_active_ds() { + # Find the zone's current dataset. This should have been created by + # zoneadm (or the attach hook). + get_zonepath_ds $zonepath + + # + # We need to tolerate errors while creating the datasets and making the + # mountpoint, since these could already exist from an attach scenario. + # + + /usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1 + if (( $? != 0 )); then + /usr/sbin/zfs create -o mountpoint=legacy -o zoned=on \ + $ZONEPATH_DS/ROOT + if (( $? != 0 )); then + fail_fatal "$f_zfs_create" + fi + else + /usr/sbin/zfs set mountpoint=legacy $ZONEPATH_DS/ROOT \ + >/dev/null 2>&1 + /usr/sbin/zfs set zoned=on $ZONEPATH_DS/ROOT \ + >/dev/null 2>&1 + fi + + BENAME=zbe-0 + /usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT/$BENAME >/dev/null 2>&1 + if (( $? != 0 )); then + /usr/sbin/zfs create -o $PROP_ACTIVE=on -o canmount=noauto \ + $ZONEPATH_DS/ROOT/$BENAME >/dev/null 2>&1 + if (( $? != 0 )); then + fail_fatal "$f_zfs_create" + fi + else + /usr/sbin/zfs set $PROP_ACTIVE=on $ZONEPATH_DS/ROOT/$BENAME \ + >/dev/null 2>&1 + /usr/sbin/zfs set canmount=noauto $ZONEPATH_DS/ROOT/$BENAME \ + >/dev/null 2>&1 + /usr/sbin/zfs inherit mountpoint $ZONEPATH_DS/ROOT/$BENAME \ + >/dev/null 2>&1 + /usr/sbin/zfs inherit zoned $ZONEPATH_DS/ROOT/$BENAME \ + >/dev/null 2>&1 + fi + + if [ ! -d $ZONEROOT ]; then + /usr/bin/mkdir -m 0755 -p $ZONEROOT || \ + fail_fatal "$f_mkdir" "$ZONEROOT" + fi + /usr/bin/chmod 700 $ZONEPATH || fail_fatal "$f_chmod" "$ZONEPATH" + + /usr/sbin/mount -F zfs $ZONEPATH_DS/ROOT/$BENAME $ZONEROOT || \ + fail_fatal "$f_zfs_mount" +} + +# +# Before booting the zone we may need to create a few mnt points, just in +# case they don't exist for some reason. +# +# Whenever we reach into the zone while running in the global zone we +# need to validate that none of the interim directories are symlinks +# that could cause us to inadvertently modify the global zone. +# +mk_zone_dirs() { + vlog "$v_mkdirs" + if [[ ! -f $ZONEROOT/tmp && ! -d $ZONEROOT/tmp ]]; then + mkdir -m 1777 -p $ZONEROOT/tmp || exit $EXIT_CODE + fi + if [[ ! -f $ZONEROOT/var/run && ! -d $ZONEROOT/var/run ]]; then + mkdir -m 1755 -p $ZONEROOT/var/run || exit $EXIT_CODE + fi + if [[ ! -f $ZONEROOT/var/tmp && ! -d $ZONEROOT/var/tmp ]]; then + mkdir -m 1777 -p $ZONEROOT/var/tmp || exit $EXIT_CODE + fi + if [[ ! -h $ZONEROOT/etc && ! -f $ZONEROOT/etc/mnttab ]]; then + /usr/bin/touch $ZONEROOT/etc/mnttab || exit $EXIT_CODE + /usr/bin/chmod 444 $ZONEROOT/etc/mnttab || exit $EXIT_CODE + fi + if [[ ! -f $ZONEROOT/proc && ! -d $ZONEROOT/proc ]]; then + mkdir -m 755 -p $ZONEROOT/proc || exit $EXIT_CODE + fi + if [[ ! -f $ZONEROOT/dev && ! -d $ZONEROOT/dev ]]; then + mkdir -m 755 -p $ZONEROOT/dev || exit $EXIT_CODE + fi + if [[ ! -h $ZONEROOT/etc && ! -h $ZONEROOT/etc/svc && \ + ! -d $ZONEROOT/etc/svc ]]; then + mkdir -m 755 -p $ZONEROOT/etc/svc/volatile || exit $EXIT_CODE + fi +} + +# +# We're sys-unconfig-ing the zone. This will normally halt the zone, however +# there are problems with sys-unconfig and it can hang when the zone is booted +# to milestone=none. Sys-unconfig also sometimes hangs halting the zone. +# Thus, we take some care to workaround these sys-unconfig limitations. +# +# On entry we expect the zone to be booted. We use sys-unconfig -R to make it +# think its working on an alternate root and let the caller halt the zone. +# +sysunconfig_zone() { + /usr/sbin/zlogin -S $ZONENAME /usr/sbin/sys-unconfig -R /./ \ + >/dev/null 2>&1 + if (( $? != 0 )); then + error "$e_unconfig" + return 1 + fi + + return 0 +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/config.xml Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,106 @@ +<?xml version="1.0"?> + +<!-- + 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 2009 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + DO NOT EDIT THIS FILE. +--> + +<!DOCTYPE brand PUBLIC "-//Sun Microsystems Inc//DTD Brands//EN" + "file:///usr/share/lib/xml/dtd/brand.dtd.1"> + +<brand name="solaris10"> + <modname>s10_brand</modname> + <initname>/sbin/init</initname> + <login_cmd>/usr/bin/login -z %Z -f %u</login_cmd> + <user_cmd>/usr/bin/getent passwd %u</user_cmd> + + <install>/usr/lib/brand/solaris10/image_install %z %R</install> + <installopts>a:d:psuv</installopts> + <boot>/usr/lib/brand/solaris10/s10_boot %z %R</boot> + <sysboot>/usr/lib/brand/solaris10/prestate %z %R 2 0</sysboot> + <halt></halt> + <verify_cfg>/usr/lib/brand/solaris10/s10_support verify</verify_cfg> + <verify_adm></verify_adm> + <attach>/usr/lib/brand/solaris10/attach %z %R</attach> + <detach>/usr/lib/brand/solaris10/detach %z %R</detach> + <clone>/usr/lib/brand/solaris10/clone -z %z -R %R</clone> + <uninstall>/usr/lib/brand/solaris10/uninstall %z %R</uninstall> + <prestatechange>/usr/lib/brand/solaris10/prestate %z %R</prestatechange> + <poststatechange>/usr/lib/brand/solaris10/poststate %z %R</poststatechange> + <query>/usr/lib/brand/shared/query %z %R</query> + + <privilege set="default" name="contract_event" /> + <privilege set="default" name="contract_identity" /> + <privilege set="default" name="contract_observer" /> + <privilege set="default" name="file_chown" /> + <privilege set="default" name="file_chown_self" /> + <privilege set="default" name="file_dac_execute" /> + <privilege set="default" name="file_dac_read" /> + <privilege set="default" name="file_dac_search" /> + <privilege set="default" name="file_dac_write" /> + <privilege set="default" name="file_owner" /> + <privilege set="default" name="file_setid" /> + <privilege set="default" name="ipc_dac_read" /> + <privilege set="default" name="ipc_dac_write" /> + <privilege set="default" name="ipc_owner" /> + <privilege set="default" name="net_bindmlp" /> + <privilege set="default" name="net_icmpaccess" /> + <privilege set="default" name="net_mac_aware" /> + <privilege set="default" name="net_observability" /> + <privilege set="default" name="net_privaddr" /> + <privilege set="default" name="net_rawaccess" ip-type="exclusive" /> + <privilege set="default" name="proc_chroot" /> + <privilege set="default" name="sys_audit" /> + <privilege set="default" name="proc_audit" /> + <privilege set="default" name="proc_lock_memory" /> + <privilege set="default" name="proc_owner" /> + <privilege set="default" name="proc_setid" /> + <privilege set="default" name="proc_taskid" /> + <privilege set="default" name="sys_acct" /> + <privilege set="default" name="sys_admin" /> + <privilege set="default" name="sys_ip_config" ip-type="exclusive" /> + <privilege set="default" name="sys_iptun_config" ip-type="exclusive" /> + <privilege set="default" name="sys_mount" /> + <privilege set="default" name="sys_nfs" /> + <privilege set="default" name="sys_resource" /> + <privilege set="default" name="sys_ppp_config" ip-type="exclusive" /> + + <privilege set="prohibited" name="dtrace_kernel" /> + <privilege set="prohibited" name="proc_zone" /> + <privilege set="prohibited" name="sys_config" /> + <privilege set="prohibited" name="sys_devices" /> + <privilege set="prohibited" name="sys_ip_config" ip-type="shared" /> + <privilege set="prohibited" name="sys_linkdir" /> + <privilege set="prohibited" name="sys_net_config" /> + <privilege set="prohibited" name="sys_res_config" /> + <privilege set="prohibited" name="sys_suser_compat" /> + <privilege set="prohibited" name="xvm_control" /> + <privilege set="prohibited" name="virt_manage" /> + <privilege set="prohibited" name="sys_ppp_config" ip-type="shared" /> + + <privilege set="required" name="proc_exec" /> + <privilege set="required" name="proc_fork" /> + <privilege set="required" name="sys_ip_config" ip-type="exclusive" /> + <privilege set="required" name="sys_mount" /> +</brand>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/detach.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,65 @@ +#!/bin/ksh -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +. /usr/lib/brand/solaris10/common.ksh + +m_usage=$(gettext "solaris10 brand usage: detach [-n].") + +EXIT_CODE=$ZONE_SUBPROC_USAGE + +# If we weren't passed at least two arguments, exit now. +(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE + +ZONENAME="$1" +ZONEPATH="$2" +# XXX shared/common script currently uses lower case zonename & zonepath +zonename="$ZONENAME" +zonepath="$ZONEPATH" + +shift; shift # remove ZONENAME and ZONEPATH from arguments array + +noexecute=0 + +# Other brand attach options are invalid for this brand. +while getopts "n" opt; do + case $opt in + n) noexecute=1 ;; + ?) printf "$m_usage\n" + exit $ZONE_SUBPROC_USAGE;; + *) printf "$m_usage\n" + exit $ZONE_SUBPROC_USAGE;; + esac +done +shift $((OPTIND-1)) + +if [[ $noexecute == 1 ]]; then + cat /etc/zones/$ZONENAME.xml + exit $ZONE_SUBPROC_OK +fi + +cp /etc/zones/$ZONENAME.xml $ZONEPATH/SUNWdetached.xml + +exit $ZONE_SUBPROC_OK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/image_install.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,258 @@ +#!/bin/ksh -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +. /usr/lib/brand/solaris10/common.ksh + +m_usage=$(gettext "solaris10 brand usage:\n\tinstall -u | -p [-v | -s] -a archive | -d directory.\n\tThe -a archive option specifies an archive name which can be a flar,\n\ttar, pax or cpio archive.\n\tThe -d directory option specifies an existing directory.\n\tThe -u option unconfigures the zone, -p preserves the configuration.") + +no_install=$(gettext "Could not create install directory '%s'") + +product_vers=$(gettext " Product: %s") +install_vers=$(gettext " Installer: %s") +install_zone=$(gettext " Zone: %s") +install_path=$(gettext " Path: %s") +installing=$(gettext " Installing: This may take several minutes...") +no_installing=$(gettext " Installing: Using pre-existing data in zonepath") +install_prog=$(gettext " Installing: %s") + +install_fail=$(gettext " Result: *** Installation FAILED ***") +install_log=$(gettext " Log File: %s") + +install_good=$(gettext " Result: Installation completed successfully.") + +unpack_done=$(gettext " Unpack result: %d") + +sanity_ok=$(gettext " Sanity Check: Passed. Looks like a Solaris 10 system.") +sanity_fail=$(gettext " Sanity Check: FAILED (see log for details).") + + +p2ving=$(gettext "Postprocessing: This may take a while...") +p2v_prog=$(gettext " Postprocess: ") +p2v_done=$(gettext " Result: Postprocessing complete.") +p2v_fail=$(gettext " Result: Postprocessing failed.") + +root_full=$(gettext "Zonepath root %s exists and contains data; remove or move aside prior to install.") + +media_missing=\ +$(gettext "you must specify an installation source using '-a', '-d' or '-r'.\n%s") + +cfgchoice_missing=\ +$(gettext "you must specify -u (sys-unconfig) or -p (preserve identity).\n%s") + +mount_failed=$(gettext "ERROR: zonecfg(1M) 'fs' mount failed") + +not_flar=$(gettext "Input is not a flash archive") +bad_flar=$(gettext "Flash archive is a corrupt") +unknown_archiver=$(gettext "Archiver %s is not supported") + +# Clean up on interrupt +trap_cleanup() +{ + msg=$(gettext "Installation cancelled due to interrupt.") + log "$msg" + + # umount any mounted file systems + umnt_fs + + trap_exit +} + +# If the install failed then clean up the ZFS datasets we created. +trap_exit() +{ + if (( $EXIT_CODE != $ZONE_SUBPROC_OK )); then + /usr/lib/brand/solaris10/uninstall $ZONENAME $ZONEPATH -F + fi + + exit $EXIT_CODE +} + +# +# The main body of the script starts here. +# +# This script should never be called directly by a user but rather should +# only be called by zoneadm to install a s10 system image into a zone. +# + +# +# Exit code to return if install is interrupted or exit code is otherwise +# unspecified. +# +EXIT_CODE=$ZONE_SUBPROC_USAGE + +trap trap_cleanup INT +trap trap_exit EXIT + +# If we weren't passed at least two arguments, exit now. +(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE + +ZONENAME="$1" +ZONEPATH="$2" +# XXX shared/common script currently uses lower case zonename & zonepath +zonename="$ZONENAME" +zonepath="$ZONEPATH" + +ZONEROOT="$ZONEPATH/root" +logdir="$ZONEROOT/var/log" + +shift; shift # remove ZONENAME and ZONEPATH from arguments array + +unset inst_type +unset msg +unset silent_mode +unset OPT_V + +# +# It is worth noting here that we require the end user to pick one of +# -u (sys-unconfig) or -p (preserve config). This is because we can't +# really know in advance which option makes a better default. Forcing +# the user to pick one or the other means that they will consider their +# choice and hopefully not be surprised or disappointed with the result. +# +unset unconfig_zone +unset preserve_zone + +while getopts "a:d:pr:suv" opt +do + case "$opt" in + a) + if [[ -n "$inst_type" ]]; then + fatal "$incompat_options" "$m_usage" + fi + inst_type="archive" + install_media="$OPTARG" + ;; + d) + if [[ -n "$inst_type" ]]; then + fatal "$incompat_options" "$m_usage" + fi + inst_type="directory" + install_media="$OPTARG" + ;; + p) preserve_zone="-p";; + r) + if [[ -n "$inst_type" ]]; then + fatal "$incompat_options" "$m_usage" + fi + inst_type="stdin" + install_media="$OPTARG" + ;; + s) silent_mode=1;; + u) unconfig_zone="-u";; + v) OPT_V="-v";; + *) printf "$m_usage\n" + exit $ZONE_SUBPROC_USAGE;; + esac +done +shift OPTIND-1 + +# The install can't be both verbose AND silent... +if [[ -n $silent_mode && -n $OPT_V ]]; then + fatal "$incompat_options" "$m_usage" +fi + +if [[ -z $install_media ]]; then + fatal "$media_missing" "$m_usage" +fi + +# The install can't both preserve and unconfigure +if [[ -n $unconfig_zone && -n $preserve_zone ]]; then + fatal "$incompat_options" "$m_usage" +fi + +# Must pick one or the other. +if [[ -z $unconfig_zone && -z $preserve_zone ]]; then + fatal "$cfgchoice_missing" "$m_usage" +fi + +LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp $ZONENAME.install_log.XXXXXX) +if [[ -z "$LOGFILE" ]]; then + fatal "$e_tmpfile" +fi +zone_logfile="${logdir}/$ZONENAME.install$$.log" +exec 2>>"$LOGFILE" +log "$install_log" "$LOGFILE" + +vlog "Starting pre-installation tasks." + +# +# From here on out, an unspecified exit or interrupt should exit with +# ZONE_SUBPROC_NOTCOMPLETE, meaning a user will need to do an uninstall before +# attempting another install, as we've modified the directories we were going +# to install to in some way. +# +EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE + +create_active_ds + +vlog "Installation started for zone \"$ZONENAME\"" +install_image "$inst_type" "$install_media" + +log "$p2ving" +vlog "running: p2v $OPT_V $unconfig_zone $ZONENAME $ZONEPATH" + +# +# Run p2v. +# +# Getting the output to the right places is a little tricky because what +# we want is for p2v to output in the same way the installer does: verbose +# messages to the log file always, and verbose messages printed to the +# user if the user passes -v. This rules out simple redirection. And +# we can't use tee or other tricks because they cause us to lose the +# return value from the p2v script due to the way shell pipelines work. +# +# The simplest way to do this seems to be to hand off the management of +# the log file to the p2v script. So we run p2v with -l to tell it where +# to find the log file and then reopen the log (O_APPEND) when p2v is done. +# +/usr/lib/brand/solaris10/p2v -l "$LOGFILE" -m "$p2v_prog" \ + $OPT_V $unconfig_zone $ZONENAME $ZONEPATH +p2v_result=$? +exec 2>>$LOGFILE + +if (( $p2v_result == 0 )); then + vlog "$p2v_done" +else + log "$p2v_fail" + log "" + log "$install_fail" + log "$install_log" "$LOGFILE" + exit $ZONE_SUBPROC_FATAL +fi + +log "" +log "$install_good" "$ZONENAME" + +safe_dir /var +safe_dir /var/log +safe_copy $LOGFILE $zone_logfile + +log "$install_log" "$zone_logfile" +rm -f $LOGFILE + +# This needs to be set since the exit trap handler is going run. +EXIT_CODE=$ZONE_SUBPROC_OK + +exit $ZONE_SUBPROC_OK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/p2v.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,618 @@ +#!/bin/ksh -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# NOTE: this script runs in the global zone and touches the non-global +# zone, so care should be taken to validate any modifications so that they +# are safe. + +. /usr/lib/brand/solaris10/common.ksh + +LOGFILE= +MSG_PREFIX="p2v: " +EXIT_CODE=1 + +usage() +{ + echo "$0 [-s] [-m msgprefix] [-u] [-v] [-b patchid]* zonename" >&2 + exit $EXIT_CODE +} + +# Clean up on interrupt +trap_cleanup() +{ + msg=$(gettext "Postprocessing cancelled due to interrupt.") + error "$msg" + + if (( $zone_is_running != 0 )); then + error "$e_shutdown" "$ZONENAME" + /usr/sbin/zoneadm -z $ZONENAME halt + fi + + exit $EXIT_CODE +} + +# +# Disable any existing live-upgrade configuration. +# We have already called safe_dir to validate the etc/lu directory. +# +fix_lu() +{ + ludir=$ZONEROOT/etc/lu + + [[ ! -d $ludir ]] && return + + safe_rm etc/lutab + safe_rm etc/lu/.BE_CONFIG + safe_rm etc/lu/.CURR_VARS + safe_rm etc/lu/ludb.local.xml + for i in $ludir/ICF* $ludir/vtoc* $ludir/GRUB* + do + nm=`basename $i` + safe_rm etc/lu/$nm + done +} + +# +# For an exclusive stack zone, fix up the network configuration files. +# We need to do this even if unconfiguring the zone so sys-unconfig works +# correctly. +# +fix_net() +{ + [[ "$STACK_TYPE" == "shared" ]] && return + + NETIF_CNT=$(/usr/bin/ls $ZONEROOT/etc/hostname.* 2>/dev/null | \ + /usr/bin/wc -l) + if (( $NETIF_CNT != 1 )); then + vlog "$v_nonetfix" + return + fi + + NET=$(LC_ALL=C /usr/sbin/zonecfg -z $ZONENAME info net) + if (( $? != 0 )); then + error "$e_badinfo" "net" + return + fi + + NETIF=$(echo $NET | /usr/bin/nawk '{ + for (i = 1; i < NF; i++) { + if ($i == "physical:") { + if (length(net) == 0) { + i++ + net = $i + } else { + multiple=1 + } + } + } + } + END { if (!multiple) + print net + }') + + if [[ -z "$NETIF" ]]; then + vlog "$v_nonetfix" + return + fi + + OLD_HOSTNET=$(/usr/bin/ls $ZONEROOT/etc/hostname.*) + if [[ "$OLD_HOSTNET" != "$ZONEROOT/etc/hostname.$NETIF" ]]; then + safe_move $OLD_HOSTNET $ZONEROOT/etc/hostname.$NETIF + fi +} + +# +# Disable all of the shares since the zone cannot be an NFS server. +# Note that we disable the various instances of the svc:/network/shares/group +# SMF service in the fix_smf function. +# +fix_nfs() +{ + zonedfs=$ZONEROOT/etc/dfs + + [[ ! -d $zonedfs ]] && return + + if [[ -h $zonedfs/dfstab || ! -f $zonedfs/dfstab ]]; then + error "$e_badfile" "/etc/dfs/dfstab" + return + fi + + tmpfile=$(mktemp -t) + if [[ $? == 1 || -z "$tmpfile" ]]; then + error "$e_tmpfile" + return + fi + + /usr/bin/nawk '{ + if (substr($1, 0, 1) == "#") { + print $0 + } else { + print "#", $0 + modified=1 + } + } + END { + if (modified == 1) { + printf("# Modified by p2v ") + system("/usr/bin/date") + exit 0 + } + exit 1 + }' $zonedfs/dfstab >>$tmpfile + + if (( $? == 0 )); then + if [[ ! -f $zonedfs/dfstab.pre_p2v ]]; then + safe_copy $zonedfs/dfstab $zonedfs/dfstab.pre_p2v + fi + safe_copy $tmpfile $zonedfs/dfstab + chown root:sys $zonedfs/dfstab || \ + fail_fatal "$f_chown" "$zonedfs/dfstab" + chmod 644 $zonedfs/dfstab || \ + fail_fatal "$f_chmod" "$zonedfs/dfstab" + fi + /usr/bin/rm -f $tmpfile +} + +# +# Comment out most of the old mounts since they are either unneeded or +# likely incorrect within a zone. Specific mounts can be manually +# reenabled if the corresponding device is added to the zone. +# +fix_vfstab() +{ + if [[ -h $ZONEROOT/etc/vfstab || ! -f $ZONEROOT/etc/vfstab ]]; then + error "$e_badfile" "/etc/vfstab" + return + fi + + tmpfile=$(mktemp -t) + if [[ $? == 1 || -z "$tmpfile" ]]; then + error "$e_tmpfile" + return + fi + + /usr/bin/nawk '{ + if (substr($1, 0, 1) == "#") { + print $0 + } else if ($1 == "fd" || $1 == "/proc" || $1 == "swap" || + $1 == "ctfs" || $1 == "objfs" || $1 == "sharefs" || + $4 == "nfs" || $4 == "lofs") { + print $0 + } else { + print "#", $0 + modified=1 + } + } + END { + if (modified == 1) { + printf("# Modified by p2v ") + system("/usr/bin/date") + exit 0 + } + exit 1 + }' $ZONEROOT/etc/vfstab >>$tmpfile + + if (( $? == 0 )); then + if [[ ! -f $ZONEROOT/etc/vfstab.pre_p2v ]]; then + safe_copy $ZONEROOT/etc/vfstab \ + $ZONEROOT/etc/vfstab.pre_p2v + fi + safe_copy $tmpfile $ZONEROOT/etc/vfstab + chown root:sys $ZONEROOT/etc/vfstab || \ + fail_fatal "$f_chown" "$ZONEROOT/etc/vfstab" + chmod 644 $ZONEROOT/etc/vfstab || \ + fail_fatal "$f_chmod" "$ZONEROOT/etc/vfstab" + fi + /usr/bin/rm -f $tmpfile +} + +# +# Collect the data needed to delete SMF services. Since we're p2v-ing a +# physical image there are SMF services which must be deleted. +# +fix_smf_pre_uoa() +{ + # + # Start by getting the svc manifests that are delivered by hollow + # pkgs then use 'svccfg inventory' to get the names of the svcs + # delivered by those manifests. The svc names are saved into a + # temporary file. + # + + SMFTMPFILE=$(mktemp -t smf.XXXXXX) + if [[ $? == 1 || -z "$SMFTMPFILE" ]]; then + error "$e_tmpfile" + return + fi + + for i in $ZONEROOT/var/sadm/pkg/* + do + pkg=$(/usr/bin/basename $i) + [[ ! -f $ZONEROOT/var/sadm/pkg/$pkg/save/pspool/$pkg/pkgmap ]] \ + && continue + + /usr/bin/egrep -s "SUNW_PKG_HOLLOW=true" \ + $ZONEROOT/var/sadm/pkg/$pkg/pkginfo || continue + + for j in $(/usr/bin/nawk '{if ($2 == "f" && + substr($4, 1, 17) == "var/svc/manifest/") print $4}' \ + $ZONEROOT/var/sadm/pkg/$pkg/save/pspool/$pkg/pkgmap) + do + svcs=$(SVCCFG_NOVALIDATE=1 \ + SVCCFG_REPOSITORY=$ZONEROOT/etc/svc/repository.db \ + /usr/sbin/svccfg inventory $ZONEROOT/$j) + for k in $svcs + do + echo $k /$j >> $SMFTMPFILE + done + done + done +} + +# +# Delete or disable SMF services. +# Zone is booted to milestone=none when this function is called. +# Use the SMF data collected by fix_smf_pre_uoa() to delete the services. +# +fix_smf() +{ + # + # Zone was already booted to milestone=none, wait until SMF door exists. + # + for i in 0 1 2 3 4 5 6 7 8 9 + do + [[ -r $ZONEROOT/etc/svc/volatile/repository_door ]] && break + sleep 5 + done + + if [[ $i -eq 9 && ! -r $ZONEROOT/etc/svc/volatile/repository_door ]]; + then + error "$e_nosmf" + /usr/bin/rm -f $SMFTMPFILE + return + fi + + insttmpfile=$(mktemp -t instsmf.XXXXXX) + if [[ $? == 1 || -z "$insttmpfile" ]]; then + error "$e_tmpfile" + /usr/bin/rm -f $SMFTMPFILE + return + fi + + vlog "$v_rmhollowsvcs" + while read fmri mfst + do + # Delete the svc. + vlog "$v_delsvc" "$fmri" + echo "/usr/sbin/svccfg delete -f $fmri" + echo "/usr/sbin/svccfg delhash -d $mfst" + echo "rm -f $mfst" + done < $SMFTMPFILE > $ZONEROOT/tmp/smf_rm + + /usr/sbin/zlogin -S $ZONENAME /bin/sh /tmp/smf_rm >/dev/null 2>&1 + + /usr/bin/rm -f $SMFTMPFILE + + # Get a list of the svcs that now exist in the zone. + LANG=C /usr/sbin/zlogin -S $ZONENAME /usr/bin/svcs -aH | \ + /usr/bin/nawk '{print $3}' >>$insttmpfile + + [[ -n $LOGFILE ]] && \ + printf "[$(date)] ${MSG_PREFIX}${v_svcsinzone}\n" >&2 + [[ -n $LOGFILE ]] && cat $insttmpfile >&2 + + # + # Fix network services if shared stack. + # + if [[ "$STACK_TYPE" == "shared" ]]; then + vlog "$v_fixnetsvcs" + + NETPHYSDEF="svc:/network/physical:default" + NETPHYSNWAM="svc:/network/physical:nwam" + + /usr/bin/egrep -s "$NETPHYSDEF" $insttmpfile + if (( $? == 0 )); then + vlog "$v_enblsvc" "$NETPHYSDEF" + /usr/sbin/zlogin -S $ZONENAME \ + /usr/sbin/svcadm enable $NETPHYSDEF || \ + error "$e_dissvc" "$NETPHYSDEF" + fi + + /usr/bin/egrep -s "$NETPHYSNWAM" $insttmpfile + if (( $? == 0 )); then + vlog "$v_dissvc" "$NETPHYSNWAM" + /usr/sbin/zlogin -S $ZONENAME \ + /usr/sbin/svcadm disable $NETPHYSNWAM || \ + error "$e_enblsvc" "$NETPHYSNWAM" + fi + + for i in $(/usr/bin/egrep network/routing $insttmpfile) + do + # Disable the svc. + vlog "$v_dissvc" "$i" + /usr/sbin/zlogin -S $ZONENAME \ + /usr/sbin/svcadm disable $i || \ + error "$e_dissvc" $i + done + fi + + # + # Disable well-known services that don't run in a zone. + # + vlog "$v_rminvalidsvcs" + for i in $(/usr/bin/egrep -hv "^#" \ + /usr/lib/brand/solaris10/smf_disable.lst \ + /etc/brand/solaris10/smf_disable.conf) + do + # Skip svcs not installed in the zone. + /usr/bin/egrep -s "$i:" $insttmpfile || continue + + # Disable the svc. + vlog "$v_dissvc" "$i" + /usr/sbin/zlogin -S $ZONENAME /usr/sbin/svcadm disable $i || \ + error "$e_dissvc" $i + done + + # + # Since zones can't be NFS servers, disable all of the instances of + # the shares svc. + # + for i in $(/usr/bin/egrep network/shares/group $insttmpfile) + do + vlog "$v_dissvc" "$i" + /usr/sbin/zlogin -S $ZONENAME /usr/sbin/svcadm disable $i || \ + error "$e_dissvc" $i + done + + /usr/bin/rm -f $insttmpfile +} + +# +# Remove well-known pkgs that do not work inside a zone. +# +rm_pkgs() +{ + /usr/bin/cat <<-EOF > $ZONEROOT/tmp/admin || fatal "$e_adminf" + mail= + instance=overwrite + partial=nocheck + runlevel=nocheck + idepend=nocheck + rdepend=nocheck + space=nocheck + setuid=nocheck + conflict=nocheck + action=nocheck + basedir=default + EOF + + for i in $(/usr/bin/egrep -hv "^#" /usr/lib/brand/solaris10/pkgrm.lst \ + /etc/brand/solaris10/pkgrm.conf) + do + [[ ! -d $ZONEROOT/var/sadm/pkg/$i ]] && continue + + vlog "$v_rmpkg" "$i" + /usr/sbin/zlogin -S $ZONENAME \ + /usr/sbin/pkgrm -na /tmp/admin $i >&2 || error "$e_rmpkg" $i + done +} + +# +# Zoneadmd writes a one-line index file into the zone when the zone boots, +# so any information about installed zones from the original system will +# be lost at that time. Here we'll warn the sysadmin about any pre-existing +# zones that they might want to clean up by hand, but we'll leave the zonepaths +# in place in case they're on shared storage and will be migrated to +# a new host. +# +warn_zones() +{ + zoneconfig=$ZONEROOT/etc/zones + + [[ ! -d $zoneconfig ]] && return + + if [[ -h $zoneconfig/index || ! -f $zoneconfig/index ]]; then + error "$e_badfile" "/etc/zones/index" + return + fi + + NGZ=$(/usr/bin/nawk -F: '{ + if (substr($1, 0, 1) == "#" || $1 == "global") + continue + + if ($2 == "installed") + printf("%s ", $1) + }' $zoneconfig/index) + + # Return if there are no installed zones to warn about. + [[ -z "$NGZ" ]] && return + + log "$v_rmzones" "$NGZ" + + NGZP=$(/usr/bin/nawk -F: '{ + if (substr($1, 0, 1) == "#" || $1 == "global") + continue + + if ($2 == "installed") + printf("%s ", $3) + }' $zoneconfig/index) + + log "$v_rmzonepaths" + + for i in $NGZP + do + log " %s" "$i" + done +} + +# +# ^C Should cleanup; if the zone is running, it should try to halt it. +# +zone_is_running=0 +trap trap_cleanup INT + +# +# Parse the command line options. +# +OPT_U= +OPT_V= +OPT_M= +OPT_L= +while getopts "uvm:l:" opt +do + case "$opt" in + u) OPT_U="-u";; + v) OPT_V="-v";; + m) MSG_PREFIX="$OPTARG"; OPT_M="-m \"$OPTARG\"";; + l) LOGFILE="$OPTARG"; OPT_L="-l \"$OPTARG\"";; + *) usage;; + esac +done +shift OPTIND-1 + +(( $# < 1 )) && usage + +(( $# > 2 )) && usage + +[[ -n $LOGFILE ]] && exec 2>>$LOGFILE + +ZONENAME=$1 +ZONEPATH=$2 +# XXX shared/common script currently uses lower case zonename & zonepath +zonename="$ZONENAME" +zonepath="$ZONEPATH" +ZONEROOT=$ZONEPATH/root + +e_badinfo=$(gettext "Failed to get '%s' zone resource") +e_badfile=$(gettext "Invalid '%s' file within the zone") +v_mkdirs=$(gettext "Creating mount points") +v_nonetfix=$(gettext "Cannot update /etc/hostname.{net} file") +v_adjust=$(gettext "Updating the image to run within a zone") +v_stacktype=$(gettext "Stack type '%s'") +v_booting=$(gettext "Booting zone to single user mode") +e_nosmf=$(gettext "SMF repository unavailable.") +v_svcsinzone=$(gettext "The following SMF services are installed:") +v_rmhollowsvcs=$(gettext "Deleting SMF services from hollow packages") +v_fixnetsvcs=$(gettext "Adjusting network SMF services") +v_rminvalidsvcs=$(gettext "Disabling invalid SMF services") +v_delsvc=$(gettext "Delete SMF svc '%s'") +e_delsvc=$(gettext "deleting SMF svc '%s'") +v_enblsvc=$(gettext "Enable SMF svc '%s'") +e_enblsvc=$(gettext "enabling SMF svc '%s'") +v_dissvc=$(gettext "Disable SMF svc '%s'") +e_dissvc=$(gettext "disabling SMF svc '%s'") +e_adminf=$(gettext "Unable to create admin file") +v_rmpkg=$(gettext "Remove package '%s'") +e_rmpkg=$(gettext "removing package '%s'") +v_rmzones=$(gettext "The following zones in this image will be unusable: %s") +v_rmzonepaths=$(gettext "These zonepaths could be removed from this image:") +v_halting=$(gettext "Halting zone") +e_shutdown=$(gettext "Shutting down zone %s...") +e_badhalt=$(gettext "Zone halt failed") +v_exitgood=$(gettext "Postprocessing successful.") +e_exitfail=$(gettext "Postprocessing failed.") + +# +# Do some validation on the paths we'll be accessing +# +safe_dir /etc +safe_dir /var +safe_opt_dir /etc/dfs +safe_opt_dir /etc/lu +safe_opt_dir /etc/zones + +mk_zone_dirs + +# Now do the work to update the zone. + +# Check for zones inside of image. +warn_zones +fix_smf_pre_uoa + +log "$v_adjust" + +# +# Any errors in these functions are not considered fatal. The zone can be +# be fixed up manually afterwards and it may need some additional manual +# cleanup in any case. +# + +STACK_TYPE=$(/usr/sbin/zoneadm -z $ZONENAME list -p | \ + /usr/bin/nawk -F: '{print $7}') +if (( $? != 0 )); then + error "$e_badinfo" "stacktype" +fi +vlog "$v_stacktype" "$STACK_TYPE" + +fix_lu +fix_net +fix_nfs +fix_vfstab + +vlog "$v_booting" + +# +# Boot the zone so that we can do all of the SMF updates needed on the zone's +# repository. +# + +zone_is_running=1 + +/usr/sbin/zoneadm -z $ZONENAME boot -f -- -m milestone=none +if (( $? != 0 )); then + error "$e_badboot" + /usr/bin/rm -f $SMFTMPFILE + fatal "$e_exitfail" +fi + +# cleanup SMF services +fix_smf + +# remove invalid pkgs +rm_pkgs + +if [[ -z $failed && -n $OPT_U ]]; then + vlog "$v_unconfig" + + sysunconfig_zone + if (( $? != 0 )); then + failed=1 + fi +fi + +vlog "$v_halting" +/usr/sbin/zoneadm -z $ZONENAME halt +if (( $? != 0 )); then + error "$e_badhalt" + failed=1 +fi +zone_is_running=0 + +if [[ -n $failed ]]; then + fatal "$e_exitfail" +fi + +vlog "$v_exitgood" +exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/pkgrm.conf Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,28 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This is a list of SVr4 packages which should be removed when installing +# the zone. Site-specific packages which must be removed should be listed +# in this file. During the zone installation, the packages will be removed +# if they existed on the original physical system. +#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/pkgrm.lst Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,30 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This is a list of SVr4 packages which should be removed when installing +# the zone. Do not edit this file. Site-specific packages which must be +# removed should be listed in the /etc/brand/solaris10/pkgrm.conf file. +# During the zone installation, the packages will be removed if they existed +# on the original physical system. +# +VRTSvxvm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/platform.xml Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,151 @@ +<?xml version="1.0"?> + +<!-- + 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 2009 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + DO NOT EDIT THIS FILE. +--> + +<!DOCTYPE platform PUBLIC "-//Sun Microsystems Inc//Zones Platform//EN" + "file:///usr/share/lib/xml/dtd/zone_platform.dtd.1"> + +<platform name="solaris10" allow-exclusive-ip="true"> + + <!-- Global filesystems to mount when booting the zone --> + <global_mount special="/dev" directory="/dev" type="dev" + opt="attrdir=%R/dev"/> + + <!-- + Local filesystems to mount when booting the zone. The + /.SUNWnative/platform entry is needed so that we can symlink a + platform-specific libc_psr for platforms which were not delivered + with S10. The /.SUNWnative/sbin entry is needed so that we can + replace ifconfig with its native counterpart (this is required for + exclusive-stack S10 zones to work). + --> + <global_mount special="/usr" directory="/.SUNWnative/usr" + opt="ro,nodevices" type="lofs" /> + <global_mount special="/lib" directory="/.SUNWnative/lib" + opt="ro,nodevices" type="lofs" /> + <global_mount special="/platform" directory="/.SUNWnative/platform" + opt="ro,nodevices" type="lofs" /> + <global_mount special="/sbin" directory="/.SUNWnative/sbin" + opt="ro,nodevices" type="lofs" /> + + <!-- Local filesystems to mount when booting the zone --> + <mount special="/proc" directory="/proc" type="proc" /> + <mount special="ctfs" directory="/system/contract" type="ctfs" /> + <mount special="mnttab" directory="/etc/mnttab" type="mntfs" /> + <mount special="objfs" directory="/system/object" type="objfs" /> + <mount special="swap" directory="/etc/svc/volatile" type="tmpfs" /> + + <!-- Devices to create under /dev --> + <device match="arp" /> + <device match="bpf" /> + <device match="conslog" /> + <device match="cpu/self/cpuid" /> + <device match="crypto" /> + <device match="cryptoadm" /> + <device match="dsk" /> + <device match="dtrace/*" /> + <device match="dtrace/provider/*" /> + <device match="fd" /> + <device match="ipnet" /> + <device match="kstat" /> + <device match="lo0" /> + <device match="log" /> + <device match="logindmux" /> + <device match="nsmb" /> + <device match="net/*" /> + <device match="null" /> + <device match="openprom" arch="sparc" /> + <device match="poll" /> + <device match="pool" /> + <device match="ptmx" /> + <device match="pts/*" /> + <device match="random" /> + <device match="rdsk" /> + <device match="rmt" /> + <device match="sad/user" /> + <device match="svvslo0" /> + <device match="svvslo1" /> + <device match="svvslo2" /> + <device match="svvslo3" /> + <device match="swap" /> + <device match="sysevent" /> + <device match="tcp" /> + <device match="tcp6" /> + <device match="term" /> + <device match="ticlts" /> + <device match="ticots" /> + <device match="ticotsord" /> + <device match="tty" /> + <device match="udp" /> + <device match="udp6" /> + <device match="urandom" /> + <device match="zero" /> + <device match="zfs" /> + + <!-- Devices to create in exclusive IP zone only --> + <device match="dld" ip-type="exclusive" /> + <device match="icmp" ip-type="exclusive" /> + <device match="icmp6" ip-type="exclusive" /> + <device match="ip" ip-type="exclusive" /> + <device match="ip6" ip-type="exclusive" /> + <device match="ipauth" ip-type="exclusive" /> + <device match="ipf" ip-type="exclusive" /> + <device match="ipl" ip-type="exclusive" /> + <device match="iplookup" ip-type="exclusive" /> + <device match="ipmpstub" ip-type="exclusive" /> + <device match="ipnat" ip-type="exclusive" /> + <device match="ipscan" ip-type="exclusive" /> + <device match="ipsecah" ip-type="exclusive" /> + <device match="ipsecesp" ip-type="exclusive" /> + <device match="ipstate" ip-type="exclusive" /> + <device match="ipsync" ip-type="exclusive" /> + <device match="iptunq" ip-type="exclusive" /> + <device match="keysock" ip-type="exclusive" /> + <device match="rawip" ip-type="exclusive" /> + <device match="rawip6" ip-type="exclusive" /> + <device match="rts" ip-type="exclusive" /> + <device match="sad/admin" ip-type="exclusive" /> + <device match="sctp" ip-type="exclusive" /> + <device match="sctp6" ip-type="exclusive" /> + <device match="spdsock" ip-type="exclusive" /> + <device match="sppp" ip-type="exclusive" /> + <device match="sppptun" ip-type="exclusive" /> + + <!-- Renamed devices to create under /dev --> + <device match="zcons/%z/zoneconsole" name="zconsole" /> + + <!-- Symlinks to create under /dev --> + <symlink source="console" target="zconsole" /> + <symlink source="dtremote" target="/dev/null" /> + <symlink source="msglog" target="zconsole" /> + <symlink source="stderr" target="./fd/2" /> + <symlink source="stdin" target="./fd/0" /> + <symlink source="stdout" target="./fd/1" /> + <symlink source="syscon" target="zconsole" /> + <symlink source="sysmsg" target="zconsole" /> + <symlink source="systty" target="zconsole" /> +</platform>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/poststate.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,60 @@ +#!/bin/ksh -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +. /usr/lib/brand/solaris10/common.ksh + +# States +# ZONE_STATE_CONFIGURED 0 (never see) +# ZONE_STATE_INCOMPLETE 1 (never see) +# ZONE_STATE_INSTALLED 2 +# ZONE_STATE_READY 3 +# ZONE_STATE_RUNNING 4 +# ZONE_STATE_SHUTTING_DOWN 5 +# ZONE_STATE_DOWN 6 +# ZONE_STATE_MOUNTED 7 + +# cmd +# +# ready 0 +# boot 1 +# halt 4 + +zonename=$1 +zonepath=$2 +state=$3 +cmd=$4 + +# If we're readying the zone, update the zone index file to look like this is +# the global zone. +if (( $cmd == 0 )); then + echo "global:installed:/" > $zonepath/root/etc/zones/index +elif (( $cmd == 4 )); then + # Leave the active dataset mounted after halting (this might be + # a different dataset than what was mounted). + mount_active_ds +fi + +exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/prestate.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,56 @@ +#!/bin/ksh -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +. /usr/lib/brand/solaris10/common.ksh + +# States +# ZONE_STATE_CONFIGURED 0 (never see) +# ZONE_STATE_INCOMPLETE 1 (never see) +# ZONE_STATE_INSTALLED 2 +# ZONE_STATE_READY 3 +# ZONE_STATE_RUNNING 4 +# ZONE_STATE_SHUTTING_DOWN 5 +# ZONE_STATE_DOWN 6 +# ZONE_STATE_MOUNTED 7 + +# cmd +# +# ready 0 +# boot 1 +# halt 4 + +zonename=$1 +zonepath=$2 +state=$3 +cmd=$4 + +# If we're not readying the zone, then just return. +if (( $cmd == 0 )); then + # Mount active dataset on the root. + mount_active_ds +fi + +exit $ZONE_SUBPROC_OK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/s10_boot.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,174 @@ +#!/bin/ksh -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# s10 boot script. +# +# The arguments to this script are the zone name and the zonepath. +# + +. /usr/lib/brand/solaris10/common.ksh + +ZONENAME=$1 +ZONEPATH=$2 +ZONEROOT=$ZONEPATH/root + +arch=`uname -p` +if [ "$arch" = "i386" ]; then + ARCH32=i86 + ARCH64=amd64 +elif [ "$arch" = "sparc" ]; then + # 32-bit SPARC not supported! + ARCH32= + ARCH64=sparcv9 +else + echo "Unsupported architecture: $arch" + exit 2 +fi + +# +# Run the s10_support boot hook. +# +/usr/lib/brand/solaris10/s10_support boot $ZONENAME +if (( $? != 0 )) ; then + exit 1 +fi + +BRANDDIR=/.SUNWnative/usr/lib/brand/solaris10; +FILEDIR=$BRANDDIR/files; +EXIT_CODE=1 + +# +# Replace the specified file in the booting zone with a wrapper script that +# invokes s10_isaexec_wrapper. This is a convenience function that reduces +# clutter and code duplication. +# +# Parameters: +# $1 The full path of the file to replace (e.g., /sbin/ifconfig) +# $2 The access mode of the replacement file in hex (e.g., 0555) +# $3 The name of the replacement file's owner (e.g., root:bin) +# +# NOTE: The checks performed in the 'if' statement below are not generic: they +# depend on the success of the zone filesystem structure validation performed +# above to ensure that intermediate directories exist and aren't symlinks. +# +replace_with_native() { + path_dname=$ZONEROOT/`dirname $1` + if [ ! -h $path_dname -a -d $path_dname ]; then + safe_replace $ZONEROOT/$1 $BRANDDIR/s10_isaexec_wrapper $2 $3 \ + remove + fi +} + +# +# Before we boot we validate and fix, if necessary, the required files within +# the zone. These modifications can be lost if a patch is applied within the +# zone, so we validate and fix the zone every time it boots. +# + +# +# BINARY REPLACEMENT +# +# This section of the boot script is responsible for replacing Solaris 10 +# binaries within the booting zone with Nevada binaries. This is a two-step +# process: First, the directory structure of the zone is validated to ensure +# that binary replacement will proceed safely. Second, Solaris 10 binaries +# are replaced with Nevada binaries. +# +# Here's an example. Suppose that you want to replace /usr/bin/zcat with the +# Nevada /usr/bin/zcat binary. Then you should do the following: +# +# 1. Go to the section below labeled "STEP ONE" and add the following +# two lines: +# +# safe_dir /usr +# safe_dir /usr/bin +# +# These lines ensure that both /usr and /usr/bin are directories +# within the booting zone that can be safely accessed by the global +# zone. +# 2. Go to the section below labeled "STEP TWO" and add the following +# line: +# +# replace_with_native /usr/bin/zcat 0555 root:bin +# +# Details about the binary replacement procedure can be found in the Solaris 10 +# Containers Developer Guide. +# + +# +# STEP ONE +# +# Validate that the zone filesystem looks like we expect it to. +# +safe_dir /usr +safe_dir /usr/lib +safe_dir /usr/bin +safe_dir /usr/sbin +safe_dir /sbin + +# +# STEP TWO +# +# Replace Solaris 10 binaries with Nevada binaries. +# + +# +# Replace various network-related programs with native wrappers. +# +replace_with_native /sbin/ifconfig 0555 root:bin + +# +# Replace automount and automountd with native wrappers. +# +if [ ! -h $ZONEROOT/usr/lib/fs/autofs -a -d $ZONEROOT/usr/lib/fs/autofs ]; then + safe_replace $ZONEROOT/usr/lib/fs/autofs/automount \ + $BRANDDIR/s10_automount 0555 root:bin remove +fi +if [ ! -h $ZONEROOT/usr/lib/autofs -a -d $ZONEROOT/usr/lib/autofs ]; then + safe_replace $ZONEROOT/usr/lib/autofs/automountd \ + $BRANDDIR/s10_automountd 0555 root:bin remove +fi + +# +# END OF STEP TWO +# + +# +# Replace add_drv and rem_drv with /usr/bin/true so that pkgs/patches which +# install or remove drivers will work. NOTE: add_drv and rem_drv are hard +# linked to isaexec so we want to remove the current executable and +# then copy true so that we don't clobber isaexec. +# +filename=$ZONEROOT/usr/sbin/add_drv +[ ! -f $filename.pre_p2v ] && safe_backup $filename $filename.pre_p2v +rm -f $filename +safe_copy $ZONEROOT/usr/bin/true $filename + +filename=$ZONEROOT/usr/sbin/rem_drv +[ ! -f $filename.pre_p2v ] && safe_backup $filename $filename.pre_p2v +rm -f $filename +safe_copy $ZONEROOT/usr/bin/true $filename + +exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/smf_disable.conf Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,28 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This is a list of SMF services which should be disabled when installing +# the zone. Site-specific services which must be disabled should be listed +# in this file. During the zone installation, the services will be disabled +# if they existed on the original physical system. +#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/smf_disable.lst Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,32 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This is a list of SMF services which should be disabled when installing +# the zone. Do not edit this file. Site-specific services which must be +# disabled should be listed in the /etc/brand/solaris10/smf_disable.conf +# file. During the zone installation, the services will be disabled if +# they existed on the original physical system. +# +svc:/network/smb/server +svc:/system/virtualbox/vboxservice +svc:/ldoms/ldmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/uninstall.ksh Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,133 @@ +#!/bin/ksh93 -p +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# common shell script functions +# +. /usr/lib/brand/solaris10/common.ksh +. /usr/lib/brand/shared/uninstall.ksh + +# +# options processing +# +zonename=$1 +if [ -z "$zonename" ]; then + printf "$f_abort\n" >&2 + exit $ZONE_SUBPROC_FATAL +fi +zonepath=$2 +if [ -z "$zonepath" ]; then + printf "$f_abort" >&2 + exit $ZONE_SUBPROC_FATAL +fi +shift 2 + +options="FhHnv" +options_repeat="" +options_seen="" + +opt_F="" +opt_n="" +opt_v="" + +# check for bad or duplicate options +OPTIND=1 +while getopts $options OPT ; do +case $OPT in + \? ) usage_err ;; # invalid argument + : ) usage_err ;; # argument expected + * ) + opt=`echo $OPT | sed 's/-\+//'` + if [ -n "$options_repeat" ]; then + echo $options_repeat | grep $opt >/dev/null + [ $? = 0 ] && break + fi + ( echo $options_seen | grep $opt >/dev/null ) && + usage_err + options_seen="${options_seen}${opt}" + ;; +esac +done + +# check for a help request +OPTIND=1 +while getopts :$options OPT ; do +case $OPT in + h|H ) usage +esac +done + +# process options +OPTIND=1 +while getopts :$options OPT ; do +case $OPT in + F ) opt_F="-F" ;; + n ) opt_n="-n" ;; + v ) opt_v="-v" ;; +esac +done +shift `expr $OPTIND - 1` + +[ $# -gt 0 ] && usage_err + +# +# main +# +zoneroot=$zonepath/root + +nop="" +if [[ -n "$opt_n" ]]; then + nop="echo" + # + # in '-n' mode we should never return success (since we haven't + # actually done anything). so override ZONE_SUBPROC_OK here. + # + ZONE_SUBPROC_OK=$ZONE_SUBPROC_FATAL +fi + +# +# We want uninstall to work in the face of various problems, such as a +# zone with no delegated root dataset or multiple active datasets, so we +# don't use the common functions. Instead, we do our own work and +# are tolerant of errors. +# +uninstall_get_zonepath_ds +uninstall_get_zonepath_root_ds + +# find all the zone BE datasets. +unset fs_all +(( fs_all_c = 0 )) +/sbin/zfs list -H -t filesystem -o name -r $ZONEPATH_RDS | while read fs; do + # only look at filesystems directly below $ZONEPATH_RDS + [[ "$fs" != ~()($ZONEPATH_RDS/+([^/])) ]] && continue + + fs_all[$fs_all_c]=$fs + (( fs_all_c = $fs_all_c + 1 )) +done + +destroy_zone_datasets + +exit $ZONE_SUBPROC_OK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/brand/solaris10/zone/version Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,31 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This is the current latest version of the solaris10 brand emulation. The +# version should be incremented if new capabilities are added to the +# emulation for new features backported to S10. The S10 required emulation +# version should also be incremented so that the enhanced version of S10 +# won't be usable in an older version of the solaris10 brand. +# +0
--- a/usr/src/pkgdefs/Makefile Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/pkgdefs/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -439,6 +439,8 @@ SUNWrsm \ SUNWrsmo \ SUNWrtls \ + SUNWs10brandr \ + SUNWs10brandu \ SUNWsacom \ SUNWsasnm \ SUNWsbp2 \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandr/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,33 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +all: $(FILES) depend +install: all pkg + +include ../Makefile.targ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandr/depend Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,36 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +P SUNWcar Core Architecture, (Root) +P SUNWcakr Core Solaris Kernel Architecture (Root) +P SUNWkvm Core Architecture, (Kvm) +P SUNWcsr Core Solaris, (Root) +P SUNWckr Core Solaris Kernel (Root) +P SUNWcnetr Core Solaris Network Infrastructure (Root) +P SUNWcsu Core Solaris, (Usr) +P SUNWcsd Core Solaris Devices +P SUNWcsl Core Solaris Libraries +P SUNWzoneu Solaris Zones (Usr) +P SUNWzoner Solaris Zones (Root)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandr/pkginfo.tmpl Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,53 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWs10brandr" +NAME="Solaris 10 Containers: solaris10 brand support (Root)" +BASEDIR=/ +ARCH="ISA" +VERSION="ONVERS,REV=0.0.0" +CATEGORY="system" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="root" +DESC="Support for the 'Solaris10' Brand" +VENDOR="Sun Microsystems, Inc." +EMAIL= +SUNW_PKGVERS=1.0 +CLASSES="none preserve" +MAXINST="1000" +HOTLINE="Please contact your local service provider" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandr/prototype_com Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,39 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Solaris 10 Brand +# + +i pkginfo +i copyright +i depend + +# solaris10 brand template +d none etc 755 root sys +d none etc/brand 755 root sys +d none etc/brand/solaris10 755 root sys +e preserve etc/brand/solaris10/pkgrm.conf 644 root sys +e preserve etc/brand/solaris10/smf_disable.conf 644 root sys +d none etc/zones 755 root sys +f none etc/zones/SUNWsolaris10.xml 444 root bin
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandr/prototype_i386 Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,31 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Solaris 10 Brand +# + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandr/prototype_sparc Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,50 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Solaris 10 Brand +# + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com + +# The kernel brand module +# Normally, brand modules are delivered via /usr/kernel because they are not +# required for boot. However, the solars10 brand syscall emulation module must +# be delivered via /platform on SPARC because it depends on platform-specific +# kernel data structures (specifically the machcpu_t) and we don't currently +# support loading platform-specific kernel modules from /usr/platform. +# +d none platform 0755 root sys +d none platform/sun4u 0755 root sys +d none platform/sun4u/kernel 0755 root sys +d none platform/sun4u/kernel/brand 0755 root sys +d none platform/sun4u/kernel/brand/sparcv9 0755 root sys +f none platform/sun4u/kernel/brand/sparcv9/s10_brand 0755 root sys +d none platform/sun4v 0755 root sys +d none platform/sun4v/kernel 0755 root sys +d none platform/sun4v/kernel/brand 0755 root sys +d none platform/sun4v/kernel/brand/sparcv9 0755 root sys +f none platform/sun4v/kernel/brand/sparcv9/s10_brand 0755 root sys
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandu/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,33 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +all: $(FILES) depend +install: all pkg + +include ../Makefile.targ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandu/depend Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,37 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +P SUNWcar Core Architecture, (Root) +P SUNWcakr Core Solaris Kernel Architecture (Root) +P SUNWkvm Core Architecture, (Kvm) +P SUNWcsr Core Solaris, (Root) +P SUNWckr Core Solaris Kernel (Root) +P SUNWcnetr Core Solaris Network Infrastructure (Root) +P SUNWcsu Core Solaris, (Usr) +P SUNWcsd Core Solaris Devices +P SUNWcsl Core Solaris Libraries +P SUNWzoneu Solaris Zones (Usr) +P SUNWzoner Solaris Zones (Root) +P SUNWs10brandr Solaris 10 Brand (Root)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandu/pkginfo.tmpl Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,53 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWs10brandu" +NAME="Solaris 10 Containers: solaris10 brand support (Usr)" +BASEDIR=/ +ARCH="ISA" +VERSION="ONVERS,REV=0.0.0" +CATEGORY="system" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +DESC="Support for the 'solaris10' Brand" +VENDOR="Sun Microsystems, Inc." +EMAIL= +SUNW_PKGVERS=1.0 +CLASSES="none" +MAXINST="1000" +HOTLINE="Please contact your local service provider" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandu/prototype_com Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,56 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +i pkginfo +i copyright +i depend + +d none usr 755 root sys +d none usr/lib 755 root bin +f none usr/lib/s10_brand.so.1 0755 root bin +f none usr/lib/s10_npreload.so.1 0755 root bin +d none usr/lib/brand 755 root bin +d none usr/lib/brand/solaris10 755 root sys +f none usr/lib/brand/solaris10/attach 755 root bin +f none usr/lib/brand/solaris10/clone 755 root bin +f none usr/lib/brand/solaris10/common.ksh 444 root bin +f none usr/lib/brand/solaris10/config.xml 444 root bin +f none usr/lib/brand/solaris10/detach 755 root bin +f none usr/lib/brand/solaris10/image_install 755 root bin +f none usr/lib/brand/solaris10/p2v 755 root bin +f none usr/lib/brand/solaris10/pkgrm.lst 444 root bin +f none usr/lib/brand/solaris10/platform.xml 444 root bin +f none usr/lib/brand/solaris10/poststate 755 root bin +f none usr/lib/brand/solaris10/prestate 755 root bin +f none usr/lib/brand/solaris10/s10_automount 755 root bin +f none usr/lib/brand/solaris10/s10_automountd 755 root bin +f none usr/lib/brand/solaris10/s10_boot 755 root bin +f none usr/lib/brand/solaris10/s10_native 755 root bin +f none usr/lib/brand/solaris10/s10_isaexec_wrapper 755 root bin +f none usr/lib/brand/solaris10/s10_support 755 root bin +f none usr/lib/brand/solaris10/solaris10_librtld_db.so.1 755 root bin +f none usr/lib/brand/solaris10/smf_disable.lst 444 root bin +f none usr/lib/brand/solaris10/uninstall 755 root bin +f none usr/lib/brand/solaris10/version 444 root bin
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandu/prototype_i386 Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,43 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Solaris 10 Brand +# + +!include prototype_com + +# the kernel brand module +d none usr/kernel 0755 root sys +d none usr/kernel/brand 0755 root sys +f none usr/kernel/brand/s10_brand 0755 root sys +d none usr/kernel/brand/amd64 0755 root sys +f none usr/kernel/brand/amd64/s10_brand 0755 root sys + +# The user library +d none usr/lib/amd64 0755 root bin +f none usr/lib/amd64/s10_brand.so.1 0755 root bin +f none usr/lib/amd64/s10_npreload.so.1 0755 root bin +d none usr/lib/brand/solaris10/amd64 755 root bin +s none usr/lib/brand/solaris10/64=amd64 755 root bin +f none usr/lib/brand/solaris10/amd64/solaris10_librtld_db.so.1 755 root bin
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/pkgdefs/SUNWs10brandu/prototype_sparc Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,36 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Solaris 10 Brand +# + +!include prototype_com + +# The user library +d none usr/lib/brand/solaris10/sparcv9 755 root bin +s none usr/lib/brand/solaris10/64=sparcv9 755 root bin +f none usr/lib/brand/solaris10/sparcv9/solaris10_librtld_db.so.1 755 root bin +d none usr/lib/sparcv9 0755 root bin +f none usr/lib/sparcv9/s10_brand.so.1 0755 root bin +f none usr/lib/sparcv9/s10_npreload.so.1 0755 root bin
--- a/usr/src/pkgdefs/SUNWzoneu/prototype_com Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/pkgdefs/SUNWzoneu/prototype_com Thu Oct 22 11:21:27 2009 -0700 @@ -60,6 +60,8 @@ f none usr/lib/brand/native/sw_support 755 root bin d none usr/lib/brand/shared 755 root sys f none usr/lib/brand/shared/common.ksh 444 root bin +f none usr/lib/brand/shared/query 755 root bin +f none usr/lib/brand/shared/uninstall.ksh 444 root bin f none usr/lib/libbrand.so.1 755 root bin f none usr/lib/libzonecfg.so.1 755 root bin d none usr/lib/zones 755 root bin
--- a/usr/src/uts/common/Makefile.rules Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/common/Makefile.rules Thu Oct 22 11:21:27 2009 -0700 @@ -100,6 +100,10 @@ $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) +$(OBJS_DIR)/%.o: $(UTSBASE)/common/brand/solaris10/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + $(OBJS_DIR)/%.o: $(UTSBASE)/common/c2/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) @@ -1525,6 +1529,9 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/common/brand/sn1/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) +$(LINTS_DIR)/%.ln: $(UTSBASE)/common/brand/solaris10/%.c + @($(LHEAD) $(LINT.c) $< $(LTAIL)) + $(LINTS_DIR)/%.ln: $(UTSBASE)/common/c2/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL))
--- a/usr/src/uts/common/brand/sn1/sn1_brand.c Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/common/brand/sn1/sn1_brand.c Thu Oct 22 11:21:27 2009 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -604,20 +604,22 @@ * calculated address from above. */ sedp->sed_ldentry = sedp->sed_entry; + sedp->sed_entry = NULL; + sedp->sed_phdr = NULL; + sedp->sed_phent = NULL; + sedp->sed_phnum = NULL; sedp->sed_lddata = NULL; - sedp->sed_base = NULL; - } - } + sedp->sed_base = voffset; - if (uphdr_vaddr != (Addr)-1) { - if (ehdr.e_type == ET_DYN) { - /* - * Delay setting the brkbase until the first call to - * brk(); see elfexec() for details. - */ - env.ex_bssbase = (caddr_t)0; - env.ex_brkbase = (caddr_t)0; - env.ex_brksize = 0; + if (ehdr.e_type == ET_DYN) { + /* + * Delay setting the brkbase until the first + * call to brk(); see elfexec() for details. + */ + env.ex_bssbase = (caddr_t)0; + env.ex_brkbase = (caddr_t)0; + env.ex_brksize = 0; + } } } @@ -706,42 +708,38 @@ * linker. */ for (i = 0; i < __KERN_NAUXV_IMPL; i++) { + ulong_t val; + switch (up->u_auxv[i].a_type) { case AT_SUN_BRAND_SN1_LDDATA: up->u_auxv[i].a_un.a_val = sed.sed_lddata; - break; + continue; case AT_BASE: - if (sedp->sed_base == NULL) { - /* Hide base for static binaries */ - up->u_auxv[i].a_type = AT_IGNORE; - up->u_auxv[i].a_un.a_val = NULL; - } else { - up->u_auxv[i].a_un.a_val = sedp->sed_base; - } + val = sedp->sed_base; break; case AT_ENTRY: - up->u_auxv[i].a_un.a_val = sedp->sed_entry; + val = sedp->sed_entry; break; case AT_PHDR: - up->u_auxv[i].a_un.a_val = sedp->sed_phdr; + val = sedp->sed_phdr; break; case AT_PHENT: - up->u_auxv[i].a_un.a_val = sedp->sed_phent; + val = sedp->sed_phent; break; case AT_PHNUM: - up->u_auxv[i].a_un.a_val = sedp->sed_phnum; + val = sedp->sed_phnum; break; case AT_SUN_LDDATA: - if (sedp->sed_lddata == NULL) { - /* Hide lddata for static binaries */ - up->u_auxv[i].a_type = AT_IGNORE; - up->u_auxv[i].a_un.a_val = NULL; - } else { - up->u_auxv[i].a_un.a_val = sedp->sed_lddata; - } + val = sedp->sed_lddata; break; default: - break; + continue; + } + + up->u_auxv[i].a_un.a_val = val; + if (val == NULL) { + /* Hide the entry for static binaries */ + up->u_auxv[i].a_type = AT_IGNORE; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/brand/solaris10/s10_brand.c Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,1019 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/errno.h> +#include <sys/exec.h> +#include <sys/kmem.h> +#include <sys/modctl.h> +#include <sys/model.h> +#include <sys/proc.h> +#include <sys/syscall.h> +#include <sys/systm.h> +#include <sys/thread.h> +#include <sys/cmn_err.h> +#include <sys/archsystm.h> +#include <sys/pathname.h> +#include <sys/sunddi.h> + +#include <sys/machbrand.h> +#include <sys/brand.h> +#include "s10_brand.h" + +char *s10_emulation_table = NULL; + +void s10_init_brand_data(zone_t *); +void s10_free_brand_data(zone_t *); +void s10_setbrand(proc_t *); +int s10_getattr(zone_t *, int, void *, size_t *); +int s10_setattr(zone_t *, int, void *, size_t); +int s10_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t, + uintptr_t, uintptr_t, uintptr_t); +void s10_copy_procdata(proc_t *, proc_t *); +void s10_proc_exit(struct proc *, klwp_t *); +void s10_exec(); +int s10_initlwp(klwp_t *); +void s10_forklwp(klwp_t *, klwp_t *); +void s10_freelwp(klwp_t *); +void s10_lwpexit(klwp_t *); +int s10_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int, + long *, int, caddr_t, cred_t *, int); + +/* s10 brand */ +struct brand_ops s10_brops = { + s10_init_brand_data, + s10_free_brand_data, + s10_brandsys, + s10_setbrand, + s10_getattr, + s10_setattr, + s10_copy_procdata, + s10_proc_exit, + s10_exec, + lwp_setrval, + s10_initlwp, + s10_forklwp, + s10_freelwp, + s10_lwpexit, + s10_elfexec +}; + +#ifdef sparc + +struct brand_mach_ops s10_mops = { + s10_brand_syscall_callback, + s10_brand_syscall32_callback +}; + +#else /* sparc */ + +#ifdef __amd64 + +struct brand_mach_ops s10_mops = { + s10_brand_sysenter_callback, + NULL, + s10_brand_int91_callback, + s10_brand_syscall_callback, + s10_brand_syscall32_callback, + NULL +}; + +#else /* ! __amd64 */ + +struct brand_mach_ops s10_mops = { + s10_brand_sysenter_callback, + NULL, + NULL, + s10_brand_syscall_callback, + NULL, + NULL +}; +#endif /* __amd64 */ + +#endif /* _sparc */ + +struct brand s10_brand = { + BRAND_VER_1, + "solaris10", + &s10_brops, + &s10_mops +}; + +static struct modlbrand modlbrand = { + &mod_brandops, /* type of module */ + "Solaris 10 Brand", /* description of module */ + &s10_brand /* driver ops */ +}; + +static struct modlinkage modlinkage = { + MODREV_1, (void *)&modlbrand, NULL +}; + +void +s10_setbrand(proc_t *p) +{ + ASSERT(p->p_brand == &s10_brand); + ASSERT(p->p_brand_data == NULL); + + /* + * We should only be called from exec(), when we know the process + * is single-threaded. + */ + ASSERT(p->p_tlist == p->p_tlist->t_forw); + + p->p_brand_data = kmem_zalloc(sizeof (s10_proc_data_t), KM_SLEEP); + (void) s10_initlwp(p->p_tlist->t_lwp); +} + +int +s10_get_zone_emul_version(zone_t *zone) +{ + return (((s10_zone_data_t *) + zone->zone_brand_data)->s10zd_emul_version); +} + +int +s10_get_emul_version() +{ + return (s10_get_zone_emul_version(curzone)); +} + +void +s10_set_emul_version(zone_t *zone, int vers) +{ + s10_zone_data_t *s10zd = (s10_zone_data_t *)zone->zone_brand_data; + s10zd->s10zd_emul_version = vers; +} + +/*ARGSUSED*/ +int +s10_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize) +{ + int num; + + ASSERT(zone->zone_brand == &s10_brand); + if (attr == S10_EMUL_VERSION_NUM) { + if (*bufsize < sizeof (int)) + return (ERANGE); + num = s10_get_emul_version(); + if (copyout(&num, buf, sizeof (int)) != 0) + return (EFAULT); + *bufsize = sizeof (int); + return (0); + } + + return (EINVAL); +} + +int +s10_setattr(zone_t *zone, int attr, void *buf, size_t bufsize) +{ + int num; + + ASSERT(zone->zone_brand == &s10_brand); + if (attr == S10_EMUL_VERSION_NUM) { + if (bufsize > sizeof (int)) + return (ERANGE); + if (copyin(buf, &num, sizeof (num)) != 0) + return (EFAULT); + s10_set_emul_version(zone, num); + return (0); + } + + return (EINVAL); +} + +#ifdef __amd64 +/* + * The Nevada kernel clears %fs for threads in 64-bit x86 processes but S10's + * libc expects %fs to be nonzero. This causes some committed + * libc/libthread interfaces (e.g., thr_main()) to fail, which impacts several + * libraries, including libdoor. This function sets the specified LWP's %fs + * register to the legacy S10 selector value (LWPFS_SEL). + * + * The best solution to the aforementioned problem is backporting CRs + * 6467491 to Solaris 10 so that 64-bit x86 Solaris 10 processes + * would accept zero for %fs. Backporting the CRs is a requirement for running + * S10 Containers in PV domUs because 64-bit Xen clears %fsbase when %fs is + * nonzero. Such behavior breaks 64-bit processes because Xen has to fetch the + * FS segments' base addresses from the LWPs' GDTs, which are only capable of + * 32-bit addressing. + */ +/*ARGSUSED*/ +static void +s10_amd64_correct_fsreg(klwp_t *l) +{ + if (lwp_getdatamodel(l) == DATAMODEL_NATIVE) { + kpreempt_disable(); + l->lwp_pcb.pcb_fs = LWPFS_SEL; + l->lwp_pcb.pcb_rupdate = 1; + lwptot(l)->t_post_sys = 1; /* Guarantee update_sregs() */ + kpreempt_enable(); + } +} +#endif /* __amd64 */ + +int +s10_native() +{ + struct user *up = PTOU(curproc); + char *args_new, *comm_new, *p; + int len; + + len = sizeof (S10_NATIVE_LINKER32 " ") - 1; + + /* + * Make sure that the process' interpreter is the native dynamic linker. + * Convention dictates that native processes executing within solaris10- + * branded zones are interpreted by the native dynamic linker (the + * process and its arguments are specified as arguments to the dynamic + * linker). If this convention is violated (i.e., + * brandsys(B_S10_NATIVE, ...) is invoked by a process that shouldn't be + * native), then do nothing and silently indicate success. + */ + if (strcmp(up->u_comm, S10_LINKER_NAME) != 0) + return (0); + if (strncmp(up->u_psargs, S10_NATIVE_LINKER64 " /", len + 4) == 0) + len += 3; /* to account for "/64" in the path */ + else if (strncmp(up->u_psargs, S10_NATIVE_LINKER32 " /", len + 1) != 0) + return (0); + + args_new = strdup(&up->u_psargs[len]); + if ((p = strchr(args_new, ' ')) != NULL) + *p = '\0'; + if ((comm_new = strrchr(args_new, '/')) != NULL) + comm_new = strdup(comm_new + 1); + else + comm_new = strdup(args_new); + if (p != NULL) + *p = ' '; + + if ((strlen(args_new) != 0) && (strlen(comm_new) != 0)) { + mutex_enter(&curproc->p_lock); + (void) strlcpy(up->u_comm, comm_new, MAXCOMLEN+1); + (void) strlcpy(up->u_psargs, args_new, PSARGSZ); + mutex_exit(&curproc->p_lock); + } + + strfree(args_new); + strfree(comm_new); + return (0); +} + +/* + * Get the address of the user-space system call handler from the user + * process and attach it to the proc structure. + */ +/*ARGSUSED*/ +int +s10_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, + uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6) +{ + s10_proc_data_t *spd; + s10_brand_reg_t reg; + proc_t *p = curproc; + int err; + + *rval = 0; + + /* + * B_EXEC_BRAND is redundant + * since the kernel assumes a native process doing an exec + * in a branded zone is going to run a branded processes. + * hence we don't support this operation. + */ + if (cmd == B_EXEC_BRAND) + return (ENOSYS); + + if (cmd == B_S10_NATIVE) + return (s10_native()); + + /* For all other operations this must be a branded process. */ + if (p->p_brand == &native_brand) + return (ENOSYS); + + ASSERT(p->p_brand == &s10_brand); + ASSERT(p->p_brand_data != NULL); + + spd = (s10_proc_data_t *)p->p_brand_data; + + switch (cmd) { + case B_EXEC_NATIVE: + err = exec_common( + (char *)arg1, (const char **)arg2, (const char **)arg3, + EBA_NATIVE); + return (err); + + case B_REGISTER: + if (p->p_model == DATAMODEL_NATIVE) { + if (copyin((void *)arg1, ®, sizeof (reg)) != 0) + return (EFAULT); +#if defined(_LP64) + } else { + s10_brand_reg32_t reg32; + + if (copyin((void *)arg1, ®32, sizeof (reg32)) != 0) + return (EFAULT); + reg.sbr_version = reg32.sbr_version; + reg.sbr_handler = (caddr_t)(uintptr_t)reg32.sbr_handler; +#endif /* _LP64 */ + } + + if (reg.sbr_version != S10_VERSION) + return (ENOTSUP); + spd->spd_handler = reg.sbr_handler; + return (0); + + case B_ELFDATA: + if (p->p_model == DATAMODEL_NATIVE) { + if (copyout(&spd->spd_elf_data, (void *)arg1, + sizeof (s10_elf_data_t)) != 0) + return (EFAULT); +#if defined(_LP64) + } else { + s10_elf_data32_t sed32; + + sed32.sed_phdr = spd->spd_elf_data.sed_phdr; + sed32.sed_phent = spd->spd_elf_data.sed_phent; + sed32.sed_phnum = spd->spd_elf_data.sed_phnum; + sed32.sed_entry = spd->spd_elf_data.sed_entry; + sed32.sed_base = spd->spd_elf_data.sed_base; + sed32.sed_ldentry = spd->spd_elf_data.sed_ldentry; + sed32.sed_lddata = spd->spd_elf_data.sed_lddata; + if (copyout(&sed32, (void *)arg1, sizeof (sed32)) != 0) + return (EFAULT); +#endif /* _LP64 */ + } + return (0); + + case B_S10_PIDINFO: + /* + * The s10 brand needs to be able to get the pid of the + * current process and the pid of the zone's init, and it + * needs to do this on every process startup. Early in + * brand startup, we can't call getpid() because calls to + * getpid() represent a magical signal to some old-skool + * debuggers. By merging all of this into one call, we + * make this quite a bit cheaper and easier to handle in + * the brand module. + */ + if (copyout(&p->p_pid, (void *)arg1, sizeof (pid_t)) != 0) + return (EFAULT); + if (copyout(&p->p_zone->zone_proc_initpid, (void *)arg2, + sizeof (pid_t)) != 0) + return (EFAULT); + return (0); + + case B_S10_TRUSS_POINT: + /* + * This subcommand exists so that we can see truss output + * from interposed system calls that return without first + * calling any other system call, meaning they would be + * invisible to truss(1). + * + * If the second argument is set non-zero, set errno to that + * value as well. + * + * Arguments are: + * + * arg1: syscall number + * arg2: errno + */ + return ((arg2 == 0) ? 0 : set_errno((uint_t)arg2)); + +#ifdef __amd64 + case B_S10_FSREGCORRECTION: + /* + * This subcommand exists so that the SYS_lwp_private and + * SYS_lwp_create syscalls can manually set the current thread's + * %fs register to the legacy S10 selector value for 64-bit x86 + * processes. + */ + s10_amd64_correct_fsreg(ttolwp(curthread)); + return (0); +#endif /* __amd64 */ + } + + return (EINVAL); +} + +/* + * Copy the per-process brand data from a parent proc to a child. + */ +void +s10_copy_procdata(proc_t *child, proc_t *parent) +{ + s10_proc_data_t *spd; + + ASSERT(parent->p_brand == &s10_brand); + ASSERT(child->p_brand == &s10_brand); + ASSERT(parent->p_brand_data != NULL); + ASSERT(child->p_brand_data == NULL); + + /* Just duplicate all the proc data of the parent for the child */ + spd = kmem_alloc(sizeof (s10_proc_data_t), KM_SLEEP); + bcopy(parent->p_brand_data, spd, sizeof (s10_proc_data_t)); + child->p_brand_data = spd; +} + +/*ARGSUSED*/ +void +s10_proc_exit(struct proc *p, klwp_t *l) +{ + ASSERT(p->p_brand == &s10_brand); + ASSERT(p->p_brand_data != NULL); + + /* + * We should only be called from proc_exit(), when we know that + * process is single-threaded. + */ + ASSERT(p->p_tlist == p->p_tlist->t_forw); + + /* upon exit, free our lwp brand data */ + (void) s10_freelwp(ttolwp(curthread)); + + /* upon exit, free our proc brand data */ + kmem_free(p->p_brand_data, sizeof (s10_proc_data_t)); + p->p_brand_data = NULL; +} + +void +s10_exec() +{ + s10_proc_data_t *spd = curproc->p_brand_data; + + ASSERT(curproc->p_brand == &s10_brand); + ASSERT(curproc->p_brand_data != NULL); + ASSERT(ttolwp(curthread)->lwp_brand != NULL); + + /* + * We should only be called from exec(), when we know the process + * is single-threaded. + */ + ASSERT(curproc->p_tlist == curproc->p_tlist->t_forw); + + /* Upon exec, reset our lwp brand data. */ + (void) s10_freelwp(ttolwp(curthread)); + (void) s10_initlwp(ttolwp(curthread)); + + /* + * Upon exec, reset all the proc brand data, except for the elf + * data associated with the executable we are exec'ing. + */ + spd->spd_handler = NULL; +} + +/*ARGSUSED*/ +int +s10_initlwp(klwp_t *l) +{ + ASSERT(l->lwp_procp->p_brand == &s10_brand); + ASSERT(l->lwp_procp->p_brand_data != NULL); + ASSERT(l->lwp_brand == NULL); + l->lwp_brand = (void *)-1; + return (0); +} + +/*ARGSUSED*/ +void +s10_forklwp(klwp_t *p, klwp_t *c) +{ + ASSERT(p->lwp_procp->p_brand == &s10_brand); + ASSERT(c->lwp_procp->p_brand == &s10_brand); + + ASSERT(p->lwp_procp->p_brand_data != NULL); + ASSERT(c->lwp_procp->p_brand_data != NULL); + + /* Both LWPs have already had been initialized via s10_initlwp() */ + ASSERT(p->lwp_brand != NULL); + ASSERT(c->lwp_brand != NULL); + +#ifdef __amd64 + /* + * Only correct the child's %fs register if the parent's %fs register + * is LWPFS_SEL. If the parent's %fs register is zero, then the Solaris + * 10 environment that we're emulating uses a version of libc that + * works when %fs is zero (i.e., it contains backports of CRs 6467491 + * and 6501650). + */ + if (p->lwp_pcb.pcb_fs == LWPFS_SEL) + s10_amd64_correct_fsreg(c); +#endif /* __amd64 */ +} + +/*ARGSUSED*/ +void +s10_freelwp(klwp_t *l) +{ + ASSERT(l->lwp_procp->p_brand == &s10_brand); + ASSERT(l->lwp_procp->p_brand_data != NULL); + ASSERT(l->lwp_brand != NULL); + l->lwp_brand = NULL; +} + +/*ARGSUSED*/ +void +s10_lwpexit(klwp_t *l) +{ + proc_t *p = l->lwp_procp; + + ASSERT(l->lwp_procp->p_brand == &s10_brand); + ASSERT(l->lwp_procp->p_brand_data != NULL); + ASSERT(l->lwp_brand != NULL); + + /* + * We should never be called for the last thread in a process. + * (That case is handled by s10_proc_exit().) There for this lwp + * must be exiting from a multi-threaded process. + */ + ASSERT(p->p_tlist != p->p_tlist->t_forw); + + l->lwp_brand = NULL; +} + +void +s10_free_brand_data(zone_t *zone) +{ + kmem_free(zone->zone_brand_data, sizeof (s10_zone_data_t)); +} + +void +s10_init_brand_data(zone_t *zone) +{ + s10_zone_data_t *data; + ASSERT(zone->zone_brand == &s10_brand); + ASSERT(zone->zone_brand_data == NULL); + data = (s10_zone_data_t *)kmem_zalloc(sizeof (s10_zone_data_t), + KM_SLEEP); + /* + * Initialize the default s10zd_emul_version to S10_EMUL_UNDEF. + * This can be changed by a call to setattr() during zone boot. + */ + data->s10zd_emul_version = S10_EMUL_UNDEF; + zone->zone_brand_data = data; +} + +#if defined(_LP64) +static void +Ehdr32to64(Elf32_Ehdr *src, Ehdr *dst) +{ + bcopy(src->e_ident, dst->e_ident, sizeof (src->e_ident)); + dst->e_type = src->e_type; + dst->e_machine = src->e_machine; + dst->e_version = src->e_version; + dst->e_entry = src->e_entry; + dst->e_phoff = src->e_phoff; + dst->e_shoff = src->e_shoff; + dst->e_flags = src->e_flags; + dst->e_ehsize = src->e_ehsize; + dst->e_phentsize = src->e_phentsize; + dst->e_phnum = src->e_phnum; + dst->e_shentsize = src->e_shentsize; + dst->e_shnum = src->e_shnum; + dst->e_shstrndx = src->e_shstrndx; +} +#endif /* _LP64 */ + +int +s10_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap, + int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred, + int brand_action) +{ + vnode_t *nvp; + Ehdr ehdr; + Addr uphdr_vaddr; + intptr_t voffset; + int interp; + int i, err; + struct execenv env; + struct user *up = PTOU(curproc); + s10_proc_data_t *spd; + s10_elf_data_t sed, *sedp; + char *linker; + uintptr_t lddata; /* lddata of executable's linker */ + + ASSERT(curproc->p_brand == &s10_brand); + ASSERT(curproc->p_brand_data != NULL); + + spd = (s10_proc_data_t *)curproc->p_brand_data; + sedp = &spd->spd_elf_data; + + args->brandname = S10_BRANDNAME; + + /* + * We will exec the brand library and then map in the target + * application and (optionally) the brand's default linker. + */ + if (args->to_model == DATAMODEL_NATIVE) { + args->emulator = S10_LIB; + linker = S10_LINKER; +#if defined(_LP64) + } else { + args->emulator = S10_LIB32; + linker = S10_LINKER32; +#endif /* _LP64 */ + } + + if ((err = lookupname(args->emulator, UIO_SYSSPACE, FOLLOW, NULLVPP, + &nvp)) != 0) { + uprintf("%s: not found.", args->emulator); + return (err); + } + + if (args->to_model == DATAMODEL_NATIVE) { + err = elfexec(nvp, uap, args, idatap, level + 1, execsz, + setid, exec_file, cred, brand_action); +#if defined(_LP64) + } else { + err = elf32exec(nvp, uap, args, idatap, level + 1, execsz, + setid, exec_file, cred, brand_action); +#endif /* _LP64 */ + } + VN_RELE(nvp); + if (err != 0) + return (err); + + /* + * The u_auxv vectors are set up by elfexec to point to the brand + * emulation library and linker. Save these so they can be copied to + * the specific brand aux vectors. + */ + bzero(&sed, sizeof (sed)); + for (i = 0; i < __KERN_NAUXV_IMPL; i++) { + switch (up->u_auxv[i].a_type) { + case AT_SUN_LDDATA: + sed.sed_lddata = up->u_auxv[i].a_un.a_val; + break; + case AT_BASE: + sed.sed_base = up->u_auxv[i].a_un.a_val; + break; + case AT_ENTRY: + sed.sed_entry = up->u_auxv[i].a_un.a_val; + break; + case AT_PHDR: + sed.sed_phdr = up->u_auxv[i].a_un.a_val; + break; + case AT_PHENT: + sed.sed_phent = up->u_auxv[i].a_un.a_val; + break; + case AT_PHNUM: + sed.sed_phnum = up->u_auxv[i].a_un.a_val; + break; + default: + break; + } + } + /* Make sure the emulator has an entry point */ + ASSERT(sed.sed_entry != NULL); + ASSERT(sed.sed_phdr != NULL); + + bzero(&env, sizeof (env)); + if (args->to_model == DATAMODEL_NATIVE) { + err = mapexec_brand(vp, args, &ehdr, &uphdr_vaddr, &voffset, + exec_file, &interp, &env.ex_bssbase, &env.ex_brkbase, + &env.ex_brksize, NULL); +#if defined(_LP64) + } else { + Elf32_Ehdr ehdr32; + Elf32_Addr uphdr_vaddr32; + err = mapexec32_brand(vp, args, &ehdr32, &uphdr_vaddr32, + &voffset, exec_file, &interp, &env.ex_bssbase, + &env.ex_brkbase, &env.ex_brksize, NULL); + Ehdr32to64(&ehdr32, &ehdr); + if (uphdr_vaddr32 == (Elf32_Addr)-1) + uphdr_vaddr = (Addr)-1; + else + uphdr_vaddr = uphdr_vaddr32; +#endif /* _LP64 */ + } + if (err != 0) + return (err); + + /* + * Save off the important properties of the executable. The brand + * library will ask us for this data later, when it is initializing + * and getting ready to transfer control to the brand application. + */ + if (uphdr_vaddr == (Addr)-1) + sedp->sed_phdr = voffset + ehdr.e_phoff; + else + sedp->sed_phdr = voffset + uphdr_vaddr; + sedp->sed_entry = voffset + ehdr.e_entry; + sedp->sed_phent = ehdr.e_phentsize; + sedp->sed_phnum = ehdr.e_phnum; + + if (interp) { + if (ehdr.e_type == ET_DYN) { + /* + * This is a shared object executable, so we need to + * pick a reasonable place to put the heap. Just don't + * use the first page. + */ + env.ex_brkbase = (caddr_t)PAGESIZE; + env.ex_bssbase = (caddr_t)PAGESIZE; + } + + /* + * If the program needs an interpreter (most do), map it in and + * store relevant information about it in the aux vector, where + * the brand library can find it. + */ + if ((err = lookupname(linker, UIO_SYSSPACE, + FOLLOW, NULLVPP, &nvp)) != 0) { + uprintf("%s: not found.", S10_LINKER); + return (err); + } + if (args->to_model == DATAMODEL_NATIVE) { + err = mapexec_brand(nvp, args, &ehdr, + &uphdr_vaddr, &voffset, exec_file, &interp, + NULL, NULL, NULL, &lddata); +#if defined(_LP64) + } else { + Elf32_Ehdr ehdr32; + Elf32_Addr uphdr_vaddr32; + err = mapexec32_brand(nvp, args, &ehdr32, + &uphdr_vaddr32, &voffset, exec_file, &interp, + NULL, NULL, NULL, &lddata); + Ehdr32to64(&ehdr32, &ehdr); + if (uphdr_vaddr32 == (Elf32_Addr)-1) + uphdr_vaddr = (Addr)-1; + else + uphdr_vaddr = uphdr_vaddr32; +#endif /* _LP64 */ + } + VN_RELE(nvp); + if (err != 0) + return (err); + + /* + * Now that we know the base address of the brand's linker, + * place it in the aux vector. + */ + sedp->sed_base = voffset; + sedp->sed_ldentry = voffset + ehdr.e_entry; + sedp->sed_lddata = voffset + lddata; + } else { + /* + * This program has no interpreter. The brand library will + * jump to the address in the AT_SUN_BRAND_LDENTRY aux vector, + * so in this case, put the entry point of the main executable + * there. + */ + if (ehdr.e_type == ET_EXEC) { + /* + * An executable with no interpreter, this must be a + * statically linked executable, which means we loaded + * it at the address specified in the elf header, in + * which case the e_entry field of the elf header is an + * absolute address. + */ + sedp->sed_ldentry = ehdr.e_entry; + sedp->sed_entry = ehdr.e_entry; + sedp->sed_lddata = NULL; + sedp->sed_base = NULL; + } else { + /* + * A shared object with no interpreter, we use the + * calculated address from above. + */ + sedp->sed_ldentry = sedp->sed_entry; + sedp->sed_entry = NULL; + sedp->sed_phdr = NULL; + sedp->sed_phent = NULL; + sedp->sed_phnum = NULL; + sedp->sed_lddata = NULL; + sedp->sed_base = voffset; + + if (ehdr.e_type == ET_DYN) { + /* + * Delay setting the brkbase until the first + * call to brk(); see elfexec() for details. + */ + env.ex_bssbase = (caddr_t)0; + env.ex_brkbase = (caddr_t)0; + env.ex_brksize = 0; + } + } + } + + env.ex_magic = elfmagic; + env.ex_vp = vp; + setexecenv(&env); + + /* + * It's time to manipulate the process aux vectors. First + * we need to update the AT_SUN_AUXFLAGS aux vector to set + * the AF_SUN_NOPLM flag. + */ + if (args->to_model == DATAMODEL_NATIVE) { + auxv_t auxflags_auxv; + + if (copyin(args->auxp_auxflags, &auxflags_auxv, + sizeof (auxflags_auxv)) != 0) + return (EFAULT); + + ASSERT(auxflags_auxv.a_type == AT_SUN_AUXFLAGS); + auxflags_auxv.a_un.a_val |= AF_SUN_NOPLM; + if (copyout(&auxflags_auxv, args->auxp_auxflags, + sizeof (auxflags_auxv)) != 0) + return (EFAULT); +#if defined(_LP64) + } else { + auxv32_t auxflags_auxv32; + + if (copyin(args->auxp_auxflags, &auxflags_auxv32, + sizeof (auxflags_auxv32)) != 0) + return (EFAULT); + + ASSERT(auxflags_auxv32.a_type == AT_SUN_AUXFLAGS); + auxflags_auxv32.a_un.a_val |= AF_SUN_NOPLM; + if (copyout(&auxflags_auxv32, args->auxp_auxflags, + sizeof (auxflags_auxv32)) != 0) + return (EFAULT); +#endif /* _LP64 */ + } + + /* Second, copy out the brand specific aux vectors. */ + if (args->to_model == DATAMODEL_NATIVE) { + auxv_t s10_auxv[] = { + { AT_SUN_BRAND_AUX1, 0 }, + { AT_SUN_BRAND_AUX2, 0 }, + { AT_SUN_BRAND_AUX3, 0 } + }; + + ASSERT(s10_auxv[0].a_type == AT_SUN_BRAND_S10_LDDATA); + s10_auxv[0].a_un.a_val = sed.sed_lddata; + + if (copyout(&s10_auxv, args->auxp_brand, + sizeof (s10_auxv)) != 0) + return (EFAULT); +#if defined(_LP64) + } else { + auxv32_t s10_auxv32[] = { + { AT_SUN_BRAND_AUX1, 0 }, + { AT_SUN_BRAND_AUX2, 0 }, + { AT_SUN_BRAND_AUX3, 0 } + }; + + ASSERT(s10_auxv32[0].a_type == AT_SUN_BRAND_S10_LDDATA); + s10_auxv32[0].a_un.a_val = (uint32_t)sed.sed_lddata; + if (copyout(&s10_auxv32, args->auxp_brand, + sizeof (s10_auxv32)) != 0) + return (EFAULT); +#endif /* _LP64 */ + } + + /* + * Third, the the /proc aux vectors set up by elfexec() point to brand + * emulation library and it's linker. Copy these to the /proc brand + * specific aux vector, and update the regular /proc aux vectors to + * point to the executable (and it's linker). This will enable + * debuggers to access the executable via the usual /proc or elf notes + * aux vectors. + * + * The brand emulation library's linker will get it's aux vectors off + * the stack, and then update the stack with the executable's aux + * vectors before jumping to the executable's linker. + * + * Debugging the brand emulation library must be done from + * the global zone, where the librtld_db module knows how to fetch the + * brand specific aux vectors to access the brand emulation libraries + * linker. + */ + for (i = 0; i < __KERN_NAUXV_IMPL; i++) { + ulong_t val; + + switch (up->u_auxv[i].a_type) { + case AT_SUN_BRAND_S10_LDDATA: + up->u_auxv[i].a_un.a_val = sed.sed_lddata; + continue; + case AT_BASE: + val = sedp->sed_base; + break; + case AT_ENTRY: + val = sedp->sed_entry; + break; + case AT_PHDR: + val = sedp->sed_phdr; + break; + case AT_PHENT: + val = sedp->sed_phent; + break; + case AT_PHNUM: + val = sedp->sed_phnum; + break; + case AT_SUN_LDDATA: + val = sedp->sed_lddata; + break; + default: + continue; + } + + up->u_auxv[i].a_un.a_val = val; + if (val == NULL) { + /* Hide the entry for static binaries */ + up->u_auxv[i].a_type = AT_IGNORE; + } + } + + /* + * The last thing we do here is clear spd->spd_handler. This is + * important because if we're already a branded process and if this + * exec succeeds, there is a window between when the exec() first + * returns to the userland of the new process and when our brand + * library get's initialized, during which we don't want system + * calls to be re-directed to our brand library since it hasn't + * been initialized yet. + */ + spd->spd_handler = NULL; + + return (0); +} + + +int +_init(void) +{ + int err; + + /* + * Set up the table indicating which system calls we want to + * interpose on. We should probably build this automatically from + * a list of system calls that is shared with the user-space + * library. + */ + s10_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP); + s10_emulation_table[SYS_exec] = 1; /* 11 */ + s10_emulation_table[SYS_ioctl] = 1; /* 54 */ + s10_emulation_table[SYS_execve] = 1; /* 59 */ + s10_emulation_table[SYS_acctctl] = 1; /* 71 */ + s10_emulation_table[S10_SYS_issetugid] = 1; /* 75 */ + s10_emulation_table[SYS_uname] = 1; /* 135 */ + s10_emulation_table[SYS_systeminfo] = 1; /* 139 */ +#ifdef __amd64 + s10_emulation_table[SYS_lwp_create] = 1; /* 159 */ + s10_emulation_table[SYS_lwp_private] = 1; /* 166 */ +#endif /* __amd64 */ + s10_emulation_table[SYS_pwrite] = 1; /* 174 */ + s10_emulation_table[SYS_auditsys] = 1; /* 186 */ + s10_emulation_table[SYS_sigqueue] = 1; /* 190 */ + s10_emulation_table[SYS_pwrite64] = 1; /* 223 */ + s10_emulation_table[SYS_zone] = 1; /* 227 */ + + err = mod_install(&modlinkage); + if (err) { + cmn_err(CE_WARN, "Couldn't install brand module"); + kmem_free(s10_emulation_table, NSYSCALL); + } + + return (err); +} + +int +_info(struct modinfo *modinfop) +{ + return (mod_info(&modlinkage, modinfop)); +} + +int +_fini(void) +{ + int err; + + /* + * If there are any zones using this brand, we can't allow it to be + * unloaded. + */ + if (brand_zone_count(&s10_brand)) + return (EBUSY); + + kmem_free(s10_emulation_table, NSYSCALL); + s10_emulation_table = NULL; + + err = mod_remove(&modlinkage); + if (err) + cmn_err(CE_WARN, "Couldn't unload s10 brand module"); + + return (err); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/brand/solaris10/s10_brand.h Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,162 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _S10_BRAND_H +#define _S10_BRAND_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/types.h> + +#define S10_BRANDNAME "solaris10" + +#define S10_VERSION_1 1 +#define S10_VERSION S10_VERSION_1 + +#define S10_NATIVE_DIR "/.SUNWnative/" +#define S10_LIB_NAME "s10_brand.so.1" +#define S10_LINKER_NAME "ld.so.1" + +#define S10_LIB32 S10_NATIVE_DIR "usr/lib/" S10_LIB_NAME +#define S10_LINKER32 "/lib/" S10_LINKER_NAME +#define S10_NATIVE_LINKER32 S10_NATIVE_DIR "lib/" S10_LINKER_NAME + +#define S10_LIB64 S10_NATIVE_DIR "usr/lib/64/" S10_LIB_NAME +#define S10_LINKER64 "/lib/64/" S10_LINKER_NAME +#define S10_NATIVE_LINKER64 S10_NATIVE_DIR "lib/64/" S10_LINKER_NAME + +#if defined(_LP64) +#define S10_LIB S10_LIB64 +#define S10_LINKER S10_LINKER64 +#else /* !_LP64 */ +#define S10_LIB S10_LIB32 +#define S10_LINKER S10_LINKER32 +#endif /* !_LP64 */ + +/* + * Brand system call subcodes. 0-127 are reserved for generic subcodes. + */ +#define B_S10_PIDINFO 128 +#define B_S10_TRUSS_POINT 129 +#define B_S10_NATIVE 130 +#define B_S10_FSREGCORRECTION 131 + +/* + * s10_brand_syscall_callback_common() needs to save 4 local registers so it + * can free them up for its own use. + */ +#define S10_CPU_REG_SAVE_SIZE (sizeof (ulong_t) * 4) + +/* + * Aux vector containing lddata pointer of brand library linkmap. + * Used by s10_librtld_db. + */ +#define AT_SUN_BRAND_S10_LDDATA AT_SUN_BRAND_AUX1 + +/* + * S10 system call codes for S10 traps that have been removed or + * re-assigned. + */ +#define S10_SYS_issetugid 75 + +/* + * S10 brand emulation versions are used to trigger different behavior + * based on the version of S10 installed in the zone. + */ +#define S10_EMUL_UNDEF -1 + +#define S10_EMUL_VERSION_NUM ZONE_ATTR_BRAND_ATTRS + +/* + * Information needed by the s10 library to launch an executable. + */ +typedef struct s10_elf_data { + ulong_t sed_phdr; + ulong_t sed_phent; + ulong_t sed_phnum; + ulong_t sed_entry; + ulong_t sed_base; + ulong_t sed_ldentry; + ulong_t sed_lddata; +} s10_elf_data_t; + +/* + * Structure used to register a branded processes + */ +typedef struct s10_brand_reg { + uint_t sbr_version; /* version number */ + caddr_t sbr_handler; /* base address of handler */ +} s10_brand_reg_t; + +#if defined(_KERNEL) +#if defined(_SYSCALL32) +typedef struct s10_elf_data32 { + uint32_t sed_phdr; + uint32_t sed_phent; + uint32_t sed_phnum; + uint32_t sed_entry; + uint32_t sed_base; + uint32_t sed_ldentry; + uint32_t sed_lddata; +} s10_elf_data32_t; + +typedef struct s10_brand_reg32 { + uint32_t sbr_version; /* version number */ + caddr32_t sbr_handler; /* base address of handler */ +} s10_brand_reg32_t; +#endif /* _SYSCALL32 */ + +/* + * Information associated with all s10 branded processes + */ +typedef struct s10_proc_data { + caddr_t spd_handler; /* address of user-space handler */ + s10_elf_data_t spd_elf_data; /* ELF data for s10 application */ +} s10_proc_data_t; + +/* brand specific data */ +typedef struct s10_zone_data { + int s10zd_emul_version; +} s10_zone_data_t; + +void s10_brand_syscall_callback(void); +void s10_brand_syscall32_callback(void); + +#if !defined(sparc) +void s10_brand_sysenter_callback(void); +#endif /* !sparc */ + +#if defined(__amd64) +void s10_brand_int91_callback(void); +#endif /* __amd64 */ +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* _S10_BRAND_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/brand/solaris10/s10_offsets.in Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,30 @@ +\ +\ Copyright 2009 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ 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 +\ +\ s10 brand structure offset for use in assembly code. +\ + +#include <s10_brand.h> + +s10_proc_data_t + spd_handler
--- a/usr/src/uts/intel/Makefile.files Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/intel/Makefile.files Thu Oct 22 11:21:27 2009 -0700 @@ -260,6 +260,7 @@ # Brand modules # SN1_BRAND_OBJS = sn1_brand.o sn1_brand_asm.o +S10_BRAND_OBJS = s10_brand.o s10_brand_asm.o LX_BRAND_OBJS = \ lx_brand.o \
--- a/usr/src/uts/intel/Makefile.intel.shared Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/intel/Makefile.intel.shared Thu Oct 22 11:21:27 2009 -0700 @@ -512,7 +512,7 @@ # # Brand modules # -BRAND_KMODS += sn1_brand lx_brand +BRAND_KMODS += sn1_brand s10_brand lx_brand DRV_KMODS += lx_systrace lx_ptm lx_audio STRMOD_KMODS += ldlinux
--- a/usr/src/uts/intel/Makefile.rules Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/intel/Makefile.rules Thu Oct 22 11:21:27 2009 -0700 @@ -60,6 +60,9 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/intel/brand/sn1/%.s $(COMPILE.s) -o $@ $< +$(OBJS_DIR)/%.o: $(UTSBASE)/intel/brand/solaris10/%.s + $(COMPILE.s) -o $@ $< + $(OBJS_DIR)/%.o: $(UTSBASE)/intel/dtrace/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) @@ -315,6 +318,9 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/intel/brand/sn1/%.s @($(LHEAD) $(LINT.s) $< $(LTAIL)) +$(LINTS_DIR)/%.ln: $(UTSBASE)/intel/brand/solaris10/%.s + @($(LHEAD) $(LINT.s) $< $(LTAIL)) + $(LINTS_DIR)/%.ln: $(UTSBASE)/intel/dtrace/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/intel/brand/solaris10/s10_brand_asm.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,403 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(lint) + +#include <sys/systm.h> + +#else /* lint */ + +#include <sys/asm_linkage.h> +#include <sys/privregs.h> +#include <sys/segments.h> +#include <s10_offsets.h> +#include "assym.h" + +#endif /* lint */ + +#ifdef lint + +void +s10_brand_sysenter_callback(void) +{ +} + +void +s10_brand_syscall_callback(void) +{ +} + +#if defined(__amd64) +void +s10_brand_syscall32_callback(void) +{ +} +#endif /* amd64 */ + +void +s10_brand_int91_callback(void) +{ +} + +#else /* lint */ + +#if defined(__amd64) +/* + * When our syscall interposition callback entry point gets invoked the + * stack looks like this: + * -------------------------------------- + * 40 | user %gs | + * 32 | callback pointer | + * 24 | saved stack pointer | + * | 16 | lwp pointer | + * v 8 | user return address (*) | + * 0 | BRAND_CALLBACK()'s return addr | + * -------------------------------------- + * (*) This is actually just the bottom value from the user's + * stack. syscall puts this in %rcx instead of the stack, + * so it's just garbage for that entry point. + */ + +#define V_COUNT 6 +#define V_END (CLONGSIZE * 6) +#define V_SSP (CLONGSIZE * 3) +#define V_LWP (CLONGSIZE * 2) +#define V_URET_ADDR (CLONGSIZE * 1) +#define V_CB_ADDR (CLONGSIZE * 0) + +#define SP_REG %rsp + +#else /* !__amd64 */ +/* + * When our syscall interposition callback entry point gets invoked the + * stack looks like this: + * -------------------------------------- + * | 24 | 'scratch space' | + * | 20 | user's %ebx | + * | 16 | user's %gs selector | + * | 12 | kernel's %gs selector | + * | 8 | lwp pointer | + * v 4 | user return address | + * 0 | callback wrapper return addr | + * -------------------------------------- + */ + +#define V_COUNT 7 +#define V_END (CLONGSIZE * 7) +#define V_U_GS (CLONGSIZE * 4) +#define V_K_GS (CLONGSIZE * 3) +#define V_LWP (CLONGSIZE * 2) +#define V_URET_ADDR (CLONGSIZE * 1) +#define V_CB_ADDR (CLONGSIZE * 0) + +#define SP_REG %esp + +#endif /* !__amd64 */ + +/* + * The following macros allow us to access to variables/parameters passed + * in on the stack. They take the following variables: + * sp - a register with the current stack pointer value + * pcnt - the number of words currently pushed onto the stack + * var - the variable to lookup + * reg - a register to read the variable into, or + * a register to write to the variable + */ +#define V_OFFSET(pcnt, var) \ + (var + (pcnt * CLONGSIZE)) + +#define GET_V(sp, pcnt, var, reg) \ + mov V_OFFSET(pcnt, var)(sp), reg + +#define SET_V(sp, pcnt, var, reg) \ + mov reg, V_OFFSET(pcnt, var)(sp) + +#define GET_PROCP(sp, pcnt, reg) \ + GET_V(sp, pcnt, V_LWP, reg) /* get lwp pointer */ ;\ + mov LWP_PROCP(reg), reg /* get proc pointer */ + +#define GET_P_BRAND_DATA(sp, pcnt, reg) \ + GET_PROCP(sp, pcnt, reg) ;\ + mov P_BRAND_DATA(reg), reg /* get p_brand_data */ + +/* + * Each of the following macros returns to the standard syscall codepath if + * it detects that this process is not able, or intended, to emulate this + * system call. They all assume that the routine provides a 'bail-out' + * label of '9'. + */ + +/* + * See if this process has a user-space hdlr registered for it. For the + * s10 brand, the per-process brand data holds the address of the handler. + * As shown in the stack diagrams below, the callback code leaves that data + * at these offsets. So check if s10_proc_data_t->spd_handler is non-NULL. + */ +#define CHECK_FOR_HANDLER(scr) \ + GET_P_BRAND_DATA(SP_REG, 1, scr) /* get p_brand_data */ ;\ + cmp $0, scr ;\ + je 9f ;\ + cmp $0, SPD_HANDLER(scr) /* check spd_handler */ ;\ + je 9f + +/* + * If the system call number is >= 1024, then it is coming from the + * emulation support library. As such we should handle it natively instead + * of sending it back to the emulation library. + */ +#define CHECK_FOR_NATIVE(reg) \ + cmp $1024, reg ;\ + jl 1f ;\ + sub $1024, reg ;\ + jmp 9f ;\ +1: + +/* + * Check to see if we want to interpose on this system call. If not, we + * jump back into the normal syscall path and pretend nothing happened. + */ +#define CHECK_FOR_INTERPOSITION(sysr, scr, scr_low) \ + lea s10_emulation_table, scr ;\ + mov (scr), scr ;\ + add sysr, scr ;\ + movb (scr), scr_low ;\ + cmpb $0, scr_low ;\ + je 9f + +#define CALLBACK_PROLOGUE(call, scr, scr_low) \ + push scr /* Save scratch register */ ;\ + CHECK_FOR_HANDLER(scr) ;\ + CHECK_FOR_NATIVE(call) ;\ + CHECK_FOR_INTERPOSITION(call, scr, scr_low) + +/* + * The callback routines: + */ + +#if defined(__amd64) + +/* + * syscall handler for 32-bit user processes: + * %rax - syscall number + * %ecx - the address of the instruction after the syscall + */ +ENTRY(s10_brand_syscall32_callback) + + CALLBACK_PROLOGUE(%rax, %r15, %r15b) + movq %rsp, %r15 /* save our stack pointer */ + + /* + * Adjust the user's stack so that the 'ret' from our user-space + * hdlr takes us to the post-syscall instruction instead of to + * the routine that called the system call. + */ + GET_V(%r15, 1, V_SSP, %rsp) /* restore user's stack pointer */ + subq $4, %rsp /* save room for the post-syscall addr */ + movl %ecx, (%rsp) /* Save post-syscall addr on stack */ + + /* + * To 'return' to our user-space handler, we just need to copy + * its address into %rcx. + */ + GET_P_BRAND_DATA(%r15, 1, %rcx);/* get p_brand_data ptr */ + movq SPD_HANDLER(%rcx), %rcx /* get p_brand_data->spd_handler ptr */ + movq (%r15), %r15 /* Restore scratch register */ + jmp nopop_sys_syscall32_swapgs_sysretl +9: + popq %r15 + retq +SET_SIZE(s10_brand_syscall32_callback) + +/* + * syscall handler for 64-bit user processes: + * %rax - syscall number + * %rcx - user space %rip + */ +ENTRY(s10_brand_syscall_callback) + + CALLBACK_PROLOGUE(%rax, %r15, %r15b) + movq %rsp, %r15 /* save our stack pointer */ + + GET_V(%r15, 1, V_SSP, %rsp) /* restore user's stack pointer */ + subq $8, %rsp /* save room for the post-syscall addr */ + movq %rcx, (%rsp) /* Save post-syscall addr on stack */ + + /* + * To 'return' to our user-space handler, we just need to copy + * its address into %rcx. + */ + GET_P_BRAND_DATA(%r15, 1, %rcx);/* get p_brand_data ptr */ + movq SPD_HANDLER(%rcx), %rcx /* get p_brand_data->spd_handler ptr */ + movq (%r15), %r15 /* Restore scratch register */ + jmp nopop_sys_syscall_swapgs_sysretq +9: + popq %r15 + retq + +SET_SIZE(s10_brand_syscall_callback) + +/* + * %eax - syscall number + * %ecx - user space %esp + * %edx - user space return address + */ +ENTRY(s10_brand_sysenter_callback) + + CALLBACK_PROLOGUE(%rax, %r15, %r15b) + + subl $4, %ecx /* Save room for user ret addr */ + movl %edx, (%rcx) /* Save current return addr */ + GET_P_BRAND_DATA(%rsp, 1, %rdx) /* get p_brand_data */ + movq SPD_HANDLER(%rdx), %rdx /* get p_brand_data->spd_handler ptr */ + popq %r15 /* Restore scratch register */ + jmp sys_sysenter_swapgs_sysexit +9: + popq %r15 + ret +SET_SIZE(s10_brand_sysenter_callback) + +/* + * The saved stack pointer points at the state saved when we took + * the interrupt: + * -------------------------------------- + * | 32 | user's %ss | + * | 24 | user's %esp | + * | 16 | EFLAGS register | + * v 8 | user's %cs | + * 0 | user's %eip | + * -------------------------------------- + */ +ENTRY(s10_brand_int91_callback) + + CALLBACK_PROLOGUE(%rax, %r15, %r15b) + pushq %rax /* Save scratch register */ + + GET_P_BRAND_DATA(%rsp, 2, %r15) /* get p_brand_data */ + movq SPD_HANDLER(%r15), %r15 /* get s10_proc_data->spd_handler ptr */ + GET_V(%rsp, 2, V_SSP, %rax) /* Get saved %esp */ + movq %r15, (%rax) /* replace iret target address with hdlr */ + + /* + * Adjust the caller's stack so we return to the instruction after + * the syscall on the next 'ret' in userspace - not to the parent + * routine. + */ + movq 24(%rax), %r15 /* Get user's %esp */ + subq $4, %r15 /* Make room for new ret addr */ + movq %r15, 24(%rax) /* Replace current with updated %esp */ + + GET_V(%rsp, 2, V_URET_ADDR, %rax) + movl %eax, (%r15) /* Put it on the user's stack */ + + popq %rax /* Restore scratch register */ + popq %r15 /* Restore scratch register */ + movq V_SSP(%rsp), %rsp /* Remove callback stuff from stack */ + jmp sys_sysint_swapgs_iret +9: + popq %r15 + retq +SET_SIZE(s10_brand_int91_callback) + +#else /* !__amd64 */ + +/* + * lcall handler for 32-bit OS + * %eax - syscall number + * + * Above the stack contents common to all callbacks is the + * int/lcall-specific state: + * -------------------------------------- + * | 44 | user's %ss | + * | 40 | user's %esp | + * | 36 | EFLAGS register | + * v 32 | user's %cs | + * 28 | user's %eip | + * -------------------------------------- + */ +#define V_U_SS (V_END + (CLONGSIZE * 4)) +#define V_U_ESP (V_END + (CLONGSIZE * 3)) +#define V_EFLAGS (V_END + (CLONGSIZE * 2)) +#define V_U_CS (V_END + (CLONGSIZE * 1)) +#define V_U_EIP (V_END + (CLONGSIZE * 0)) + +ENTRY(s10_brand_syscall_callback) + + CALLBACK_PROLOGUE(%eax, %ebx, %bl) + pushl %eax /* Save scratch register */ + + /* replace iret target address with user-space hdlr */ + GET_P_BRAND_DATA(%esp, 2, %ebx) /* get p_brand_data ptr */ + movl SPD_HANDLER(%ebx), %ebx /* get p_brand_data->spd_handler ptr */ + SET_V(%esp, 2, V_U_EIP, %ebx) /* set iret target address to hdlr */ + + /* + * Adjust the caller's stack so we return to the instruction after + * the syscall on the next 'ret' in userspace - not to the parent + * routine. + */ + GET_V(%esp, 2, V_URET_ADDR, %ebx) /* Get new post-syscall ret addr */ + GET_V(%esp, 2, V_U_ESP, %eax) /* Get user %esp */ + subl $4, %eax /* Make room for new ret addr */ + SET_V(%esp, 2, V_U_ESP, %eax) /* Updated user %esp */ + movl %ebx, (%eax) /* Put new ret addr on user stack */ + + GET_V(%esp, 2, V_U_GS, %ebx) /* grab the the user %gs */ + movw %bx, %gs /* restore the user %gs */ + + popl %eax /* Restore scratch register */ + popl %ebx /* Restore scratch register */ + addl $V_END, %esp /* Remove all callback stuff from stack */ + jmp nopop_sys_rtt_syscall +9: + popl %ebx + ret +SET_SIZE(s10_brand_syscall_callback) + +/* + * %eax - syscall number + * %ecx - user space %esp + * %edx - user space return address + */ +ENTRY(s10_brand_sysenter_callback) + + CALLBACK_PROLOGUE(%eax, %ebx, %bl) + + subl $4, %ecx /* Save room for user ret addr */ + movl %edx, (%ecx) /* Save current return addr */ + GET_P_BRAND_DATA(%esp, 1, %edx) /* get p_brand_data */ + movl SPD_HANDLER(%edx), %edx /* get p_brand_data->spd_handler */ + + GET_V(%esp, 1, V_U_GS, %ebx) /* grab the the user %gs */ + movw %bx, %gs /* restore the user %gs */ + + popl %ebx /* Restore scratch register */ + sysexit +9: + popl %ebx + ret +SET_SIZE(s10_brand_sysenter_callback) + +#endif /* !__amd64 */ +#endif /* lint */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/intel/s10_brand/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,106 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This makefile drives the production of the kernel component of +# the Solaris 10 brand +# + +# +# Path to the base of the uts directory tree (usually /usr/src/uts). +# +UTSBASE = ../.. +S10_BASE = $(UTSBASE)/common/brand/solaris10 + +# +# Define the module and object file sets. +# +MODULE = s10_brand +OFFSETS_H = $(OBJS_DIR)/s10_offsets.h +OFFSETS_SRC = $(S10_BASE)/s10_offsets.in +OBJECTS = $(S10_BRAND_OBJS:%=$(OBJS_DIR)/%) +LINTS = $(S10_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln) +ROOTMODULE = $(USR_BRAND_DIR)/$(MODULE) + +# +# Include common rules. +# +include $(UTSBASE)/intel/Makefile.intel + +# +# Define targets +# +ALL_TARGET = $(OFFSETS_H) $(BINARY) +LINT_TARGET = $(MODULE).lint +INSTALL_TARGET = $(OFFSETS_H) $(BINARY) $(ROOTMODULE) + + +# +# Update compiler variables. +# +INC_PATH += -I$(S10_BASE) -I$(OBJS_DIR) +AS_INC_PATH += -I$(UTSBASE)/i86pc/genassym/$(OBJS_DIR) +LDFLAGS += -dy -Nexec/elfexec + +# +# Ugh, this is a gross hack. s10_brand_asm.s uses lots of defines +# to simplify variable access. All these defines work fine for amd64 +# compiles because when compiling for amd64 we use the GNU assembler, +# gas. For 32-bit code we use the Sun assembler, as. Unfortunatly +# as does not handle certian constructs that gas does. So rather than +# make our code less readable, we'll just use gas to compile our 32-bit +# code as well. +# +i386_AS = $(amd64_AS) + +# +# Default build targets. +# +.KEEP_STATE: + +def: $(DEF_DEPS) + +all: $(ALL_DEPS) + +clean: $(CLEAN_DEPS) + +clobber: $(CLOBBER_DEPS) + +lint: $(LINT_DEPS) + +modlintlib: $(MODLINTLIB_DEPS) + +clean.lint: $(CLEAN_LINT_DEPS) + +install: $(INSTALL_DEPS) + +# +# Create genassym.h +# +$(OFFSETS_H): $(OFFSETS_SRC) + $(OFFSETS_CREATE) <$(OFFSETS_SRC) >$@ + +# +# Include common targets. +# +include $(UTSBASE)/intel/Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/sun4/brand/solaris10/s10_brand_asm.s Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,290 @@ +/* + * 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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(lint) + +#include <sys/systm.h> + +void +s10_brand_syscall32_callback(void) +{ +} + +void +s10_brand_syscall_callback(void) +{ +} + +#else /* !lint */ + +#include <sys/asm_linkage.h> +#include <sys/machthread.h> +#include <sys/privregs.h> +#include <s10_offsets.h> +#include "assym.h" + +#if defined(sun4v) + +#define GLOBALS_SWAP(reg) \ + rdpr %gl, reg ;\ + wrpr reg, 1, %gl + +/* + * The GLOBALS_RESTORE macro can only be one instruction since it's + * used in a delay slot. + */ +#define GLOBALS_RESTORE(reg) \ + wrpr reg, 0, %gl + +#else /* !sun4v */ + +#define GLOBALS_SWAP(reg) \ + rdpr %pstate, reg ;\ + wrpr reg, PSTATE_AG, %pstate + +/* + * The GLOBALS_RESTORE macro can only be one instruction since it's + * used in a delay slot. + */ +#define GLOBALS_RESTORE(reg) \ + wrpr reg, %g0, %pstate + +#endif /* !sun4v */ + + /* + * Input parameters: + * %g1: return point + * %g2: pointer to our cpu structure + */ + ENTRY(s10_brand_syscall32_callback) + /* + * If the trapping thread has the address mask bit clear, then it's + * a 64-bit process, and has no business calling 32-bit syscalls. + */ + rdpr %tstate, %g3 ! %tstate.am is the trapping + andcc %g3, TSTATE_AM, %g3 ! threads address mask bit + bne,pt %xcc, _entry + nop + jmp %g1 ! 64 bit process, bail out + nop + SET_SIZE(s10_brand_syscall32_callback) + + /* + * Input parameters: + * %g1: return point + * %g2: pointer to our cpu structure + */ + ENTRY(s10_brand_syscall_callback) + /* + * If the trapping thread has the address mask bit set, then it's + * a 32-bit process, and has no business calling 64-bit syscalls. + */ + rdpr %tstate, %g3 ! %tstate.am is the trapping + andcc %g3, TSTATE_AM, %g3 ! threads address mask bit + be,pt %xcc, _entry + nop + jmp %g1 ! 32 bit process, bail out + nop + SET_SIZE(s10_brand_syscall_callback) + + ENTRY(s10_brand_syscall_callback_common) +_entry: + /* + * Input parameters: + * %g1: return point + * %g2: pointer to our cpu structure + * + * Note that we're free to use any %g? registers as long as + * we are are executing with alternate globals. If we're + * executing with user globals we need to backup any registers + * that we want to use so that we can restore them when we're + * done. + * + * Save some locals in the CPU tmp area to give us a little + * room to work. + */ + stn %l0, [%g2 + CPU_TMP1] + stn %l1, [%g2 + CPU_TMP2] + +#if defined(sun4v) + /* + * On sun4v save our input parameters (which are stored in the + * alternate globals) since we'll need to switch between alternate + * globals and normal globals, and on sun4v the alternate globals + * are not preserved across these types of switches. + */ + stn %l2, [%g2 + CPU_TMP3] + stn %l3, [%g2 + CPU_TMP4] + + mov %g1, %l2 ! save %g1 in %l2 + mov %g2, %l3 ! save %g2 in %l3 +#endif /* sun4v */ + + /* + * Switch from the alternate to user globals to grab the syscall + * number. + */ + GLOBALS_SWAP(%l0) ! switch to normal globals + + /* + * If the system call number is >= 1024, then it is a native + * syscall that doesn't need emulation. + */ + cmp %g1, 1024 ! is this a native syscall? + bl,a _indirect_check ! probably not, continue checking + mov %g1, %l1 ! delay slot - grab syscall number + + /* + * This is a native syscall, probably from the emulation library. + * Subtract 1024 from the syscall number and let it go through. + */ + sub %g1, 1024, %g1 ! convert magic num to real syscall + ba _exit ! jump back into syscall path + GLOBALS_RESTORE(%l0) ! delay slot - + ! switch back to alternate globals + +_indirect_check: + /* + * If the system call number is 0 (SYS_syscall), then this might be + * an indirect syscall, in which case the actual syscall number + * would be stored in %o0, in which case we need to redo the + * the whole >= 1024 check. + */ + brnz,pt %g1, _emulation_check ! is this an indirect syscall? + nop ! if not, goto the emulation check + + /* + * Indirect syscalls are only supported for 32 bit processes so + * consult the tstate address mask again. + */ + rdpr %tstate, %l1 ! %tstate.am is the trapping + andcc %l1, TSTATE_AM, %l1 ! threads address mask bit + be,a,pn %xcc, _exit + GLOBALS_RESTORE(%l0) ! delay slot - + ! switch back to alternate globals + + /* + * The caller is 32 bit and this an indirect system call. + */ + cmp %o0, 1024 ! is this a native syscall? + bl,a _emulation_check ! no, goto the emulation check + mov %o0, %l1 ! delay slot - grab syscall number + + /* + * This is native indirect syscall, probably from the emulation library. + * Subtract 1024 from the syscall number and let it go through. + */ + sub %o0, 1024, %o0 ! convert magic num to real syscall + ba _exit ! jump back into syscall path + GLOBALS_RESTORE(%l0) ! delay slot - + ! switch back to alternate globals + +_emulation_check: + GLOBALS_RESTORE(%l0) ! switch back to alternate globals + + /* + * Check to see if we want to interpose on this system call. If + * not, we jump back into the normal syscall path and pretend + * nothing happened. %l1 contains the syscall we're invoking. + */ + set s10_emulation_table, %g3 + ldn [%g3], %g3 + add %g3, %l1, %g3 + ldub [%g3], %g3 + brz %g3, _exit + nop + + /* + * Find the address of the userspace handler. + * cpu->cpu_thread->t_procp->p_brand_data->spd_handler. + */ +#if defined(sun4v) + ! restore the alternate global registers after incrementing %gl + mov %l3, %g2 +#endif /* sun4v */ + ldn [%g2 + CPU_THREAD], %g3 ! get thread ptr + ldn [%g3 + T_PROCP], %g4 ! get proc ptr + ldn [%g4 + P_BRAND_DATA], %g5 ! get brand data ptr + ldn [%g5 + SPD_HANDLER], %g5 ! get userland brand handler ptr + brz %g5, _exit ! has it been set? + nop + + /* + * Make sure this isn't an agent lwp. We can't do syscall + * interposition for system calls made by a agent lwp. See + * the block comments in the top of the brand emulation library + * for more information. + */ + ldn [%g4 + P_AGENTTP], %g4 ! get agent thread ptr + cmp %g3, %g4 ! is this an agent thread? + be,pn %xcc, _exit ! if so don't emulate + nop + + /* + * Now the magic happens. Grab the trap return address and then + * reset it to point to the user space handler. When we execute + * the 'done' instruction, we will jump into our handler instead of + * the user's code. We also stick the old return address in %g5, + * so we can return to the proper instruction in the user's code. + * Note: we also pass back the base address of the syscall + * emulation table. This is a performance hack to avoid having to + * look it up on every call. + */ + rdpr %tnpc, %l1 ! save old tnpc + wrpr %g0, %g5, %tnpc ! setup tnpc + GLOBALS_SWAP(%l0) ! switch to normal globals + mov %l1, %g5 ! pass tnpc to user code in %g5 + GLOBALS_RESTORE(%l0) ! switch back to alternate globals + + /* Update the address we're going to return to */ +#if defined(sun4v) + set fast_trap_done_chk_intr, %l2 +#else /* !sun4v */ + set fast_trap_done_chk_intr, %g1 +#endif /* !sun4v */ + +_exit: + /* + * Restore registers before returning. + * + * Note that %g2 should be loaded with the CPU struct addr and + * %g1 should be loaded the address we're going to return to. + */ +#if defined(sun4v) + ! restore the alternate global registers after incrementing %gl + mov %l2, %g1 ! restore %g1 from %l2 + mov %l3, %g2 ! restore %g2 from %l3 + + ldn [%g2 + CPU_TMP4], %l3 ! restore locals + ldn [%g2 + CPU_TMP3], %l2 +#endif /* sun4v */ + + ldn [%g2 + CPU_TMP2], %l1 ! restore locals + ldn [%g2 + CPU_TMP1], %l0 + + jmp %g1 + nop + SET_SIZE(s10_brand_syscall_callback_common) +#endif /* !lint */
--- a/usr/src/uts/sun4u/Makefile.files Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/sun4u/Makefile.files Thu Oct 22 11:21:27 2009 -0700 @@ -186,6 +186,7 @@ # Brand modules # SN1_BRAND_OBJS = sn1_brand.o sn1_brand_asm.o +S10_BRAND_OBJS = s10_brand.o s10_brand_asm.o # # Performance Counter BackEnd (PCBE) Modules
--- a/usr/src/uts/sun4u/Makefile.rules Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/sun4u/Makefile.rules Thu Oct 22 11:21:27 2009 -0700 @@ -20,11 +20,9 @@ # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# # This Makefile defines the build rules for the directory uts/sun4u # and its children. These are the source files which sun4u # "implementation architecture" dependent. @@ -108,6 +106,9 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/sun4/brand/sn1/%.s $(COMPILE.s) -o $@ $< +$(OBJS_DIR)/%.o: $(UTSBASE)/sun4/brand/solaris10/%.s + $(COMPILE.s) -o $@ $< + $(OBJS_DIR)/%.o: $(UTSBASE)/sun4u/vm/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) @@ -223,6 +224,9 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/sun4/brand/sn1/%.s @($(LHEAD) $(LINT.s) $< $(LTAIL)) +$(LINTS_DIR)/%.ln: $(UTSBASE)/sun4/brand/solaris10/%.s + @($(LHEAD) $(LINT.s) $< $(LTAIL)) + $(LINTS_DIR)/%.ln: $(UTSBASE)/sun4u/vm/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL))
--- a/usr/src/uts/sun4u/Makefile.sun4u.shared Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/sun4u/Makefile.sun4u.shared Thu Oct 22 11:21:27 2009 -0700 @@ -441,7 +441,7 @@ # # Brand modules # -BRAND_KMODS += sn1_brand +BRAND_KMODS += sn1_brand s10_brand # # Software Cryptographic Providers (/kernel/crypto):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/sun4u/s10_brand/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,93 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This makefile drives the production of the kernel component of +# the Solaris 10 brand +# + +# +# Path to the base of the uts directory tree (usually /usr/src/uts). +# +UTSBASE = ../.. +S10_BASE = $(UTSBASE)/common/brand/solaris10 + +# +# Define the module and object file sets. +# +MODULE = s10_brand +OFFSETS_H = $(OBJS_DIR)/s10_offsets.h +OFFSETS_SRC = $(S10_BASE)/s10_offsets.in +OBJECTS = $(S10_BRAND_OBJS:%=$(OBJS_DIR)/%) +LINTS = $(S10_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln) +ROOTMODULE = $(ROOT_PSM_BRAND_DIR)/$(MODULE) + +# +# Include common rules. +# +include $(UTSBASE)/sun4u/Makefile.sun4u + +# +# Define targets +# +ALL_TARGET = $(OFFSETS_H) $(BINARY) +LINT_TARGET = $(MODULE).lint +INSTALL_TARGET = $(OFFSETS_H) $(BINARY) $(ROOTMODULE) + +# +# Update compiler variables. +# +INC_PATH += -I$(S10_BASE) -I$(OBJS_DIR) +LDFLAGS += -dy -Nexec/elfexec + +# +# Default build targets. +# +.KEEP_STATE: + +def: $(DEF_DEPS) + +all: $(ALL_DEPS) + +clean: $(CLEAN_DEPS) + +clobber: $(CLOBBER_DEPS) + +lint: $(LINT_DEPS) + +modlintlib: $(MODLINTLIB_DEPS) + +clean.lint: $(CLEAN_LINT_DEPS) + +install: $(INSTALL_DEPS) + +# +# Create genassym.h +# +$(OFFSETS_H): $(OFFSETS_SRC) + $(OFFSETS_CREATE) <$(OFFSETS_SRC) >$@ + +# +# Include common targets. +# +include $(UTSBASE)/sun4u/Makefile.targ
--- a/usr/src/uts/sun4v/Makefile.files Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/sun4v/Makefile.files Thu Oct 22 11:21:27 2009 -0700 @@ -173,6 +173,7 @@ # Brand modules # SN1_BRAND_OBJS = sn1_brand.o sn1_brand_asm.o +S10_BRAND_OBJS = s10_brand.o s10_brand_asm.o # # Performance Counter BackEnd (PCBE) Modules
--- a/usr/src/uts/sun4v/Makefile.rules Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/sun4v/Makefile.rules Thu Oct 22 11:21:27 2009 -0700 @@ -20,11 +20,9 @@ # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# # This Makefile defines the build rules for the directory uts/sun4v # and its children. These are the source files which sun4v # "implementation architecture" dependent. @@ -65,6 +63,9 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/sun4/brand/sn1/%.s $(COMPILE.s) -o $@ $< +$(OBJS_DIR)/%.o: $(UTSBASE)/sun4/brand/solaris10/%.s + $(COMPILE.s) -o $@ $< + $(OBJS_DIR)/%.o: $(UTSBASE)/sun4v/promif/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) @@ -213,6 +214,9 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/sun4/brand/sn1/%.s @($(LHEAD) $(LINT.s) $< $(LTAIL)) +$(LINTS_DIR)/%.ln: $(UTSBASE)/sun4/brand/solaris10/%.s + @($(LHEAD) $(LINT.s) $< $(LTAIL)) + $(LINTS_DIR)/%.ln: $(UTSBASE)/sun4v/promif/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL))
--- a/usr/src/uts/sun4v/Makefile.sun4v.shared Thu Oct 22 09:11:59 2009 -0600 +++ b/usr/src/uts/sun4v/Makefile.sun4v.shared Thu Oct 22 11:21:27 2009 -0700 @@ -407,7 +407,7 @@ # # Brand modules # -BRAND_KMODS += sn1_brand +BRAND_KMODS += sn1_brand s10_brand # # Software Cryptographic Providers (/kernel/crypto):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/sun4v/s10_brand/Makefile Thu Oct 22 11:21:27 2009 -0700 @@ -0,0 +1,93 @@ +# +# 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 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This makefile drives the production of the kernel component of +# the Solaris 10 brand +# + +# +# Path to the base of the uts directory tree (usually /usr/src/uts). +# +UTSBASE = ../.. +S10_BASE = $(UTSBASE)/common/brand/solaris10 + +# +# Define the module and object file sets. +# +MODULE = s10_brand +OFFSETS_H = $(OBJS_DIR)/s10_offsets.h +OFFSETS_SRC = $(S10_BASE)/s10_offsets.in +OBJECTS = $(S10_BRAND_OBJS:%=$(OBJS_DIR)/%) +LINTS = $(S10_BRAND_OBJS:%.o=$(LINTS_DIR)/%.ln) +ROOTMODULE = $(ROOT_PSM_BRAND_DIR)/$(MODULE) + +# +# Include common rules. +# +include $(UTSBASE)/sun4v/Makefile.sun4v + +# +# Define targets +# +ALL_TARGET = $(OFFSETS_H) $(BINARY) +LINT_TARGET = $(MODULE).lint +INSTALL_TARGET = $(OFFSETS_H) $(BINARY) $(ROOTMODULE) + +# +# Update compiler variables. +# +INC_PATH += -I$(S10_BASE) -I$(OBJS_DIR) +LDFLAGS += -dy -Nexec/elfexec + +# +# Default build targets. +# +.KEEP_STATE: + +def: $(DEF_DEPS) + +all: $(ALL_DEPS) + +clean: $(CLEAN_DEPS) + +clobber: $(CLOBBER_DEPS) + +lint: $(LINT_DEPS) + +modlintlib: $(MODLINTLIB_DEPS) + +clean.lint: $(CLEAN_LINT_DEPS) + +install: $(INSTALL_DEPS) + +# +# Create genassym.h +# +$(OFFSETS_H): $(OFFSETS_SRC) + $(OFFSETS_CREATE) <$(OFFSETS_SRC) >$@ + +# +# Include common targets. +# +include $(UTSBASE)/sun4v/Makefile.targ