changeset 7942:422b01fe8860

6761478 In OpenSolaris, new hostids are being generated even if there is already a hostid on system 6754523 bfu complains zoneadm: not found after integration of 6559979
author Ken Erickson <Ken.Erickson@Sun.COM>
date Sat, 25 Oct 2008 12:23:20 -0700
parents 6689b49d56b5
children 2e311d2e8482
files usr/src/tools/Makefile usr/src/tools/SUNWonbld/prototype_i386 usr/src/tools/SUNWonbld/prototype_sparc usr/src/tools/hostid/Makefile usr/src/tools/hostid/extract_hostid.c usr/src/tools/scripts/bfu.sh usr/src/uts/i86pc/os/startup.c
diffstat 7 files changed, 39 insertions(+), 401 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/tools/Makefile	Sat Oct 25 07:18:39 2008 -0500
+++ b/usr/src/tools/Makefile	Sat Oct 25 12:23:20 2008 -0700
@@ -42,7 +42,6 @@
 	env \
 	fastfs \
 	findunref \
-	hostid \
 	ndrgen \
 	onbld \
 	pmodes \
--- a/usr/src/tools/SUNWonbld/prototype_i386	Sat Oct 25 07:18:39 2008 -0500
+++ b/usr/src/tools/SUNWonbld/prototype_i386	Sat Oct 25 12:23:20 2008 -0700
@@ -39,7 +39,6 @@
 f none opt/onbld/bin/i386/ctfstabs 555 root bin
 f none opt/onbld/bin/i386/cw 555 root bin
 f none opt/onbld/bin/i386/elfextract 555 root bin
-f none opt/onbld/bin/i386/extract_hostid 555 root bin
 f none opt/onbld/bin/i386/fastfs 555 root bin
 f none opt/onbld/bin/i386/findunref 555 root bin
 f none opt/onbld/bin/i386/install 555 root bin
--- a/usr/src/tools/SUNWonbld/prototype_sparc	Sat Oct 25 07:18:39 2008 -0500
+++ b/usr/src/tools/SUNWonbld/prototype_sparc	Sat Oct 25 12:23:20 2008 -0700
@@ -37,7 +37,6 @@
 f none opt/onbld/bin/sparc/ctfmerge 555 root bin
 f none opt/onbld/bin/sparc/ctfstabs 555 root bin
 f none opt/onbld/bin/sparc/cw 555 root bin
-f none opt/onbld/bin/sparc/extract_hostid 555 root bin
 f none opt/onbld/bin/sparc/fastfs 555 root bin
 f none opt/onbld/bin/sparc/findunref 555 root bin
 f none opt/onbld/bin/sparc/forth 555 root bin
--- a/usr/src/tools/hostid/Makefile	Sat Oct 25 07:18:39 2008 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-PROG=	extract_hostid
-OBJS=	$(PROG).o
-SRCS=	$(OBJS:%.o=%.c)
-CLEANFILES += $(OBJS)
-
-include ../Makefile.tools
-
-CFLAGS += $(CCVERBOSE)
-LDLIBS += -lelf
-
-.KEEP_STATE:
-
-all:	$(PROG)
-
-$(PROG): $(OBJS)
-	$(LINK.c) -o $@ $(OBJS) $(LDLIBS)
-	$(POST_PROCESS)
-
-install: all .WAIT $(ROOTONBLDMACHPROG)
-
-lint:	lint_SRCS
-
-clean:
-	$(RM) $(CLEANFILES)
-
-include ../Makefile.targ
--- a/usr/src/tools/hostid/extract_hostid.c	Sat Oct 25 07:18:39 2008 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <locale.h>
-#include <ctype.h>
-#include <string.h>
-#include <elf.h>
-
-/*
- * These definitions historically lived in usr/src/uts/common/io/sysinit.c
- * in the ON consolidation.  They were used to generate the old style
- * hostid that was patched into the sysinit module by install.  They
- * are reproduced here so that we can read existing hostids from old
- * sysinit modules.
- */
-
-#define	V1	0x38d4419a
-#define	V1_K1	0x7a5fd043
-#define	V1_K2	0x65cb612e
-
-
-#define	A	16807
-#define	M	2147483647
-#define	Q	127773
-#define	R	2836
-#define	x() if ((s = ((A * (s % Q)) - (R * (s/Q)))) <= 0) s += M
-
-static int32_t t[3] = {V1, V1_K1, V1_K2 };
-
-/*
- * Private function prototypes
- */
-static void Usage();
-static int get_serial32(int fd, int32_t *value1, int32_t *value2);
-static int get_serial64(int fd, int32_t *value1, int32_t *value2);
-
-/*
- * extract_hostid - transitional utility designed to pull the existing
- * hostid value out of a sysinit module and write it to stdout.  Most
- * likely useful for use with bfu, when moving from old style hostid
- * to new style hostid on non-sparc
- */
-int
-main(int argc, char *argv[])
-{
-	Elf32_Ehdr Ehdr;
-	int fd;
-	int rc = 0;
-	off_t offset;
-	int opt;
-	int32_t s, value1, value2;
-
-	(void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
-#define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
-#endif
-	(void) textdomain(TEXT_DOMAIN);
-
-	while ((opt = getopt(argc, argv, "h")) != EOF) {
-		switch (opt) {
-		case 'h':
-			Usage();
-			break;
-
-		default:
-			Usage();
-		}
-	}
-
-	if (argv[optind] == NULL)
-		return (0);
-
-	/* open the module file */
-	if ((fd = open(argv[optind], O_RDWR)) < 0) {
-		perror(argv[optind]);
-		return (rc);
-	}
-
-	/* read the elf header */
-	offset = 0;
-	if (pread(fd, &Ehdr, sizeof (Ehdr), offset) < 0) {
-		perror(argv[optind]);
-		(void) close(fd);
-		return (rc);
-	}
-
-	/* figure out if 32 or 64 bit */
-	if (Ehdr.e_ident[EI_CLASS] == ELFCLASS32)
-		rc = get_serial32(fd, &value1, &value2);
-	else
-		rc = get_serial64(fd, &value1, &value2);
-
-	if (rc < 0) {
-		(void) close(fd);
-		return (rc);
-	}
-
-	s = value1;
-	x();
-	if (value2 == s) {
-		x();
-		s %= 1000000000;
-	} else
-		s = 0;
-
-	(void) printf("%08lx\n", (unsigned long)s);
-
-	(void) close(fd);
-	return (rc);
-}
-
-static int
-get_serial32(int fd, int32_t *value1, int32_t *value2)
-{
-	Elf32_Ehdr Ehdr;
-	Elf32_Shdr Shdr;
-	int rc;
-	char name[6];
-	off_t offset;
-	off_t shstrtab_offset;
-	off_t data_offset;
-	int i;
-
-	rc = -1;	/* assume module doesn't exist */
-
-	/* read the elf header */
-	offset = 0;
-	if (pread(fd, &Ehdr, sizeof (Ehdr), offset) < 0) {
-		goto out;
-	}
-
-	/* read the section header for the section string table */
-	offset = Ehdr.e_shoff + (Ehdr.e_shstrndx * Ehdr.e_shentsize);
-	if (pread(fd, &Shdr, sizeof (Shdr), offset) < 0) {
-		goto out;
-	}
-
-	/* save the offset of the section string table */
-	shstrtab_offset = Shdr.sh_offset;
-
-	/* find the .data section header */
-	/*CSTYLED*/
-	for (i = 1; ; ) {
-		offset = Ehdr.e_shoff + (i * Ehdr.e_shentsize);
-		if (pread(fd, &Shdr, sizeof (Shdr), offset) < 0) {
-			goto out;
-		}
-		offset = shstrtab_offset + Shdr.sh_name;
-		if (pread(fd, name, sizeof (name), offset) < 0) {
-			goto out;
-		}
-		if (strcmp(name, ".data") == 0)
-			break;
-		if (++i >= (int)Ehdr.e_shnum) {
-			/* reached end of table */
-			goto out;
-		}
-	}
-
-	/* save the offset of the data section */
-	data_offset = Shdr.sh_offset;
-
-	/* read and check the version number and initial seed values */
-	offset = data_offset;
-	if (pread(fd, &t[0], sizeof (t[0]) * 3, offset) < 0) {
-		goto out;
-	}
-
-	*value1 = t[1];
-	*value2 = t[2];
-	rc = 0;
-
-out:	return (rc);
-}
-
-static int
-get_serial64(int fd, int32_t *value1, int32_t *value2)
-{
-	Elf64_Ehdr Ehdr;
-	Elf64_Shdr Shdr;
-	int rc;
-	char name[6];
-	off_t offset;
-	off_t shstrtab_offset;
-	off_t data_offset;
-	int i;
-
-	rc = -1;	/* assume module doesn't exist */
-
-	/* read the elf header */
-	offset = 0;
-	if (pread(fd, &Ehdr, sizeof (Ehdr), offset) < 0) {
-		goto out;
-	}
-
-	/* read the section header for the section string table */
-	offset = Ehdr.e_shoff + (Ehdr.e_shstrndx * Ehdr.e_shentsize);
-	if (pread(fd, &Shdr, sizeof (Shdr), offset) < 0) {
-		goto out;
-	}
-
-	/* save the offset of the section string table */
-	shstrtab_offset = Shdr.sh_offset;
-
-	/* find the .data section header */
-	/*CSTYLED*/
-	for (i = 1; ; ) {
-		offset = Ehdr.e_shoff + (i * Ehdr.e_shentsize);
-		if (pread(fd, &Shdr, sizeof (Shdr), offset) < 0) {
-			goto out;
-		}
-		offset = shstrtab_offset + Shdr.sh_name;
-		if (pread(fd, name, sizeof (name), offset) < 0) {
-			goto out;
-		}
-		if (strcmp(name, ".data") == 0)
-			break;
-		if (++i >= (int)Ehdr.e_shnum) {
-			/* reached end of table */
-			goto out;
-		}
-	}
-
-	/* save the offset of the data section */
-	data_offset = Shdr.sh_offset;
-
-	/* read and check the version number and initial seed values */
-	offset = data_offset;
-	if (pread(fd, &t[0], sizeof (t[0]) * 3, offset) < 0) {
-		goto out;
-	}
-
-	*value1 = t[1];
-	*value2 = t[2];
-	rc = 0;
-
-out:	return (rc);
-}
-
-static void
-Usage()
-{
-	(void) printf(gettext("usage: extract_hostid [-h] filename\n"));
-	exit(1);
-}
--- a/usr/src/tools/scripts/bfu.sh	Sat Oct 25 07:18:39 2008 -0500
+++ b/usr/src/tools/scripts/bfu.sh	Sat Oct 25 12:23:20 2008 -0700
@@ -2872,14 +2872,6 @@
 	${GZIPBIN-$GATE/public/bin/$bfu_isa/gzip}
 "
 #
-# Conditionally add extract_hostid program to the bfucmd list if we
-# are on x86 - to migrate hostid from /kernel/misc/sysinit to /etc/hostid
-#
-if [ $target_isa = i386 ]; then
-    bfucmd="$bfucmd ${EXTRACT_HOSTID-$GATE/public/bin/$bfu_isa/extract_hostid}"
-fi
-
-#
 # Scripts needed by BFU. These must be modified to use the interpreters in
 # /tmp/bfubin. The interpreters in /usr/bin may not be compatible with the
 # libraries in the archives being extracted.
@@ -4227,61 +4219,6 @@
 	fi
 }
 
-# Migrate hostid from /kernel/misc/sysinit binary to new format
-# stored in /etc/hostid.  The ON-private 'extract_hostid' binary
-# (built as part of the ON tools) must be in bfu's path - usually
-# copied from $GATE/public/$isa/bin/.
-#
-migrate_hostid()
-{
-#
-# Currently, we only support a single hostid per machine, which
-# is set in the global zone.  Don't do anything to non-global zone
-# roots.  Still have to allow for alternate roots that aren't in
-# a non-global zone, though.
-#
-numzones=`zoneadm list -pi|wc -l`
-if [ $numzones -ne 1 ]; then
-    for zmpt in \
-	`zoneadm list -pi|nawk -F: '$2 != "global" {print $4} 2>/dev/null'`
-    do
-	if [ "$zmpt" = "$root" ]; then
-	    set -
-	    return 0
-	fi
-    done
-fi
-#
-# if /etc/hostid exists - already migrated - do nothing
-#
-if [ -f ${rootprefix}/etc/hostid ]; then
-    print "New hostid mechanism already in use..."
-    return 0
-fi
-#
-# try to get hostid from /kernel/misc/sysinit 
-#
-if [ -f ${rootprefix}/kernel/misc/sysinit ]; then
-    hostid=`extract_hostid ${rootprefix}/kernel/misc/sysinit 2>/dev/null`
-	if [ $? -eq 0 ]; then
-	    echo "# DO NOT EDIT" > ${rootprefix}/etc/hostid
-	    r=`echo "0x${hostid}" | perl -e \
-		'while(<STDIN>){chop;tr/!-~/P-~!-O/;print $_,"\n";}exit 0;'`
-	    printf "\"%s\"\n"  $r >> ${rootprefix}/etc/hostid
-	    print "Moving hostid from /kernel/misc/sysinit to /etc/hostid ... done"
-	elif [ "$force_override" = "no" ]; then
-	    print "\n\nERROR: Unable to extract current hostid from sysinit file, " \
-		"and /etc/hostid does not exist.  Machine will be initialized " \
-		"with a new hostid at first reboot after bfu.  If this is OK, you " \
-		"must run bfu with the -f flag."
-	    exit
-	fi
-	return 0
-fi
-
-return 0
-}
-
 #
 # Check to see if root in $1 has a mounted boot, and that
 # it's mounted at the right place for bfu to handle it.
@@ -7658,10 +7595,6 @@
 	#
 	rm -f $root/usr/platform/i86pc/lib/fm/topo/maps/Sun-Fire-*-topology.xml
 
-	# Migrate hostid
-	#
-	migrate_hostid
-
 	# End of pre-archive extraction hacks.
 
 	if [ $diskless = no -a $zone = global ]; then
--- a/usr/src/uts/i86pc/os/startup.c	Sat Oct 25 07:18:39 2008 -0500
+++ b/usr/src/uts/i86pc/os/startup.c	Sat Oct 25 12:23:20 2008 -0700
@@ -2118,6 +2118,10 @@
 }
 
 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).
+ */
 char *_hs1107 = hw_serial;
 ulong_t  _bdhs34;
 
@@ -2532,11 +2536,16 @@
  * it in the kernel, for subsequent saving by a userland process
  * once the system is up and the root filesystem is mounted r/w.
  *
+ * In order to gracefully support upgrade on OpenSolaris, if
+ * /etc/hostid does not exist, we will attempt to get a serial number
+ * using the legacy method (/kernel/misc/sysinit).
+ *
  * In an attempt to make the hostid less prone to abuse
  * (for license circumvention, etc), we store it in /etc/hostid
  * in rot47 format.
  */
 extern volatile unsigned long tenmicrodata;
+static int atoi(char *);
 
 static int32_t
 set_soft_hostid(void)
@@ -2546,6 +2555,7 @@
 	token_t token;
 	int done = 0;
 	u_longlong_t tmp;
+	int i;
 	int32_t hostid = -1;
 	unsigned char *c;
 	hrtime_t tsc;
@@ -2562,12 +2572,23 @@
 	 */
 
 	if ((file = kobj_open_file(hostid_file)) == (struct _buf *)-1) {
-		/* hostid file not found */
-		tsc = tsc_read();
-		if (tsc == 0)	/* tsc_read can return zero sometimes */
-			hostid = (int32_t)tenmicrodata & 0x0CFFFFF;
-		else
-			hostid = (int32_t)tsc & 0x0CFFFFF;
+		/*
+		 * hostid file not found - try to load sysinit module
+		 * and see if it has a nonzero hostid value...use that
+		 * instead of generating a new hostid here if so.
+		 */
+		if ((i = modload("misc", "sysinit")) != -1) {
+			if (strlen(hw_serial) > 0)
+				hostid = (int32_t)atoi(hw_serial);
+			(void) modunload(i);
+		}
+		if (hostid == -1) {
+			tsc = tsc_read();
+			if (tsc == 0)	/* tsc_read can return zero sometimes */
+				hostid = (int32_t)tenmicrodata & 0x0CFFFFF;
+			else
+				hostid = (int32_t)tsc & 0x0CFFFFF;
+		}
 	} else {
 		/* hostid file found */
 		while (!done) {
@@ -2628,6 +2649,18 @@
 	 */
 	return (hostid);
 }
+
+static int
+atoi(char *p)
+{
+	int i = 0;
+
+	while (*p != '\0')
+		i = 10 * i + (*p++ - '0');
+
+	return (i);
+}
+
 #endif /* _SOFT_HOSTID */
 
 void