PSARC/2008/647 Configurable Hostids for Non-Global Zones
authorjv227347 <Jordan.Vaughan@Sun.com>
Fri, 30 Jan 2009 12:25:48 -0800
changeset 8662 18153249ee93
parent 8661 b1325220ebe7
child 8663 14f7a0ff322b
PSARC/2008/647 Configurable Hostids for Non-Global Zones 6580939 RFE: provide unique hostid for each non-global zone
usr/src/cmd/hostid/hostid.c
usr/src/cmd/zoneadmd/vplat.c
usr/src/cmd/zonecfg/zonecfg.c
usr/src/cmd/zonecfg/zonecfg.h
usr/src/cmd/zonecfg/zonecfg_grammar.y
usr/src/cmd/zonecfg/zonecfg_lex.l
usr/src/head/libzonecfg.h
usr/src/lib/brand/lx/lx_support/lx_support.c
usr/src/lib/libc/port/gen/gethostid.c
usr/src/lib/libzonecfg/common/libzonecfg.c
usr/src/lib/libzonecfg/common/mapfile-vers
usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1
usr/src/lib/libzpool/common/kernel.c
usr/src/lib/libzpool/common/sys/zfs_context.h
usr/src/uts/common/conf/param.c
usr/src/uts/common/fs/nfs/nfs3_srv.c
usr/src/uts/common/fs/nfs/nfs3_vnops.c
usr/src/uts/common/fs/nfs/nfs4_srv.c
usr/src/uts/common/fs/nfs/nfs4_vnops.c
usr/src/uts/common/fs/nfs/nfs_subr.c
usr/src/uts/common/fs/zfs/spa.c
usr/src/uts/common/fs/zfs/spa_config.c
usr/src/uts/common/io/comstar/stmf/stmf.c
usr/src/uts/common/io/lvm/md/md_mddb.c
usr/src/uts/common/io/mms/dda/dda.c
usr/src/uts/common/nfs/nfs.h
usr/src/uts/common/os/sunddi.c
usr/src/uts/common/os/zone.c
usr/src/uts/common/sys/systeminfo.h
usr/src/uts/common/sys/zone.h
usr/src/uts/common/syscall/systeminfo.c
usr/src/uts/i86pc/os/startup.c
usr/src/uts/sun4/os/ddi_impl.c
--- a/usr/src/cmd/hostid/hostid.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/cmd/hostid/hostid.c	Fri Jan 30 12:25:48 2009 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,22 +19,21 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <sys/systeminfo.h>
 
 int
 main(void)
 {
 	long hostval;
 
-	if ((hostval = gethostid()) == -1) {
+	if ((unsigned int)(hostval = gethostid()) == HW_INVALID_HOSTID) {
 		(void) fprintf(stderr, "bad hostid format\n");
 		exit(1);
 	}
--- a/usr/src/cmd/zoneadmd/vplat.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/cmd/zoneadmd/vplat.c	Fri Jan 30 12:25:48 2009 -0800
@@ -71,6 +71,7 @@
 #include <sys/sockio.h>
 #include <sys/stropts.h>
 #include <sys/conf.h>
+#include <sys/systeminfo.h>
 
 #include <libdlpi.h>
 #include <libdllink.h>
@@ -3966,6 +3967,69 @@
 	return (Z_OK);
 }
 
+/*
+ * Sets the hostid of the new zone based on its configured value.  The zone's
+ * zone_t structure must already exist in kernel memory.  'zlogp' refers to the
+ * log used to report errors and warnings and must be non-NULL.  'zone_namep'
+ * is the name of the new zone and must be non-NULL.  'zoneid' is the numeric
+ * ID of the new zone.
+ *
+ * This function returns zero on success and a nonzero error code on failure.
+ */
+static int
+setup_zone_hostid(zlog_t *zlogp, char *zone_namep, zoneid_t zoneid)
+{
+	int res;
+	zone_dochandle_t handle;
+	char hostidp[HW_HOSTID_LEN];
+	unsigned int hostid;
+
+	if ((handle = zonecfg_init_handle()) == NULL) {
+		zerror(zlogp, B_TRUE, "getting zone configuration handle");
+		return (Z_BAD_HANDLE);
+	}
+	if ((res = zonecfg_get_snapshot_handle(zone_namep, handle)) != Z_OK) {
+		zerror(zlogp, B_FALSE, "invalid configuration");
+		zonecfg_fini_handle(handle);
+		return (res);
+	}
+
+	if ((res = zonecfg_get_hostid(handle, hostidp, sizeof (hostidp))) ==
+	    Z_OK) {
+		if (zonecfg_valid_hostid(hostidp) != Z_OK) {
+			zerror(zlogp, B_FALSE,
+			    "zone hostid is not valid: %s", hostidp);
+			zonecfg_fini_handle(handle);
+			return (Z_HOSTID_FUBAR);
+		}
+		hostid = (unsigned int)strtoul(hostidp, NULL, 16);
+		if (zone_setattr(zoneid, ZONE_ATTR_HOSTID, &hostid,
+		    sizeof (hostid)) != 0) {
+			zerror(zlogp, B_TRUE,
+			    "zone hostid is not valid: %s", hostidp);
+			zonecfg_fini_handle(handle);
+			return (Z_SYSTEM);
+		}
+	} else if (res != Z_BAD_PROPERTY) {
+		/*
+		 * Z_BAD_PROPERTY is an acceptable error value (from
+		 * zonecfg_get_hostid()) because it indicates that the zone
+		 * doesn't have a hostid.
+		 */
+		if (res == Z_TOO_BIG)
+			zerror(zlogp, B_FALSE, "hostid string in zone "
+			    "configuration is too large.");
+		else
+			zerror(zlogp, B_TRUE, "fetching zone hostid from "
+			    "configuration");
+		zonecfg_fini_handle(handle);
+		return (res);
+	}
+
+	zonecfg_fini_handle(handle);
+	return (Z_OK);
+}
+
 zoneid_t
 vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd)
 {
@@ -4152,12 +4216,15 @@
 		struct brand_attr attr;
 		char modname[MAXPATHLEN];
 
+		if (setup_zone_hostid(zlogp, zone_name, zoneid) != Z_OK)
+			goto error;
+
 		if ((zone_get_brand(zone_name, attr.ba_brandname,
 		    MAXNAMELEN) != Z_OK) ||
 		    (bh = brand_open(attr.ba_brandname)) == NULL) {
 			zerror(zlogp, B_FALSE,
 			    "unable to determine brand name");
-			return (-1);
+			goto error;
 		}
 
 		/*
@@ -4168,7 +4235,7 @@
 			brand_close(bh);
 			zerror(zlogp, B_FALSE,
 			    "unable to determine brand kernel module");
-			return (-1);
+			goto error;
 		}
 		brand_close(bh);
 
@@ -4182,10 +4249,8 @@
 			}
 		}
 
-		if (setup_zone_rm(zlogp, zone_name, zoneid) != Z_OK) {
-			(void) zone_shutdown(zoneid);
+		if (setup_zone_rm(zlogp, zone_name, zoneid) != Z_OK)
 			goto error;
-		}
 
 		set_mlps(zlogp, zoneid, zcent);
 	}
@@ -4194,8 +4259,10 @@
 	zoneid = -1;
 
 error:
-	if (zoneid != -1)
+	if (zoneid != -1) {
+		(void) zone_shutdown(zoneid);
 		(void) zone_destroy(zoneid);
+	}
 	if (rctlbuf != NULL)
 		free(rctlbuf);
 	priv_freeset(privs);
--- a/usr/src/cmd/zonecfg/zonecfg.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/cmd/zonecfg/zonecfg.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -73,6 +73,7 @@
 #include <libzfs.h>
 #include <sys/brand.h>
 #include <libbrand.h>
+#include <sys/systeminfo.h>
 #include <libdladm.h>
 #include <libinetutil.h>
 
@@ -180,6 +181,7 @@
 	"scheduling-class",
 	"ip-type",
 	"capped-cpu",
+	"hostid",
 	NULL
 };
 
@@ -221,6 +223,7 @@
 	"scheduling-class",
 	"ip-type",
 	"defrouter",
+	"hostid",
 	NULL
 };
 
@@ -332,6 +335,7 @@
 	"set " ALIAS_MAXMSGIDS "=",
 	"set " ALIAS_MAXSEMIDS "=",
 	"set " ALIAS_SHARES "=",
+	"set hostid=",
 	NULL
 };
 
@@ -361,6 +365,7 @@
 	"info max-msg-ids",
 	"info max-sem-ids",
 	"info cpu-shares",
+	"info hostid",
 	NULL
 };
 
@@ -1143,6 +1148,8 @@
 		(void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
 		    pt_to_str(PT_IPTYPE));
 		(void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
+		    pt_to_str(PT_HOSTID));
+		(void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
 		    pt_to_str(PT_MAXLWPS));
 		(void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"),
 		    pt_to_str(PT_MAXSHMMEM));
@@ -1625,6 +1632,7 @@
 	char bootargs[BOOTARGS_MAX];
 	char sched[MAXNAMELEN];
 	char brand[MAXNAMELEN];
+	char hostidp[HW_HOSTID_LEN];
 	char *limitpriv;
 	FILE *of;
 	boolean_t autoboot;
@@ -1728,6 +1736,11 @@
 		}
 	}
 
+	if (zonecfg_get_hostid(handle, hostidp, sizeof (hostidp)) == Z_OK) {
+		(void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET),
+		    pt_to_str(PT_HOSTID), hostidp);
+	}
+
 	if ((err = zonecfg_setipdent(handle)) != Z_OK) {
 		zone_perror(zone, err, B_FALSE);
 		goto done;
@@ -2281,7 +2294,7 @@
 	return (global_zone && (type == RT_ZONENAME || type == RT_ZONEPATH ||
 	    type == RT_AUTOBOOT || type == RT_LIMITPRIV ||
 	    type == RT_BOOTARGS || type == RT_BRAND || type == RT_SCHED ||
-	    type == RT_IPTYPE));
+	    type == RT_IPTYPE || type == RT_HOSTID));
 }
 
 static boolean_t
@@ -2290,7 +2303,7 @@
 	return (global_zone && (type == PT_ZONENAME || type == PT_ZONEPATH ||
 	    type == PT_AUTOBOOT || type == PT_LIMITPRIV ||
 	    type == PT_BOOTARGS || type == PT_BRAND || type == PT_SCHED ||
-	    type == PT_IPTYPE));
+	    type == PT_IPTYPE || type == PT_HOSTID));
 }
 
 void
@@ -3482,6 +3495,12 @@
 	case PT_SHARES:
 		remove_aliased_rctl(PT_SHARES, ALIAS_SHARES);
 		return;
+	case PT_HOSTID:
+		if ((err = zonecfg_set_hostid(handle, NULL)) != Z_OK)
+			z_cmd_rt_perror(CMD_CLEAR, RT_HOSTID, err, B_TRUE);
+		else
+			need_to_commit = B_TRUE;
+		return;
 	default:
 		zone_perror(pt_to_str(type), Z_NO_PROPERTY_TYPE, B_TRUE);
 		long_usage(CMD_CLEAR, B_TRUE);
@@ -3937,6 +3956,8 @@
 			res_type = RT_MAXSEMIDS;
 		} else if (prop_type == PT_SHARES) {
 			res_type = RT_SHARES;
+		} else if (prop_type == PT_HOSTID) {
+			res_type = RT_HOSTID;
 		} else {
 			zerr(gettext("Cannot set a resource-specific property "
 			    "from the global scope."));
@@ -4139,6 +4160,19 @@
 	case RT_SHARES:
 		set_aliased_rctl(ALIAS_SHARES, prop_type, prop_id);
 		return;
+	case RT_HOSTID:
+		if ((err = zonecfg_set_hostid(handle, prop_id)) != Z_OK) {
+			if (err == Z_TOO_BIG) {
+				zerr(gettext("hostid string is too large: %s"),
+				    prop_id);
+				saw_error = B_TRUE;
+			} else {
+				zone_perror(pt_to_str(prop_type), err, B_TRUE);
+			}
+			return;
+		}
+		need_to_commit = B_TRUE;
+		return;
 	case RT_FS:
 		switch (prop_type) {
 		case PT_DIR:
@@ -4653,6 +4687,21 @@
 }
 
 static void
+info_hostid(zone_dochandle_t handle, FILE *fp)
+{
+	char hostidp[HW_HOSTID_LEN];
+
+	/*
+	 * This will display "hostid: " if there isn't a hostid or an
+	 * error occurs while retrieving the hostid from the configuration
+	 * file.
+	 */
+	if (zonecfg_get_hostid(handle, hostidp, sizeof (hostidp)) != Z_OK)
+		hostidp[0] = '\0';
+	(void) fprintf(fp, "%s: %s\n", pt_to_str(PT_HOSTID), hostidp);
+}
+
+static void
 output_fs(FILE *fp, struct zone_fstab *fstab)
 {
 	zone_fsopt_t *this;
@@ -5197,6 +5246,7 @@
 			info_limitpriv(handle, fp);
 			info_sched(handle, fp);
 			info_iptype(handle, fp);
+			info_hostid(handle, fp);
 		}
 		info_aliased_rctl(handle, fp, ALIAS_MAXLWPS);
 		info_aliased_rctl(handle, fp, ALIAS_MAXSHMMEM);
@@ -5294,6 +5344,9 @@
 	case RT_MCAP:
 		info_mcap(handle, fp);
 		break;
+	case RT_HOSTID:
+		info_hostid(handle, fp);
+		break;
 	default:
 		zone_perror(rt_to_str(cmd->cmd_res_type), Z_NO_RESOURCE_TYPE,
 		    B_TRUE);
@@ -5431,6 +5484,7 @@
 	char zonepath[MAXPATHLEN];
 	char sched[MAXNAMELEN];
 	char brand[MAXNAMELEN];
+	char hostidp[HW_HOSTID_LEN];
 	int err, ret_val = Z_OK, arg;
 	int pset_res;
 	boolean_t save = B_FALSE;
@@ -5507,6 +5561,12 @@
 	}
 	(void) zonecfg_endipdent(handle);
 
+	if (zonecfg_get_hostid(handle, hostidp, sizeof (hostidp)) == Z_OK &&
+	    (err = zonecfg_valid_hostid(hostidp)) != Z_OK) {
+		zone_perror(zone, err, B_TRUE);
+		return;
+	}
+
 	if ((err = zonecfg_setfsent(handle)) != Z_OK) {
 		zone_perror(zone, err, B_TRUE);
 		return;
--- a/usr/src/cmd/zonecfg/zonecfg.h	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/cmd/zonecfg/zonecfg.h	Fri Jan 30 12:25:48 2009 -0800
@@ -20,15 +20,13 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #ifndef _ZONECFG_H
 #define	_ZONECFG_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * header file for zonecfg command
  */
@@ -90,9 +88,10 @@
 #define	RT_SCHED	23	/* really a property, but for info ... */
 #define	RT_IPTYPE	24	/* really a property, but for info ... */
 #define	RT_PCAP		25
+#define	RT_HOSTID	26	/* really a property, but for info ... */
 
 #define	RT_MIN		RT_UNKNOWN
-#define	RT_MAX		RT_PCAP
+#define	RT_MAX		RT_HOSTID
 
 /* property types: increment PT_MAX when expanding this list */
 #define	PT_UNKNOWN	0
@@ -131,9 +130,10 @@
 #define	PT_SCHED	33
 #define	PT_IPTYPE	34
 #define	PT_DEFROUTER	35
+#define	PT_HOSTID	36
 
 #define	PT_MIN		PT_UNKNOWN
-#define	PT_MAX		PT_DEFROUTER
+#define	PT_MAX		PT_HOSTID
 
 #define	MAX_EQ_PROP_PAIRS	3
 
--- a/usr/src/cmd/zonecfg/zonecfg_grammar.y	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/cmd/zonecfg/zonecfg_grammar.y	Fri Jan 30 12:25:48 2009 -0800
@@ -21,12 +21,10 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdio.h>
 
 #include "zonecfg.h"
@@ -59,7 +57,7 @@
 %token HELP CREATE EXPORT ADD DELETE REMOVE SELECT SET INFO CANCEL END VERIFY
 %token COMMIT REVERT EXIT SEMICOLON TOKEN ZONENAME ZONEPATH AUTOBOOT POOL NET
 %token FS IPD ATTR DEVICE RCTL SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL
-%token IPTYPE
+%token IPTYPE HOSTID
 %token NAME MATCH PRIV LIMIT ACTION VALUE EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET
 %token OPEN_PAREN CLOSE_PAREN COMMA DATASET LIMITPRIV BOOTARGS BRAND PSET PCAP
 %token MCAP NCPUS IMPORTANCE SHARES MAXLWPS MAXSHMMEM MAXSHMIDS MAXMSGIDS
@@ -71,7 +69,7 @@
 %type <ival> resource_type NET FS IPD DEVICE RCTL ATTR DATASET PSET PCAP MCAP
 %type <ival> property_name SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL NAME
     MATCH ZONENAME ZONEPATH AUTOBOOT POOL LIMITPRIV BOOTARGS VALUE PRIV LIMIT
-    ACTION BRAND SCHED IPTYPE DEFROUTER
+    ACTION BRAND SCHED IPTYPE DEFROUTER HOSTID
 %type <cmd> command
 %type <cmd> add_command ADD
 %type <cmd> cancel_command CANCEL
@@ -542,6 +540,15 @@
 		$$->cmd_res_type = RT_MAXSEMIDS;
 		$$->cmd_prop_nv_pairs = 0;
 	}
+	|	INFO HOSTID
+	{
+		if (($$ = alloc_cmd()) == NULL)
+			YYERROR;
+		cmd = $$;
+		$$->cmd_handler = &info_func;
+		$$->cmd_res_type = RT_HOSTID;
+		$$->cmd_prop_nv_pairs = 0;
+	}
 	|	INFO resource_type property_name EQUAL property_value
 	{
 		if (($$ = alloc_cmd()) == NULL)
@@ -884,6 +891,7 @@
 	| MAXMSGIDS	{ $$ = PT_MAXMSGIDS; }
 	| MAXSEMIDS	{ $$ = PT_MAXSEMIDS; }
 	| SCHED		{ $$ = PT_SCHED; }
+	| HOSTID	{ $$ = PT_HOSTID; }
 
 /*
  * The grammar builds data structures from the bottom up.  Thus various
--- a/usr/src/cmd/zonecfg/zonecfg_lex.l	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/cmd/zonecfg/zonecfg_lex.l	Fri Jan 30 12:25:48 2009 -0800
@@ -21,12 +21,10 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <string.h>
 #include <libintl.h>
 #include "zonecfg.h"
@@ -273,6 +271,9 @@
 <TSTATE>scheduling-class	{ return SCHED; }
 <CSTATE>scheduling-class	{ return SCHED; }
 
+<TSTATE>hostid		{ return HOSTID; }
+<CSTATE>hostid		{ return HOSTID; }
+
 <TSTATE>=	{ return EQUAL; }
 <LSTATE>=	{ return EQUAL; }
 <CSTATE>=	{ return EQUAL; }
--- a/usr/src/head/libzonecfg.h	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/head/libzonecfg.h	Fri Jan 30 12:25:48 2009 -0800
@@ -20,15 +20,13 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #ifndef _LIBZONECFG_H
 #define	_LIBZONECFG_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Zone configuration header file.
  */
@@ -100,6 +98,7 @@
 #define	Z_NO_POOL		47	/* no such pool configured */
 #define	Z_POOL_CREATE		48	/* pool create failed */
 #define	Z_POOL_BIND		49	/* pool bind failed */
+#define	Z_HOSTID_FUBAR		50	/* invalid hostid provided */
 
 /*
  * Warning: these are shared with the admin/install consolidation.
@@ -342,6 +341,13 @@
 extern	int	zonecfg_lookup_nwif(zone_dochandle_t, struct zone_nwiftab *);
 
 /*
+ * Hostid emulation configuration.
+ */
+extern	int	zonecfg_get_hostid(zone_dochandle_t, char *, size_t);
+extern	int	zonecfg_set_hostid(zone_dochandle_t, const char *);
+extern	int	zonecfg_valid_hostid(const char *);
+
+/*
  * Device configuration and rule matching.
  */
 extern	int	zonecfg_add_dev(zone_dochandle_t, struct zone_devtab *);
--- a/usr/src/lib/brand/lx/lx_support/lx_support.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/lib/brand/lx/lx_support/lx_support.c	Fri Jan 30 12:25:48 2009 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -29,7 +29,6 @@
  * intended to be called by users - it is intended to be invoked by the
  * zones utilities.
  */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <ctype.h>
 #include <errno.h>
@@ -44,6 +43,7 @@
 #include <stropts.h>
 #include <sys/ioccom.h>
 #include <sys/stat.h>
+#include <sys/systeminfo.h>
 #include <sys/types.h>
 #include <sys/varargs.h>
 #include <unistd.h>
@@ -444,6 +444,7 @@
 	boolean_t		audio, restart;
 	char			*idev, *odev, *kvers;
 	zone_iptype_t		iptype;
+	char			hostidp[HW_HOSTID_LEN];
 
 	if ((handle = zonecfg_init_handle()) == NULL)
 		lxs_err(gettext("internal libzonecfg.so.1 error"), 0);
@@ -507,6 +508,14 @@
 		    "ip-type"));
 	}
 
+	/*
+	 * Check to see whether the zone has hostid emulation enabled.
+	 */
+	if (zonecfg_get_hostid(handle, hostidp, sizeof (hostidp)) == Z_OK) {
+		zonecfg_fini_handle(handle);
+		lxs_err(gettext("lx zones do not support hostid emulation"));
+	}
+
 	/* Extract any relevant attributes from the config file. */
 	lxs_getattrs(handle, &restart, &audio, &idev, &odev, &kvers);
 	zonecfg_fini_handle(handle);
--- a/usr/src/lib/libc/port/gen/gethostid.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/lib/libc/port/gen/gethostid.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -32,25 +32,25 @@
  * under license from the Regents of the University of California.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include "lint.h"
 #include <sys/types.h>
 #include <sys/systeminfo.h>
 #include <stdlib.h>
 
-#define	HOSTIDLEN	40
-
 long
 gethostid(void)
 {
-	char	name[HOSTIDLEN+1], *end;
-	unsigned long	hostid;
+	char name[HW_HOSTID_LEN], *end;
+	unsigned long hostid;
 
-	if (sysinfo(SI_HW_SERIAL, name, HOSTIDLEN) == -1)
-		return (-1);
+	/*
+	 * HW_INVALID_HOSTID must be cast to an int to ensure that it's sign
+	 * extended to 64 bits in 64-bit builds.
+	 */
+	if (sysinfo(SI_HW_SERIAL, name, sizeof (name)) == -1)
+		return ((int)HW_INVALID_HOSTID);
 	hostid = strtoul(name, &end, 10);
 	if (end == name)
-		return (-1);
+		return ((int)HW_INVALID_HOSTID);
 	return ((long)hostid);
 }
--- a/usr/src/lib/libzonecfg/common/libzonecfg.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/lib/libzonecfg/common/libzonecfg.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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 @@
 #include <sys/nvpair.h>
 #include <sys/types.h>
 #include <sys/sockio.h>
+#include <sys/systeminfo.h>
 #include <ftw.h>
 #include <pool.h>
 #include <libscf.h>
@@ -123,6 +124,7 @@
 #define	DTD_ATTR_MODE		(const xmlChar *) "mode"
 #define	DTD_ATTR_ACL		(const xmlChar *) "acl"
 #define	DTD_ATTR_BRAND		(const xmlChar *) "brand"
+#define	DTD_ATTR_HOSTID		(const xmlChar *) "hostid"
 
 #define	DTD_ENTITY_BOOLEAN	"boolean"
 #define	DTD_ENTITY_DEVPATH	"devpath"
@@ -2340,6 +2342,90 @@
 	return (Z_OK);
 }
 
+/*
+ * Gets the zone hostid string stored in the specified zone configuration
+ * document.  This function returns Z_OK on success.  Z_BAD_PROPERTY is returned
+ * if the config file doesn't specify a hostid or if the hostid is blank.
+ *
+ * Note that buflen should be at least HW_HOSTID_LEN.
+ */
+int
+zonecfg_get_hostid(zone_dochandle_t handle, char *bufp, size_t buflen)
+{
+	int err;
+
+	if ((err = getrootattr(handle, DTD_ATTR_HOSTID, bufp, buflen)) != Z_OK)
+		return (err);
+	if (bufp[0] == '\0')
+		return (Z_BAD_PROPERTY);
+	return (Z_OK);
+}
+
+/*
+ * Sets the hostid string in the specified zone config document to the given
+ * string value.  If 'hostidp' is NULL, then the config document's hostid
+ * attribute is cleared.  Non-NULL hostids are validated.  This function returns
+ * Z_OK on success.  Any other return value indicates failure.
+ */
+int
+zonecfg_set_hostid(zone_dochandle_t handle, const char *hostidp)
+{
+	int err;
+
+	/*
+	 * A NULL hostid string is interpreted as a request to clear the
+	 * hostid.
+	 */
+	if (hostidp == NULL || (err = zonecfg_valid_hostid(hostidp)) == Z_OK)
+		return (setrootattr(handle, DTD_ATTR_HOSTID, hostidp));
+	return (err);
+}
+
+/*
+ * Determines if the specified string is a valid hostid string.  This function
+ * returns Z_OK if the string is a valid hostid string.  It returns Z_INVAL if
+ * 'hostidp' is NULL, Z_TOO_BIG if 'hostidp' refers to a string buffer
+ * containing a hex string with more than 8 digits, and Z_HOSTID_FUBAR if the
+ * string has an invalid format.
+ */
+int
+zonecfg_valid_hostid(const char *hostidp)
+{
+	char *currentp;
+	u_longlong_t hostidval;
+	size_t len;
+
+	if (hostidp == NULL)
+		return (Z_INVAL);
+
+	/* Empty strings and strings with whitespace are invalid. */
+	if (*hostidp == '\0')
+		return (Z_HOSTID_FUBAR);
+	for (currentp = (char *)hostidp; *currentp != '\0'; ++currentp) {
+		if (isspace(*currentp))
+			return (Z_HOSTID_FUBAR);
+	}
+	len = (size_t)(currentp - hostidp);
+
+	/*
+	 * The caller might pass a hostid that is larger than the maximum
+	 * unsigned 32-bit integral value.  Check for this!  Also, make sure
+	 * that the whole string is converted (this helps us find illegal
+	 * characters) and that the whole string fits within a buffer of size
+	 * HW_HOSTID_LEN.
+	 */
+	currentp = (char *)hostidp;
+	if (strncmp(hostidp, "0x", 2) == 0 || strncmp(hostidp, "0X", 2) == 0)
+		currentp += 2;
+	hostidval = strtoull(currentp, &currentp, 16);
+	if ((size_t)(currentp - hostidp) >= HW_HOSTID_LEN)
+		return (Z_TOO_BIG);
+	if (hostidval > UINT_MAX || hostidval == HW_INVALID_HOSTID ||
+	    currentp != hostidp + len)
+		return (Z_HOSTID_FUBAR);
+	return (Z_OK);
+}
+
 int
 zonecfg_lookup_dev(zone_dochandle_t handle, struct zone_devtab *tabptr)
 {
@@ -3373,6 +3459,8 @@
 		    "Could not create a temporary pool"));
 	case Z_POOL_BIND:
 		return (dgettext(TEXT_DOMAIN, "Could not bind zone to pool"));
+	case Z_HOSTID_FUBAR:
+		return (dgettext(TEXT_DOMAIN, "Specified hostid is invalid"));
 	case Z_SYSTEM:
 		return (strerror(errno));
 	default:
--- a/usr/src/lib/libzonecfg/common/mapfile-vers	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/lib/libzonecfg/common/mapfile-vers	Fri Jan 30 12:25:48 2009 -0800
@@ -19,11 +19,9 @@
 # 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.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 
 SUNWprivate_1.1 {
     global:
@@ -106,6 +104,7 @@
 	zonecfg_getdsent;
 	zonecfg_getfsent;
 	zonecfg_get_handle;
+	zonecfg_get_hostid;
 	zonecfg_getipdent;
 	zonecfg_get_iptype;
 	zonecfg_get_limitpriv;
@@ -177,6 +176,7 @@
 	zonecfg_setdevperment;
 	zonecfg_setdsent;
 	zonecfg_setfsent;
+	zonecfg_set_hostid;
 	zonecfg_setipdent;
 	zonecfg_set_iptype;
 	zonecfg_set_limitpriv;
@@ -193,6 +193,7 @@
 	zonecfg_validate_zonename;
 	zonecfg_valid_alias_limit;
 	zonecfg_valid_fs_type;
+	zonecfg_valid_hostid;
 	zonecfg_valid_importance;
 	zonecfg_valid_memlimit;
 	zonecfg_valid_ncpus;
--- a/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1	Fri Jan 30 12:25:48 2009 -0800
@@ -20,10 +20,9 @@
 
  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.
 
- ident	"%Z%%M%	%I%	%E% SMI"
 -->
 
 <!--Element Definitions-->
@@ -132,12 +131,15 @@
 
 <!ATTLIST mcap		physcap		CDATA #REQUIRED>
 
-<!ELEMENT zone		(filesystem | inherited-pkg-dir | network | device | deleted-device | rctl | attr | dataset | package | patch | dev-perm | tmp_pool | pset | mcap)*>
+<!ELEMENT zone		(filesystem | inherited-pkg-dir | network | device |
+			deleted-device | rctl | attr | dataset | package |
+			patch | dev-perm | tmp_pool | pset | mcap)*>
 
 <!ATTLIST zone		name		CDATA #REQUIRED
 			zonepath	CDATA #REQUIRED
 			autoboot	(true | false) #REQUIRED
 			ip-type		CDATA ""
+			hostid		CDATA ""
 			pool		CDATA ""
 			limitpriv	CDATA ""
 			bootargs	CDATA ""
--- a/usr/src/lib/libzpool/common/kernel.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/lib/libzpool/common/kernel.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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,6 +36,7 @@
 #include <sys/zfs_context.h>
 #include <sys/zmod.h>
 #include <sys/utsname.h>
+#include <sys/systeminfo.h>
 
 /*
  * Emulation of kernel services in userland.
@@ -43,7 +44,7 @@
 
 uint64_t physmem;
 vnode_t *rootdir = (vnode_t *)0xabcd1234;
-char hw_serial[11];
+char hw_serial[HW_HOSTID_LEN];
 
 struct utsname utsname = {
 	"userland", "libzpool", "1", "1", "na"
@@ -778,7 +779,7 @@
 	dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
 	    (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
 
-	snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid());
+	(void) snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid());
 
 	VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
 	VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
--- a/usr/src/lib/libzpool/common/sys/zfs_context.h	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/lib/libzpool/common/sys/zfs_context.h	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -490,7 +490,7 @@
 /*
  * Hostname information
  */
-extern char hw_serial[];
+extern char hw_serial[];	/* for userland-emulated hostid access */
 extern int ddi_strtoul(const char *str, char **nptr, int base,
     unsigned long *result);
 
--- a/usr/src/uts/common/conf/param.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/conf/param.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -63,6 +63,7 @@
 #include <sys/cyclic_impl.h>
 #include <sys/disp.h>
 #include <sys/tuneable.h>
+#include <sys/systeminfo.h>
 
 #include <sys/vmem.h>
 #include <sys/clock.h>
@@ -494,6 +495,14 @@
  * System Configuration Information
  */
 
+/*
+ * The physical system's host identifier, expressed as a decimal string.
+ * Code should only directly access this value when writing to it (setting the
+ * physical system's host identifier).  Code that reads the physical system's
+ * host identifier should use zone_get_hostid(NULL) instead.
+ */
+char hw_serial[HW_HOSTID_LEN] = "0";
+
 #if defined(__sparc)
 
 /*
@@ -502,7 +511,6 @@
  */
 char architecture[] = "sparcv9";
 char architecture_32[] = "sparc";
-char hw_serial[11];
 char hw_provider[] = "Sun_Microsystems";
 
 #elif defined(__i386)
@@ -513,7 +521,6 @@
  */
 char architecture[] = "i386";
 char architecture_32[] = "i386";
-char hw_serial[11] = "0";
 char hw_provider[SYS_NMLN] = "";
 
 #elif defined(__amd64)
@@ -524,7 +531,6 @@
  */
 char architecture[] = "amd64";
 char architecture_32[] = "i386";
-char hw_serial[11] = "0";
 char hw_provider[SYS_NMLN] = "";
 
 #else
--- a/usr/src/uts/common/fs/nfs/nfs3_srv.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs3_srv.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -61,6 +61,8 @@
 #include <sys/tsol/label.h>
 #include <sys/tsol/tndb.h>
 
+#include <sys/zone.h>
+
 #include <inet/ip.h>
 #include <inet/ip6.h>
 
@@ -4574,7 +4576,7 @@
 	gethrestime(&now);
 	verfp = (struct rfs3_verf_overlay *)&write3verf;
 	verfp->ts = (int)now.tv_sec;
-	verfp->id = (uint_t)nfs_atoi(hw_serial);
+	verfp->id = zone_get_hostid(NULL);
 
 	if (verfp->id == 0)
 		verfp->id = (uint_t)now.tv_nsec;
--- a/usr/src/uts/common/fs/nfs/nfs3_vnops.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs3_vnops.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -61,6 +61,7 @@
 #include <sys/atomic.h>
 #include <sys/policy.h>
 #include <sys/sdt.h>
+#include <sys/zone.h>
 
 #include <rpc/types.h>
 #include <rpc/auth.h>
@@ -2393,7 +2394,7 @@
 		 * reasonable.
 		 */
 		verfp = (nfstime3 *)&args.how.createhow3_u.verf;
-		verfp->seconds = nfs_atoi(hw_serial);
+		verfp->seconds = zone_get_hostid(NULL);
 		if (verfp->seconds != 0)
 			verfp->nseconds = newnum();
 		else {
--- a/usr/src/uts/common/fs/nfs/nfs4_srv.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_srv.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -54,6 +54,7 @@
 #include <sys/fem.h>
 #include <sys/sdt.h>
 #include <sys/ddi.h>
+#include <sys/zone.h>
 
 #include <rpc/types.h>
 #include <rpc/auth.h>
@@ -521,7 +522,7 @@
 	 * different servers will have the same verifier.
 	 * XXX - this is broken on LP64 kernels.
 	 */
-	verf.tv_sec = (time_t)nfs_atoi(hw_serial);
+	verf.tv_sec = (time_t)zone_get_hostid(NULL);
 	if (verf.tv_sec != 0) {
 		verf.tv_nsec = gethrestime_sec();
 	} else {
--- a/usr/src/uts/common/fs/nfs/nfs4_vnops.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs4_vnops.c	Fri Jan 30 12:25:48 2009 -0800
@@ -62,6 +62,7 @@
 #include <sys/sdt.h>
 #include <sys/list.h>
 #include <sys/stat.h>
+#include <sys/zone.h>
 
 #include <rpc/types.h>
 #include <rpc/auth.h>
@@ -929,7 +930,7 @@
 		open_args->mode = createmode;
 		if (createmode == EXCLUSIVE4) {
 			if (did_excl_setup == FALSE) {
-				verf.seconds = nfs_atoi(hw_serial);
+				verf.seconds = zone_get_hostid(NULL);
 				if (verf.seconds != 0)
 					verf.nseconds = newnum();
 				else {
--- a/usr/src/uts/common/fs/nfs/nfs_subr.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/fs/nfs/nfs_subr.c	Fri Jan 30 12:25:48 2009 -0800
@@ -19,12 +19,10 @@
  * 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.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/systm.h>
@@ -3302,20 +3300,6 @@
 	return (news);
 }
 
-int
-nfs_atoi(char *cp)
-{
-	int n;
-
-	n = 0;
-	while (*cp != '\0') {
-		n = n * 10 + (*cp - '0');
-		cp++;
-	}
-
-	return (n);
-}
-
 /*
  * Snapshot callback for nfs:0:nfs_client as registered with the kstat
  * framework.
--- a/usr/src/uts/common/fs/zfs/spa.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/fs/zfs/spa.c	Fri Jan 30 12:25:48 2009 -0800
@@ -60,6 +60,10 @@
 #include <sys/sunddi.h>
 #include <sys/spa_boot.h>
 
+#ifdef	_KERNEL
+#include <sys/zone.h>
+#endif	/* _KERNEL */
+
 #include "zfs_prop.h"
 #include "zfs_comutil.h"
 
@@ -1222,9 +1226,17 @@
 			VERIFY(nvlist_lookup_string(newconfig,
 			    ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
 
+#ifdef	_KERNEL
+			myhostid = zone_get_hostid(NULL);
+#else	/* _KERNEL */
+			/*
+			 * We're emulating the system's hostid in userland, so
+			 * we can't use zone_get_hostid().
+			 */
 			(void) ddi_strtoul(hw_serial, NULL, 10, &myhostid);
+#endif	/* _KERNEL */
 			if (hostid != 0 && myhostid != 0 &&
-			    (unsigned long)hostid != myhostid) {
+			    hostid != myhostid) {
 				cmn_err(CE_WARN, "pool '%s' could not be "
 				    "loaded as it was last accessed by "
 				    "another system (host: %s hostid: 0x%lx). "
--- a/usr/src/uts/common/fs/zfs/spa_config.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/fs/zfs/spa_config.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -36,6 +36,7 @@
 #include <sys/sunddi.h>
 #ifdef _KERNEL
 #include <sys/kobj.h>
+#include <sys/zone.h>
 #endif
 
 /*
@@ -352,7 +353,15 @@
 	    txg) == 0);
 	VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
 	    spa_guid(spa)) == 0);
+#ifdef	_KERNEL
+	hostid = zone_get_hostid(NULL);
+#else	/* _KERNEL */
+	/*
+	 * We're emulating the system's hostid in userland, so we can't use
+	 * zone_get_hostid().
+	 */
 	(void) ddi_strtoul(hw_serial, NULL, 10, &hostid);
+#endif	/* _KERNEL */
 	if (hostid != 0) {
 		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID,
 		    hostid) == 0);
--- a/usr/src/uts/common/io/comstar/stmf/stmf.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/io/comstar/stmf/stmf.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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,6 +36,7 @@
 #include <sys/ethernet.h>
 #include <sys/sdt.h>
 #include <sys/nvpair.h>
+#include <sys/zone.h>
 
 #include <stmf.h>
 #include <lpif.h>
@@ -463,7 +464,7 @@
 		mutex_enter(&stmf_state.stmf_lock);
 		iocd->stmf_obuf_max_nentries = stmf_state.stmf_nlus;
 		n = min(stmf_state.stmf_nlus,
-				(iocd->stmf_obuf_size)/sizeof (slist_lu_t));
+		    (iocd->stmf_obuf_size)/sizeof (slist_lu_t));
 		iocd->stmf_obuf_nentries = n;
 		ilu = stmf_state.stmf_ilulist;
 		luid_list = (slist_lu_t *)obuf;
@@ -480,7 +481,7 @@
 		mutex_enter(&stmf_state.stmf_lock);
 		iocd->stmf_obuf_max_nentries = stmf_state.stmf_nlports;
 		n = min(stmf_state.stmf_nlports,
-			(iocd->stmf_obuf_size)/sizeof (slist_target_port_t));
+		    (iocd->stmf_obuf_size)/sizeof (slist_target_port_t));
 		iocd->stmf_obuf_nentries = n;
 		ilport = stmf_state.stmf_ilportlist;
 		lportid_list = (slist_target_port_t *)obuf;
@@ -502,7 +503,7 @@
 		}
 		mutex_enter(&stmf_state.stmf_lock);
 		for (ilport = stmf_state.stmf_ilportlist; ilport; ilport =
-				ilport->ilport_next) {
+		    ilport->ilport_next) {
 			uint8_t *id;
 			id = (uint8_t *)ilport->ilport_lport->lport_id;
 			if ((p_id[3] == id[3]) &&
@@ -1224,7 +1225,7 @@
 			if (ilport->ilport_prev_state != STMF_STATE_ONLINE)
 				continue;
 			(void) stmf_ctl(STMF_CMD_LPORT_ONLINE,
-					ilport->ilport_lport, &ssi);
+			    ilport->ilport_lport, &ssi);
 		}
 
 		for (ilu = stmf_state.stmf_ilulist; ilu != NULL;
@@ -1333,7 +1334,7 @@
 
 	additional_size = (additional_size + 7) & (~7);
 	stmf_size = stmf_sizes[struct_id].shared +
-		stmf_sizes[struct_id].fw_private + additional_size;
+	    stmf_sizes[struct_id].fw_private + additional_size;
 
 	sh = (__stmf_t *)kmem_zalloc(stmf_size, kmem_flag);
 
@@ -1681,7 +1682,7 @@
 	}
 
 	for (pppd = &stmf_state.stmf_ppdlist; *pppd != NULL;
-			pppd = &((*pppd)->ppd_next)) {
+	    pppd = &((*pppd)->ppd_next)) {
 		if (*pppd == ppd)
 			break;
 	}
@@ -1898,7 +1899,7 @@
 	}
 	ilport->ilport_tg =
 	    stmf_lookup_group_for_target(lport->lport_id->ident,
-		lport->lport_id->ident_length);
+	    lport->lport_id->ident_length);
 	ilport->ilport_rtpid = atomic_add_16_nv(&stmf_rtpid_counter, 1);
 	STMF_EVENT_ALLOC_HANDLE(ilport->ilport_event_hdl);
 	if (stmf_workers_state == STMF_WORKERS_DISABLED) {
@@ -2007,7 +2008,7 @@
 stmf_deregister_scsi_session(stmf_local_port_t *lport, stmf_scsi_session_t *ss)
 {
 	stmf_i_local_port_t *ilport = (stmf_i_local_port_t *)
-					lport->lport_stmf_private;
+	    lport->lport_stmf_private;
 	stmf_i_scsi_session_t *iss, **ppss;
 	int found = 0;
 
@@ -2019,7 +2020,7 @@
 try_dereg_ss_again:
 	mutex_enter(&stmf_state.stmf_lock);
 	atomic_and_32(&iss->iss_flags,
-		~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
+	    ~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
 	if (iss->iss_flags & ISS_EVENT_ACTIVE) {
 		mutex_exit(&stmf_state.stmf_lock);
 		delay(1);
@@ -2053,10 +2054,10 @@
 
 	mutex_enter(&stmf_state.stmf_lock);
 	for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
-					ilport = ilport->ilport_next) {
+	    ilport = ilport->ilport_next) {
 		rw_enter(&ilport->ilport_lock, RW_WRITER);
 		for (iss = ilport->ilport_ss_list; iss != NULL;
-					iss = iss->iss_next) {
+		    iss = iss->iss_next) {
 			if (iss->iss_ss->ss_session_id == session_id) {
 				if (!stay_locked)
 					rw_exit(&ilport->ilport_lock);
@@ -2081,7 +2082,7 @@
 	ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
 	mutex_enter(&ilu->ilu_task_lock);
 	for (itlpp = &ilu->ilu_itl_list; (*itlpp) != NULL;
-					itlpp = &(*itlpp)->itl_next) {
+	    itlpp = &(*itlpp)->itl_next) {
 		if ((*itlpp) == itl)
 			break;
 	}
@@ -2089,7 +2090,7 @@
 	*itlpp = itl->itl_next;
 	mutex_exit(&ilu->ilu_task_lock);
 	lu->lu_abort(lu, STMF_LU_ITL_HANDLE_REMOVED, itl->itl_handle,
-				(uint32_t)itl->itl_hdlrm_reason);
+	    (uint32_t)itl->itl_hdlrm_reason);
 	kmem_free(itl, sizeof (*itl));
 }
 
@@ -2115,7 +2116,7 @@
 
 	n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
 	lun_map_ent = (stmf_lun_map_ent_t *)
-			stmf_get_ent_from_map(iss->iss_sm, n);
+	    stmf_get_ent_from_map(iss->iss_sm, n);
 	if ((lun_map_ent == NULL) || (lun_map_ent->ent_lu != lu)) {
 		rw_exit(iss->iss_lockp);
 		return (STMF_NOT_FOUND);
@@ -2189,7 +2190,7 @@
 	if (nmaps == 0)
 		return (STMF_NOT_FOUND);
 	itl_list = (stmf_itl_data_t **)kmem_zalloc(
-			nmaps * sizeof (stmf_itl_data_t *), KM_SLEEP);
+	    nmaps * sizeof (stmf_itl_data_t *), KM_SLEEP);
 	mutex_enter(&stmf_state.stmf_lock);
 	if (nmaps != ilu->ilu_ref_cnt) {
 		/* Something changed, start all over */
@@ -2199,10 +2200,10 @@
 	}
 	nu = 0;
 	for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
-				ilport = ilport->ilport_next) {
+	    ilport = ilport->ilport_next) {
 		rw_enter(&ilport->ilport_lock, RW_WRITER);
 		for (iss = ilport->ilport_ss_list; iss != NULL;
-					iss = iss->iss_next) {
+		    iss = iss->iss_next) {
 			lm = iss->iss_sm;
 			if (!lm)
 				continue;
@@ -2211,7 +2212,7 @@
 					continue;
 				ent = (stmf_lun_map_ent_t *)lm->lm_plus[i];
 				if ((ent->ent_lu == lu) &&
-						(ent->ent_itl_datap)) {
+				    (ent->ent_itl_datap)) {
 					itl_list[nu++] = ent->ent_itl_datap;
 					ent->ent_itl_datap = NULL;
 					if (nu == nmaps) {
@@ -2229,7 +2230,7 @@
 
 	for (i = 0; i < nu; i++) {
 		stmf_do_itl_dereg(lu, itl_list[i],
-					STMF_ITL_REASON_DEREG_REQUEST);
+		    STMF_ITL_REASON_DEREG_REQUEST);
 	}
 	kmem_free(itl_list, nmaps * sizeof (stmf_itl_data_t *));
 
@@ -2266,7 +2267,7 @@
 	if (lun) {
 		n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
 		ent = (stmf_lun_map_ent_t *)
-				stmf_get_ent_from_map(iss->iss_sm, n);
+		    stmf_get_ent_from_map(iss->iss_sm, n);
 	} else {
 		if (itl_handle == NULL) {
 			rw_exit(iss->iss_lockp);
@@ -2284,7 +2285,7 @@
 		}
 	}
 	if ((ent == NULL) || (ent->ent_lu != lu) ||
-			(ent->ent_itl_datap == NULL)) {
+	    (ent->ent_itl_datap == NULL)) {
 		rw_exit(iss->iss_lockp);
 		return (STMF_NOT_FOUND);
 	}
@@ -2329,7 +2330,7 @@
 	} else {
 		n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
 		ent = (stmf_lun_map_ent_t *)
-				stmf_get_ent_from_map(iss->iss_sm, n);
+		    stmf_get_ent_from_map(iss->iss_sm, n);
 		if (lu && (ent->ent_lu != lu))
 			ent = NULL;
 	}
@@ -2442,7 +2443,8 @@
 		mutex_enter(&ilu->ilu_task_lock);
 		for (ppitask = &ilu->ilu_free_tasks; (*ppitask != NULL) &&
 		    ((*ppitask)->itask_cdb_buf_size < cdb_length);
-		    ppitask = &((*ppitask)->itask_lu_free_next));
+		    ppitask = &((*ppitask)->itask_lu_free_next))
+			;
 		if (*ppitask) {
 			itask = *ppitask;
 			*ppitask = (*ppitask)->itask_lu_free_next;
@@ -2743,14 +2745,14 @@
 {
 	stmf_local_port_t *lport = task->task_lport;
 	stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
-					task->task_stmf_private;
+	    task->task_stmf_private;
 
 	stmf_free_task_bufs(itask, lport);
 	if (itask->itask_itl_datap) {
 		if (atomic_add_32_nv(&itask->itask_itl_datap->itl_counter,
 		    -1) == 0) {
 			stmf_release_itl_handle(task->task_lu,
-						itask->itask_itl_datap);
+			    itask->itask_itl_datap);
 		}
 	}
 	lport->lport_task_free(task);
@@ -2915,8 +2917,8 @@
 		return (STMF_ABORTED);
 #ifdef	DEBUG
 	if (stmf_drop_buf_counter > 0) {
-		if (atomic_add_32_nv((uint32_t *)&stmf_drop_buf_counter,
-								-1) == 1)
+		if (atomic_add_32_nv((uint32_t *)&stmf_drop_buf_counter, -1) ==
+		    1)
 			return (STMF_SUCCESS);
 	}
 #endif
@@ -3004,7 +3006,7 @@
 stmf_send_scsi_status(scsi_task_t *task, uint32_t ioflags)
 {
 	stmf_i_scsi_task_t *itask =
-		(stmf_i_scsi_task_t *)task->task_stmf_private;
+	    (stmf_i_scsi_task_t *)task->task_stmf_private;
 	if (ioflags & STMF_IOF_LU_DONE) {
 		uint32_t new, old;
 		do {
@@ -3029,12 +3031,12 @@
 	    task->task_expected_xfer_length) {
 		task->task_status_ctrl = TASK_SCTRL_OVER;
 		task->task_resid = task->task_cmd_xfer_length -
-					task->task_expected_xfer_length;
+		    task->task_expected_xfer_length;
 	} else if (task->task_nbytes_transferred <
-					task->task_expected_xfer_length) {
+	    task->task_expected_xfer_length) {
 		task->task_status_ctrl = TASK_SCTRL_UNDER;
 		task->task_resid = task->task_expected_xfer_length -
-					task->task_nbytes_transferred;
+		    task->task_nbytes_transferred;
 	} else {
 		task->task_status_ctrl = 0;
 		task->task_resid = 0;
@@ -3121,7 +3123,7 @@
 stmf_task_lu_done(scsi_task_t *task)
 {
 	stmf_i_scsi_task_t *itask =
-		(stmf_i_scsi_task_t *)task->task_stmf_private;
+	    (stmf_i_scsi_task_t *)task->task_stmf_private;
 	stmf_worker_t *w = itask->itask_worker;
 	uint32_t new, old;
 
@@ -3447,8 +3449,7 @@
 		}
 	} while (atomic_cas_32(&itask->itask_flags, old, new) != old);
 	if (call_port_abort) {
-		ret = lport->lport_abort(lport, STMF_LPORT_ABORT_TASK,
-								task, 0);
+		ret = lport->lport_abort(lport, STMF_LPORT_ABORT_TASK, task, 0);
 		if ((ret == STMF_ABORT_SUCCESS) || (ret == STMF_NOT_FOUND)) {
 			stmf_task_lport_aborted(task, ret, STMF_IOF_LPORT_DONE);
 		} else if (ret == STMF_BUSY) {
@@ -3715,11 +3716,11 @@
 		return (stmf_info_impl(cmd, arg1, arg2, buf, bufsizep));
 	}
 	if (cl == SI_LPORT) {
-		return (((stmf_local_port_t *)arg1)->lport_info(cmd,
-				arg1, arg2, buf, bufsizep));
+		return (((stmf_local_port_t *)arg1)->lport_info(cmd, arg1,
+		    arg2, buf, bufsizep));
 	} else if (cl == SI_LU) {
-		return (((stmf_lu_t *)arg1)->lu_info(cmd, arg1, arg2,
-						buf, bufsizep));
+		return (((stmf_lu_t *)arg1)->lu_info(cmd, arg1, arg2, buf,
+		    bufsizep));
 	}
 
 	return (STMF_NOT_SUPPORTED);
@@ -3784,7 +3785,6 @@
 
 
 static uint16_t stmf_lu_id_gen_number = 0;
-extern char hw_serial[];
 
 stmf_status_t
 stmf_scsilib_uniq_lu_id(uint32_t company_id, scsi_devid_desc_t *lu_id)
@@ -3811,8 +3811,7 @@
 	p[6] = (company_id >> 4) & 0xff;
 	p[7] = (company_id << 4) & 0xf0;
 	if (!localetheraddr((struct ether_addr *)NULL, &mac)) {
-		char *hp = &hw_serial[0];
-		int hid = BE_32(stoi(&hp));
+		int hid = BE_32((int)zone_get_hostid(NULL));
 
 		e[0] = (hid >> 24) & 0xff;
 		e[1] = (hid >> 16) & 0xff;
@@ -3916,7 +3915,7 @@
 			p[1] = 0x14;
 			p[3] = 4;
 			ilport = (stmf_i_local_port_t *)
-					task->task_lport->lport_stmf_private;
+			    task->task_lport->lport_stmf_private;
 			p[6] = (ilport->ilport_rtpid >> 8) & 0xff;
 			p[7] = ilport->ilport_rtpid & 0xff;
 			sz = 8;
@@ -3937,7 +3936,7 @@
 stmf_scsilib_handle_report_tpgs(scsi_task_t *task, stmf_data_buf_t *dbuf)
 {
 	stmf_i_scsi_task_t *itask =
-			(stmf_i_scsi_task_t *)task->task_stmf_private;
+	    (stmf_i_scsi_task_t *)task->task_stmf_private;
 	stmf_xfer_data_t *xd;
 	uint32_t sz, minsz;
 
@@ -3956,7 +3955,7 @@
 
 	if (task->task_cmd_xfer_length < 16) {
 		stmf_scsilib_send_status(task, STATUS_CHECK,
-			STMF_SAA_INVALID_FIELD_IN_CDB);
+		    STMF_SAA_INVALID_FIELD_IN_CDB);
 		return;
 	}
 
@@ -4038,7 +4037,7 @@
 	if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
 		mutex_exit(&stmf_state.stmf_lock);
 		stmf_scsilib_send_status(task, STATUS_CHECK,
-				STMF_SAA_OPERATION_IN_PROGRESS);
+		    STMF_SAA_OPERATION_IN_PROGRESS);
 		return;
 	}
 	atomic_or_32(&ilu->ilu_flags, ILU_RESET_ACTIVE);
@@ -4058,7 +4057,7 @@
 	if (stmf_task_poll_lu(task, ITASK_DEFAULT_POLL_TIMEOUT)
 	    != STMF_SUCCESS) {
 		stmf_abort(STMF_QUEUE_TASK_ABORT, task, STMF_ALLOC_FAILURE,
-						NULL);
+		    NULL);
 		return;
 	}
 }
@@ -4090,7 +4089,7 @@
 		rw_exit(iss->iss_lockp);
 		mutex_exit(&stmf_state.stmf_lock);
 		stmf_scsilib_send_status(task, STATUS_CHECK,
-				STMF_SAA_OPERATION_IN_PROGRESS);
+		    STMF_SAA_OPERATION_IN_PROGRESS);
 		return;
 	}
 	atomic_or_32(&iss->iss_flags, ISS_RESET_ACTIVE);
@@ -4111,7 +4110,7 @@
 			rw_exit(iss->iss_lockp);
 			mutex_exit(&stmf_state.stmf_lock);
 			stmf_scsilib_send_status(task, STATUS_CHECK,
-					STMF_SAA_OPERATION_IN_PROGRESS);
+			    STMF_SAA_OPERATION_IN_PROGRESS);
 			return;
 		}
 	}
@@ -4126,7 +4125,7 @@
 
 	/* ok, start the damage */
 	itask->itask_flags |= ITASK_DEFAULT_HANDLING |
-					ITASK_CAUSING_TARGET_RESET;
+	    ITASK_CAUSING_TARGET_RESET;
 	for (i = 0; i < lm->lm_nentries; i++) {
 		if (lm->lm_plus[i] == NULL)
 			continue;
@@ -4142,14 +4141,14 @@
 			continue;
 		lm_ent = (stmf_lun_map_ent_t *)lm->lm_plus[i];
 		stmf_abort(STMF_QUEUE_ABORT_LU, task, STMF_ABORTED,
-				lm_ent->ent_lu);
+		    lm_ent->ent_lu);
 	}
 
 	/* Start polling on this task */
 	if (stmf_task_poll_lu(task, ITASK_DEFAULT_POLL_TIMEOUT)
 	    != STMF_SUCCESS) {
 		stmf_abort(STMF_QUEUE_TASK_ABORT, task, STMF_ALLOC_FAILURE,
-						NULL);
+		    NULL);
 		return;
 	}
 }
@@ -4168,7 +4167,7 @@
 		return (0);
 	}
 	atomic_and_32(&iss->iss_flags,
-		~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
+	    ~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
 	rw_exit(iss->iss_lockp);
 
 	if (task->task_cdb[0] == SCMD_REPORT_LUNS) {
@@ -4289,7 +4288,7 @@
 					    w->worker_wait_head;
 				else
 					w->worker_task_tail->itask_worker_next =
-						w->worker_wait_head;
+					    w->worker_wait_head;
 				w->worker_task_tail = w->worker_wait_tail;
 				w->worker_wait_head = w->worker_wait_tail =
 				    NULL;
@@ -4732,7 +4731,7 @@
 
 		if (sz < 16) {
 			stmf_scsilib_send_status(task, STATUS_CHECK,
-				STMF_SAA_INVALID_FIELD_IN_CDB);
+			    STMF_SAA_INVALID_FIELD_IN_CDB);
 			return;
 		}
 
@@ -4764,7 +4763,7 @@
 		stmf_xd_to_dbuf(dbuf);
 
 		atomic_and_32(&iss->iss_flags,
-			~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
+		    ~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
 		dbuf->db_flags = DB_DIRECTION_TO_RPORT;
 		(void) stmf_xfer_data(task, dbuf, 0);
 		return;
@@ -4809,7 +4808,7 @@
 {
 	scsi_task_t *task = (scsi_task_t *)arg;
 	stmf_i_scsi_task_t *itask =
-			(stmf_i_scsi_task_t *)task->task_stmf_private;
+	    (stmf_i_scsi_task_t *)task->task_stmf_private;
 	stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
 	int i;
 	uint8_t map;
@@ -4931,7 +4930,7 @@
 stmf_abort_target_reset(scsi_task_t *task)
 {
 	stmf_i_scsi_session_t *iss = (stmf_i_scsi_session_t *)
-				task->task_session->ss_stmf_private;
+	    task->task_session->ss_stmf_private;
 	stmf_lun_map_t *lm;
 	stmf_lun_map_ent_t *lm_ent;
 	stmf_i_lu_t *ilu;
@@ -5018,7 +5017,7 @@
 stmf_target_reset_poll(struct scsi_task *task)
 {
 	stmf_i_scsi_session_t *iss = (stmf_i_scsi_session_t *)
-				task->task_session->ss_stmf_private;
+	    task->task_session->ss_stmf_private;
 	stmf_lun_map_t *lm;
 	stmf_lun_map_ent_t *lm_ent;
 	stmf_i_lu_t *ilu;
@@ -5102,7 +5101,7 @@
 stmf_lport_add_event(stmf_local_port_t *lport, int eventid)
 {
 	stmf_i_local_port_t *ilport =
-		(stmf_i_local_port_t *)lport->lport_stmf_private;
+	    (stmf_i_local_port_t *)lport->lport_stmf_private;
 
 	if ((eventid < 0) || (eventid >= STMF_MAX_NUM_EVENTS)) {
 		return (STMF_INVALID_ARG);
@@ -5116,7 +5115,7 @@
 stmf_lport_remove_event(stmf_local_port_t *lport, int eventid)
 {
 	stmf_i_local_port_t *ilport =
-		(stmf_i_local_port_t *)lport->lport_stmf_private;
+	    (stmf_i_local_port_t *)lport->lport_stmf_private;
 
 	if (eventid == STMF_EVENT_ALL) {
 		STMF_EVENT_CLEAR_ALL(ilport->ilport_event_hdl);
@@ -5239,7 +5238,7 @@
 			/* Kill all the pending I/Os for this LU */
 			mutex_exit(&stmf_state.stmf_lock);
 			stmf_task_lu_killall((stmf_lu_t *)req->svc_obj, NULL,
-				STMF_ABORTED);
+			    STMF_ABORTED);
 			mutex_enter(&stmf_state.stmf_lock);
 			waitq_add = 1;
 			break;
@@ -5369,28 +5368,28 @@
 					port_level++;
 					stmf_level++;
 					atomic_and_32(&iss->iss_flags,
-						~ISS_GOT_INITIAL_LUNS);
+					    ~ISS_GOT_INITIAL_LUNS);
 					atomic_or_32(&iss->iss_flags,
-						ISS_EVENT_ACTIVE);
+					    ISS_EVENT_ACTIVE);
 					rw_exit(&ilport->ilport_lock);
 					mutex_exit(&stmf_state.stmf_lock);
 					stmf_generate_lport_event(ilport,
 					    LPORT_EVENT_INITIAL_LUN_MAPPED,
 					    iss->iss_ss, 0);
 					atomic_and_32(&iss->iss_flags,
-						~ISS_EVENT_ACTIVE);
+					    ~ISS_EVENT_ACTIVE);
 					mutex_enter(&stmf_state.stmf_lock);
 					/*
 					 * scan all the ilports again as the
 					 * ilport list might have changed.
 					 */
 					next_ilport =
-						stmf_state.stmf_ilportlist;
+					    stmf_state.stmf_ilportlist;
 					break;
 				}
 				if (port_level == 0) {
 					atomic_and_32(&ilport->ilport_flags,
-						~ILPORT_SS_GOT_INITIAL_LUNS);
+					    ~ILPORT_SS_GOT_INITIAL_LUNS);
 				}
 				/* drop the lock if we are holding it. */
 				if (rw_lock_held(&ilport->ilport_lock))
--- a/usr/src/uts/common/io/lvm/md/md_mddb.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/io/lvm/md/md_mddb.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -3413,7 +3413,7 @@
 	bzero((caddr_t)&tag, sizeof (mddb_dtag_t));
 
 	/* Get the HW serial number for this host */
-	(void) strncpy(tag.dt_sn, hw_serial, MDDB_SN_LEN);
+	(void) snprintf(tag.dt_sn, MDDB_SN_LEN, "%u", zone_get_hostid(NULL));
 	tag.dt_sn[MDDB_SN_LEN - 1] = '\0';
 
 	/* Get the nodename that this host goes by */
@@ -6005,106 +6005,133 @@
 		 * Don't do this during upgrade.
 		 */
 		if (!(MD_UPGRADE)) {
-		    for (li = 0; li < lbp->lb_loccnt; li++) {
-			lp = &lbp->lb_locators[li];
-			if (lp->l_flags & MDDB_F_DELETED)
-				continue;
-			did_info = &(did_icp->did_ic_blkp->blk_info[li]);
-			if ((did_info->info_flags & MDDB_DID_VALID) &&
-			    !(did_info->info_flags & MDDB_DID_UPDATED)) {
-				if (lbp->lb_flags & MDDB_MNSET) {
-					int 	j;
-					int	index = -1;
-					mnlbp = (mddb_mnlb_t *)lbp;
-					for (j = 0; j < MD_MNMAXSIDES; j++) {
-					    mnslp = &mnlbp->
-						lb_mnsidelocators[j][li];
-					    if (mnslp->mnl_sideno ==
-						s->s_sideno)
-						break;
-					    if (mnslp->mnl_sideno == 0)
-						index = j;
+			for (li = 0; li < lbp->lb_loccnt; li++) {
+				lp = &lbp->lb_locators[li];
+				if (lp->l_flags & MDDB_F_DELETED)
+					continue;
+				did_info = &(did_icp->did_ic_blkp->blk_info
+				    [li]);
+				if ((did_info->info_flags & MDDB_DID_VALID) &&
+				    !(did_info->info_flags &
+				    MDDB_DID_UPDATED)) {
+					if (lbp->lb_flags & MDDB_MNSET) {
+						int j;
+						int index = -1;
+						mnlbp = (mddb_mnlb_t *)lbp;
+						for (j = 0; j < MD_MNMAXSIDES;
+						    j++) {
+							mnslp = &mnlbp->
+							    lb_mnsidelocators[j]
+							    [li];
+							if (mnslp->mnl_sideno ==
+							    s->s_sideno)
+								break;
+							if (mnslp->mnl_sideno ==
+							    0)
+								index = j;
+						}
+						if (j == MD_MNMAXSIDES) {
+							/*
+							 * No match found; take
+							 * empty
+							 */
+							mnslp = &mnlbp->
+							    lb_mnsidelocators
+							    [index][li];
+							write_lb = 1;
+							mnslp->mnl_mnum =
+							    md_getminor(newdev
+							    [li]);
+						} else if (mnslp->mnl_mnum !=
+						    md_getminor(newdev[li])) {
+							write_lb = 1;
+							mnslp->mnl_mnum =
+							    md_getminor(newdev
+							    [li]);
+						}
+					} else {
+						slp = &lbp->
+						    lb_sidelocators[s->s_sideno]
+						    [li];
+						if (slp->l_mnum !=
+						    md_getminor(newdev[li])) {
+							write_lb = 1;
+							slp->l_mnum =
+							    md_getminor(newdev
+							    [li]);
+						}
 					}
-					if (j == MD_MNMAXSIDES) {
-					    /* No match found; take empty */
-					    mnslp = &mnlbp->
-						lb_mnsidelocators[index][li];
-					    write_lb = 1;
-					    mnslp->mnl_mnum =
-						md_getminor(newdev[li]);
-					} else if (mnslp->mnl_mnum !=
-					    md_getminor(newdev[li])) {
+					name = ddi_major_to_name(md_getmajor(
+					    newdev[li]));
+					if (lbp->lb_flags & MDDB_MNSET)
+						i = mnslp->mnl_drvnm_index;
+					else
+						i = slp->l_drvnm_index;
+					if (strncmp(lbp->lb_drvnm[i].dn_data,
+					    name, lbp->lb_drvnm[i].dn_len) !=
+					    0) {
+						/* Driver name has changed */
+						len = strlen(name);
+						/* Look for the driver name */
+						for (i = 0; i < MDDB_DRVNMCNT;
+						    i++) {
+							if (lbp->lb_drvnm[i].
+							    dn_len != len)
+								continue;
+							if (strncmp(lbp->
+							    lb_drvnm[i].dn_data,
+							    name, len) == 0)
+								break;
+						}
+						/* Didn't find one, add it */
+						if (i == MDDB_DRVNMCNT) {
+							for (i = 0; i <
+							    MDDB_DRVNMCNT;
+							    i++) {
+								if (lbp->
+								    lb_drvnm[i].
+								    dn_len == 0)
+									break;
+							}
+							if (i ==
+							    MDDB_DRVNMCNT) {
+								cmn_err(CE_WARN,
+								    "Unable to "
+								    " update "
+								    "driver "
+								    " name for "
+								    "dev:  "
+								    "major = %d"
+								    ", minor = "
+								    "%d\n",
+								    md_getmajor(
+								    newdev[li]),
+								    md_getminor(
+								    newdev
+								    [li]));
+								continue;
+							}
+							(void) strncpy(lbp->
+							    lb_drvnm[i].dn_data,
+							    name, MD_MAXDRVNM);
+							lbp->lb_drvnm[i].
+							    dn_len = (uchar_t)
+							    strlen(name);
+						}
+						/* Fill in the drvnm index */
+						if (lbp->lb_flags &
+						    MDDB_MNSET)
+							mnslp->mnl_drvnm_index =
+							    i;
+						else
+							slp->l_drvnm_index = i;
 						write_lb = 1;
-						mnslp->mnl_mnum =
-						    md_getminor(newdev[li]);
 					}
-				} else {
-					slp = &lbp->
-					    lb_sidelocators[s->s_sideno][li];
-					if (slp->l_mnum !=
-					    md_getminor(newdev[li])) {
-						write_lb = 1;
-						slp->l_mnum =
-						    md_getminor(newdev[li]);
-					}
-				}
-				name = ddi_major_to_name(
-						md_getmajor(newdev[li]));
-				if (lbp->lb_flags & MDDB_MNSET) {
-					i = mnslp->mnl_drvnm_index;
-				} else {
-					i = slp->l_drvnm_index;
+					did_info->info_flags |=
+					    MDDB_DID_UPDATED;
 				}
-				if (strncmp(lbp->lb_drvnm[i].dn_data, name,
-					lbp->lb_drvnm[i].dn_len) != 0) {
-					/* Driver name has changed */
-					len = strlen(name);
-					/* Look for the driver name */
-					for (i = 0; i < MDDB_DRVNMCNT; i++) {
-						if (lbp->lb_drvnm[i].dn_len
-						    != len)
-							continue;
-						if (strncmp(
-						    lbp->lb_drvnm[i].dn_data,
-						    name, len) == 0)
-							break;
-					}
-					/* Didn't find one, add it */
-					if (i == MDDB_DRVNMCNT) {
-					    for (i = 0; i < MDDB_DRVNMCNT;
-						i++) {
-						if (lbp->lb_drvnm[i].dn_len
-						    == 0)
-							break;
-					    }
-					    if (i == MDDB_DRVNMCNT) {
-						cmn_err(CE_WARN,
-						    "Unable to update driver"
-						    " name for dev:  "
-						    "major = %d, "
-						    "minor = %d\n",
-						    md_getmajor(newdev[li]),
-						    md_getminor(newdev[li]));
-						continue;
-					    }
-					    (void) strncpy(
-						lbp->lb_drvnm[i].dn_data,
-						name, MD_MAXDRVNM);
-					    lbp->lb_drvnm[i].dn_len =
-						(uchar_t)strlen(name);
-					}
-					/* Fill in the drvnm index */
-					if (lbp->lb_flags & MDDB_MNSET) {
-						mnslp->mnl_drvnm_index = i;
-					} else {
-						slp->l_drvnm_index = i;
-					}
-					write_lb = 1;
-				}
-				did_info->info_flags |= MDDB_DID_UPDATED;
-			}
-		}
-	    }
+			}
+		}
 	}
 	kmem_free(newdev, sizeof (md_dev64_t) * MDDB_NLB);
 
@@ -7092,7 +7119,8 @@
 	s->s_setno = setno;
 	s->s_sideno = sideno;
 	if (setno == MD_LOCAL_SET) {
-		(void) strcpy(s->s_ident.serial, hw_serial);
+		(void) snprintf(s->s_ident.serial, sizeof (s->s_ident.serial),
+		    "%u", zone_get_hostid(NULL));
 	} else {
 		s->s_ident.createtime = *created;
 		s->s_setname = (char *)kmem_alloc(strlen(setname) + 1,
@@ -11356,34 +11384,38 @@
 				for (tdep = first_dep; tdep;
 				    tdep = tdep->de_next) {
 					if (dep->de_recid == tdep->de_recid) {
-					    writeout = 0;
-					    /* Check first mddb location */
-					    if ((dep->de_optinfo[0].o_li !=
-						tdep->de_optinfo[0].o_li) ||
-						(dep->de_optinfo[0].o_flags !=
-						tdep->de_optinfo[0].o_flags)) {
-						    dep->de_optinfo[0] =
-						    tdep->de_optinfo[0];
-						    writeout = 1;
-					    }
-					    /* Check second mddb location */
-					    if ((dep->de_optinfo[1].o_li !=
-						tdep->de_optinfo[1].o_li) ||
-						(dep->de_optinfo[1].o_flags !=
-						tdep->de_optinfo[1].o_flags)) {
-						    dep->de_optinfo[1] =
-						    tdep->de_optinfo[1];
-						    writeout = 1;
-					    }
-					    /* Record owner should rewrite it */
-					    if ((writeout) &&
-						(dep->de_owner_nodeid ==
-						md_set[mpp->c_setno].
-						s_nodeid)) {
-						    (void) writeoptrecord(s,
-							dep);
-					    }
-					    break;
+						writeout = 0;
+						/* Check first mddb location */
+						if ((dep->de_optinfo[0].o_li !=
+						    tdep->de_optinfo[0].o_li) ||
+						    (dep->de_optinfo[0].
+						    o_flags != tdep->de_optinfo
+						    [0].o_flags)) {
+							dep->de_optinfo[0] =
+							    tdep->de_optinfo[0];
+							writeout = 1;
+						}
+						/* Check second mddb location */
+						if ((dep->de_optinfo[1].o_li !=
+						    tdep->de_optinfo[1].o_li) ||
+						    (dep->de_optinfo[1].
+						    o_flags != tdep->de_optinfo
+						    [1].o_flags)) {
+							dep->de_optinfo[1] =
+							    tdep->de_optinfo[1];
+							writeout = 1;
+						}
+						/*
+						 * Record owner should rewrite
+						 * it
+						 */
+						if ((writeout) &&
+						    (dep->de_owner_nodeid ==
+						    md_set[mpp->c_setno].
+						    s_nodeid))
+							(void) writeoptrecord(s,
+							    dep);
+						break;
 					}
 				}
 			}
--- a/usr/src/uts/common/io/mms/dda/dda.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/io/mms/dda/dda.c	Fri Jan 30 12:25:48 2009 -0800
@@ -18,7 +18,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.
  */
 
@@ -82,6 +82,7 @@
 #include <sys/scsi/impl/uscsi.h>	/* uscsi commands */
 #include <sys/ioctl.h>
 #include <sys/mtio.h>			/* tape io */
+#include <sys/systeminfo.h>		/* for hostid access */
 #include <sys/scsi/targets/stdef.h>
 #include <sys/fs/ufs_inode.h>
 #include <sys/vfs.h>
@@ -314,7 +315,6 @@
 
 /* dev_info structure, one instance per dda device */
 static void *dda_state;
-extern char hw_serial[];
 
 /* Loadable module configuration entry points */
 
@@ -1629,9 +1629,6 @@
  * Parameters:
  *	- dda:		DDA tape drive.
  *
- * Globals:
- *	- hw_serial:	Hostid.
- *
  * Generate DDA unit serial number from the computer hostid and drive
  * instance number.
  *
@@ -1645,16 +1642,13 @@
 	char		sn[100];
 	int		len;
 	int		off;
-	char		*hostid_p = &hw_serial[0];
-	int		hostid_i;
 
 	/*
 	 * Generate unit serial number:
 	 *	zeros, hostid, instance number
 	 */
-	hostid_i = stoi(&hostid_p);
-	len = snprintf(sn, sizeof (sn),
-	    "%016x%x%x", 0, hostid_i, dda->dda_inst);
+	len = snprintf(sn, sizeof (sn), "%016x%x%x", 0, zone_get_hostid(NULL),
+	    dda->dda_inst);
 
 	/*
 	 * Use least significant part of generated serial number
--- a/usr/src/uts/common/nfs/nfs.h	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/nfs/nfs.h	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -914,7 +914,6 @@
 extern int	setdirmode(vnode_t *, mode_t *, cred_t *);
 extern int	newnum(void);
 extern char	*newname(void);
-extern int	nfs_atoi(char *);
 extern int	nfs_subrinit(void);
 extern void	nfs_subrfini(void);
 extern enum nfsstat puterrno(int);
--- a/usr/src/uts/common/os/sunddi.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/os/sunddi.c	Fri Jan 30 12:25:48 2009 -0800
@@ -82,6 +82,7 @@
 #include <sys/ctype.h>
 #include <net/if.h>
 #include <sys/rctl.h>
+#include <sys/zone.h>
 
 extern	pri_t	minclsyspri;
 
@@ -7614,7 +7615,6 @@
 	return (DDI_FAILURE);
 }
 
-extern char	hw_serial[];
 static kmutex_t devid_gen_mutex;
 static short	devid_gen_number;
 
@@ -7858,8 +7858,7 @@
 	/* Fill in id field */
 	if (devid_type == DEVID_FAB) {
 		char		*cp;
-		int		hostid;
-		char		*hostid_cp = &hw_serial[0];
+		uint32_t	hostid;
 		struct timeval32 timestamp32;
 		int		i;
 		int		*ip;
@@ -7873,7 +7872,7 @@
 		cp = i_devid->did_id;
 
 		/* Fill in host id (big-endian byte ordering) */
-		hostid = stoi(&hostid_cp);
+		hostid = zone_get_hostid(NULL);
 		*cp++ = hibyte(hiword(hostid));
 		*cp++ = lobyte(hiword(hostid));
 		*cp++ = hibyte(loword(hostid));
--- a/usr/src/uts/common/os/zone.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/os/zone.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -1725,6 +1725,7 @@
 	zone0.zone_name = GLOBAL_ZONENAME;
 	zone0.zone_nodename = utsname.nodename;
 	zone0.zone_domain = srpc_domain;
+	zone0.zone_hostid = HW_INVALID_HOSTID;
 	zone0.zone_ref = 1;
 	zone0.zone_id = GLOBAL_ZONEID;
 	zone0.zone_status = ZONE_IS_RUNNING;
@@ -2906,6 +2907,27 @@
 }
 
 /*
+ * Gets the 32-bit hostid of the specified zone as an unsigned int.  If 'zonep'
+ * is NULL or it points to a zone with no hostid emulation, then the machine's
+ * hostid (i.e., the global zone's hostid) is returned.  This function returns
+ * zero if neither the zone nor the host machine (global zone) have hostids.  It
+ * returns HW_INVALID_HOSTID if the function attempts to return the machine's
+ * hostid and the machine's hostid is invalid.
+ */
+uint32_t
+zone_get_hostid(zone_t *zonep)
+{
+	unsigned long machine_hostid;
+
+	if (zonep == NULL || zonep->zone_hostid == HW_INVALID_HOSTID) {
+		if (ddi_strtoul(hw_serial, NULL, 10, &machine_hostid) != 0)
+			return (HW_INVALID_HOSTID);
+		return ((uint32_t)machine_hostid);
+	}
+	return (zonep->zone_hostid);
+}
+
+/*
  * Similar to thread_create(), but makes sure the thread is in the appropriate
  * zone's zsched process (curproc->p_zone->zone_zsched) before returning.
  */
@@ -3800,6 +3822,7 @@
 
 	zone->zone_domain = kmem_alloc(_SYS_NMLN, KM_SLEEP);
 	zone->zone_domain[0] = '\0';
+	zone->zone_hostid = HW_INVALID_HOSTID;
 	zone->zone_shares = 1;
 	zone->zone_shmmax = 0;
 	zone->zone_ipc.ipcq_shmmni = 0;
@@ -4722,6 +4745,17 @@
 
 		mutex_exit(&class_lock);
 		break;
+	case ZONE_ATTR_HOSTID:
+		if (zone->zone_hostid != HW_INVALID_HOSTID &&
+		    bufsize == sizeof (zone->zone_hostid)) {
+			size = sizeof (zone->zone_hostid);
+			if (buf != NULL && copyout(&zone->zone_hostid, buf,
+			    bufsize) != 0)
+				error = EFAULT;
+		} else {
+			error = EINVAL;
+		}
+		break;
 	default:
 		if ((attr >= ZONE_ATTR_BRAND_ATTRS) && ZONE_IS_BRANDED(zone)) {
 			size = bufsize;
@@ -4791,6 +4825,16 @@
 	case ZONE_ATTR_SCHED_CLASS:
 		err = zone_set_sched_class(zone, (const char *)buf);
 		break;
+	case ZONE_ATTR_HOSTID:
+		if (bufsize == sizeof (zone->zone_hostid)) {
+			if (copyin(buf, &zone->zone_hostid, bufsize) == 0)
+				err = 0;
+			else
+				err = EFAULT;
+		} else {
+			err = EINVAL;
+		}
+		break;
 	default:
 		if ((attr >= ZONE_ATTR_BRAND_ATTRS) && ZONE_IS_BRANDED(zone))
 			err = ZBROP(zone)->b_setattr(zone, attr, buf, bufsize);
--- a/usr/src/uts/common/sys/systeminfo.h	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/sys/systeminfo.h	Fri Jan 30 12:25:48 2009 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -31,8 +30,6 @@
 #ifndef _SYS_SYSTEMINFO_H
 #define	_SYS_SYSTEMINFO_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.4 */
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -40,7 +37,7 @@
 #ifdef	_KERNEL
 extern char architecture[];
 extern char architecture_32[];
-extern char hw_serial[];
+extern char hw_serial[];	/* machine's 32-bit hostid; a decimal string */
 extern char hw_provider[];
 extern char srpc_domain[];
 extern char platform[];
@@ -93,7 +90,12 @@
 /* Solaris defined `set' commands (769-1024) (none currently assigned) */
 
 
-#define	DOM_NM_LN		64	/* maximum length of domain name */
+#define	HW_INVALID_HOSTID	0xFFFFFFFF	/* an invalid hostid */
+#define	HW_HOSTID_LEN		11		/* minimum buffer size needed */
+						/* to hold a decimal or hex */
+						/* hostid string */
+#define	DOM_NM_LN		64		/* maximum length of domain */
+						/* name */
 
 #if !defined(_KERNEL)
 #if defined(__STDC__)
--- a/usr/src/uts/common/sys/zone.h	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/sys/zone.h	Fri Jan 30 12:25:48 2009 -0800
@@ -19,15 +19,13 @@
  * 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.
  */
 
 #ifndef _SYS_ZONE_H
 #define	_SYS_ZONE_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <sys/mutex.h>
 #include <sys/param.h>
@@ -97,6 +95,7 @@
 #define	ZONE_ATTR_PHYS_MCAP	12
 #define	ZONE_ATTR_SCHED_CLASS	13
 #define	ZONE_ATTR_FLAGS		14
+#define	ZONE_ATTR_HOSTID	15
 
 /* Start of the brand-specific attribute namespace */
 #define	ZONE_ATTR_BRAND_ATTRS	32768
@@ -320,6 +319,17 @@
 	char		*zone_nodename;	/* utsname.nodename equivalent */
 	char		*zone_domain;	/* srpc_domain equivalent */
 	/*
+	 * zone_hostid is used for per-zone hostid emulation.
+	 * Currently it isn't modified after it's set (so no locks protect
+	 * accesses), but that might have to change when we allow
+	 * administrators to change running zones' properties.
+	 *
+	 * The global zone's zone_hostid must always be HW_INVALID_HOSTID so
+	 * that zone_get_hostid() will function correctly.
+	 */
+	uint32_t	zone_hostid;	/* zone's hostid, HW_INVALID_HOSTID */
+					/* if not emulated */
+	/*
 	 * zone_lock protects the following fields of a zone_t:
 	 * 	zone_ref
 	 * 	zone_cred_ref
@@ -599,6 +609,13 @@
 extern zone_status_t zone_status_get(zone_t *);
 
 /*
+ * Safely get the hostid of the specified zone (defaults to machine's hostid
+ * if the specified zone doesn't emulate a hostid).  Passing NULL retrieves
+ * the global zone's (i.e., physical system's) hostid.
+ */
+extern uint32_t zone_get_hostid(zone_t *);
+
+/*
  * Get the "kcred" credentials corresponding to the given zone.
  */
 extern struct cred *zone_get_kcred(zoneid_t);
--- a/usr/src/uts/common/syscall/systeminfo.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/common/syscall/systeminfo.c	Fri Jan 30 12:25:48 2009 -0800
@@ -19,15 +19,13 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
 /*	  All rights reserved.	*/
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/sysmacros.h>
@@ -57,6 +55,7 @@
 	int error = 0;
 	long strcnt, getcnt;
 	char *kstr;
+	char hostidp[HW_HOSTID_LEN];
 
 	if (count < 0 && command != SI_SET_HOSTNAME &&
 	    command != SI_SET_SRPC_DOMAIN)
@@ -103,7 +102,9 @@
 		break;
 #endif
 	case SI_HW_SERIAL:
-		kstr = hw_serial;
+		(void) snprintf(hostidp, sizeof (hostidp), "%u",
+		    zone_get_hostid(curzone));
+		kstr = hostidp;
 		break;
 	case SI_HW_PROVIDER:
 		kstr = hw_provider;
--- a/usr/src/uts/i86pc/os/startup.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/i86pc/os/startup.c	Fri Jan 30 12:25:48 2009 -0800
@@ -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.
  */
 
@@ -114,6 +114,7 @@
 #include <sys/debug_info.h>
 #include <sys/bootinfo.h>
 #include <sys/ddi_timer.h>
+#include <sys/systeminfo.h>
 #include <sys/multiboot.h>
 
 #ifdef __xpv
@@ -144,7 +145,6 @@
 #include <sys/rtc.h>
 
 static int32_t set_soft_hostid(void);
-extern char hw_serial[];
 static char hostid_file[] = "/etc/hostid";
 
 #endif
@@ -1484,11 +1484,11 @@
 	/*
 	 * This is needed here to initialize hw_serial[] for cluster booting.
 	 */
-	if ((h = set_soft_hostid()) == -1)
+	if ((h = set_soft_hostid()) == HW_INVALID_HOSTID) {
 		cmn_err(CE_WARN, "Unable to set hostid");
-	else {
+	} else {
 		for (v = h, cnt = 0; cnt < 10; cnt++) {
-			d[cnt] = v % 10;
+			d[cnt] = (char)(v % 10);
 			v /= 10;
 			if (v == 0)
 				break;
@@ -2118,7 +2118,6 @@
 	PRM_POINT("startup_end() done");
 }
 
-extern char hw_serial[];
 /*
  * Don't remove the following 2 variables.  They are necessary
  * for reading the hostid from the legacy file (/kernel/misc/sysinit).
@@ -2557,7 +2556,7 @@
 	int done = 0;
 	u_longlong_t tmp;
 	int i;
-	int32_t hostid = -1;
+	int32_t hostid = (int32_t)HW_INVALID_HOSTID;
 	unsigned char *c;
 	hrtime_t tsc;
 
@@ -2583,7 +2582,7 @@
 				hostid = (int32_t)atoi(hw_serial);
 			(void) modunload(i);
 		}
-		if (hostid == -1) {
+		if (hostid == HW_INVALID_HOSTID) {
 			tsc = tsc_read();
 			if (tsc == 0)	/* tsc_read can return zero sometimes */
 				hostid = (int32_t)tenmicrodata & 0x0CFFFFF;
@@ -2638,7 +2637,7 @@
 
 			}
 		}
-		if (hostid == -1) /* didn't find a hostid string */
+		if (hostid == HW_INVALID_HOSTID) /* didn't find a hostid */
 			kobj_file_err(CE_WARN, file,
 			    "hostid missing or corrupt");
 
@@ -2646,7 +2645,8 @@
 	}
 	/*
 	 * hostid is now the value read from /etc/hostid, or the
-	 * new hostid we generated in this routine or -1 if not set.
+	 * new hostid we generated in this routine or HW_INVALID_HOSTID if not
+	 * set.
 	 */
 	return (hostid);
 }
--- a/usr/src/uts/sun4/os/ddi_impl.c	Fri Jan 30 11:54:57 2009 -0800
+++ b/usr/src/uts/sun4/os/ddi_impl.c	Fri Jan 30 12:25:48 2009 -0800
@@ -20,12 +20,10 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * sun4 specific DDI implementation
  */
@@ -1742,14 +1740,10 @@
 parse_idprom(void)
 {
 	if (idprom.id_format == IDFORM_1) {
-		uint_t i;
-
 		(void) localetheraddr((struct ether_addr *)idprom.id_ether,
 		    (struct ether_addr *)NULL);
-
-		i = idprom.id_machine << 24;
-		i = i + idprom.id_serial;
-		numtos((ulong_t)i, hw_serial);
+		(void) snprintf(hw_serial, HW_HOSTID_LEN, "%u",
+		    (idprom.id_machine << 24) + idprom.id_serial);
 	} else
 		prom_printf("Invalid format code in IDprom.\n");
 }