Move the UUID generator into its own function, called kern_uuidgen(),

so that UUIDs can be generated from within the kernel. The uuidgen(2)
syscall now allocates kernel memory, calls the generator, and does a
copyout() for the whole UUID store. This change is in support of GPT.
This commit is contained in:
Marcel Moolenaar 2005-09-18 21:40:15 +00:00
parent 8434c29b28
commit 73130b2224
2 changed files with 41 additions and 29 deletions

View File

@ -131,30 +131,12 @@ uuid_time(void)
return (time & ((1LL << 60) - 1LL));
}
#ifndef _SYS_SYSPROTO_H_
struct uuidgen_args {
struct uuid *store;
int count;
};
#endif
int
uuidgen(struct thread *td, struct uuidgen_args *uap)
struct uuid *
kern_uuidgen(struct uuid *store, size_t count)
{
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 (uap->count < 1 || uap->count > 2048)
return (EINVAL);
/* XXX: pre-validate accessibility to the whole of the UUID store? */
size_t n;
mtx_lock(&uuid_mutex);
@ -171,25 +153,53 @@ uuidgen(struct thread *td, struct uuidgen_args *uap)
uuid.seq = uuid_last.seq;
uuid_last = uuid;
uuid_last.time.ll = (time + uap->count - 1) & ((1LL << 60) - 1LL);
uuid_last.time.ll = (time + count - 1) & ((1LL << 60) - 1LL);
mtx_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. */
for (n = 0; n < count; n++) {
/* Set time and version (=1). */
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, uap->store, sizeof(uuid));
uap->store++;
uap->count--;
store[n] = *(struct uuid *)&uuid;
time++;
} while (uap->count > 0 && !error);
}
return (store);
}
#ifndef _SYS_SYSPROTO_H_
struct uuidgen_args {
struct uuid *store;
int count;
};
#endif
int
uuidgen(struct thread *td, struct uuidgen_args *uap)
{
struct uuid *store;
size_t count;
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 probably needs to be tunable.
*/
if (uap->count < 1 || uap->count > 2048)
return (EINVAL);
count = uap->count;
store = malloc(count * sizeof(struct uuid), M_TEMP, M_WAITOK);
kern_uuidgen(store, count);
error = copyout(store, uap->store, count * sizeof(struct uuid));
free(store, M_TEMP);
return (error);
}

View File

@ -56,6 +56,8 @@ struct uuid {
struct sbuf;
struct uuid *kern_uuidgen(struct uuid *, size_t);
int snprintf_uuid(char *, size_t, struct uuid *);
int printf_uuid(struct uuid *);
int sbuf_printf_uuid(struct sbuf *, struct uuid *);