uuidgen(2) syscall. Originally from FreeBSD, ported by John Franklin in

PR#23470, with minor updates by me. This is only the syscall support
from that PR, for now.

Changes: port over fix from FreeBSD for multicast address generation.
Changed bcopy to memcpy.  For now, #ifdef notyet the portions of
kern_uuid.c that are meant to be used by (currently nonexistent) other
things in the kernel.  Added syscall to COMPAT_FREEBSD as well, though
that's currently not useful, as any program new enough to use this call
also uses other syscalls we don't (yet) emulate.
This commit is contained in:
tsarna 2004-01-29 02:00:02 +00:00
parent ab83e1a00d
commit 72489e1ea0
20 changed files with 591 additions and 34 deletions

View File

@ -1,6 +1,6 @@
# $NetBSD: shl.mi,v 1.254 2004/01/15 19:46:20 kleink Exp $
# $NetBSD: shl.mi,v 1.255 2004/01/29 02:00:02 tsarna Exp $
# Note: libtermcap and libtermlib are hardlinked and share the same version.
./lib/libc.so.12.110 base-sys-shlib
./lib/libc.so.12.111 base-sys-shlib
./lib/libcrypt.so.0.1 base-sys-shlib
./lib/libcrypto.so.2.1 base-crypto-shlib crypto
./lib/libedit.so.2.9 base-sys-shlib
@ -32,7 +32,7 @@
./usr/lib/libasn1.so.6.1 base-krb5-shlib kerberos
./usr/lib/libbsdmalloc.so.0.0 base-sys-shlib
./usr/lib/libbz2.so.1.0 base-sys-shlib
./usr/lib/libc.so.12.110 base-sys-shlib
./usr/lib/libc.so.12.111 base-sys-shlib
./usr/lib/libcdk.so.1.0 base-sys-shlib
./usr/lib/libcom_err.so.4.1 base-krb5-shlib kerberos
./usr/lib/libcrypt.so.0.1 base-sys-shlib

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.667 2004/01/28 17:44:25 jdolecek Exp $
# $NetBSD: mi,v 1.668 2004/01/29 02:00:02 tsarna Exp $
./usr/bin/addr2line comp-debug-bin bfd
./usr/bin/ar comp-util-bin bfd
./usr/bin/as comp-util-bin bfd
@ -1387,6 +1387,7 @@
./usr/include/sys/unpcb.h comp-c-include
./usr/include/sys/user.h comp-c-include
./usr/include/sys/utsname.h comp-c-include
./usr/include/sys/uuid.h comp-c-include
./usr/include/sys/vadvise.h comp-c-include
./usr/include/sys/vcmd.h comp-obsolete obsolete
./usr/include/sys/verified_exec.h comp-c-include
@ -2100,6 +2101,7 @@
./usr/share/man/cat2/unmount.0 comp-c-catman .cat
./usr/share/man/cat2/utimes.0 comp-c-catman .cat
./usr/share/man/cat2/utrace.0 comp-c-catman .cat
./usr/share/man/cat2/uuidgen.0 comp-c-catman
./usr/share/man/cat2/vfork.0 comp-c-catman .cat
./usr/share/man/cat2/wait.0 comp-c-catman .cat
./usr/share/man/cat2/wait3.0 comp-c-catman .cat
@ -5711,6 +5713,7 @@
./usr/share/man/man2/unmount.2 comp-c-man .man
./usr/share/man/man2/utimes.2 comp-c-man .man
./usr/share/man/man2/utrace.2 comp-c-man .man
./usr/share/man/man2/uuidgen.2 comp-c-man
./usr/share/man/man2/vfork.2 comp-c-man .man
./usr/share/man/man2/wait.2 comp-c-man .man
./usr/share/man/man2/wait3.2 comp-c-man .man

View File

@ -1,4 +1,4 @@
# $NetBSD: shlib_version,v 1.144 2004/01/15 19:44:46 kleink Exp $
# $NetBSD: shlib_version,v 1.145 2004/01/29 02:00:02 tsarna Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
# things we wish to do on next major version bump:
@ -13,4 +13,4 @@
# - infinity{,f,l}.c, math.h: __infinity -> __huge_val
#
major=12
minor=110
minor=111

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.146 2004/01/02 18:56:39 cl Exp $
# $NetBSD: Makefile.inc,v 1.147 2004/01/29 02:00:02 tsarna Exp $
# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
# sys sources
@ -72,7 +72,7 @@ ASM= access.S acct.S bind.S chdir.S chflags.S \
__sigaction_sigtramp.S __sigtimedwait.S \
socket.S socketpair.S __stat13.S statfs.S \
swapctl.S symlink.S umask.S undelete.S unlink.S \
unmount.S utimes.S utrace.S vadvise.S \
unmount.S utimes.S utrace.S uuidgen.S vadvise.S \
__sysctl.S \
__posix_chown.S __posix_fchown.S __posix_lchown.S __posix_rename.S \
_lwp_create.S _lwp_exit.S _lwp_self.S _lwp_wait.S \
@ -154,7 +154,7 @@ MAN+= accept.2 access.2 acct.2 adjtime.2 bind.2 brk.2 chdir.2 \
socketpair.2 stat.2 statfs.2 swapctl.2 swapon.3 symlink.2 \
sync.2 sysarch.2 syscall.2 timer_create.2 timer_delete.2 \
timer_settime.2 truncate.2 umask.2 undelete.2 \
unlink.2 utimes.2 utrace.2 vfork.2 wait.2 write.2
unlink.2 utimes.2 utrace.2 uuidgen.2 vfork.2 wait.2 write.2
MLINKS+=_exit.2 _Exit.2
MLINKS+=brk.2 sbrk.2

View File

@ -1,5 +1,5 @@
#!/bin/sh -
# $NetBSD: makelintstub,v 1.15 2003/09/30 22:30:16 christos Exp $
# $NetBSD: makelintstub,v 1.16 2004/01/29 02:00:02 tsarna Exp $
#
# Copyright (c) 1996, 1997 Christopher G. Demetriou
# All rights reserved.
@ -67,6 +67,7 @@ header()
#include <sys/timex.h>
#include <sys/socket.h>
#include <sys/event.h>
#include <sys/uuid.h>
#ifdef __STDC__
#include <stdarg.h>
#else

146
lib/libc/sys/uuidgen.2 Normal file
View File

@ -0,0 +1,146 @@
.\" $NetBSD: uuidgen.2,v 1.1 2004/01/29 02:00:02 tsarna Exp $
.\" $FreeBSD: src/lib/libc/sys/uuidgen.2,v 1.7 2003/06/27 13:41:29 yar Exp $
.\" Copyright (c) 2002 Marcel Moolenaar
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD: src/lib/libc/sys/uuidgen.2,v 1.7 2003/06/27 13:41:29 yar Exp $
.\"
.Dd May 26, 2002
.Dt UUIDGEN 2
.Os
.Sh NAME
.Nm uuidgen
.Nd generate universally unique identifiers
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In sys/uuid.h
.Ft int
.Fn uuidgen "struct uuid *store" "int count"
.Sh DESCRIPTION
The
.Fn uuidgen
system call generates
.Fa count
universally unique identifiers (UUIDs) and writes them to the buffer
pointed to by
.Fa store .
The identifiers are generated according to the syntax and semantics of the
DCE version 1 variant of universally unique identifiers.
See below for a more in-depth description of the identifiers.
When no IEEE 802
address is available for the node field, a random multicast address is
generated for each invocation of the system call.
According to the algorithm of generating time-based UUIDs, this will also
force a new random clock sequence, thereby increasing the likelyhood for
the identifier to be unique.
.Pp
When multiple identifiers are to be generated, the
.Fn uuidgen
system call will generate a set of identifiers that is dense in such a way
that there is no identifier that is larger than the smallest identifier in the
set and smaller than the largest identifier in the set and that is not already
in the set.
.Pp
Universally unique identifiers, also known as globally unique identifiers
(GUIDs), have a binary representation of 128-bits.
The grouping and meaning of these bits is described by the following
structure and its description of the fields that follow it:
.Bd -literal
struct uuid {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint8_t clock_seq_hi_and_reserved;
uint8_t clock_seq_low;
uint8_t node[_UUID_NODE_LEN];
};
.Ed
.Bl -tag -width ".Va clock_seq_hi_and_reserved"
.It Va time_low
The least significant 32 bits of a 60-bit timestamp.
This field is stored in the native byte-order.
.It Va time_mid
The least significant 16 bits of the most significant 28 bits of the 60-bit
timestamp.
This field is stored in the native byte-order.
.It Va time_hi_and_version
The most significant 12 bits of the 60-bit timestamp multiplexed with a 4-bit
version number.
The version number is stored in the most significant 4 bits of the 16-bit
field.
This field is stored in the native byte-order.
.It Va clock_seq_hi_and_reserved
The most significant 6 bits of a 14-bit sequence number multiplexed with a
2-bit variant value.
Note that the width of the variant value is determined by the variant itself.
Identifiers generated by the
.Fn uuidgen
system call have variant value 10b.
the variant value is stored in the most significant bits of the field.
.It Va clock_seq_low
The least significant 8 bits of a 14-bit sequence number.
.It Va node
The 6-byte IEEE 802 (MAC) address of one of the interfaces of the node.
If no such interface exists, a random multi-cast address is used instead.
.El
.Pp
The binary representation is sensitive to byte ordering.
Any multi-byte field is to be stored in the local or native byte-order and
identifiers must be converted when transmitted to hosts that do not agree
on the byte-order.
The specification does not however document what this means in concrete
terms and is otherwise beyond the scope of this system call.
.Sh RETURN VALUES
.Rv -std
.Sh ERRORS
The
.Fn uuidgen
system call can fail with:
.Bl -tag -width Er
.It Bq Er EFAULT
The buffer pointed to by
.Fa store
could not be written to for any or all identifiers.
.It Bq Er EINVAL
The
.Fa count
argument is less than 1 or larger than the hard upper limit of 2048.
.El
.Sh SEE ALSO
.Xr uuidgen 1 ,
.Xr uuid 3
.Sh STANDARDS
The identifiers are represented and generated in conformance with the DCE 1.1
RPC specification.
The
.Fn uuidgen
system call is itself not part of the specification.
.Sh HISTORY
The
.Fn uuidgen
system call first appeared in
.Fx 5.0 ,
and was subsequently added to
.Nx 2.0 .

View File

@ -1,4 +1,4 @@
/* $NetBSD: freebsd_syscall.h,v 1.52 2003/11/26 19:23:29 jdolecek Exp $ */
/* $NetBSD: freebsd_syscall.h,v 1.53 2004/01/29 02:00:02 tsarna Exp $ */
/*
* System call numbers.
@ -762,6 +762,9 @@
/* syscall: "lchflags" ret: "int" args: "const char *" "u_long" */
#define FREEBSD_SYS_lchflags 391
/* syscall: "uuidgen" ret: "int" args: "struct uuid *" "int" */
#define FREEBSD_SYS_uuidgen 392
#if defined(P1003_1B_SEMAPHORE) || !defined(_KERNEL)
/* syscall: "_ksem_close" ret: "int" args: "semid_t" */
#define FREEBSD_SYS__ksem_close 400

View File

@ -1,4 +1,4 @@
/* $NetBSD: freebsd_syscallargs.h,v 1.54 2003/11/26 19:23:29 jdolecek Exp $ */
/* $NetBSD: freebsd_syscallargs.h,v 1.55 2004/01/29 02:00:02 tsarna Exp $ */
/*
* System call argument lists.
@ -855,6 +855,8 @@ int sys___sigpending14(struct lwp *, void *, register_t *);
int sys_lchflags(struct lwp *, void *, register_t *);
int sys_uuidgen(struct lwp *, void *, register_t *);
#if defined(P1003_1B_SEMAPHORE) || !defined(_KERNEL)
int sys__ksem_close(struct lwp *, void *, register_t *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: freebsd_syscalls.c,v 1.52 2003/11/26 19:23:29 jdolecek Exp $ */
/* $NetBSD: freebsd_syscalls.c,v 1.53 2004/01/29 02:00:02 tsarna Exp $ */
/*
* System call names.
@ -8,7 +8,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: freebsd_syscalls.c,v 1.52 2003/11/26 19:23:29 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: freebsd_syscalls.c,v 1.53 2004/01/29 02:00:02 tsarna Exp $");
#if defined(_KERNEL_OPT)
#if defined(_KERNEL_OPT)
@ -492,7 +492,7 @@ const char *const freebsd_syscallnames[] = {
"#389 (unimplemented __mac_set_file)", /* 389 = unimplemented __mac_set_file */
"#390 (unimplemented kenv)", /* 390 = unimplemented kenv */
"lchflags", /* 391 = lchflags */
"#392 (unimplemented uuidgen)", /* 392 = unimplemented uuidgen */
"uuidgen", /* 392 = uuidgen */
"#393 (unimplemented sendfile)", /* 393 = unimplemented sendfile */
"#394 (unimplemented mac_syscall)", /* 394 = unimplemented mac_syscall */
"#395 (unimplemented getfsstat)", /* 395 = unimplemented getfsstat */

View File

@ -1,4 +1,4 @@
/* $NetBSD: freebsd_sysent.c,v 1.54 2003/11/26 19:23:29 jdolecek Exp $ */
/* $NetBSD: freebsd_sysent.c,v 1.55 2004/01/29 02:00:02 tsarna Exp $ */
/*
* System call switch table.
@ -8,7 +8,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: freebsd_sysent.c,v 1.54 2003/11/26 19:23:29 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: freebsd_sysent.c,v 1.55 2004/01/29 02:00:02 tsarna Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ktrace.h"
@ -910,8 +910,8 @@ struct sysent freebsd_sysent[] = {
sys_nosys }, /* 390 = unimplemented kenv */
{ 2, s(struct sys_lchflags_args), 0,
sys_lchflags }, /* 391 = lchflags */
{ 0, 0, 0,
sys_nosys }, /* 392 = unimplemented uuidgen */
{ 2, s(struct sys_uuidgen_args), 0,
sys_uuidgen }, /* 392 = uuidgen */
{ 0, 0, 0,
sys_nosys }, /* 393 = unimplemented sendfile */
{ 0, 0, 0,

View File

@ -1,4 +1,4 @@
$NetBSD: syscalls.master,v 1.42 2003/11/26 19:22:57 jdolecek Exp $
$NetBSD: syscalls.master,v 1.43 2004/01/29 02:00:02 tsarna Exp $
; from: @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@ -659,7 +659,7 @@
389 UNIMPL __mac_set_file
390 UNIMPL kenv
391 NOARGS { int sys_lchflags(const char *path, u_long flags); }
392 UNIMPL uuidgen
392 NOARGS { int sys_uuidgen(struct uuid *store, int count); }
393 UNIMPL sendfile
394 UNIMPL mac_syscall
395 UNIMPL getfsstat

View File

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.651 2004/01/20 19:58:01 jdolecek Exp $
# $NetBSD: files,v 1.652 2004/01/29 02:00:02 tsarna Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@ -1150,6 +1150,7 @@ file kern/kern_synch.c
file kern/kern_sysctl.c
file kern/kern_time.c
file kern/kern_timeout.c
file kern/kern_uuid.c
file kern/kern_xxx.c
file kern/kgdb_stub.c kgdb
file kern/subr_autoconf.c

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_sysent.c,v 1.152 2004/01/02 18:53:45 cl Exp $ */
/* $NetBSD: init_sysent.c,v 1.153 2004/01/29 02:00:03 tsarna Exp $ */
/*
* System call switch table.
@ -8,7 +8,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_sysent.c,v 1.152 2004/01/02 18:53:45 cl Exp $");
__KERNEL_RCSID(0, "$NetBSD: init_sysent.c,v 1.153 2004/01/29 02:00:03 tsarna Exp $");
#include "opt_ktrace.h"
#include "opt_nfsserver.h"
@ -953,8 +953,8 @@ struct sysent sysent[] = {
sys_nosys }, /* 353 = unimplemented sys_sched_rr_get_interval */
{ 4, s(struct sys_fsync_range_args), 0,
sys_fsync_range }, /* 354 = fsync_range */
{ 0, 0, 0,
sys_nosys }, /* 355 = filler */
{ 2, s(struct sys_uuidgen_args), 0,
sys_uuidgen }, /* 355 = uuidgen */
{ 0, 0, 0,
sys_nosys }, /* 356 = filler */
{ 0, 0, 0,

310
sys/kern/kern_uuid.c Normal file
View File

@ -0,0 +1,310 @@
/* $NetBSD: kern_uuid.c,v 1.1 2004/01/29 02:00:03 tsarna Exp $ */
/* $FreeBSD: /repoman/r/ncvs/src/sys/kern/kern_uuid.c,v 1.7 2004/01/12 13:34:11 rse Exp $ */
/*
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_uuid.c,v 1.1 2004/01/29 02:00:03 tsarna Exp $");
#include <sys/param.h>
#include <sys/endian.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/uuid.h>
/* NetBSD */
#include <sys/proc.h>
#include <sys/sa.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
#include <sys/uio.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
int sys_uuidgen(struct lwp *, void *, register_t *);
/*
* See also:
* http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
* http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
*
* Note that the generator state is itself an UUID, but the time and clock
* sequence fields are written in the native byte order.
*/
/* XXX Do we have a similar ASSERT()? */
#define CTASSERT(x)
CTASSERT(sizeof(struct uuid) == 16);
/* We use an alternative, more convenient representation in the generator. */
struct uuid_private {
union {
uint64_t ll; /* internal. */
struct {
uint32_t low;
uint16_t mid;
uint16_t hi;
} x;
} time;
uint16_t seq; /* Big-endian. */
uint16_t node[UUID_NODE_LEN>>1];
};
CTASSERT(sizeof(struct uuid_private) == 16);
static struct uuid_private uuid_last;
/* "UUID generator mutex lock" */
static struct simplelock uuid_mutex = SIMPLELOCK_INITIALIZER;
/*
* Return the first MAC address we encounter or, if none was found,
* construct a sufficiently random multicast address. We don't try
* to return the same MAC address as previously returned. We always
* generate a new multicast address if no MAC address exists in the
* system.
* It would be nice to know if 'ifnet' or any of its sub-structures
* has been changed in any way. If not, we could simply skip the
* scan and safely return the MAC address we returned before.
*/
static void
uuid_node(uint16_t *node)
{
struct ifnet *ifp;
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
int i, s;
s = splnet();
TAILQ_FOREACH(ifp, &ifnet, if_list) {
/* Walk the address list */
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
sdl = (struct sockaddr_dl*)ifa->ifa_addr;
if (sdl != NULL && sdl->sdl_family == AF_LINK &&
sdl->sdl_type == IFT_ETHER) {
/* Got a MAC address. */
memcpy(node, LLADDR(sdl), UUID_NODE_LEN);
splx(s);
return;
}
}
}
splx(s);
for (i = 0; i < (UUID_NODE_LEN>>1); i++)
node[i] = (uint16_t)arc4random();
*((uint8_t*)node) |= 0x01;
}
/*
* Get the current time as a 60 bit count of 100-nanosecond intervals
* since 00:00:00.00, October 15,1582. We apply a magic offset to convert
* the Unix time since 00:00:00.00, January 1, 1970 to the date of the
* Gregorian reform to the Christian calendar.
*/
/*
* At present, NetBSD has no timespec source, only timeval sources. So,
* we use timeval.
*/
static uint64_t
uuid_time(void)
{
struct timeval tv;
uint64_t time = 0x01B21DD213814000LL;
microtime(&tv);
time += (uint64_t)tv.tv_sec * 10000000LL;
time += (uint64_t)(10 * tv.tv_usec);
return (time & ((1LL << 60) - 1LL));
}
int
sys_uuidgen(struct lwp *l, void *v, register_t *retval)
{
struct sys_uuidgen_args *uap = v;
struct uuid_private uuid;
uint64_t time;
int error;
/*
* Limit the number of UUIDs that can be created at the same time
* to some arbitrary number. This isn't really necessary, but I
* like to have some sort of upper-bound that's less than 2G :-)
* XXX needs to be tunable.
*/
if (SCARG(uap,count) < 1 || SCARG(uap,count) > 2048)
return (EINVAL);
/* XXX: pre-validate accessibility to the whole of the UUID store? */
simple_lock(&uuid_mutex);
uuid_node(uuid.node);
time = uuid_time();
if (uuid_last.time.ll == 0LL || uuid_last.node[0] != uuid.node[0] ||
uuid_last.node[1] != uuid.node[1] ||
uuid_last.node[2] != uuid.node[2])
uuid.seq = (uint16_t)arc4random() & 0x3fff;
else if (uuid_last.time.ll >= time)
uuid.seq = (uuid_last.seq + 1) & 0x3fff;
else
uuid.seq = uuid_last.seq;
uuid_last = uuid;
uuid_last.time.ll = (time + SCARG(uap,count) - 1) & ((1LL << 60) - 1LL);
simple_unlock(&uuid_mutex);
/* Set sequence and variant and deal with byte order. */
uuid.seq = htobe16(uuid.seq | 0x8000);
/* XXX: this should copyout larger chunks at a time. */
do {
/* Set time and version (=1) and deal with byte order. */
uuid.time.x.low = (uint32_t)time;
uuid.time.x.mid = (uint16_t)(time >> 32);
uuid.time.x.hi = ((uint16_t)(time >> 48) & 0xfff) | (1 << 12);
error = copyout(&uuid, SCARG(uap,store), sizeof(uuid));
SCARG(uap,store)++;
SCARG(uap,count)--;
time++;
} while (SCARG(uap,count) > 0 && !error);
return (error);
}
#ifdef notyet
int
snprintf_uuid(char *buf, size_t sz, struct uuid *uuid)
{
struct uuid_private *id;
int cnt;
id = (struct uuid_private *)uuid;
cnt = snprintf(buf, sz, "%08x-%04x-%04x-%04x-%04x%04x%04x",
id->time.x.low, id->time.x.mid, id->time.x.hi, be16toh(id->seq),
be16toh(id->node[0]), be16toh(id->node[1]), be16toh(id->node[2]));
return (cnt);
}
int
printf_uuid(struct uuid *uuid)
{
char buf[38];
snprintf_uuid(buf, sizeof(buf), uuid);
printf("%s", buf);
return 0;
}
/*
* Encode/Decode UUID into byte-stream.
* http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | time_low |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | time_mid | time_hi_and_version |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |clk_seq_hi_res | clk_seq_low | node (0-1) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | node (2-5) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
void
le_uuid_enc(void *buf, struct uuid const *uuid)
{
u_char *p;
int i;
p = buf;
le32enc(p, uuid->time_low);
le16enc(p + 4, uuid->time_mid);
le16enc(p + 6, uuid->time_hi_and_version);
p[8] = uuid->clock_seq_hi_and_reserved;
p[9] = uuid->clock_seq_low;
for (i = 0; i < _UUID_NODE_LEN; i++)
p[10 + i] = uuid->node[i];
}
void
le_uuid_dec(void const *buf, struct uuid *uuid)
{
u_char const *p;
int i;
p = buf;
uuid->time_low = le32dec(p);
uuid->time_mid = le16dec(p + 4);
uuid->time_hi_and_version = le16dec(p + 6);
uuid->clock_seq_hi_and_reserved = p[8];
uuid->clock_seq_low = p[9];
for (i = 0; i < _UUID_NODE_LEN; i++)
uuid->node[i] = p[10 + i];
}
void
be_uuid_enc(void *buf, struct uuid const *uuid)
{
u_char *p;
int i;
p = buf;
be32enc(p, uuid->time_low);
be16enc(p + 4, uuid->time_mid);
be16enc(p + 6, uuid->time_hi_and_version);
p[8] = uuid->clock_seq_hi_and_reserved;
p[9] = uuid->clock_seq_low;
for (i = 0; i < _UUID_NODE_LEN; i++)
p[10 + i] = uuid->node[i];
}
void
be_uuid_dec(void const *buf, struct uuid *uuid)
{
u_char const *p;
int i;
p = buf;
uuid->time_low = be32dec(p);
uuid->time_mid = le16dec(p + 4);
uuid->time_hi_and_version = be16dec(p + 6);
uuid->clock_seq_hi_and_reserved = p[8];
uuid->clock_seq_low = p[9];
for (i = 0; i < _UUID_NODE_LEN; i++)
uuid->node[i] = p[10 + i];
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscalls.c,v 1.147 2004/01/02 18:53:47 cl Exp $ */
/* $NetBSD: syscalls.c,v 1.148 2004/01/29 02:00:03 tsarna Exp $ */
/*
* System call names.
@ -8,7 +8,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: syscalls.c,v 1.147 2004/01/02 18:53:47 cl Exp $");
__KERNEL_RCSID(0, "$NetBSD: syscalls.c,v 1.148 2004/01/29 02:00:03 tsarna Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ktrace.h"
@ -494,4 +494,5 @@ const char *const syscallnames[] = {
"#352 (unimplemented sys_sched_get_priority_min)", /* 352 = unimplemented sys_sched_get_priority_min */
"#353 (unimplemented sys_sched_rr_get_interval)", /* 353 = unimplemented sys_sched_rr_get_interval */
"fsync_range", /* 354 = fsync_range */
"uuidgen", /* 355 = uuidgen */
};

View File

@ -1,4 +1,4 @@
$NetBSD: syscalls.master,v 1.135 2004/01/02 18:52:17 cl Exp $
$NetBSD: syscalls.master,v 1.136 2004/01/29 02:00:03 tsarna Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@ -709,3 +709,4 @@
354 STD { int sys_fsync_range(int fd, int flags, off_t start, \
off_t length); }
355 STD { int sys_uuidgen(struct uuid *store, int count); }

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.62 2003/11/18 23:00:04 lukem Exp $
# $NetBSD: Makefile,v 1.63 2004/01/29 02:00:03 tsarna Exp $
INCSDIR= /usr/include/sys
@ -28,7 +28,7 @@ INCS= acct.h agpio.h ansi.h ataio.h audioio.h \
tablet.h termios.h time.h timeb.h timepps.h times.h \
timex.h tprintf.h trace.h tree.h tty.h ttychars.h ttycom.h \
ttydefaults.h ttydev.h types.h \
ucontext.h ucred.h uio.h un.h unistd.h unpcb.h user.h utsname.h \
ucontext.h ucred.h uio.h un.h unistd.h unpcb.h user.h utsname.h uuid.h \
vadvise.h verified_exec.h vmmeter.h vnode.h vnode_if.h \
wait.h wdog.h

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.h,v 1.145 2004/01/02 18:53:47 cl Exp $ */
/* $NetBSD: syscall.h,v 1.146 2004/01/29 02:00:03 tsarna Exp $ */
/*
* System call numbers.
@ -973,5 +973,8 @@
/* syscall: "fsync_range" ret: "int" args: "int" "int" "off_t" "off_t" */
#define SYS_fsync_range 354
#define SYS_MAXSYSCALL 355
/* syscall: "uuidgen" ret: "int" args: "struct uuid *" "int" */
#define SYS_uuidgen 355
#define SYS_MAXSYSCALL 356
#define SYS_NSYSENT 512

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscallargs.h,v 1.127 2004/01/02 18:53:47 cl Exp $ */
/* $NetBSD: syscallargs.h,v 1.128 2004/01/29 02:00:03 tsarna Exp $ */
/*
* System call argument lists.
@ -1461,6 +1461,11 @@ struct sys_fsync_range_args {
syscallarg(off_t) length;
};
struct sys_uuidgen_args {
syscallarg(struct uuid *) store;
syscallarg(int) count;
};
/*
* System call prototypes.
*/
@ -2091,4 +2096,6 @@ int sys_kevent(struct lwp *, void *, register_t *);
int sys_fsync_range(struct lwp *, void *, register_t *);
int sys_uuidgen(struct lwp *, void *, register_t *);
#endif /* _SYS__SYSCALLARGS_H_ */

79
sys/sys/uuid.h Normal file
View File

@ -0,0 +1,79 @@
/* $NetBSD: uuid.h,v 1.1 2004/01/29 02:00:03 tsarna Exp $ */
/* $FreeBSD: /repoman/r/ncvs/src/sys/sys/uuid.h,v 1.3 2003/05/31 16:47:07 phk Exp $ */
/*
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: /repoman/r/ncvs/src/sys/sys/uuid.h,v 1.3 2003/05/31 16:47:07 phk Exp $
*/
#ifndef _SYS_UUID_H_
#define _SYS_UUID_H_
#include <sys/cdefs.h>
/* Length of a node address (an IEEE 802 address). */
#define _UUID_NODE_LEN 6
/*
* See also:
* http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
* http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
*
* A DCE 1.1 compatible source representation of UUIDs.
*/
struct uuid {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint8_t clock_seq_hi_and_reserved;
uint8_t clock_seq_low;
uint8_t node[_UUID_NODE_LEN];
};
#ifdef _KERNEL
#define UUID_NODE_LEN _UUID_NODE_LEN
#ifdef notyet
int snprintf_uuid(char *, size_t, struct uuid *);
int printf_uuid(struct uuid *);
void be_uuid_dec(void const *buf, struct uuid *uuid);
void be_uuid_enc(void *buf, struct uuid const *uuid);
void le_uuid_dec(void const *buf, struct uuid *uuid);
void le_uuid_enc(void *buf, struct uuid const *uuid);
#endif
#else /* _KERNEL */
/* XXX namespace pollution? */
typedef struct uuid uuid_t;
__BEGIN_DECLS
int uuidgen(struct uuid *, int);
__END_DECLS
#endif /* _KERNEL */
#endif /* _SYS_UUID_H_ */