4194 need to make installadm tool changes for SPARC
authorSue Sohn <Susan.Sohn@Sun.COM>
Thu, 08 Jan 2009 13:23:22 -0700
changeset 400 f7861b6d6614
parent 399 f78a9ed16216
child 401 2f6d4bf63451
4194 need to make installadm tool changes for SPARC
usr/src/cmd/installadm/Makefile
usr/src/cmd/installadm/create-client.sh
usr/src/cmd/installadm/installadm-common.sh
usr/src/cmd/installadm/installadm.c
usr/src/cmd/installadm/installadm.h
usr/src/cmd/installadm/setup-dhcp.sh
usr/src/cmd/installadm/setup-sparc.sh
usr/src/cmd/installadm/setup-tftp-links.sh
usr/src/pkgdefs/SUNWinstalladm-tools/prototype_com
--- a/usr/src/cmd/installadm/Makefile	Thu Jan 08 11:49:29 2009 -0700
+++ b/usr/src/cmd/installadm/Makefile	Thu Jan 08 13:23:22 2009 -0700
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -44,6 +44,7 @@
 		setup-image \
 		setup-dhcp \
 		setup-service \
+		setup-sparc \
 		setup-tftp-links
 
 HDRS	=	installadm.h
--- a/usr/src/cmd/installadm/create-client.sh	Thu Jan 08 11:49:29 2009 -0700
+++ b/usr/src/cmd/installadm/create-client.sh	Thu Jan 08 13:23:22 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.
 
 #
@@ -36,16 +36,17 @@
 #          service. The administrator can set up manifiests with that service
 #          to serve the clients.
 #
-#       2. Creates a bootfile and /tftpboot entries. The bootfile name is
-#          derived from the MAC address.
+#       2. For x86, creates a bootfile and /tftpboot entries. The bootfile
+#	   name is derived from the MAC address.
+#	   For sparc, setup wanboot files and create wanboot.conf
 #
-#       3. Setup the dhcp macro with the bootfile information if it doesn't
-#          exist.
+#       3. Setup the dhcp macro with the server and bootfile (and rootpath
+#	   for sparc) information if it doesn't exist.
 #
 # Files potentially changed on server:
 # /tftpboot/ - directory created/populated with pxegrub files and links.
 # /etc/inetd.conf - to turn on tftpboot daemon
-
+# /etc/netboot/<network number>/<MACID>/wanboot.conf
 
 # make sure path is ok
 PATH=/usr/bin:/usr/sbin:/sbin:${PATH}; export PATH
@@ -228,11 +229,6 @@
 fi
 
 
-# Set BUILD for menu.lst file in /tftpboot (create_menu_lst_file)
-#
-BUILD=`basename ${IMAGE_PATH}`
-
-
 # Verify that IMAGE_PATH is a valid directory
 #
 if [ ! -d ${IMAGE_PATH} ]; then
@@ -240,7 +236,6 @@
     exit 1
 fi
 
-
 # Verify valid image
 #
 if [ ! -f ${IMAGE_PATH}/solaris.zlib ]; then
@@ -249,9 +244,20 @@
 	exit 1
 fi
 
-# Append "boot" to IMAGE_PATH provided by user
+
+# Determine if image is sparc or x86
 #
-IMAGE_PATH=${IMAGE_PATH}/boot
+IMAGE_TYPE=`get_image_type ${IMAGE_PATH}`
+
+# For sparc, make sure the user hasn't specified a boot file via
+# the "-f" option. If they have, the BOOT_FILE variable will be set.
+#
+if [ "${IMAGE_TYPE}" = "${SPARC_IMAGE}" ]; then
+	if [ "X$BOOT_FILE" != "X" ] ; then
+	    echo "${myname}: \"-f\" is an invalid option for SPARC"
+	    exit 1
+	fi
+fi
 
 # Verify that service corresponding to SERVICE_NAME exists
 #
@@ -262,11 +268,6 @@
 fi
 
 
-# lofs mount /boot directory under /tftpboot
-#
-mount_lofs_boot
-
-
 # Convert the Ethernet address to DHCP "default client-ID" form:
 #    uppercase hex, preceded by the hardware
 #    address type ("01" for ethernet)
@@ -282,146 +283,180 @@
 		}
 	}'`
 
-# CLEAN file is used so delete-client can undo the setup
-#
-CLEAN="${Bootdir}/rm.${DHCP_CLIENT_ID}"
-CLEANUP_FOR="${MAC_ADDR}"
+
 
-# if config file already exists, run the cleanup - before checking tftpboot
+# Perform x86/sparc specific setup activities
 #
-if [ -f "${CLEAN}" ] ; then
-    # do the cleanup (of old stuff)
-    if [ ! -x ${DIRNAME}/delete-client ] ; then
-        echo "WARNING: could not execute: ${DIRNAME}/delete-client"
-        echo "  cannot clean up preexisting install client \"${CLEANUP_FOR}\""
-        echo "  continuing anyway"
-    else
-        echo "Cleaning up preexisting install client \"${CLEANUP_FOR}\""
-        ${DIRNAME}/delete-client -q ${CLEANUP_FOR}
-    fi
-fi
+if [ "${IMAGE_TYPE}" = "${X86_IMAGE}" ]; then
+	echo "Setting up X86 client..." 
+	# lofs mount /boot directory under /tftpboot
+	#
+	mount_lofs_boot
+
+
+	# CLEAN file is used so delete-client can undo the setup
+	#
+	CLEAN="${Bootdir}/rm.${DHCP_CLIENT_ID}"
+	CLEANUP_FOR="${MAC_ADDR}"
+
+	# if config file already exists, run the cleanup - before
+	# checking tftpboot
+	#
+	if [ -f "${CLEAN}" ] ; then
+	    # do the cleanup (of old stuff)
+	    if [ ! -x ${DIRNAME}/delete-client ] ; then
+	        echo "WARNING: could not execute: ${DIRNAME}/delete-client"
+	        echo "  cannot clean up preexisting install client, " 
+	        echo "  \"${CLEANUP_FOR}\", continuing anyway"
+	    else
+	        echo "Cleaning up preexisting install client \"${CLEANUP_FOR}\""
+	        ${DIRNAME}/delete-client -q ${CLEANUP_FOR}
+	    fi
+	fi
+
+	# Obtain a unique name for file in tftpboot dir.
+	#
+	aBootfile=${IMAGE_PATH}/boot/grub/pxegrub
+	Bootfile=`tftp_file_name $aBootfile pxegrub`
 
-# Obtain a unique name for file in tftpboot dir.
-#
-aBootfile=${IMAGE_PATH}/grub/pxegrub
-Bootfile=`tftp_file_name $aBootfile pxegrub`
+	# If the caller has specified a boot file name, we're going to
+	# eventually create a symlink from the pxegrub file to the caller
+	# specified name.  If that link already exists, make sure it points
+	# to the boot file we're going to use.
+	#
+	if [ "X$BOOT_FILE" != "X" ] ; then
+	    if [ -h "${Bootdir}/$BOOT_FILE" -a \
+				! -f "${Bootdir}/$BOOT_FILE" ] ; then
+		    echo "ERROR: Specified boot file ${BOOT_FILE} already"
+		    echo "       exists, but does not point to anything."
+		    exit 1
+	    fi
 
-# If the caller has specified a boot file name, we're going to eventually
-# create a symlink from the pxegrub file to the caller specified name.  If
-# that link already exists, make sure it points to the boot file we're
-# going to use.
-#
-if [ "X$BOOT_FILE" != "X" ] ; then
-	if [ -h "${Bootdir}/$BOOT_FILE" -a ! -f "${Bootdir}/$BOOT_FILE" ] ; then
-		echo "ERROR: Specified boot file ${BOOT_FILE} already exists, "
-		echo "       but does not point to anything."
-		exit 1
+	    if [ -f "${Bootdir}/$BOOT_FILE" ] ; then
+		    cmp -s "${Bootdir}/${Bootfile}" "${Bootdir}/${BOOT_FILE}"
+		    if [ $? != 0 ] ; then
+			    echo "ERROR: Specified boot file ${BOOT_FILE}"
+			    echo "       already exists and is of a different" 
+			    echo "       version than the one needed for this"
+			    echo "       client."
+			    exit 1
+		    fi
+	    fi
+   	fi
+
+	# Create the boot file area, if not already created
+	#
+	if [ ! -d "${Bootdir}" ]; then
+	    echo "making ${Bootdir}"
+	    mkdir ${Bootdir}
+	    chmod 775 ${Bootdir}
 	fi
 
-	if [ -f "${Bootdir}/$BOOT_FILE" ] ; then
-		cmp -s "${Bootdir}/${Bootfile}" "${Bootdir}/${BOOT_FILE}"
-		if [ $? != 0 ] ; then
-			echo "ERROR: Specified boot file ${BOOT_FILE} already ,"
-			echo "       exists and is of a different version than" 
-			echo "       the one needed for this client."
-			exit 1
-		fi
-	fi
-fi
+	# start tftpd if needed
+	#
+	start_tftpd
+
+
+	# start creating clean up file
+	#
+	echo "#!/sbin/sh" > ${CLEAN}			# (re)create it
+	echo "# cleanup file for ${CLEANUP_FOR} - sourced by installadm " \
+	    "delete-client"  >> ${CLEAN}
 
-# Create the boot file area, if not already created
-#
-if [ ! -d "${Bootdir}" ]; then
-	echo "making ${Bootdir}"
-	mkdir ${Bootdir}
-	chmod 775 ${Bootdir}
-fi
+	# install boot program (pxegrub)
+	if [ ! -f ${Bootdir}/${Bootfile} ]; then
+	    echo "copying boot file to ${Bootdir}/${Bootfile}"
+	    cp ${aBootfile} ${Bootdir}/${Bootfile}
+	    chmod 755 ${Bootdir}/${Bootfile}
+	fi
 
-# start tftpd if needed
-#
-start_tftpd
+	# create tftp symlink to bootfile
+	#
+	Menufile=${Bootdir}/menu.lst.${DHCP_CLIENT_ID}
+	setup_tftp "${DHCP_CLIENT_ID}" "${Bootfile}"
+
+
+	# create the menu.lst.<macaddr> file
+	#
+	create_menu_lst_file
+
+
+	# prepare for cleanup action
+	#
+	printf "rm -f ${Menufile}\n" >> ${CLEAN}
 
 
-# start creating clean up file
-#
-echo "#!/sbin/sh" > ${CLEAN}			# (re)create it
-echo "# cleanup file for ${CLEANUP_FOR} - sourced by installadm delete-client" \
-	>> ${CLEAN}
+	# Make tftpboot symlink if caller specified boot file
+	#
+	if [ "X$BOOT_FILE" != "X" ] ; then
+	    # Link from the pxegrub file to the user-specified name
+	    # We don't want to use setup_tftp because we don't want
+	    # to save removal commands in the cleanup file
+	    #
+	    ln -s ${Bootfile} ${Bootdir}/$BOOT_FILE
 
-# install boot program (pxegrub)
-if [ ! -f ${Bootdir}/${Bootfile} ]; then
-	echo "copying boot file to ${Bootdir}/${Bootfile}"
-	cp ${aBootfile} ${Bootdir}/${Bootfile}
-	chmod 755 ${Bootdir}/${Bootfile}
-fi
-
-# create tftp symlink to bootfile
-#
-Menufile=${Bootdir}/menu.lst.${DHCP_CLIENT_ID}
-setup_tftp "${DHCP_CLIENT_ID}" "${Bootfile}"
-
-
-# create the menu.lst.<macaddr> file
-#
-create_menu_lst_file
+	    cat <<-EOF >>${CLEAN}
+		if [ -h "${Bootdir}/${BOOT_FILE}" -o \
+				-f "${Bootdir}/${BOOT_FILE}" ] ; then
+		    echo "Not removing manually specified boot file"
+		    echo "\"${BOOT_FILE}\" because other clients may be"
+		    echo "using it."
+		else
+		    echo "The pxegrub file corresponding to the boot file,"
+		    echo "\"${BOOT_FILE}\", does not exist."
+		    echo "Deleting \"${BOOT_FILE}\"."
+		    rm -f ${Bootdir}/${BOOT_FILE}
+		fi
+		EOF
+	fi
 
 
-# prepare for cleanup action
-#
-if [ "X${DHCP_CLIENT_ID}" != "X" ]; then
-	printf "rm -f ${Menufile}\n" >> ${CLEAN}
-fi
-
-
-# Make tftpboot symlink if caller specified boot file
-#
-if [ "X$BOOT_FILE" != "X" ] ; then
-	# Link from the pxegrub file to the user-specified name
-	# We don't want to use setup_tftp because we don't want
-	# to save removal commands in the cleanup file
+	# Set value of DHCP_BOOT_FILE.
+	DHCP_BOOT_FILE=${DHCP_CLIENT_ID}
+	if [ "X${BOOT_FILE}" != "X" ] ; then
+	    DHCP_BOOT_FILE=${BOOT_FILE}
+	fi
+	dhcptype="x86"
+	dhcprootpath="x86"
+else
+	echo "Setting up SPARC client..." 
+	# For sparc, set value of DHCP_BOOT_FILE and setup wanboot.conf file.
 	#
-	ln -s ${Bootfile} ${Bootdir}/$BOOT_FILE
-
-	cat <<-EOF >>${CLEAN}
-		if [ -h "${Bootdir}/${BOOT_FILE}" -o -f "${Bootdir}/${BOOT_FILE}" ] ; then
-		    echo "Not removing manually specified boot file \"${BOOT_FILE}\""
-		    echo "because other clients may be using it."
-		else
-		    echo "The pxegrub file corresponding to the boot file \"${BOOT_FILE}\""
-		    echo "does not exist.  Deleting \"${BOOT_FILE}\"."
-		    rm -f ${Bootdir}/${BOOT_FILE}
-		fi
-	EOF
+	DHCP_BOOT_FILE="http://${SERVER_IP}:${HTTP_PORT}/${CGIBIN_WANBOOTCGI}"
+	${DIRNAME}/setup-sparc client ${DHCP_CLIENT_ID} ${IMAGE_PATH}
+	status=$?
+	if [ $status -ne 0 ]; then
+		echo "${myname}: Unable to setup SPARC client"
+		exit 1
+	fi
+	dhcptype="sparc"
+	dhcprootpath="http://${SERVER_IP}:${HTTP_PORT}${IMAGE_PATH}"
 fi
 
 
 # Try to update the DHCP server automatically. If not possible,
 # then tell the user how to define the DHCP macro.
 #
-DHCP_BOOT_FILE=${DHCP_CLIENT_ID}
-if [ "X${BOOT_FILE}" != "X" ] ; then
-	DHCP_BOOT_FILE=${BOOT_FILE}
-fi
-
-status=0
-if [ ! -x ${DIRNAME}/setup-dhcp ]; then
-	status=1
-else
-	${DIRNAME}/setup-dhcp client ${SERVER_IP} ${DHCP_CLIENT_ID} \
-							 ${DHCP_BOOT_FILE}
-	status=$?
-fi
+${DIRNAME}/setup-dhcp client ${dhcptype} ${SERVER_IP} ${DHCP_CLIENT_ID} \
+				${DHCP_BOOT_FILE} ${dhcprootpath}
+status=$?
 
 if [ $status -eq 0 ]; then
-	echo "Enabled PXE boot by adding a macro named ${DHCP_CLIENT_ID}"
+	echo "Enabled network boot by adding a macro named ${DHCP_CLIENT_ID}"
 	echo "to DHCP server with:"
-	echo "  Boot server IP (BootSrvA) : ${SERVER_IP}"
-	echo "  Boot file      (BootFile) : ${DHCP_BOOT_FILE}"
+	echo "  Boot server IP     (BootSrvA) : ${SERVER_IP}"
+	echo "  Boot file          (BootFile) : ${DHCP_BOOT_FILE}"
+	if [ "${IMAGE_TYPE}" = "${SPARC_IMAGE}" ]; then
+		echo "  Root path          (Rootpath) : ${dhcprootpath}"
+	fi
 else
-	echo "If not already configured, enable PXE boot by creating"
+	echo "If not already configured, enable network boot by creating"
 	echo "a macro named ${DHCP_CLIENT_ID} with:"
-	echo "  Boot server IP (BootSrvA) : ${SERVER_IP}"
-	echo "  Boot file      (BootFile) : ${DHCP_BOOT_FILE}"
+	echo "  Boot server IP     (BootSrvA) : ${SERVER_IP}"
+	echo "  Boot file          (BootFile) : ${DHCP_BOOT_FILE}"
+	if [ "${IMAGE_TYPE}" = "${SPARC_IMAGE}" ]; then
+		echo "  Root path          (Rootpath) : ${dhcprootpath}"
+	fi
 fi
 
 exit 0
--- a/usr/src/cmd/installadm/installadm-common.sh	Thu Jan 08 11:49:29 2009 -0700
+++ b/usr/src/cmd/installadm/installadm-common.sh	Thu Jan 08 13:23:22 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.
 #
 # Description:
@@ -37,6 +37,11 @@
 VERSION=OpenSolaris
 HTTP_PORT=5555
 
+SPARC_IMAGE="sparc_image"
+X86_IMAGE="x86_image"
+DOT_RELEASE=".release"
+CGIBIN_WANBOOTCGI="cgi-bin/wanboot-cgi"
+
 #
 # get_host_ip
 #
@@ -50,7 +55,7 @@
 get_host_ip()
 {
 	hname=$1
-	HOST_IP=`getent hosts ${hname} | nawk '{ print $1 }`
+	HOST_IP=`getent hosts ${hname} | nawk '{ print $1 }'`
 	echo "$HOST_IP"
 }
 
@@ -72,6 +77,30 @@
 }
 
 #
+# get_image_type
+#
+# Purpose : Determine if image is sparc or x86
+#
+# Arguments : 
+#	$1 - path to image
+#
+# Returns: "sparc_image" or "x86_image"
+#
+get_image_type()
+{
+	image_path=$1
+	if [ -f ${image_path}/boot/sparc.microroot ]; then
+		image_type="${SPARC_IMAGE}"
+	elif [ -f ${image_path}/boot/x86.microroot ]; then
+		image_type="${X86_IMAGE}"
+	else 
+		echo "Missing microroot file, invalid OpenSolaris install image"
+		exit 1
+	fi
+	echo "$image_type"
+}
+
+#
 # clean_entry
 #
 # Purpose : Cleanup the /tftpboot files corresponding the entry
@@ -115,9 +144,9 @@
 #
 get_relinfo()
 {
-	releasepath=$1/.release
+	releasepath=$1/${DOT_RELEASE}
 	if [ -f ${releasepath} ]; then
-		releaseinfo=`head -1 ${releasepath} | sed -e 's/  //g'`
+		releaseinfo=`head -1 ${releasepath}`
 	else
 		releaseinfo=$VERSION
 	fi
@@ -127,45 +156,50 @@
 #
 # create_menu_lst_file
 #
-# Purpose : Create the menu.lst file so that the client can get the information
-#	    about the netimage and dwonload the necessary files.
+# Purpose : Create the menu.lst file so that the x86 client can get the
+#	    information about the netimage and download the necessary files.
 #	    It also adds location of the kernel, microroot and other options.
 #
 # Arguments : 
-#	None. But expected $Menufile is set to correct file.
-#
+#	None, but it is expected that:
+#		$Menufile is set to the correct file.
+#		$IMAGE_PATH is set to the absolute path of the image.
+#		$SERVICE_NAME is set to the service name.
+#		$IMAGE_IP is set to the IP of the server hosting the image.
 #
 create_menu_lst_file()
 {
+
 	# create the menu.lst.<bootfile> file
 	#
-	touch ${Menufile}
-	grep "kernel /${BootLofs}/x86.microroot" ${Menufile} > /dev/null 2>&1
-	if [ $? != 0 ]; then
-		printf "default=0\n" > $Menufile
-		printf "timeout=30\n" >> $Menufile
-		dir=`dirname "${IMAGE_PATH}"`
-		relinfo=`get_relinfo $dir`
-		printf "title ${relinfo} \n" >> $Menufile
+	tmpmenu=${Menufile}.$$
+
+	printf "default=0\n" > ${tmpmenu}
+	printf "timeout=30\n" >> ${tmpmenu}
 
-		printf "\tkernel\$ /${BootLofs}/platform/i86pc/kernel/\$ISADIR/unix -B ${BARGLIST}" >> $Menufile
+	# get release info and strip leading spaces
+	relinfo=`get_relinfo ${IMAGE_PATH}`
+	title=`echo title ${relinfo} | sed -e 's/  //g'`
+	printf "${title} \n" >> ${tmpmenu}
+
+	printf "\tkernel\$ /${BootLofs}/platform/i86pc/kernel/\$ISADIR/unix -B ${BARGLIST}" >> ${tmpmenu}
 
-		# add install media path, install boot archive,
-		# and service name
-		#
-		printf "install_media=" >> $Menufile
-		printf "http://${IMAGE_IP}:${HTTP_PORT}" >> $Menufile
-		printf "${dir}" >> $Menufile	
-		printf ",install_boot=" >> $Menufile
-		printf "http://${IMAGE_IP}:${HTTP_PORT}" >> $Menufile
-		printf "${IMAGE_PATH}" >> $Menufile
+	# add install media path and service name
+	#
+	printf "install_media=" >> ${tmpmenu}
+	printf "http://${IMAGE_IP}:${HTTP_PORT}" >> ${tmpmenu}
+	printf "${IMAGE_PATH}" >> ${tmpmenu}	
 
-		printf ",install_service=" >> $Menufile
-		printf "${SERVICE_NAME}"  >> $Menufile
+	printf ",install_service=" >> ${tmpmenu}
+	printf "${SERVICE_NAME}"  >> ${tmpmenu}
 
-		printf ",livemode=text\n" >> $Menufile
-		printf "\tmodule /${BootLofs}/x86.microroot\n" >> $Menufile
-	fi
+	printf ",livemode=text\n" >> ${tmpmenu}
+	printf "\tmodule /${BootLofs}/x86.microroot\n" >> ${tmpmenu}
+
+        mv ${tmpmenu} ${Menufile}
+
+        return 0
+
 }
 
 #
@@ -176,8 +210,8 @@
 #	    mounted.
 #
 # Arguments : 
-#	None. But expected $IMAGE_PATH is set to the netimage and
-#	$Bootdir is set to /tftpboot
+#	None. But it is expected that $IMAGE_PATH is set to the netimage
+#	and $Bootdir is set to /tftpboot
 #
 #
 mount_lofs_boot()
@@ -185,14 +219,15 @@
 	# lofs mount /boot directory under /tftpboot
 	# First, check if it is already mounted
 	#
-	line=`grep "^${IMAGE_PATH}[ 	]" /etc/vfstab`
+	IMAGE_BOOTDIR=${IMAGE_PATH}/boot
+	line=`grep "^${IMAGE_BOOTDIR}[ 	]" /etc/vfstab`
 	if [ $? = 0 ]; then
 		# already mounted
 		mountpt=`echo $line | cut -d ' ' -f3`
 		BootLofs=`basename "${mountpt}"`
 		BootLofsdir=`dirname "${mountpt}"`
 		if [ ${BootLofsdir} != ${Bootdir} ]; then
-			printf "${myname}: ${IMAGE_PATH} mounted at"
+			printf "${myname}: ${IMAGE_BOOTDIR} mounted at"
 			printf " ${mountpt}\n"
 			printf "${myname}: retry after unmounting and deleting"
 			printf " entry form /etc/vfstab\n"
@@ -212,7 +247,7 @@
 			mount $mountpt
 		fi
 	else
-		# Not mounted. Get a new directory name and mount IMAGE_PATH
+		# Not mounted. Get a new directory name and mount IMAGE_BOOTDIR
 		max=0
 		for i in ${Bootdir}/I86PC.${VERSION}* ; do
 			max_num=`expr $i : ".*boot.I86PC.${VERSION}-\(.*\)"`
@@ -224,13 +259,13 @@
 
 		BootLofs=I86PC.${VERSION}-${max}
 		mkdir -p ${Bootdir}/${BootLofs}
-		mount -F lofs -o ro ${IMAGE_PATH} ${Bootdir}/${BootLofs}
+		mount -F lofs -o ro ${IMAGE_BOOTDIR} ${Bootdir}/${BootLofs}
 		if [ $? != 0 ]; then
-			echo "${myname}: failed to mount ${IMAGE_PATH} on" \
+			echo "${myname}: failed to mount ${IMAGE_BOOTDIR} on" \
 			   "${Bootdir}/${BootLofs}"
 			exit 1
 		fi
-		printf "${IMAGE_PATH} - ${Bootdir}/${BootLofs} " >> /etc/vfstab
+		printf "${IMAGE_BOOTDIR} - ${Bootdir}/${BootLofs} " >> /etc/vfstab
 		printf "lofs - yes ro\n" >> /etc/vfstab
 	fi
 }
--- a/usr/src/cmd/installadm/installadm.c	Thu Jan 08 11:49:29 2009 -0700
+++ b/usr/src/cmd/installadm/installadm.c	Thu Jan 08 13:23:22 2009 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -205,6 +205,7 @@
 	boolean_t	create_netimage = B_FALSE;
 	boolean_t	use_remote_dhcp_server = B_FALSE;
 	boolean_t	create_service = B_FALSE;
+	boolean_t	have_sparc = B_FALSE;
 
 	char		*boot_file = NULL;
 	char		*ip_start = NULL;
@@ -216,6 +217,7 @@
 
 	struct stat	stat_buf;
 	char		cmd[MAXPATHLEN];
+	char		mpath[MAXPATHLEN];
 	char		bfile[MAXPATHLEN];
 	char		srv_name[MAXPATHLEN];
 	char		txt_record[DATALEN];
@@ -361,6 +363,22 @@
 	}
 
 	/*
+	 * Check whether image is sparc or x86
+	 */
+	(void) snprintf(mpath, sizeof (mpath), "%s/%s", target_directory,
+			"boot/sparc.microroot");
+	if (access(mpath, F_OK) == 0) {
+		have_sparc = B_TRUE;
+	} else {
+		(void) snprintf(mpath, sizeof (mpath), "%s/%s",
+			target_directory, "boot/x86.microroot");
+		if (access(mpath, F_OK) != 0) {
+			(void) fprintf(stderr, MSG_MISSING_MICROROOT_ERR);
+			return (INSTALLADM_FAILURE);
+		}
+	}
+
+	/*
 	 * The net-image is created, now start the service
 	 * If the user provided the name of the service, use it
 	 */
@@ -448,6 +466,8 @@
 		struct	hostent	*hp;
 		char	server_ip[128];
 		struct in_addr in;
+		char	dhcpbfile[MAXPATHLEN];
+		char	dhcprpath[MAXPATHLEN];
 
 		if (gethostname(host, sizeof (host)) != 0) {
 			(void) fprintf(stderr, MSG_GET_HOSTNAME_FAIL);
@@ -469,9 +489,25 @@
 		snprintf(dhcp_macro, sizeof (dhcp_macro),
 		    "dhcp_macro_%s", bfile);
 
-		snprintf(cmd, sizeof (cmd), "%s %s %s %s %s",
-		    SETUP_DHCP_SCRIPT, DHCP_MACRO,
-		    server_ip, dhcp_macro, bfile);
+		/*
+		 * determine contents of bootfile info passed to dhcp script
+		 * as well as rootpath for sparc
+		 */
+		if (have_sparc) {
+			snprintf(dhcpbfile, sizeof (dhcpbfile),
+				"http://%s:%s/%s", server_ip, HTTP_PORT,
+				WANBOOTCGI);
+			snprintf(dhcprpath, sizeof (dhcprpath),
+				"http://%s:%s%s", server_ip, HTTP_PORT,
+				target_directory);
+		} else {
+			strlcpy(dhcpbfile, bfile, sizeof (dhcpbfile));
+		}
+
+		snprintf(cmd, sizeof (cmd), "%s %s %s %s %s %s %s",
+		    SETUP_DHCP_SCRIPT, DHCP_MACRO, have_sparc?"sparc":"x86",
+		    server_ip, dhcp_macro, dhcpbfile,
+		    have_sparc?dhcprpath:"x86");
 		if (installadm_system(cmd) != 0) {
 			(void) fprintf(stderr,
 			    MSG_ASSIGN_DHCP_MACRO_ERR);
@@ -492,12 +528,27 @@
 		/* handle later */
 	}
 
-	snprintf(cmd, sizeof (cmd), "%s %s %s %s",
-	    SETUP_TFTP_LINKS_SCRIPT, srv_name, target_directory, bfile);
-	if (installadm_system(cmd) != 0) {
+	/*
+	 * Perform sparc/x86 specific actions.
+	 */
+	if (have_sparc) {
+	    /* sparc only */
+	    snprintf(cmd, sizeof (cmd), "%s %s %s %s",
+		SETUP_SPARC_SCRIPT, SPARC_SERVER, target_directory, srv_name);
+	    if (installadm_system(cmd) != 0) {
+		(void) fprintf(stderr, MSG_SETUP_SPARC_FAIL);
+		return (INSTALLADM_FAILURE);
+	    }
+	} else {
+	    /* x86 only */
+	    snprintf(cmd, sizeof (cmd), "%s %s %s %s",
+		SETUP_TFTP_LINKS_SCRIPT, srv_name, target_directory, bfile);
+	    if (installadm_system(cmd) != 0) {
 		(void) fprintf(stderr, MSG_CREATE_TFTPBOOT_FAIL);
 		return (INSTALLADM_FAILURE);
+	    }
 	}
+
 	/*
 	 * Register the information about the service, image and boot file
 	 * so that it can be used later
--- a/usr/src/cmd/installadm/installadm.h	Thu Jan 08 11:49:29 2009 -0700
+++ b/usr/src/cmd/installadm/installadm.h	Thu Jan 08 13:23:22 2009 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -58,6 +58,11 @@
 
 #define	SETUP_TFTP_LINKS_SCRIPT	"/usr/lib/installadm/setup-tftp-links"
 
+#define	SETUP_SPARC_SCRIPT	"/usr/lib/installadm/setup-sparc"
+#define	SPARC_SERVER		"server"
+#define HTTP_PORT		"5555"
+#define	WANBOOTCGI		"cgi-bin/wanboot-cgi"
+
 #define	AI_SERVICE_DATA		"/var/installadm/service_data"
 #define	LOCALHOST		"127.0.0.1"
 /*
@@ -106,6 +111,8 @@
 	"Cannot access directory %s, error = %d.\n")
 #define	MSG_CREATE_IMAGE_ERR	INSTALLADMSTR(\
 	"Create image failed.\n")
+#define	MSG_MISSING_MICROROOT_ERR	INSTALLADMSTR(\
+	"Missing microroot file, invalid OpenSolaris install image.\n")
 #define	MSG_REGISTER_SERVICE_FAIL	INSTALLADMSTR(\
 	"Failed to register Install Service %s.\n")
 #define	MSG_LIST_SERVICE_FAIL	INSTALLADMSTR(\
@@ -122,6 +129,8 @@
 	"Failed to assign DHCP macro to IP address. Please assign manually.\n")
 #define	MSG_CREATE_TFTPBOOT_FAIL	INSTALLADMSTR(\
 	"Failed to setup the TFTP bootfile.\n")
+#define	MSG_SETUP_SPARC_FAIL	INSTALLADMSTR(\
+	"Failed to setup the SPARC configuration file.\n")
 #define	MSG_REMOVE_SERVICE_FAIL		INSTALLADMSTR(\
 	"Failed to delete Install Service %s.\n")
 #define	MSG_SERVICE_DATA_FILE_FAIL	INSTALLADMSTR(\
--- a/usr/src/cmd/installadm/setup-dhcp.sh	Thu Jan 08 11:49:29 2009 -0700
+++ b/usr/src/cmd/installadm/setup-dhcp.sh	Thu Jan 08 13:23:22 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.
 
 # Description:
@@ -40,6 +40,7 @@
 TMP_DHCP=/tmp/installadm.dhtadm-P.$$
 BOOTSRVA="BootSrvA"
 BOOTFILE="BootFile"
+ROOTPATH="Rootpath"
 INCLUDE="Include"
 GRUBMENU="GrubMenu"
 macro_value=""
@@ -84,6 +85,8 @@
 	macro=$1
 	svr_ipaddr=$2
 	bootfile=$3
+	rootpath=$4
+	sparc=$5
 	menu_lst_file="menu.lst.${bootfile}"
 	
 	echo "  If the site specific symbol GrubMenu is not present,"
@@ -93,21 +96,46 @@
 	echo "  Additionally, create a DHCP macro named ${macro} with:"
 	echo "  Boot server IP (BootSrvA) : ${svr_ipaddr}"
 	echo "  Boot file      (BootFile) : ${bootfile}"
-	echo "  GRUB Menu      (GrubMenu) : ${menu_lst_file}"
+	if [  "$sparc" ]; then
+		echo "  Root path      (Rootpath) : ${rootpath}"
+	else
+		echo "  GRUB Menu      (GrubMenu) : ${menu_lst_file}"
+	fi
 }
 
 #
-# The X86 macro needs only Boot server address and the bootfile
+# Set up the dhcp macro
+#    Both sparc/x86 use boot server address and boot file, but contents of
+#    boot file differ between sparc/x86. In addition, sparc uses the dhcp
+#    macro symbol, Rootpath,  and x86 uses dhcp macro symbol, GrubMenu,
+#    which are defined by ROOTPATH and GRUBMENU, respectively.
 # 
-setup_x86_dhcp_macro()
+setup_dhcp_macro()
 {
 	caller=$1
 	name=$2
 	svr_ipaddr=$3
 	bootfile=$4
-	menu_lst_file="menu.lst.${bootfile}"
+	rootpath=$5
+	sparc=$6
+
 	server_name=`uname -n`
 
+	bootfilesave="${bootfile}"
+	rootpathsave="${rootpath}"
+	if [ "$sparc" ]; then
+		# For sparc, bootfile and rootpath are urls, and contain
+		# an embedded colon. Enclose bootpath and rootpath
+		# in quotes so that the colon doesn't terminate the
+		# macro string.
+		bootfile="\"${bootfile}\""
+		rootpath="\"${rootpath}\""
+	else
+		# set menu.lst for x86
+		menu_lst_file="menu.lst.${bootfile}"
+	fi
+
+
 	$DHTADM -P > ${TMP_DHCP} 2>&1
 	if [ $? -ne 0 ]; then
 		#
@@ -118,13 +146,17 @@
 			return 1
 		fi
 		echo "Could not retrieve DHCP information from dhcp server"
-		print_dhcp_macro_info $name $svr_ipaddr $bootfile
+		print_dhcp_macro_info $name $svr_ipaddr $bootfilesave $rootpathsave $sparc
 		return 1
 	fi
 	update_macro_value ${INCLUDE} ${server_name}
 	update_macro_value ${BOOTSRVA} ${svr_ipaddr}
 	update_macro_value ${BOOTFILE} ${bootfile}
-	update_macro_value ${GRUBMENU} ${menu_lst_file}
+	if [ "$sparc" ]; then
+		update_macro_value ${ROOTPATH} ${rootpath}
+	else
+		update_macro_value ${GRUBMENU} ${menu_lst_file}
+	fi
 	add_macro $name $macro_value
 }
 
@@ -246,11 +278,17 @@
 		status=$?
 	fi
 elif [ "$1" = "macro" ]; then
-	srv_ip=$2
-	macro=$3
-	boot_file=$4
+	imgtype=$2	# x86 or sparc
+	srv_ip=$3
+	macro=$4
+	boot_file=$5
+	rpath=$6
 
-	setup_x86_dhcp_macro $1 $macro $srv_ip $boot_file
+	sparc=
+	if [ "${imgtype}" = "sparc" ]; then
+		sparc="true"
+	fi
+	setup_dhcp_macro $1 $macro $srv_ip $boot_file $rpath $sparc
 	status=$?
 elif [ "$1" = "assign" ]; then
 	client_ip_start=$2
@@ -260,12 +298,18 @@
 	assign_dhcp_macro $macro $client_ip_start $ip_count	
 	status=$?
 elif [ "$1" = "client" ]; then
-	srv_ip=$2
-	macro=$3
-	boot_file=$4
-	client_ip=$5
-
-	setup_x86_dhcp_macro $1 $macro $srv_ip $boot_file
+	imgtype=$2	# x86 or sparc
+	srv_ip=$3
+	macro=$4
+	boot_file=$5
+	rpath=$6
+	client_ip=$7
+	
+	sparc=
+	if [ "${imgtype}" = "sparc" ]; then
+		sparc="true"
+	fi
+	setup_dhcp_macro $1 $macro $srv_ip $boot_file $rpath $sparc
 	status=$?
 	if [ $status -eq 0 -a "X${client_ip}" != "X" ]; then
 		assign_dhcp_macro $macro $client_ip 1	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/installadm/setup-sparc.sh	Thu Jan 08 13:23:22 2009 -0700
@@ -0,0 +1,175 @@
+#!/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.
+
+# Description:
+#	This script sets up the wanboot.conf file which is used
+#	to boot the sparc netimage.
+#
+# Files potentially changed on server:
+# /etc/netboot - directory created
+# /etc/netboot/<network number> - directory created
+# /etc/netboot/wanboot.conf - file created
+# /etc/netboot/<network number>/<MACID>/wanboot.conf - file created 
+# <image>/install.conf - file created 
+
+. /usr/lib/installadm/installadm-common
+
+
+NETBOOTDIR="/etc/netboot"
+WANBOOTCGI="/usr/lib/inet/wanboot/wanboot-cgi"
+CGIBINDIR="/var/ai/image-server/cgi-bin"
+
+
+#
+# Create the install.conf file (replace if it already exists)
+#
+# Arguments:
+#	$1 - Name of service
+#	$2 - Absolute path to image (where file will be placed)
+#
+create_installconf()
+{
+	svcname=$1
+	image_path=$2
+
+	installconf=${image_path}/install.conf
+	tmpconf=${installconf}.$$
+
+	printf "install_service=" > ${tmpconf}
+	printf "${svcname}\n" >> ${tmpconf}
+
+	# Rename the tmp file to the real thing
+	mv ${tmpconf} ${installconf}
+
+	return 0
+}
+
+#
+# Create the wanboot.conf file (replace if it already exists)
+#
+# Arguments:
+#	$1 - directory in which to place the wanboot.conf file
+#	$2 - ip address of server
+#	$3 - Absolute path to image
+#
+create_wanbootconf()
+{
+	confdir=$1
+	svr_ip=$2
+	image_path=$3
+
+	wanbootconf=${confdir}/wanboot.conf
+	tmpconf=${wanbootconf}.$$
+	pgrp="sun4v"	# hardcoded for now
+
+	printf "root_server=" > ${tmpconf}
+	printf "http://${svr_ip}:${HTTP_PORT}/" >> ${tmpconf}
+	printf "${CGIBIN_WANBOOTCGI}\n" >> ${tmpconf}
+
+	printf "root_file=" >> ${tmpconf}
+	printf "${image_path}/boot/sparc.microroot\n" >> ${tmpconf}
+
+	printf "boot_file=" >> ${tmpconf}
+	printf "${image_path}/platform/${pgrp}/wanboot\n" >> ${tmpconf}
+
+	printf "encryption_type=\n" >> ${tmpconf}
+	printf "signature_type=\n" >> ${tmpconf}
+	printf "server_authentication=no\n" >> ${tmpconf}
+	printf "client_authentication=no\n" >> ${tmpconf}
+
+	# rename the tmp file to the real thing
+	echo "Creating SPARC configuration file"
+	mv ${tmpconf} ${wanbootconf}
+
+	return 0
+}
+
+		
+#
+# This is an internal function
+# So we expect only limited use
+
+if [ $# -lt 3 ]; then
+	echo "Internal function to manage SPARC setup doesn't have enough data"
+	exit 1
+fi
+
+# get server ip address
+srv_ip=`get_server_ip`
+
+# determine network
+n1=`echo $srv_ip | cut -d'.' -f1-3`
+net=$n1.0
+
+if [ "$1" = "server" ]; then
+	img_path=$2
+	svc_name=$3
+
+	if [ ! -f "${WANBOOTCGI}" ]; then
+		echo "${WANBOOTCGI} does not exist"
+		exit 1
+	fi
+
+	if [ ! -d "${CGIBINDIR}" ]; then
+		echo "${CGIBINDIR} does not exist"
+		exit 1
+	fi
+
+	# copy over wanboot-cgi
+	cp ${WANBOOTCGI} ${CGIBINDIR}
+
+	# create install.conf file at top of image.
+	# it contains the service name
+	#
+	create_installconf $svc_name $img_path
+
+	# create /etc/netboot directories
+	#
+	mkdir -p ${NETBOOTDIR}/${net}
+
+	create_wanbootconf ${NETBOOTDIR} $srv_ip $img_path
+	status=$?
+
+elif [ "$1" = "client" ]; then
+	macid=$2
+	img_path=$3
+
+	# create /etc/netboot sub-directories
+	#
+	wbootdir="${NETBOOTDIR}/${net}/${macid}"
+	mkdir -p ${wbootdir}
+
+	create_wanbootconf $wbootdir $srv_ip $img_path
+	status=$?
+else 
+	echo " $1 - unsupported SPARC setup service action"
+	exit 1
+fi
+
+
+if [ $status -eq 0 ]; then
+	exit 0
+else
+	exit 1
+fi
--- a/usr/src/cmd/installadm/setup-tftp-links.sh	Thu Jan 08 11:49:29 2009 -0700
+++ b/usr/src/cmd/installadm/setup-tftp-links.sh	Thu Jan 08 13:23:22 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.
 
 # Description:
@@ -42,7 +42,8 @@
 fi
 
 SERVICE_NAME=$1
-IMAGE_PATH=$2/boot
+IMAGE_PATH=$2
+IMAGE_BOOT=$2/boot
 BOOT_FILE=$3
 
 Bootdir=/tftpboot
@@ -53,9 +54,7 @@
 IMAGE_IP=`get_server_ip`
 
 # lofs mount /boot directory under /tftpboot
-# First, check if it is already mounted
 #
-
 mount_lofs_boot
 
 # Clean the entry in /tftpboot if there is one already
@@ -63,7 +62,7 @@
 
 # Obtain a unique name for file in tftpboot dir.
 #
-aBootfile=${IMAGE_PATH}/grub/pxegrub
+aBootfile=${IMAGE_BOOT}/grub/pxegrub
 Bootfile=`tftp_file_name $aBootfile pxegrub`
 
 # If the caller has specified a boot file name, we're going to eventually
--- a/usr/src/pkgdefs/SUNWinstalladm-tools/prototype_com	Thu Jan 08 11:49:29 2009 -0700
+++ b/usr/src/pkgdefs/SUNWinstalladm-tools/prototype_com	Thu Jan 08 13:23:22 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.
 #
 #
@@ -46,6 +46,7 @@
 f none usr/lib/installadm/setup-dhcp 755 root bin
 f none usr/lib/installadm/setup-image 755 root bin
 f none usr/lib/installadm/setup-service 755 root bin
+f none usr/lib/installadm/setup-sparc 755 root bin
 f none usr/lib/installadm/setup-tftp-links 755 root bin
 f none usr/lib/installadm/publish-manifest 755 root bin
 f none usr/lib/installadm/delete-manifest 755 root bin
@@ -98,6 +99,7 @@
 d none var 755 root sys
 d none var/ai 755 root sys
 d none var/ai/image-server 755 root sys
+d none var/ai/image-server/cgi-bin 755 root sys
 d none var/ai/image-server/images 755 root sys
 d none var/ai/image-server/logs 755 root sys
 d none var/installadm 755 root sys