[RFC PATCH] libuuid: introduce safe variant of uuid_generate_time()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

RFC: 

Sometimes, when there are multiple processes generating time-based
UUIDs in a loop (each of them using multiple threads), it can happen
that the socket backlog in uuidd daemon is full and so the connection
request is refused. uuid_generate_time() then fallbacks to unsafe way of
generating UUID, which may cause duplicate time-based UUIDs to be
generated.

The problem with libuuid interface is that it is impossible to
inform the caller of uuid_generate_time() that unsafe fallback has
been used (the function returns void).

This patch introduces new function,

int uuid_generate_time_nf(uuid_t out)     /* nf = "no fallback" */

which, in case uuidd was needed, but for whatever reason could not be
used, returns -1 and leaves content in @out undefined.

Signed-off-by: Petr Uzel <petr.uzel@xxxxxxx>
---
 shlibs/uuid/src/gen_uuid.c |   40 +++++++++++++++++++++++++++++++++++-----
 shlibs/uuid/src/uuid.h     |    1 +
 shlibs/uuid/src/uuid.sym   |   10 +++++++++-
 3 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/shlibs/uuid/src/gen_uuid.c b/shlibs/uuid/src/gen_uuid.c
index a90bd8e..45af07f 100644
--- a/shlibs/uuid/src/gen_uuid.c
+++ b/shlibs/uuid/src/gen_uuid.c
@@ -587,7 +587,17 @@ void uuid__generate_time(uuid_t out, int *num)
 	uuid_pack(&uu, out);
 }
 
-void uuid_generate_time(uuid_t out)
+/*
+ * Generate time-based UUID and store it to @out
+ *
+ * If @fallback is nonzero and uuidd is needed, but could not be used,
+ * then do not use the usafe fallback.
+ *
+ * Returns 0 on success, -1 on failure (could not connect to uuidd and
+ * @fallback=0)
+ *
+ */
+static int uuid_generate_time_generic(uuid_t out, int fallback)
 {
 #ifdef HAVE_TLS
 	THREAD_LOCAL int		num = 0;
@@ -607,7 +617,7 @@ void uuid_generate_time(uuid_t out)
 			last_time = time(0);
 			uuid_unpack(out, &uu);
 			num--;
-			return;
+			return 0;
 		}
 		num = 0;
 	}
@@ -620,14 +630,34 @@ void uuid_generate_time(uuid_t out)
 		}
 		num--;
 		uuid_pack(&uu, out);
-		return;
+		return 0;
 	}
 #else
 	if (get_uuid_via_daemon(UUIDD_OP_TIME_UUID, out, 0) == 0)
-		return;
+		return 0;
 #endif
 
-	uuid__generate_time(out, 0);
+	if (fallback) {
+		uuid__generate_time(out, 0);
+		return 0;
+	}
+	else
+		/* fallback==0: disabled */
+		return -1;
+}
+
+void uuid_generate_time(uuid_t out)
+{
+	(void)uuid_generate_time_generic(out, 1);
+}
+
+
+/*
+ * Same as uuid_generate_time, but with unsafe fallback disabled.
+ */
+int uuid_generate_time_nf(uuid_t out)
+{
+	return uuid_generate_time_generic(out, 0);
 }
 
 
diff --git a/shlibs/uuid/src/uuid.h b/shlibs/uuid/src/uuid.h
index e329bf7..c7442ee 100644
--- a/shlibs/uuid/src/uuid.h
+++ b/shlibs/uuid/src/uuid.h
@@ -79,6 +79,7 @@ void uuid_copy(uuid_t dst, const uuid_t src);
 void uuid_generate(uuid_t out);
 void uuid_generate_random(uuid_t out);
 void uuid_generate_time(uuid_t out);
+int uuid_generate_time_nf(uuid_t out);
 
 /* isnull.c */
 int uuid_is_null(const uuid_t uu);
diff --git a/shlibs/uuid/src/uuid.sym b/shlibs/uuid/src/uuid.sym
index 05d9f39..719f133 100644
--- a/shlibs/uuid/src/uuid.sym
+++ b/shlibs/uuid/src/uuid.sym
@@ -1,6 +1,6 @@
 /*
  * The symbol versioning ensures that a new application requiring symbol foo()
- * can't run with old libblkid.so not providing foo() - the global SONAME
+ * can't run with old libuuid.so not providing foo() - the global SONAME
  * version info can't enforce this since we never change the SONAME.
  *
  * The original libuuid from e2fsprogs (<=1.41.5) does not to use
@@ -31,3 +31,11 @@ global:
 local:
 	*;
 };
+
+/*
+ * version(s) since util-linux 2.19
+ */
+UUID_2.19 {
+global:
+	uuid_generate_time_nf;
+} UUID_1.0;
-- 
1.7.1


Petr

--
Petr Uzel
IRC: ptr_uzl @ freenode

Attachment: pgpz8FhcdEFHk.pgp
Description: PGP signature


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux