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