changeset 7908:52b12fdb5fdf

6663818 Poor 'uuid_generate_time' performance in comparision to other OSes
author Rafael Vanoni Polanczyk <Rafael.Vanoni@Sun.COM>
date Wed, 22 Oct 2008 19:33:27 -0700
parents ca1310195b6f
children a10e699aa927
files usr/src/lib/libuuid/common/uuid.c usr/src/lib/libuuid/common/uuid_misc.c usr/src/lib/libuuid/common/uuid_misc.h
diffstat 3 files changed, 249 insertions(+), 371 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libuuid/common/uuid.c	Wed Oct 22 18:11:09 2008 -0700
+++ b/usr/src/lib/libuuid/common/uuid.c	Wed Oct 22 19:33:27 2008 -0700
@@ -23,8 +23,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * The copyright in this file is taken from the original Leach & Salz
  * UUID specification, from which this implementation is derived.
@@ -49,12 +47,10 @@
  */
 
 /*
- * Module:		uuid.c
- *
- * Description:		This module is the workhorse for generating abstract
- *			UUIDs.  It delegates system-specific tasks (such
- *			as obtaining the node identifier or system time)
- *			to the sysdep module.
+ * This module is the workhorse for generating abstract
+ * UUIDs.  It delegates system-specific tasks (such
+ * as obtaining the node identifier or system time)
+ * to the sysdep module.
  */
 
 #include <ctype.h>
@@ -66,124 +62,125 @@
 #include <strings.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <uuid/uuid.h>
-#include <thread.h>
 #include <synch.h>
+#include <sys/mman.h>
 #include "uuid_misc.h"
 
-#define	STATE_LOCATION		"/var/sadm/system/uuid_state"
-#define	URANDOM_PATH		"/dev/urandom"
-#define	MAX_RETRY		8
-#define	VER1_MASK		0xefff
+shared_buffer_t		*data;
+
+static	uuid_node_t	node_id_cache;
+static	int		node_init;
+static	int		buffer_init;
+static	int		file_type;
+static	int		fd;
 
-static	mutex_t			ulock = DEFAULTMUTEX;
+/*
+ * misc routines
+ */
+uint16_t		get_random(void);
+void			get_current_time(uuid_time_t *);
 
-uint16_t	_get_random(void);
-void		_get_current_time(uuid_time_t *);
-void		struct_to_string(uuid_t, struct uuid *);
-void		string_to_struct(struct uuid *, uuid_t);
-int		get_ethernet_address(uuid_node_t *);
+void			struct_to_string(uuid_t, struct uuid *);
+void			string_to_struct(struct uuid *, uuid_t);
+int			get_ethernet_address(uuid_node_t *);
 
 /*
  * local functions
  */
-static	int	_lock_state(char *);
-static	void	_unlock_state(int);
-static	void	_read_state(int, uint16_t *, uuid_time_t *,
-		    uuid_node_t *);
-static	int	_write_state(int, uint16_t, uuid_time_t, uuid_node_t);
-static	void 	_format_uuid(struct uuid *, uint16_t, uuid_time_t,
-		    uuid_node_t);
-static	void	fill_random_bytes(uchar_t *, int);
-static	int	uuid_create(struct uuid *);
+static	int		map_state();
+static	void 		format_uuid(struct uuid *, uint16_t, uuid_time_t,
+    uuid_node_t);
+static	void		fill_random_bytes(uchar_t *, int);
+static	int		uuid_create(struct uuid *);
+static	void		gen_ethernet_address(uuid_node_t *);
+static	void		revalidate_data(uuid_node_t *);
 
-static	void	gen_ethernet_address(uuid_node_t *);
 /*
- * Name:		uuid_create.
- *
- * Description:	Generates a uuid based on Version 1 format
- *
- * Returns:	0 on success, -1 on Error
+ * Generates a uuid based on version 1 format.
+ * Returns 0 on success and -1 on failure.
  */
 static int
 uuid_create(struct uuid *uuid)
 {
-	uuid_time_t	timestamp, last_time;
-	uint16_t	clockseq = 0;
-	uuid_node_t	last_node;
+	uuid_time_t	timestamp;
 	uuid_node_t	system_node;
-	int		locked_state_fd;
-	int		non_unique = 0;
+	int		ret, non_unique = 0;
 
-	if (mutex_lock(&ulock) != 0) {
-	    return (-1);
+	/*
+	 * Get the system MAC address and/or cache it
+	 */
+	if (node_init) {
+		bcopy(&node_id_cache, &system_node, sizeof (uuid_node_t));
+	} else {
+		gen_ethernet_address(&system_node);
+		bcopy(&system_node, &node_id_cache, sizeof (uuid_node_t));
+		node_init = 1;
 	}
 
-	gen_ethernet_address(&system_node);
 	/*
-	 * acquire system wide lock so we're alone
+	 * Access the state file, mmap it and initialize the shared lock.
+	 * file_type tells us whether we had access to the state file or
+	 * created a temporary one.
 	 */
-	locked_state_fd = _lock_state(STATE_LOCATION);
-	if (locked_state_fd < 0) {
-	    /* couldn't create and/or lock state; don't have access */
-	    non_unique++;
-	} else {
-	    /* read saved state from disk */
-	    _read_state(locked_state_fd, &clockseq, &last_time,
-			&last_node);
-	}
+	buffer_init = map_state();
 
-	if (clockseq == 0) {
-	    /* couldn't read clock sequence; generate a random one */
-	    clockseq = _get_random();
-	    non_unique++;
-	}
-	if (memcmp(&system_node, &last_node, sizeof (uuid_node_t)) != 0) {
-	    clockseq++;
+	if (!buffer_init) {
+		return (buffer_init);
 	}
 
 	/*
-	 * get current time
+	 * Acquire the lock
 	 */
-	_get_current_time(&timestamp);
+	for (;;) {
+		if ((ret = mutex_lock(&data->lock)) == 0)
+			break;
+		else
+			switch (ret) {
+				case EOWNERDEAD:
+					revalidate_data(&system_node);
+					(void) mutex_consistent(&data->lock);
+					(void) mutex_unlock(&data->lock);
+					break;
+				case ENOTRECOVERABLE:
+					return (ret);
+					break;
+			}
+	}
+
+	/* State file is either new or is temporary, get a random clock seq */
+	if (data->state.clock == 0) {
+		data->state.clock = get_random();
+		non_unique++;
+	}
+
+	if (memcmp(&system_node, &data->state.node, sizeof (uuid_node_t)) != 0)
+		data->state.clock++;
+
+	get_current_time(&timestamp);
 
 	/*
-	 * If timestamp is not set or is not in the past,
-	 * increment clock sequence.
+	 * If timestamp is not set or is not in the past, bump
+	 * data->state.clock
 	 */
-	if ((last_time == 0) || (last_time >= timestamp)) {
-	    clockseq++;
-	    last_time = timestamp;
+	if ((data->state.ts == 0) || (data->state.ts >= timestamp)) {
+		data->state.clock++;
+		data->state.ts = timestamp;
 	}
 
 	if (non_unique)
 		system_node.nodeID[0] |= 0x80;
-	/*
-	 * stuff fields into the UUID
-	 */
-	_format_uuid(uuid, clockseq, timestamp, system_node);
-	if ((locked_state_fd >= 0) &&
-		(_write_state(locked_state_fd, clockseq, timestamp,
-		system_node) == -1)) {
-	    _unlock_state(locked_state_fd);
-	    (void) mutex_unlock(&ulock);
-	    return (-1);
-	}
-	/*
-	 * Unlock system-wide lock
-	 */
-	_unlock_state(locked_state_fd);
-	(void) mutex_unlock(&ulock);
+
+	/* Stuff fields into the UUID struct */
+	format_uuid(uuid, data->state.clock, timestamp, system_node);
+
+	(void) mutex_unlock(&data->lock);
+
 	return (0);
 }
 
 /*
- * Name:	gen_ethernet_address
- *
- * Description: Fills system_node with Ethernet address if available,
- *		else fills random numbers
- *
- * Returns:	Nothing
+ * Fills system_node with Ethernet address if available,
+ * else fills random numbers
  */
 static void
 gen_ethernet_address(uuid_node_t *system_node)
@@ -204,16 +201,11 @@
 }
 
 /*
- * Name:	_format_uuid
- *
- * Description: Formats a UUID, given the clock_seq timestamp,
- * 		and node address.  Fills in passed-in pointer with
- *		the resulting uuid.
- *
- * Returns:	None.
+ * Formats a UUID, given the clock_seq timestamp, and node address.
+ * Fills in passed-in pointer with the resulting uuid.
  */
 static void
-_format_uuid(struct uuid *uuid, uint16_t clock_seq,
+format_uuid(struct uuid *uuid, uint16_t clock_seq,
     uuid_time_t timestamp, uuid_node_t node)
 {
 
@@ -222,8 +214,7 @@
 	 */
 	uuid->time_low = (uint32_t)(timestamp & 0xFFFFFFFF);
 	uuid->time_mid = (uint16_t)((timestamp >> 32) & 0xFFFF);
-	uuid->time_hi_and_version = (uint16_t)((timestamp >> 48) &
-	    0x0FFF);
+	uuid->time_hi_and_version = (uint16_t)((timestamp >> 48) & 0x0FFF);
 
 	/*
 	 * This is version 1, so say so in the UUID version field (4 bits)
@@ -253,72 +244,63 @@
 }
 
 /*
- * Name:	_read_state
- *
- * Description: Reads non-volatile state from a (possibly) saved statefile.
- * 		For each non-null pointer passed-in, the corresponding
- *		information from the statefile is filled in.
- *		the resulting uuid.
- *
- * Returns:	Nothing.
+ * Opens/creates the state file, falling back to a tmp
  */
-static void
-_read_state(int fd, uint16_t *clockseq,
-    uuid_time_t *timestamp, uuid_node_t *node)
+static int
+map_state()
 {
-	uuid_state_t	vol_state;
+	FILE	*tmp;
+
+	/* If file's mapped, return */
+	if (file_type != 0)
+		return (1);
 
-	bzero(node, sizeof (uuid_node_t));
-	*timestamp = 0;
-	*clockseq = 0;
+	if ((fd = open(STATE_LOCATION, O_RDWR)) < 0) {
+		file_type = TEMP_FILE;
 
-	if (read(fd, &vol_state, sizeof (vol_state)) < sizeof (vol_state)) {
-		/* This file is being accessed the first time */
-		return;
+		if ((tmp = tmpfile()) == NULL)
+			return (-1);
+		else
+			fd = fileno(tmp);
+	} else {
+		file_type = STATE_FILE;
 	}
 
-	*node = vol_state.node;
-	*timestamp = vol_state.ts;
-	*clockseq = vol_state.cs;
+	(void) ftruncate(fd, (off_t)sizeof (shared_buffer_t));
+
+	/* LINTED - alignment */
+	data = (shared_buffer_t *)mmap(NULL, sizeof (shared_buffer_t),
+	    PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+
+	if (data == MAP_FAILED)
+		return (-1);
+
+	(void) mutex_init(&data->lock, USYNC_PROCESS|LOCK_ROBUST, 0);
+
+	(void) close(fd);
+
+	return (1);
 }
 
+static void
+revalidate_data(uuid_node_t *node)
+{
+	int i;
+
+	data->state.ts = 0;
+
+	for (i = 0; i < sizeof (data->state.node.nodeID); i++)
+		data->state.node.nodeID[i] = 0;
+
+	data->state.clock = 0;
+
+	gen_ethernet_address(node);
+	bcopy(node, &node_id_cache, sizeof (uuid_node_t));
+	node_init = 1;
+}
 
 /*
- * Name:	_write_state
- *
- * Description: Writes non-volatile state from the passed-in information.
- *
- * Returns:	-1 on error, 0 otherwise.
- */
-static int
-_write_state(int fd, uint16_t clockseq,
-    uuid_time_t timestamp, uuid_node_t node)
-{
-	uuid_state_t	vol_state;
-
-	vol_state.cs = clockseq;
-	vol_state.ts = timestamp;
-	vol_state.node = node;
-	/*
-	 * seek to beginning of file and write data
-	 */
-	if (lseek(fd, 0, SEEK_SET) != -1) {
-	    if (write(fd, &vol_state, sizeof (uuid_state_t)) != -1) {
-		return (0);
-	    }
-	}
-	return (-1);
-}
-
-
-
-/*
- * Name:	_uuid_print
- *
- * Description:	Prints a nicely-formatted uuid to stdout.
- *
- * Returns:	None.
- *
+ * Prints a nicely-formatted uuid to stdout.
  */
 void
 uuid_print(struct uuid u)
@@ -334,72 +316,10 @@
 }
 
 /*
- * Name:	_lock_state
- *
- * Description:	Locks down the statefile, by first creating the file
- *		if it doesn't exist.
- *
- * Returns:	A non-negative file descriptor referring to the locked
- *		state file, if it was able to be created and/or locked,
- *		or -1 otherwise.
- */
-static int
-_lock_state(char *loc)
-{
-	int fd;
-	struct flock lock;
-
-	fd = open(loc, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
-
-	if (fd < 0) {
-		return (-1);
-	}
-
-	lock.l_type = F_WRLCK;
-	lock.l_start = 0;
-	lock.l_whence = SEEK_SET;
-	lock.l_len = 0;
-
-	if (fcntl(fd, F_SETLKW, &lock) == -1) {
-		/*
-		 * File could not be locked, bail
-		 */
-		(void) close(fd);
-		return (-1);
-	}
-	return (fd);
-}
-
-/*
- * Name:	_unlock_state
- *
- * Description:	Unlocks a locked statefile, and close()'s the file.
- *
- * Returns:	Nothing.
- */
-void
-_unlock_state(int fd)
-{
-	struct flock lock;
-
-	lock.l_type = F_UNLCK;
-	lock.l_start = 0;
-	lock.l_whence = SEEK_SET;
-	lock.l_len = 0;
-
-	(void) fcntl(fd, F_SETLK, &lock);
-	(void) close(fd);
-}
-
-/*
- * Name:	fill_random_bytes
- *
- * Description:	fills buf with random numbers - nbytes is the number of bytes
- *		to fill-in. Tries to use /dev/urandom random number generator-
- *		if that fails for some reason, it retries MAX_RETRY times. If
- *		it still fails then it uses srand48(3C)
- *
- * Returns:	Nothing.
+ * Fills buf with random numbers - nbytes is the number of bytes
+ * to fill-in. Tries to use /dev/urandom random number generator-
+ * if that fails for some reason, it retries MAX_RETRY times. If
+ * it still fails then it uses srand48(3C)
  */
 static void
 fill_random_bytes(uchar_t *buf, int nbytes)
@@ -408,40 +328,35 @@
 
 	fd = open(URANDOM_PATH, O_RDONLY);
 	if (fd >= 0) {
-	    while (nbytes > 0) {
-		i = read(fd, buf, nbytes);
-		if ((i < 0) && (errno == EINTR)) {
-		    continue;
+		while (nbytes > 0) {
+			i = read(fd, buf, nbytes);
+			if ((i < 0) && (errno == EINTR)) {
+				continue;
+			}
+			if (i <= 0) {
+				if (retries++ == MAX_RETRY)
+					break;
+				continue;
+			}
+			nbytes -= i;
+			buf += i;
+			retries = 0;
 		}
-		if (i <= 0) {
-		    if (retries++ == MAX_RETRY)
-			break;
-		    continue;
+		if (nbytes == 0) {
+			(void) close(fd);
+			return;
 		}
-		nbytes -= i;
-		buf += i;
-		retries = 0;
-	    }
-	    if (nbytes == 0) {
-		(void) close(fd);
-		return;
-	    }
 	}
 	for (i = 0; i < nbytes; i++) {
-	    *buf++ = _get_random() & 0xFF;
+		*buf++ = get_random() & 0xFF;
 	}
 	if (fd >= 0) {
-	    (void) close(fd);
+		(void) close(fd);
 	}
 }
 
 /*
- * Name:	struct_to_string
- *
- * Description:	Unpacks the structure members in "struct uuid" to a char
- *		string "uuid_t".
- *
- * Returns:	Nothing.
+ * Unpacks the structure members in "struct uuid" to a char string "uuid_t".
  */
 void
 struct_to_string(uuid_t ptr, struct uuid *uu)
@@ -478,18 +393,13 @@
 }
 
 /*
- * Name:	string_to_struct
- *
- * Description:	Packs the values in the "uuid_t" string into "struct uuid".
- *
- * Returns:	Nothing
+ * Packs the values in the "uuid_t" string into "struct uuid".
  */
 void
 string_to_struct(struct uuid *uuid, uuid_t in)
 {
-
-	uchar_t 	*ptr;
-	uint_t		tmp;
+	uchar_t	*ptr;
+	uint_t	tmp;
 
 	ptr = in;
 
@@ -518,20 +428,15 @@
 }
 
 /*
- * Name:	uuid_generate_random
- *
- * Description:	Generates UUID based on DCE Version 4
- *
- * Returns:	Nothing. uu contains the newly generated UUID
+ * Generates UUID based on DCE Version 4
  */
 void
 uuid_generate_random(uuid_t uu)
 {
-
 	struct uuid	uuid;
 
 	if (uu == NULL)
-	    return;
+		return;
 
 	(void) memset(uu, 0, sizeof (uuid_t));
 	(void) memset(&uuid, 0, sizeof (struct uuid));
@@ -562,36 +467,29 @@
 }
 
 /*
- * Name:	uuid_generate_time
- *
- * Description:	Generates UUID based on DCE Version 1.
- *
- * Returns:	Nothing. uu contains the newly generated UUID.
+ * Generates UUID based on DCE Version 1.
  */
 void
 uuid_generate_time(uuid_t uu)
 {
-	struct uuid uuid;
+	struct 	uuid uuid;
 
 	if (uu == NULL)
-	    return;
+		return;
 
-	if (uuid_create(&uuid) == -1) {
-	    uuid_generate_random(uu);
-	    return;
+	if (uuid_create(&uuid) < 0) {
+		uuid_generate_random(uu);
+		return;
 	}
+
 	struct_to_string(uu, &uuid);
 }
 
 /*
- * Name:	uuid_generate
- *
- * Description:	Creates a new UUID. The uuid will be generated based on
- *		high-quality randomness from /dev/urandom, if available by
- *		calling uuid_generate_random. If it failed to generate UUID
- *		then uuid_generate will call uuid_generate_time.
- *
- * Returns:	Nothing. uu contains the newly generated UUID.
+ * Creates a new UUID. The uuid will be generated based on high-quality
+ * randomness from /dev/urandom, if available by calling uuid_generate_random.
+ * If it failed to generate UUID then uuid_generate will call
+ * uuid_generate_time.
  */
 void
 uuid_generate(uuid_t uu)
@@ -599,38 +497,28 @@
 	int fd;
 
 	if (uu == NULL) {
-	    return;
+		return;
 	}
 	fd = open(URANDOM_PATH, O_RDONLY);
 	if (fd >= 0) {
-	    (void) close(fd);
-	    uuid_generate_random(uu);
+		(void) close(fd);
+		uuid_generate_random(uu);
 	} else {
-	    (void) uuid_generate_time(uu);
+		(void) uuid_generate_time(uu);
 	}
 }
 
 /*
- * Name:	uuid_copy
- *
- * Description:	The uuid_copy function copies the UUID variable src to dst
- *
- * Returns:	Nothing
+ * Copies the UUID variable src to dst.
  */
 void
 uuid_copy(uuid_t dst, uuid_t src)
 {
-
 	(void) memcpy(dst, src, UUID_LEN);
 }
 
 /*
- * Name:	uuid_clear
- *
- * Description:	The uuid_clear function sets the value of the supplied uuid
- *		variable uu, to the NULL value.
- *
- * Returns:	Nothing
+ * Sets the value of the supplied uuid variable uu, to the NULL value.
  */
 void
 uuid_clear(uuid_t uu)
@@ -639,13 +527,9 @@
 }
 
 /*
- * Name:	uuid_unparse
- *
- * Description:	This function converts the supplied UUID uu from the internal
- *		binary format into a 36-byte string (plus trailing null char)
- *		and stores this value in the character string pointed to by out
- *
- * Returns:	Nothing.
+ * This function converts the supplied UUID uu from the internal
+ * binary format into a 36-byte string (plus trailing null char)
+ * and stores this value in the character string pointed to by out.
  */
 void
 uuid_unparse(uuid_t uu, char *out)
@@ -657,7 +541,7 @@
 
 	/* basic sanity checking */
 	if (uu == NULL) {
-	    return;
+		return;
 	}
 
 	/* XXX user should have allocated enough memory */
@@ -670,25 +554,20 @@
 	clock_seq = uuid.clock_seq_hi_and_reserved;
 	clock_seq = (clock_seq  << 8) | uuid.clock_seq_low;
 	for (i = 0; i < 6; i++) {
-	    (void) sprintf(&etheraddr[index++], "%.2x", uuid.node_addr[i]);
-	    index++;
+		(void) sprintf(&etheraddr[index++], "%.2x", uuid.node_addr[i]);
+		index++;
 	}
 	etheraddr[index] = '\0';
 
 	(void) snprintf(out, 25, "%08x-%04x-%04x-%04x-",
-	    uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
-		clock_seq);
+	    uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, clock_seq);
 	(void) strlcat(out, etheraddr, UUID_PRINTABLE_STRING_LENGTH);
 }
 
 /*
- * Name:	uuid_is_null
- *
- * Description:	The uuid_is_null function compares the value of the supplied
- *		UUID variable uu to the NULL value. If the value is equal
- *		to the NULL UUID, 1 is returned, otherwise 0 is returned.
- *
- * Returns:	0 if uu is NOT null, 1 if uu is NULL.
+ * The uuid_is_null function compares the value of the supplied
+ * UUID variable uu to the NULL value. If the value is equal
+ * to the NULL UUID, 1 is returned, otherwise 0 is returned.
  */
 int
 uuid_is_null(uuid_t uu)
@@ -699,23 +578,19 @@
 	(void) memset(null_uu, 0, sizeof (uuid_t));
 	i = memcmp(uu, null_uu, sizeof (uuid_t));
 	if (i == 0) {
-	/* uu is NULL uuid */
-	    return (1);
+		/* uu is NULL uuid */
+		return (1);
 	} else {
-	    return (0);
+		return (0);
 	}
 }
 
 /*
- * Name:	uuid_parse
- *
- * Description:	uuid_parse converts the UUID string given by 'in' into the
- *		internal uuid_t format. The input UUID is a string of the form
- *		cefa7a9c-1dd2-11b2-8350-880020adbeef in printf(3C) format.
- *		Upon successfully parsing the input string, UUID is stored
- *		in the location pointed to by uu
- *
- * Returns:	0 if the UUID is successfully stored, -1 otherwise.
+ * uuid_parse converts the UUID string given by 'in' into the
+ * internal uuid_t format. The input UUID is a string of the form
+ * cefa7a9c-1dd2-11b2-8350-880020adbeef in printf(3C) format.
+ * Upon successfully parsing the input string, UUID is stored
+ * in the location pointed to by uu
  */
 int
 uuid_parse(char *in, uuid_t uu)
@@ -728,20 +603,20 @@
 
 	/* do some sanity checking */
 	if ((strlen(in) != 36) || (uu == NULL) || (in[36] != '\0')) {
-	    return (-1);
+		return (-1);
 	}
 
 	ptr = in;
 	for (i = 0; i < 36; i++, ptr++) {
-	    if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) {
-		if (*ptr != '-') {
-		    return (-1);
+		if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) {
+			if (*ptr != '-') {
+				return (-1);
+			}
+		} else {
+			if (!isxdigit(*ptr)) {
+				return (-1);
+			}
 		}
-	    } else {
-		if (!isxdigit(*ptr)) {
-		    return (-1);
-		}
-	    }
 	}
 
 	uuid.time_low = strtoul(in, NULL, 16);
@@ -754,26 +629,21 @@
 	ptr = in+24;
 	buf[2] = '\0';
 	for (i = 0; i < 6; i++) {
-	    buf[0] = *ptr++;
-	    buf[1] = *ptr++;
-	    uuid.node_addr[i] = strtoul(buf, NULL, 16);
+		buf[0] = *ptr++;
+		buf[1] = *ptr++;
+		uuid.node_addr[i] = strtoul(buf, NULL, 16);
 	}
 	struct_to_string(uu, &uuid);
 	return (0);
 }
 
 /*
- * Name:	uuid_time
- *
- * Description:	uuid_time extracts the time at which the supplied UUID uu
- *		was created. This function can only extract the creation
- *		time for UUIDs created with the uuid_generate_time function.
- *		The time at which the UUID was created, in seconds and
- *		microseconds since the epoch is stored in the location
- *		pointed to by ret_tv.
- *
- * Returns:	The time at which the UUID was created, in seconds since
- *		January  1, 1970 GMT (the epoch). -1 otherwise.
+ * uuid_time extracts the time at which the supplied UUID uu
+ * was created. This function can only extract the creation
+ * time for UUIDs created with the uuid_generate_time function.
+ * The time at which the UUID was created, in seconds and
+ * microseconds since the epoch is stored in the location
+ * pointed to by ret_tv.
  */
 time_t
 uuid_time(uuid_t uu, struct timeval *ret_tv)
@@ -791,7 +661,7 @@
 
 	/* check if uu is NULL, Version = 1 of DCE and Variant = 0b10x */
 	if ((uu == NULL) || ((tmp & 0x01) != 0x01) || ((clk & 0x80) != 0x80)) {
-	    return (-1);
+		return (-1);
 	}
 	high = uuid.time_mid | ((uuid.time_hi_and_version & 0xFFF) << 16);
 	clock_reg = uuid.time_low | ((u_longlong_t)high << 32);
@@ -801,7 +671,7 @@
 	tv.tv_usec = (clock_reg % 10000000) / 10;
 
 	if (ret_tv) {
-	    *ret_tv = tv;
+		*ret_tv = tv;
 	}
 
 	return (tv.tv_sec);
--- a/usr/src/lib/libuuid/common/uuid_misc.c	Wed Oct 22 18:11:09 2008 -0700
+++ b/usr/src/lib/libuuid/common/uuid_misc.c	Wed Oct 22 19:33:27 2008 -0700
@@ -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.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -49,8 +48,6 @@
  * suitability of this software for any purpose.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <uuid/uuid.h>
 #include <stdlib.h>
 #include <strings.h>
@@ -64,7 +61,7 @@
 void		get_system_time(uuid_time_t *);
 
 /*
- * Name:	_get_current_time
+ * Name:	get_current_time
  *
  * Description:	get-current_time -- get time as 60 bit 100ns ticks
  *		since the beginning of unix time.
@@ -75,7 +72,7 @@
  *
  */
 void
-_get_current_time(uuid_time_t *timestamp)
+get_current_time(uuid_time_t *timestamp)
 {
 	uuid_time_t		time_now;
 	static uuid_time_t	time_last = 0;
@@ -113,7 +110,7 @@
 }
 
 /*
- * Name:	_get_random
+ * Name:	get_random
  *
  * Description:	Gets a random number.
  *
@@ -121,7 +118,7 @@
  *
  */
 uint16_t
-_get_random(void)
+get_random(void)
 {
 	static int	initted = 0;
 	uuid_time_t	time_now;
--- a/usr/src/lib/libuuid/common/uuid_misc.h	Wed Oct 22 18:11:09 2008 -0700
+++ b/usr/src/lib/libuuid/common/uuid_misc.h	Wed Oct 22 19:33:27 2008 -0700
@@ -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,15 +19,13 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2000, 2002 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #ifndef	_UUID_MISC_H
 #define	_UUID_MISC_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * The copyright in this file is taken from the original Leach
  * & Salz UUID specification, from which this implementation
@@ -59,19 +56,33 @@
 
 #include <uuid/uuid.h>
 #include <sys/types.h>
+#include <thread.h>
 
-typedef uint64_t	uuid_time_t;
+typedef uint64_t		uuid_time_t;
 
 /*
  * data type for UUID generator persistent state
  */
 typedef struct {
-	uuid_time_t	ts;	/* saved timestamp */
-	uuid_node_t	node;	/* saved node ID */
-	uint16_t	cs;	/* saved clock sequence */
+	uuid_time_t		ts;	/* saved timestamp */
+	uuid_node_t		node;	/* saved node ID */
+	uint16_t		clock;	/* saved clock sequence */
 } uuid_state_t;
 
-#ifdef __cplusplus
+typedef struct {
+	mutex_t			lock;
+	uuid_state_t		state;
+} shared_buffer_t;
+
+#define	STATE_LOCATION		"/var/sadm/system/uuid_state"
+#define	URANDOM_PATH		"/dev/urandom"
+#define	MAX_RETRY		8
+#define	VER1_MASK		0xefff
+
+#define	STATE_FILE		1
+#define	TEMP_FILE		2
+
+#ifdef	__cplusplus
 }
 #endif