diff --git a/distrib/sets/lists/base/shl.mi b/distrib/sets/lists/base/shl.mi index f1df8a8414d3..17366bb4c9bb 100644 --- a/distrib/sets/lists/base/shl.mi +++ b/distrib/sets/lists/base/shl.mi @@ -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 diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index e3d6a8bfaca6..ce189d12f20c 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -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 diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 63ed6f96f73e..2e36ab16d334 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -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 diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 6b36e895fc50..370fecf3a3c7 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -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 diff --git a/lib/libc/sys/makelintstub b/lib/libc/sys/makelintstub index bde70d6f9e55..e66a42bdbb0a 100755 --- a/lib/libc/sys/makelintstub +++ b/lib/libc/sys/makelintstub @@ -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 #include #include + #include #ifdef __STDC__ #include #else diff --git a/lib/libc/sys/uuidgen.2 b/lib/libc/sys/uuidgen.2 new file mode 100644 index 000000000000..f15b4738398c --- /dev/null +++ b/lib/libc/sys/uuidgen.2 @@ -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 . diff --git a/sys/compat/freebsd/freebsd_syscall.h b/sys/compat/freebsd/freebsd_syscall.h index 29f3b949ae1e..0cf313a3c15b 100644 --- a/sys/compat/freebsd/freebsd_syscall.h +++ b/sys/compat/freebsd/freebsd_syscall.h @@ -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 diff --git a/sys/compat/freebsd/freebsd_syscallargs.h b/sys/compat/freebsd/freebsd_syscallargs.h index 369da16c8088..c1dd7424222f 100644 --- a/sys/compat/freebsd/freebsd_syscallargs.h +++ b/sys/compat/freebsd/freebsd_syscallargs.h @@ -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 *); diff --git a/sys/compat/freebsd/freebsd_syscalls.c b/sys/compat/freebsd/freebsd_syscalls.c index e765dbe3ef40..2c5e56b7a768 100644 --- a/sys/compat/freebsd/freebsd_syscalls.c +++ b/sys/compat/freebsd/freebsd_syscalls.c @@ -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 -__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 */ diff --git a/sys/compat/freebsd/freebsd_sysent.c b/sys/compat/freebsd/freebsd_sysent.c index c00b889101b9..01867463a296 100644 --- a/sys/compat/freebsd/freebsd_sysent.c +++ b/sys/compat/freebsd/freebsd_sysent.c @@ -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 -__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, diff --git a/sys/compat/freebsd/syscalls.master b/sys/compat/freebsd/syscalls.master index 3a49672c58b1..539c7a11f6e0 100644 --- a/sys/compat/freebsd/syscalls.master +++ b/sys/compat/freebsd/syscalls.master @@ -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 diff --git a/sys/conf/files b/sys/conf/files index a93ae3f3cdb9..4ce262822890 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -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 diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index d9f37201ed5a..7be58bbba37f 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -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 -__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, diff --git a/sys/kern/kern_uuid.c b/sys/kern/kern_uuid.c new file mode 100644 index 000000000000..047f4d7f14ab --- /dev/null +++ b/sys/kern/kern_uuid.c @@ -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 +__KERNEL_RCSID(0, "$NetBSD: kern_uuid.c,v 1.1 2004/01/29 02:00:03 tsarna Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +/* NetBSD */ +#include +#include +#include +#include +#include + +#include +#include +#include + + +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 diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index ee3fd17c7fe7..7cb03fa42d8b 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -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 -__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 */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index b8d18ce8d20d..9eb3f4af8fe9 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -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); } diff --git a/sys/sys/Makefile b/sys/sys/Makefile index 2c108d42b333..fca41771a3dc 100644 --- a/sys/sys/Makefile +++ b/sys/sys/Makefile @@ -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 diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 74b2da65774d..8759298f469a 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -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 diff --git a/sys/sys/syscallargs.h b/sys/sys/syscallargs.h index 91ea8c252551..fa95875799c5 100644 --- a/sys/sys/syscallargs.h +++ b/sys/sys/syscallargs.h @@ -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_ */ diff --git a/sys/sys/uuid.h b/sys/sys/uuid.h new file mode 100644 index 000000000000..da47e18fe688 --- /dev/null +++ b/sys/sys/uuid.h @@ -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 + +/* 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_ */