Mercurial > illumos > illumos-gate
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(×tamp); + 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(×tamp); /* - * 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(ðeraddr[index++], "%.2x", uuid.node_addr[i]); - index++; + (void) sprintf(ðeraddr[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