forked from pool/e2fsprogs
309 lines
6.9 KiB
Diff
309 lines
6.9 KiB
Diff
|
--- e2fsprogs-1.39/lib/uuid/Makefile.in
|
||
|
+++ e2fsprogs-1.39/lib/uuid/Makefile.in
|
||
|
@@ -19,6 +19,8 @@
|
||
|
OBJS= clear.o \
|
||
|
compare.o \
|
||
|
copy.o \
|
||
|
+ pv.o \
|
||
|
+ shm.o \
|
||
|
gen_uuid.o \
|
||
|
isnull.o \
|
||
|
pack.o \
|
||
|
@@ -30,6 +32,8 @@
|
||
|
SRCS= $(srcdir)/clear.c \
|
||
|
$(srcdir)/compare.c \
|
||
|
$(srcdir)/copy.c \
|
||
|
+ $(srcdir)/pv.c \
|
||
|
+ $(srcdir)/shm.c \
|
||
|
$(srcdir)/gen_uuid.c \
|
||
|
$(srcdir)/isnull.c \
|
||
|
$(srcdir)/pack.c \
|
||
|
@@ -82,7 +86,7 @@
|
||
|
|
||
|
uuid_time: $(srcdir)/uuid_time.c $(DEPLIBUUID)
|
||
|
@echo " LD $@"
|
||
|
- @$(CC) $(ALL_CFLAGS) -DDEBUG -o uuid_time $(srcdir)/uuid_time.c \
|
||
|
+ @$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -DDEBUG -o uuid_time $(srcdir)/uuid_time.c \
|
||
|
$(LIBUUID)
|
||
|
|
||
|
uuid.3: $(DEP_SUBSTITUTE) $(srcdir)/uuid.3.in
|
||
|
--- e2fsprogs-1.39/lib/uuid/gen_uuid.c
|
||
|
+++ e2fsprogs-1.39/lib/uuid/gen_uuid.c
|
||
|
@@ -71,6 +71,10 @@
|
||
|
#endif
|
||
|
|
||
|
#include "uuidP.h"
|
||
|
+#include "pv.h"
|
||
|
+#include "shm.h"
|
||
|
+#include <pthread.h>
|
||
|
+#include <stdio.h>
|
||
|
|
||
|
#ifdef HAVE_SRANDOM
|
||
|
#define srand(x) srandom(x)
|
||
|
@@ -224,42 +228,55 @@
|
||
|
/* Assume that the gettimeofday() has microsecond granularity */
|
||
|
#define MAX_ADJUSTMENT 10
|
||
|
|
||
|
+static pthread_once_t m_uuid_init_guard = PTHREAD_ONCE_INIT;
|
||
|
+static pthread_mutex_t m_uuid_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||
|
+static int m_uuid_sem_id = -1;
|
||
|
+
|
||
|
+void m_uuid_init_once()
|
||
|
+{
|
||
|
+ m_uuid_sem_id = uuid_sem_init((int)'u');
|
||
|
+}
|
||
|
+
|
||
|
static int get_clock(uint32_t *clock_high, uint32_t *clock_low, uint16_t *ret_clock_seq)
|
||
|
{
|
||
|
- static int adjustment = 0;
|
||
|
- static struct timeval last = {0, 0};
|
||
|
- static uint16_t clock_seq;
|
||
|
- struct timeval tv;
|
||
|
- unsigned long long clock_reg;
|
||
|
-
|
||
|
+ unsigned long long clock_reg;
|
||
|
+ struct timeval tv;
|
||
|
+ static uint16_t clock_seq;
|
||
|
+ static int adjustment = 0;
|
||
|
+
|
||
|
+ int shm_id = shm_init((int)'s', sizeof(struct timeval));
|
||
|
+ struct timeval *clock_time = (struct timeval*)shm_addr(shm_id);
|
||
|
+
|
||
|
try_again:
|
||
|
gettimeofday(&tv, 0);
|
||
|
- if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
|
||
|
+ if ((clock_time->tv_sec == 0) && (clock_time->tv_usec == 0)) {
|
||
|
get_random_bytes(&clock_seq, sizeof(clock_seq));
|
||
|
clock_seq &= 0x3FFF;
|
||
|
- last = tv;
|
||
|
- last.tv_sec--;
|
||
|
+ *clock_time = tv;
|
||
|
+ clock_time->tv_sec--;
|
||
|
}
|
||
|
- if ((tv.tv_sec < last.tv_sec) ||
|
||
|
- ((tv.tv_sec == last.tv_sec) &&
|
||
|
- (tv.tv_usec < last.tv_usec))) {
|
||
|
+ if ((tv.tv_sec < clock_time->tv_sec) ||
|
||
|
+ ((tv.tv_sec == clock_time->tv_sec) &&
|
||
|
+ (tv.tv_usec < clock_time->tv_usec))) {
|
||
|
clock_seq = (clock_seq+1) & 0x3FFF;
|
||
|
adjustment = 0;
|
||
|
- last = tv;
|
||
|
- } else if ((tv.tv_sec == last.tv_sec) &&
|
||
|
- (tv.tv_usec == last.tv_usec)) {
|
||
|
+ *clock_time = tv;
|
||
|
+ } else if ((tv.tv_sec == clock_time->tv_sec) &&
|
||
|
+ (tv.tv_usec == clock_time->tv_usec)) {
|
||
|
if (adjustment >= MAX_ADJUSTMENT)
|
||
|
goto try_again;
|
||
|
adjustment++;
|
||
|
} else {
|
||
|
adjustment = 0;
|
||
|
- last = tv;
|
||
|
+ *clock_time = tv;
|
||
|
}
|
||
|
-
|
||
|
+
|
||
|
+ clock_seq = (clock_seq+1) & 0x3FFF;
|
||
|
+
|
||
|
clock_reg = tv.tv_usec*10 + adjustment;
|
||
|
- clock_reg += ((unsigned long long) tv.tv_sec)*10000000;
|
||
|
- clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
|
||
|
-
|
||
|
+ clock_reg += ((unsigned long)tv.tv_sec)*10000000;
|
||
|
+ clock_reg += (((unsigned long long)0x01B21DD2) << 23) + 0x13814000;
|
||
|
+
|
||
|
*clock_high = clock_reg >> 32;
|
||
|
*clock_low = clock_reg;
|
||
|
*ret_clock_seq = clock_seq;
|
||
|
@@ -268,10 +285,16 @@
|
||
|
|
||
|
void uuid_generate_time(uuid_t out)
|
||
|
{
|
||
|
+ pthread_mutex_lock(&m_uuid_mutex);
|
||
|
+
|
||
|
+ pthread_once(&m_uuid_init_guard, m_uuid_init_once);
|
||
|
+
|
||
|
+ if(m_uuid_sem_id != -1) uuid_sem_P(m_uuid_sem_id);
|
||
|
+
|
||
|
static unsigned char node_id[6];
|
||
|
static int has_init = 0;
|
||
|
struct uuid uu;
|
||
|
- uint32_t clock_mid;
|
||
|
+ uint32_t clock_mid;
|
||
|
|
||
|
if (!has_init) {
|
||
|
if (get_node_id(node_id) <= 0) {
|
||
|
@@ -291,6 +314,10 @@
|
||
|
uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000;
|
||
|
memcpy(uu.node, node_id, 6);
|
||
|
uuid_pack(&uu, out);
|
||
|
+
|
||
|
+ if(m_uuid_sem_id != -1) uuid_sem_V(m_uuid_sem_id);
|
||
|
+
|
||
|
+ pthread_mutex_unlock(&m_uuid_mutex);
|
||
|
}
|
||
|
|
||
|
void uuid_generate_random(uuid_t out)
|
||
|
--- e2fsprogs-1.39/lib/uuid/pv.c
|
||
|
+++ e2fsprogs-1.39/lib/uuid/pv.c
|
||
|
@@ -0,0 +1,88 @@
|
||
|
+#include <sys/types.h>
|
||
|
+#include <sys/stat.h>
|
||
|
+#include <sys/sem.h>
|
||
|
+#include <sys/ipc.h>
|
||
|
+
|
||
|
+#if defined(PV_REPORT_VERBOSE)
|
||
|
+#include <stdio.h>
|
||
|
+
|
||
|
+#define report(msg) perror(msg)
|
||
|
+#else
|
||
|
+#define report(msg)
|
||
|
+#endif
|
||
|
+#include <errno.h>
|
||
|
+
|
||
|
+#include "pv.h"
|
||
|
+
|
||
|
+int uuid_sem_init(int project_id)
|
||
|
+{
|
||
|
+ key_t sem_key;
|
||
|
+ int sem_id;
|
||
|
+
|
||
|
+ sem_key = ftok("/", project_id);
|
||
|
+ if(sem_key == (key_t)-1)
|
||
|
+ {
|
||
|
+ report("Can't generate semaphore key");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ sem_id = semget(sem_key, 0, 0);
|
||
|
+ if(sem_id == -1)
|
||
|
+ {
|
||
|
+ sem_id = semget(sem_key, 1, IPC_CREAT | IPC_EXCL |
|
||
|
+ S_IRUSR | S_IWUSR | S_IRGRP |
|
||
|
+ S_IWGRP | S_IROTH | S_IWOTH);
|
||
|
+ if(sem_id != -1)
|
||
|
+ {
|
||
|
+ union semun {
|
||
|
+ int val;
|
||
|
+ struct semid_ds *buf;
|
||
|
+ unsigned short *array;
|
||
|
+ struct seminfo *__buf;
|
||
|
+ } arg;
|
||
|
+ arg.val = 1;
|
||
|
+
|
||
|
+ if(semctl(sem_id, 0, SETVAL, arg) == -1)
|
||
|
+ {
|
||
|
+ report("Can't initialize semaphore");
|
||
|
+
|
||
|
+ /* try to remove -- we've created it */
|
||
|
+ semctl(sem_id, 0, IPC_RMID, (int)0);
|
||
|
+ sem_id = -1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else
|
||
|
+ if(errno == EEXIST)
|
||
|
+ {
|
||
|
+ if( (sem_id = semget(sem_key, 0, 0)) == -1)
|
||
|
+ {
|
||
|
+ report("Can't acquire / create semahore");
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ report("Can't neither acquire nor create semahore");
|
||
|
+ }
|
||
|
+ }
|
||
|
+ return sem_id;
|
||
|
+}
|
||
|
+
|
||
|
+static inline int sem_pv(int id, int op)
|
||
|
+{
|
||
|
+ struct sembuf sb;
|
||
|
+ sb.sem_num = 0;
|
||
|
+ sb.sem_op = op;
|
||
|
+ sb.sem_flg = /*SEM_UNDO*/0;
|
||
|
+ return semop(id, &sb, 1);
|
||
|
+}
|
||
|
+
|
||
|
+int uuid_sem_P(int id)
|
||
|
+{
|
||
|
+ return sem_pv(id, -1);
|
||
|
+}
|
||
|
+
|
||
|
+int uuid_sem_V(int id)
|
||
|
+{
|
||
|
+ return sem_pv(id, 1);
|
||
|
+}
|
||
|
+
|
||
|
--- e2fsprogs-1.39/lib/uuid/pv.h
|
||
|
+++ e2fsprogs-1.39/lib/uuid/pv.h
|
||
|
@@ -0,0 +1,9 @@
|
||
|
+#ifndef PV_H_INCLUDE_GUARD
|
||
|
+#define PV_H_INCLUDE_GUARD
|
||
|
+
|
||
|
+int uuid_sem_init(int project_id);
|
||
|
+int uuid_sem_P(int id);
|
||
|
+int uuid_sem_V(int id);
|
||
|
+
|
||
|
+#endif // PV_H_INCLUDE_GUARD
|
||
|
+
|
||
|
--- e2fsprogs-1.39/lib/uuid/shm.c
|
||
|
+++ e2fsprogs-1.39/lib/uuid/shm.c
|
||
|
@@ -0,0 +1,43 @@
|
||
|
+#include <sys/ipc.h>
|
||
|
+#include <sys/types.h>
|
||
|
+#include <sys/shm.h>
|
||
|
+
|
||
|
+#if defined(SHM_REPORT_VERBOSE)
|
||
|
+#include <stdio.h>
|
||
|
+
|
||
|
+#define report(msg) perror(msg)
|
||
|
+#else
|
||
|
+#define report(msg)
|
||
|
+#endif
|
||
|
+#include <errno.h>
|
||
|
+
|
||
|
+#include "shm.h"
|
||
|
+
|
||
|
+int shm_init(int project_id, size_t size) {
|
||
|
+ key_t key;
|
||
|
+ int id;
|
||
|
+
|
||
|
+ key = ftok("/", project_id);
|
||
|
+ if (key == (key_t)-1) {
|
||
|
+ report("Can't generate shared memory key");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ id = shmget(key, 0, 0);
|
||
|
+ if (id == -1) {
|
||
|
+ id = shmget(key, size, 0666 | IPC_CREAT);
|
||
|
+ if (id == -1 && errno == EEXIST) {
|
||
|
+ if ((id = shmget(key, 0, 0)) == -1) {
|
||
|
+ report("Can't acquire/create shared memory");
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else if (id == -1) {
|
||
|
+ report("Can neither acquire nor create shared memory");
|
||
|
+ }
|
||
|
+ }
|
||
|
+ return id;
|
||
|
+}
|
||
|
+
|
||
|
+void *shm_addr(int id) {
|
||
|
+ return shmat(id, NULL, 0);
|
||
|
+}
|
||
|
--- e2fsprogs-1.39/lib/uuid/shm.h
|
||
|
+++ e2fsprogs-1.39/lib/uuid/shm.h
|
||
|
@@ -0,0 +1,9 @@
|
||
|
+#ifndef SHM_H_INCLUDE_GUARD
|
||
|
+#define SHM_H_INCLUDE_GUARD
|
||
|
+
|
||
|
+#include <stddef.h>
|
||
|
+
|
||
|
+int shm_init(int project_id, size_t size);
|
||
|
+void *shm_addr(int id);
|
||
|
+
|
||
|
+#endif // SHM_H_INCLUDE_GUARD
|