import util-linux-2.32.1-39.el8_7
This commit is contained in:
parent
a4286b4101
commit
4e5311c2f1
@ -0,0 +1,375 @@
|
||||
From ce49a152fd8a830b1c9c0a8b745ea71feff71697 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Trapp <michael.trapp@sap.com>
|
||||
Date: Mon, 20 Jun 2022 17:10:36 +0200
|
||||
Subject: libuuid: Implement continuous clock handling for time based UUIDs
|
||||
|
||||
In a uuidd setup, the daemon is a singleton and can maintain it's own
|
||||
resources for time based UUID generation. This requires a dedicated
|
||||
'clock sequence range' but does not need any further lock/update of
|
||||
the LIBUUID_CLOCK_FILE from uuidd. The range of available clock values
|
||||
is extended by a continuous handling of the clock updates - instead of
|
||||
updating the value to the current timestamp, it is incremented by
|
||||
the number of requested UUIDs.
|
||||
|
||||
[kzak@redhat.com: - backport from upstream v2.39 to to RHEL-8]
|
||||
|
||||
Upstream: http://github.com/util-linux/util-linux/commit/3cfba7d39b66eff4307218fefd8bb34bb1621f83
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2141969
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
---
|
||||
libuuid/src/gen_uuid.c | 91 ++++++++++++++++++++++++++++++++++++++---
|
||||
libuuid/src/libuuid.sym | 1 +
|
||||
libuuid/src/uuidd.h | 1 +
|
||||
misc-utils/uuidd.8.in | 12 ++++++
|
||||
misc-utils/uuidd.c | 86 ++++++++++++++++++++++++++++++++++++--
|
||||
5 files changed, 182 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libuuid/src/gen_uuid.c b/libuuid/src/gen_uuid.c
|
||||
index 27c135db5..f557053f7 100644
|
||||
--- a/libuuid/src/gen_uuid.c
|
||||
+++ b/libuuid/src/gen_uuid.c
|
||||
@@ -209,6 +209,8 @@ static int get_node_id(unsigned char *node_id)
|
||||
|
||||
/* Assume that the gettimeofday() has microsecond granularity */
|
||||
#define MAX_ADJUSTMENT 10
|
||||
+/* Reserve a clock_seq value for the 'continuous clock' implementation */
|
||||
+#define CLOCK_SEQ_CONT 0
|
||||
|
||||
/*
|
||||
* Get clock from global sequence clock counter.
|
||||
@@ -275,8 +277,10 @@ static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
|
||||
}
|
||||
|
||||
if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
|
||||
- random_get_bytes(&clock_seq, sizeof(clock_seq));
|
||||
- clock_seq &= 0x3FFF;
|
||||
+ do {
|
||||
+ random_get_bytes(&clock_seq, sizeof(clock_seq));
|
||||
+ clock_seq &= 0x3FFF;
|
||||
+ } while (clock_seq == CLOCK_SEQ_CONT);
|
||||
gettimeofday(&last, NULL);
|
||||
last.tv_sec--;
|
||||
}
|
||||
@@ -286,7 +290,9 @@ try_again:
|
||||
if ((tv.tv_sec < last.tv_sec) ||
|
||||
((tv.tv_sec == last.tv_sec) &&
|
||||
(tv.tv_usec < last.tv_usec))) {
|
||||
- clock_seq = (clock_seq+1) & 0x3FFF;
|
||||
+ do {
|
||||
+ clock_seq = (clock_seq+1) & 0x3FFF;
|
||||
+ } while (clock_seq == CLOCK_SEQ_CONT);
|
||||
adjustment = 0;
|
||||
last = tv;
|
||||
} else if ((tv.tv_sec == last.tv_sec) &&
|
||||
@@ -331,6 +337,64 @@ try_again:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Get current time in 100ns ticks.
|
||||
+ */
|
||||
+static uint64_t get_clock_counter(void)
|
||||
+{
|
||||
+ struct timeval tv;
|
||||
+ uint64_t clock_reg;
|
||||
+
|
||||
+ gettimeofday(&tv, NULL);
|
||||
+ clock_reg = tv.tv_usec*10;
|
||||
+ clock_reg += ((uint64_t) tv.tv_sec) * 10000000ULL;
|
||||
+
|
||||
+ return clock_reg;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Get continuous clock value.
|
||||
+ *
|
||||
+ * Return -1 if there is no further clock counter available,
|
||||
+ * otherwise return 0.
|
||||
+ *
|
||||
+ * This implementation doesn't deliver clock counters based on
|
||||
+ * the current time because last_clock_reg is only incremented
|
||||
+ * by the number of requested UUIDs.
|
||||
+ * max_clock_offset is used to limit the offset of last_clock_reg.
|
||||
+ */
|
||||
+static int get_clock_cont(uint32_t *clock_high,
|
||||
+ uint32_t *clock_low,
|
||||
+ int num,
|
||||
+ uint32_t max_clock_offset)
|
||||
+{
|
||||
+ /* 100ns based time offset according to RFC 4122. 4.1.4. */
|
||||
+ const uint64_t reg_offset = (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
|
||||
+ static uint64_t last_clock_reg = 0;
|
||||
+ uint64_t clock_reg;
|
||||
+
|
||||
+ if (last_clock_reg == 0)
|
||||
+ last_clock_reg = get_clock_counter();
|
||||
+
|
||||
+ clock_reg = get_clock_counter();
|
||||
+ if (max_clock_offset) {
|
||||
+ uint64_t clock_offset = max_clock_offset * 10000000ULL;
|
||||
+ if (last_clock_reg < (clock_reg - clock_offset))
|
||||
+ last_clock_reg = clock_reg - clock_offset;
|
||||
+ }
|
||||
+
|
||||
+ clock_reg += MAX_ADJUSTMENT;
|
||||
+
|
||||
+ if ((last_clock_reg + num) >= clock_reg)
|
||||
+ return -1;
|
||||
+
|
||||
+ *clock_high = (last_clock_reg + reg_offset) >> 32;
|
||||
+ *clock_low = last_clock_reg + reg_offset;
|
||||
+ last_clock_reg += num;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
#if defined(HAVE_UUIDD) && defined(HAVE_SYS_UN_H)
|
||||
|
||||
/*
|
||||
@@ -403,7 +467,7 @@ static int get_uuid_via_daemon(int op __attribute__((__unused__)),
|
||||
}
|
||||
#endif
|
||||
|
||||
-int __uuid_generate_time(uuid_t out, int *num)
|
||||
+static int __uuid_generate_time_internal(uuid_t out, int *num, uint32_t cont_offset)
|
||||
{
|
||||
static unsigned char node_id[6];
|
||||
static int has_init = 0;
|
||||
@@ -423,7 +487,14 @@ int __uuid_generate_time(uuid_t out, int *num)
|
||||
}
|
||||
has_init = 1;
|
||||
}
|
||||
- ret = get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num);
|
||||
+ if (cont_offset) {
|
||||
+ ret = get_clock_cont(&clock_mid, &uu.time_low, *num, cont_offset);
|
||||
+ uu.clock_seq = CLOCK_SEQ_CONT;
|
||||
+ if (ret != 0) /* fallback to previous implpementation */
|
||||
+ ret = get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num);
|
||||
+ } else {
|
||||
+ ret = get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num);
|
||||
+ }
|
||||
uu.clock_seq |= 0x8000;
|
||||
uu.time_mid = (uint16_t) clock_mid;
|
||||
uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000;
|
||||
@@ -432,6 +503,16 @@ int __uuid_generate_time(uuid_t out, int *num)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int __uuid_generate_time(uuid_t out, int *num)
|
||||
+{
|
||||
+ return __uuid_generate_time_internal(out, num, 0);
|
||||
+}
|
||||
+
|
||||
+int __uuid_generate_time_cont(uuid_t out, int *num, uint32_t cont_offset)
|
||||
+{
|
||||
+ return __uuid_generate_time_internal(out, num, cont_offset);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Generate time-based UUID and store it to @out
|
||||
*
|
||||
diff --git a/libuuid/src/libuuid.sym b/libuuid/src/libuuid.sym
|
||||
index 9e3e80035..0a072b703 100644
|
||||
--- a/libuuid/src/libuuid.sym
|
||||
+++ b/libuuid/src/libuuid.sym
|
||||
@@ -51,6 +51,7 @@ global:
|
||||
UUIDD_PRIVATE {
|
||||
global:
|
||||
__uuid_generate_time;
|
||||
+ __uuid_generate_time_cont;
|
||||
__uuid_generate_random;
|
||||
local:
|
||||
*;
|
||||
diff --git a/libuuid/src/uuidd.h b/libuuid/src/uuidd.h
|
||||
index e55c86f2f..14a01ade2 100644
|
||||
--- a/libuuid/src/uuidd.h
|
||||
+++ b/libuuid/src/uuidd.h
|
||||
@@ -50,5 +50,6 @@
|
||||
|
||||
extern int __uuid_generate_time(uuid_t out, int *num);
|
||||
extern void __uuid_generate_random(uuid_t out, int *num);
|
||||
+extern int __uuid_generate_time_cont(uuid_t out, int *num, uint32_t cont);
|
||||
|
||||
#endif /* _UUID_UUID_H */
|
||||
diff --git a/misc-utils/uuidd.8.in b/misc-utils/uuidd.8.in
|
||||
index 0a5cf471b..28bcb48b5 100644
|
||||
--- a/misc-utils/uuidd.8.in
|
||||
+++ b/misc-utils/uuidd.8.in
|
||||
@@ -16,6 +16,18 @@ universally unique identifiers (UUIDs), especially time-based UUIDs,
|
||||
in a secure and guaranteed-unique fashion, even in the face of large
|
||||
numbers of threads running on different CPUs trying to grab UUIDs.
|
||||
.SH OPTIONS
|
||||
+
|
||||
+.TP
|
||||
+.BR \-C , " \-\-cont\-clock " [\fInumber\fR]
|
||||
+Activate continuous clock handling for time based UUIDs. uuidd could use all
|
||||
+possible clock values, beginning with the daemon's start time. The optional
|
||||
+argument can be used to set a value for the max_clock_offset. This gurantees,
|
||||
+that a clock value of a UUID will always be within the range of the
|
||||
+max_clock_offset. '-C' or '--cont-clock' enables the feature with a default
|
||||
+max_clock_offset of 2 hours. '-C<NUM>[hd]' or '--cont-clock=<NUM>[hd]' enables
|
||||
+the feature with a max_clock_offset of NUM seconds. In case of an appended h or
|
||||
+d, the NUM value is read in hours or days. The minimum value is 60 seconds, the
|
||||
+maximum value is 365 days.
|
||||
.TP
|
||||
.BR \-d , " \-\-debug "
|
||||
Run uuidd in debugging mode. This prevents uuidd from running as a daemon.
|
||||
diff --git a/misc-utils/uuidd.c b/misc-utils/uuidd.c
|
||||
index 8b83d91c0..e3c0abad7 100644
|
||||
--- a/misc-utils/uuidd.c
|
||||
+++ b/misc-utils/uuidd.c
|
||||
@@ -49,6 +49,8 @@ struct uuidd_cxt_t {
|
||||
const char *cleanup_pidfile;
|
||||
const char *cleanup_socket;
|
||||
uint32_t timeout;
|
||||
+ uint32_t cont_clock_offset;
|
||||
+
|
||||
unsigned int debug: 1,
|
||||
quiet: 1,
|
||||
no_fork: 1,
|
||||
@@ -73,6 +75,8 @@ static void __attribute__((__noreturn__)) usage(void)
|
||||
fputs(_(" -P, --no-pid do not create pid file\n"), out);
|
||||
fputs(_(" -F, --no-fork do not daemonize using double-fork\n"), out);
|
||||
fputs(_(" -S, --socket-activation do not create listening socket\n"), out);
|
||||
+ fputs(_(" -C, --cont-clock[=<NUM>[hd]]\n"), out);
|
||||
+ fputs(_(" activate continuous clock handling\n"), out);
|
||||
fputs(_(" -d, --debug run in debugging mode\n"), out);
|
||||
fputs(_(" -q, --quiet turn on quiet mode\n"), out);
|
||||
fputs(USAGE_SEPARATOR, out);
|
||||
@@ -401,6 +405,15 @@ static void server_loop(const char *socket_path, const char *pidfile_path,
|
||||
pfd[POLLFD_SOCKET].fd = s;
|
||||
pfd[POLLFD_SIGNAL].events = pfd[POLLFD_SOCKET].events = POLLIN | POLLERR | POLLHUP;
|
||||
|
||||
+ num = 1;
|
||||
+ if (uuidd_cxt->cont_clock_offset) {
|
||||
+ /* trigger initialization */
|
||||
+ (void) __uuid_generate_time_cont(uu, &num, uuidd_cxt->cont_clock_offset);
|
||||
+ if (uuidd_cxt->debug)
|
||||
+ fprintf(stderr, _("max_clock_offset = %u sec\n"),
|
||||
+ uuidd_cxt->cont_clock_offset);
|
||||
+ }
|
||||
+
|
||||
while (1) {
|
||||
ret = poll(pfd, ARRAY_SIZE(pfd),
|
||||
uuidd_cxt->timeout ?
|
||||
@@ -458,7 +471,7 @@ static void server_loop(const char *socket_path, const char *pidfile_path,
|
||||
break;
|
||||
case UUIDD_OP_TIME_UUID:
|
||||
num = 1;
|
||||
- __uuid_generate_time(uu, &num);
|
||||
+ __uuid_generate_time_cont(uu, &num, uuidd_cxt->cont_clock_offset);
|
||||
if (uuidd_cxt->debug) {
|
||||
uuid_unparse(uu, str);
|
||||
fprintf(stderr, _("Generated time UUID: %s\n"), str);
|
||||
@@ -477,7 +490,7 @@ static void server_loop(const char *socket_path, const char *pidfile_path,
|
||||
reply_len = sizeof(uu);
|
||||
break;
|
||||
case UUIDD_OP_BULK_TIME_UUID:
|
||||
- __uuid_generate_time(uu, &num);
|
||||
+ __uuid_generate_time_cont(uu, &num, uuidd_cxt->cont_clock_offset);
|
||||
if (uuidd_cxt->debug) {
|
||||
uuid_unparse(uu, str);
|
||||
fprintf(stderr, P_("Generated time UUID %s "
|
||||
@@ -530,6 +543,64 @@ static void __attribute__ ((__noreturn__)) unexpected_size(int size)
|
||||
errx(EXIT_FAILURE, _("Unexpected reply length from server %d"), size);
|
||||
}
|
||||
|
||||
+/* Backport from v2.39 lib/strutils.c */
|
||||
+static int ul_strtos64(const char *str, int64_t *num, int base)
|
||||
+{
|
||||
+ char *end = NULL;
|
||||
+
|
||||
+ if (str == NULL || *str == '\0')
|
||||
+ return -(errno = EINVAL);
|
||||
+
|
||||
+ errno = 0;
|
||||
+ *num = (int64_t) strtoimax(str, &end, base);
|
||||
+
|
||||
+ if (errno != 0)
|
||||
+ return -errno;
|
||||
+ if (str == end || (end && *end))
|
||||
+ return -(errno = EINVAL);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Backport from v2.39 lib/strutils.c */
|
||||
+static int64_t str2num_or_err(const char *str, int base, const char *errmesg,
|
||||
+ int64_t low, int64_t up)
|
||||
+{
|
||||
+ int64_t num = 0;
|
||||
+ int rc;
|
||||
+
|
||||
+ rc = ul_strtos64(str, &num, base);
|
||||
+ if (rc == 0 && ((low && num < low) || (up && num > up)))
|
||||
+ rc = -(errno = ERANGE);
|
||||
+
|
||||
+ if (rc) {
|
||||
+ if (errno == ERANGE)
|
||||
+ err(EXIT_FAILURE, "%s: '%s'", errmesg, str);
|
||||
+ errx(EXIT_FAILURE, "%s: '%s'", errmesg, str);
|
||||
+ }
|
||||
+ return num;
|
||||
+}
|
||||
+
|
||||
+static uint32_t parse_cont_clock(char *arg)
|
||||
+{
|
||||
+ uint32_t min_val = 60,
|
||||
+ max_val = (3600 * 24 * 365),
|
||||
+ factor = 1;
|
||||
+ char *p = &arg[strlen(arg)-1];
|
||||
+
|
||||
+ if ('h' == *p) {
|
||||
+ *p = '\0';
|
||||
+ factor = 3600;
|
||||
+ min_val = 1;
|
||||
+ }
|
||||
+ if ('d' == *p) {
|
||||
+ *p = '\0';
|
||||
+ factor = 24 * 3600;
|
||||
+ min_val = 1;
|
||||
+ }
|
||||
+ return factor * str2num_or_err(optarg, 10, _("failed to parse --cont-clock/-C"),
|
||||
+ min_val, max_val / factor);
|
||||
+}
|
||||
+
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *socket_path = UUIDD_SOCKET_PATH;
|
||||
@@ -543,7 +614,7 @@ int main(int argc, char **argv)
|
||||
int no_pid = 0;
|
||||
int s_flag = 0;
|
||||
|
||||
- struct uuidd_cxt_t uuidd_cxt = { .timeout = 0 };
|
||||
+ struct uuidd_cxt_t uuidd_cxt = { .timeout = 0, .cont_clock_offset = 0 };
|
||||
|
||||
static const struct option longopts[] = {
|
||||
{"pid", required_argument, NULL, 'p'},
|
||||
@@ -556,6 +627,7 @@ int main(int argc, char **argv)
|
||||
{"no-pid", no_argument, NULL, 'P'},
|
||||
{"no-fork", no_argument, NULL, 'F'},
|
||||
{"socket-activation", no_argument, NULL, 'S'},
|
||||
+ {"cont-clock", optional_argument, NULL, 'C'},
|
||||
{"debug", no_argument, NULL, 'd'},
|
||||
{"quiet", no_argument, NULL, 'q'},
|
||||
{"version", no_argument, NULL, 'V'},
|
||||
@@ -576,10 +648,16 @@ int main(int argc, char **argv)
|
||||
atexit(close_stdout);
|
||||
|
||||
while ((c =
|
||||
- getopt_long(argc, argv, "p:s:T:krtn:PFSdqVh", longopts,
|
||||
+ getopt_long(argc, argv, "p:s:T:krtn:PFSC::dqVh", longopts,
|
||||
NULL)) != -1) {
|
||||
err_exclusive_options(c, longopts, excl, excl_st);
|
||||
switch (c) {
|
||||
+ case 'C':
|
||||
+ if (optarg != NULL)
|
||||
+ uuidd_cxt.cont_clock_offset = parse_cont_clock(optarg);
|
||||
+ else
|
||||
+ uuidd_cxt.cont_clock_offset = 7200; /* default 2h */
|
||||
+ break;
|
||||
case 'd':
|
||||
uuidd_cxt.debug = 1;
|
||||
break;
|
||||
--
|
||||
2.38.1
|
||||
|
@ -0,0 +1,35 @@
|
||||
From fffaa2c0856de8c42b17c52a641cbc5d00ec012b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Trapp <michael.trapp@sap.com>
|
||||
Date: Tue, 2 Aug 2022 14:16:43 +0200
|
||||
Subject: libuuid: check clock value from LIBUUID_CLOCK_FILE
|
||||
|
||||
The clock value from the LIBUUID_CLOCK_FILE must be checked in
|
||||
case of an update of libuuid. If clock==CLOCK_SEQ_CONT it must
|
||||
be set to a new value.
|
||||
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
Upstream: http://github.com/util-linux/util-linux/commit/5d1424d85ac9e2a1369ee920038825c154ee5443
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2141969
|
||||
---
|
||||
libuuid/src/gen_uuid.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/libuuid/src/gen_uuid.c b/libuuid/src/gen_uuid.c
|
||||
index f557053f7..8dc38559f 100644
|
||||
--- a/libuuid/src/gen_uuid.c
|
||||
+++ b/libuuid/src/gen_uuid.c
|
||||
@@ -274,6 +274,11 @@ static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
|
||||
last.tv_usec = tv2;
|
||||
adjustment = a;
|
||||
}
|
||||
+ // reset in case of reserved CLOCK_SEQ_CONT
|
||||
+ if (clock_seq == CLOCK_SEQ_CONT) {
|
||||
+ last.tv_sec = 0;
|
||||
+ last.tv_usec = 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
|
||||
--
|
||||
2.38.1
|
||||
|
@ -2,7 +2,7 @@
|
||||
Summary: A collection of basic system utilities
|
||||
Name: util-linux
|
||||
Version: 2.32.1
|
||||
Release: 38%{?dist}
|
||||
Release: 39%{?dist}
|
||||
License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain
|
||||
Group: System Environment/Base
|
||||
URL: http://en.wikipedia.org/wiki/Util-linux
|
||||
@ -261,6 +261,11 @@ Patch82: 0082-lslogins-improve-prefixes-interpretation.patch
|
||||
Patch83: 0083-tests-update-atari-blkid-tests.patch
|
||||
Patch84: 0084-tests-update-atari-partx-tests.patch
|
||||
|
||||
### RHEL-8.7.Z
|
||||
###
|
||||
# 2141969 - Add --cont-clock feature for libuuid and uuidd
|
||||
Patch85: 0085-libuuid-Implement-continuous-clock-handling-for-time.patch
|
||||
Patch86: 0086-libuuid-check-clock-value-from-LIBUUID_CLOCK_FILE.patch
|
||||
|
||||
%description
|
||||
The util-linux package contains a large variety of low-level system
|
||||
@ -1109,6 +1114,9 @@ fi
|
||||
%{_libdir}/python*/site-packages/libmount/
|
||||
|
||||
%changelog
|
||||
* Wed Nov 16 2022 Karel Zak <kzak@redhat.com> 2.32.1-39
|
||||
- fix #2141969 - Add --cont-clock feature for libuuid and uuidd
|
||||
|
||||
* Mon Aug 22 2022 Karel Zak <kzak@redhat.com> 2.32.1-38
|
||||
- improve tmpfiles.d use in spec file (related to #2059241)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user