* [PATCH 1/5] unshare: add global child_pid variable for signal forwarding
From: Kiran Rangoon @ 2026-01-08 18:31 UTC (permalink / raw)
To: util-linux; +Cc: Kiran Rangoon
In-Reply-To: <20260108183134.23980-1-kiranrangoon0@gmail.com>
Add a global variable to store the child process PID, which will be
used by the signal handler to forward SIGTERM/SIGINT to the child.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
sys-utils/unshare.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c
index 5370ab981..6df53666a 100644
--- a/sys-utils/unshare.c
+++ b/sys-utils/unshare.c
@@ -74,6 +74,9 @@ static struct namespace_file {
static int npersists; /* number of persistent namespaces */
+/* Global PID of child process for signal forwarding */
+static volatile pid_t child_pid = 0;
+
enum {
SETGROUPS_NONE = -1,
SETGROUPS_DENY = 0,
--
2.47.3
^ permalink raw reply related
* [PATCH 0/5] unshare: fix signal forwarding to child processes
From: Kiran Rangoon @ 2026-01-08 18:31 UTC (permalink / raw)
To: util-linux; +Cc: Kiran Rangoon
This series fixes a bug where unshare with --fork was not properly
forwarding SIGTERM and SIGINT to child processes, causing premature
termination during system shutdown.
The problem occurred because the parent process was blocking signals
instead of handling and forwarding them. When systemd sent SIGTERM
during shutdown, the parent would receive it but the child would
continue running until the kernel forcibly killed it. This resulted
in scripts being unable to handle SIGTERM traps properly and perform
cleanup operations.
The fix replaces signal blocking with signal handlers that forward
SIGTERM/SIGINT to the child process, allowing proper signal handling
and graceful shutdown. The waitpid loop is also updated to handle
EINTR interruptions from the signal forwarding mechanism.
Kiran Rangoon (5):
unshare: add global child_pid variable for signal forwarding
unshare: add signal forwarding handler
unshare: replace signal blocking with signal handlers
unshare: store child PID in global variable
unshare: handle EINTR in waitpid loop
sys-utils/unshare.c | 47 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 42 insertions(+), 5 deletions(-)
--
2.47.3
^ permalink raw reply
* Re: [PATCH v5 0/4] libuuid: Fix pre-1970 UUID timestamp overflow
From: Karel Zak @ 2026-01-05 13:35 UTC (permalink / raw)
To: Kiran Rangoon; +Cc: util-linux, thomas
In-Reply-To: <20251229035100.5778-1-kiranrangoon0@gmail.com>
On Sun, Dec 28, 2025 at 10:50:56PM -0500, Kiran Rangoon wrote:
> Kiran Rangoon (4):
> libuuid: simplify gregorian-to-unix offset calculation
> libuuid: refactor gregorian_to_unix to populate timeval directly
> libuuid: fix timestamp overflow for pre-1970 dates
> tests: correct UUID timestamp test expectations
Applied (from PR created by Thomas). Thanks to both for all the work!
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply
* [PATCH v5 4/4] tests: correct UUID timestamp test expectations
From: Kiran Rangoon @ 2025-12-29 3:51 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <20251229035100.5778-1-kiranrangoon0@gmail.com>
Update expected timestamps for additional test UUIDs to match actual
output. These test cases provide coverage for various timestamp ranges
including pre-epoch, historical, and far-future dates.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
tests/expected/uuid/uuidparse | 3 +++
tests/ts/uuid/uuidparse | 3 +++
2 files changed, 6 insertions(+)
diff --git a/tests/expected/uuid/uuidparse b/tests/expected/uuid/uuidparse
index e44964b30..61b49ef66 100644
--- a/tests/expected/uuid/uuidparse
+++ b/tests/expected/uuid/uuidparse
@@ -29,6 +29,9 @@ UUID VARIANT TYPE TIME
9b274c46-544a-11e7-a972-00037f500001 DCE time-based 2017-06-18 17:21:46,544647+00:00
1ec9414c-232a-6b00-b3c8-9f6bdeced846 DCE time-v6 2022-02-22 19:22:22,000000+00:00
017f22e2-79b2-7cc3-98c4-dc0c0c07398f DCE time-v7 2022-02-22 19:22:22,002000+00:00
+bf2eb110-d788-1003-aa59-ce1e9e293641 DCE time-based 1586-03-19 15:05:26,3611398+00:00
+f81d4fae-7dec-11d0-a765-00a0c91e6bf6 DCE time-based 1997-02-03 17:43:12,216875+00:00
+01234567-89ab-1def-8000-123456789abc DCE time-based 4764-11-18 19:35:47,841162+00:00
5c146b14-3c52-8afd-938a-375d0df1fbf6 DCE vendor
invalid-input invalid invalid invalid
return value: 0
diff --git a/tests/ts/uuid/uuidparse b/tests/ts/uuid/uuidparse
index 2903ce56d..f131986ba 100755
--- a/tests/ts/uuid/uuidparse
+++ b/tests/ts/uuid/uuidparse
@@ -56,6 +56,9 @@ echo '00000000-0000-0000-0000-000000000000
9b274c46-544a-11e7-a972-00037f500001
1ec9414c-232a-6b00-b3c8-9f6bdeced846
017f22e2-79b2-7cc3-98c4-dc0c0c07398f
+bf2eb110-d788-1003-aa59-ce1e9e293641
+f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+01234567-89ab-1def-8000-123456789abc
5c146b14-3c52-8afd-938a-375d0df1fbf6
invalid-input' | $TS_CMD_UUIDPARSE >> $TS_OUTPUT 2>> $TS_ERRLOG
--
2.47.3
^ permalink raw reply related
* [PATCH v5 3/4] libuuid: fix timestamp overflow for pre-1970 dates
From: Kiran Rangoon @ 2025-12-29 3:50 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <20251229035100.5778-1-kiranrangoon0@gmail.com>
Use int64_t arithmetic to correctly handle timestamps before Unix epoch.
This fixes the overflow that was causing UUID timestamps from 1582 to
appear as far-future dates. Update test expectations accordingly.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 2 +-
tests/expected/uuid/uuidparse | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index 2f7c6652c..63179fd76 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -63,7 +63,7 @@ time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
const uint64_t offset = 0x01B21DD213814000ULL;
- uint64_t clock_reg = ts - offset;
+ int64_t clock_reg = (int64_t)(ts - offset);
tv->tv_sec = clock_reg / 10000000;
tv->tv_usec = (clock_reg % 10000000) / 10;
}
diff --git a/tests/expected/uuid/uuidparse b/tests/expected/uuid/uuidparse
index 9edb05e4e..e44964b30 100644
--- a/tests/expected/uuid/uuidparse
+++ b/tests/expected/uuid/uuidparse
@@ -11,7 +11,7 @@ UUID VARIANT TYPE TIME
00000000-0000-3000-8000-000000000000 DCE name-based
00000000-0000-4000-8000-000000000000 DCE random
00000000-0000-5000-8000-000000000000 DCE sha1-based
-00000000-0000-6000-8000-000000000000 DCE time-v6 60038-03-11 05:36:10,955161+00:00
+00000000-0000-6000-8000-000000000000 DCE time-v6 1582-10-15 00:00:00,000000+00:00
00000000-0000-0000-d000-000000000000 Microsoft
00000000-0000-1000-d000-000000000000 Microsoft
00000000-0000-2000-d000-000000000000 Microsoft
--
2.47.3
^ permalink raw reply related
* [PATCH v5 2/4] libuuid: refactor gregorian_to_unix to populate timeval directly
From: Kiran Rangoon @ 2025-12-29 3:50 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <20251229035100.5778-1-kiranrangoon0@gmail.com>
Change function signature to take struct timeval pointer and populate
it directly, eliminating duplicate conversion code in callers.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index e2b991d74..2f7c6652c 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -60,10 +60,12 @@
/* prototype to make compiler happy */
time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
-static uint64_t gregorian_to_unix(uint64_t ts)
+static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
const uint64_t offset = 0x01B21DD213814000ULL;
- return ts - offset;
+ uint64_t clock_reg = ts - offset;
+ tv->tv_sec = clock_reg / 10000000;
+ tv->tv_usec = (clock_reg % 10000000) / 10;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
@@ -74,9 +76,7 @@ static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
high = uuid->time_mid | ((uuid->time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid->time_low | ((uint64_t) high << 32);
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
@@ -89,9 +89,7 @@ static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
clock_reg <<= 12;
clock_reg |= uuid->time_hi_and_version & 0xFFF;
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v7(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related
* [PATCH v5 1/4] libuuid: simplify gregorian-to-unix offset calculation
From: Kiran Rangoon @ 2025-12-29 3:50 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <20251229035100.5778-1-kiranrangoon0@gmail.com>
Replace complex bit-shift offset calculation with a simple constant
definition for better readability and maintainability.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index c7516152b..e2b991d74 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -62,7 +62,8 @@ time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
static uint64_t gregorian_to_unix(uint64_t ts)
{
- return ts - ((((uint64_t) 0x01B21DD2) << 32) + 0x13814000);
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ return ts - offset;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related
* [PATCH v5 0/4] libuuid: Fix pre-1970 UUID timestamp overflow
From: Kiran Rangoon @ 2025-12-29 3:50 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
> On 2025-12-18 16:31:21-0500, Kiran Rangoon wrote:
> > I revised the code in response to your feedback.
> Thanks!
> > > Looking at this more closely: __uuid_time() is directly exposed to users
> > > of libuuid as uuid_time(). This means that any change of the function's
> > > contract would break all external users and should be avoided at all
> > > costs.
> >
> > Reversed the change there.
>
> Your new revision is based on top of your old series.
> Instead it should always be based on upstream code.
> In this case the util-linux master branch.
Fixed in v4: I rebased directly on origin/master instead of building
on my previous patch series.
>
> > > Fortunately it turns out that the timestamps embedded in UUIDs
> > > only use 60 bits. This means that the calculation can be performed in an
> > > int64_t without any risk of over- or underflow. Please try to implement
> > > it that way instead.
> >
> > I'm using signed int64_t here as suggested.
> >
> > > It might be useful to change the signature of gregorian_to_unix() to
> > > "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
> >
> > I revised the code to use a struct timeval now.
>
> That looks good. However that refactoring should be in its own commit.
> More on that below.
Fixed in v4: The refactoring is now in its own dedicated commit (patch 2/4).
>
> > > Also please perform each logical step in a dedicated commit.
> >
> > > I made two commits, one for the code change and the other for tests, but
> > > if there is a way you would perfer me to do it I could change it.
> >
> The test is a bad candidate to split out. After each commit the
> repository needs to be in a consistent state, which means that the code
> builds and the tests pass. As the code change breaks the existing test,
> the test needs to be adapted in lockstep.
Understood. In v4, the test updates are included with the code changes
that require them, maintaining repository consistency at each commit.
>
> I see the following commits:
>
> 1) Switch to the simpler constant definition
> 2) Pass 'struct timeval' to gregorian_to_unix()
> 3) Fix the overflow, adapt the existing test
> 4) Add a hand full of additional testcases.
Implemented exactly as suggested in v4.
> Also this patch now lost its useful commit message which got replaced by
> our discussion. This should not happen. Each commit should explain why
> it is being done.
Fixed in v4: All commits now have proper descriptive messages explaining
the rationale for each change.
>
> > + const uint64_t offset = 0x01B21DD213814000ULL;
> > + int64_t t = (int64_t) ts - (int64_t) offset;
>
> Whitespace corruption?
Fixed in v4: Proper tab indentation is used throughout.
---
This v4 patch series addresses all the feedback points above:
Kiran Rangoon (4):
libuuid: simplify gregorian-to-unix offset calculation
libuuid: refactor gregorian_to_unix to populate timeval directly
libuuid: fix timestamp overflow for pre-1970 dates
tests: correct UUID timestamp test expectations
libuuid/src/uuid_time.c | 15 +++++++--------
tests/expected/uuid/uuidparse | 5 ++++-
tests/ts/uuid/uuidparse | 3 +++
3 files changed, 14 insertions(+), 9 deletions(-)
--
2.47.3
^ permalink raw reply
* Re: [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow
From: Thomas Weißschuh @ 2025-12-28 8:47 UTC (permalink / raw)
To: Kiran Rangoon; +Cc: util-linux
In-Reply-To: <20251223180055.2396-1-kiranrangoon0@gmail.com>
Hi Kiran,
On 2025-12-23 13:00:51-0500, Kiran Rangoon wrote:
(...)
> Kiran Rangoon (4):
> libuuid: simplify gregorian-to-unix offset calculation
> libuuid: refactor gregorian_to_unix to populate timeval directly
> libuuid: fix timestamp overflow for pre-1970 dates
> tests: correct UUID timestamp test expectations
>
> libuuid/src/uuid_time.c | 15 +++++++--------
> tests/expected/uuid/uuidparse | 5 ++++-
> tests/ts/uuid/uuidparse | 3 +++
> 3 files changed, 14 insertions(+), 9 deletions(-)
The series can't be applied as is. There are two 'PATCH 1/4' and the
'In-Reply-To' headers are broken. How did you send the patches?
Please just use 'git send-email' or 'b4' [0].
Also don't make your v5 a reply to the v4, it makes things messy.
Just start a new thread.
Thomas
[0] https://b4.docs.kernel.org/en/latest/
^ permalink raw reply
* Re: [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow
From: Thomas Weißschuh @ 2025-12-23 18:22 UTC (permalink / raw)
To: Kiran Rangoon; +Cc: util-linux
In-Reply-To: <20251223180055.2396-1-kiranrangoon0@gmail.com>
Dec 23, 2025 19:01:03 Kiran Rangoon <kiranrangoon0@gmail.com>:
(...)
>> > This v4 patch series addresses all the feedback points above:
>
> Kiran Rangoon (4):
> libuuid: simplify gregorian-to-unix offset calculation
> libuuid: refactor gregorian_to_unix to populate timeval directly
> libuuid: fix timestamp overflow for pre-1970 dates
> tests: correct UUID timestamp test expectations
>
> libuuid/src/uuid_time.c | 15 +++++++--------
> tests/expected/uuid/uuidparse | 5 ++++-
> tests/ts/uuid/uuidparse | 3 +++
> 3 files changed, 14 insertions(+), 9 deletions(-)
Thanks!
For the series, given it passes CI:
Reviewed-by: Thomas Weißschuh <thomas@t-8ch.de>
^ permalink raw reply
* [PATCH v4 4/4] tests: correct UUID timestamp test expectations
From: Kiran Rangoon @ 2025-12-23 18:05 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <9c4332f5-7aad-4804-b8f5-783e06572533@t-8ch.de>
Update expected timestamps for additional test UUIDs to match actual
output. These test cases provide coverage for various timestamp ranges
including pre-epoch, historical, and far-future dates.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
tests/expected/uuid/uuidparse | 3 +++
tests/ts/uuid/uuidparse | 3 +++
2 files changed, 6 insertions(+)
diff --git a/tests/expected/uuid/uuidparse b/tests/expected/uuid/uuidparse
index e44964b30..61b49ef66 100644
--- a/tests/expected/uuid/uuidparse
+++ b/tests/expected/uuid/uuidparse
@@ -29,6 +29,9 @@ UUID VARIANT TYPE TIME
9b274c46-544a-11e7-a972-00037f500001 DCE time-based 2017-06-18 17:21:46,544647+00:00
1ec9414c-232a-6b00-b3c8-9f6bdeced846 DCE time-v6 2022-02-22 19:22:22,000000+00:00
017f22e2-79b2-7cc3-98c4-dc0c0c07398f DCE time-v7 2022-02-22 19:22:22,002000+00:00
+bf2eb110-d788-1003-aa59-ce1e9e293641 DCE time-based 1586-03-19 15:05:26,3611398+00:00
+f81d4fae-7dec-11d0-a765-00a0c91e6bf6 DCE time-based 1997-02-03 17:43:12,216875+00:00
+01234567-89ab-1def-8000-123456789abc DCE time-based 4764-11-18 19:35:47,841162+00:00
5c146b14-3c52-8afd-938a-375d0df1fbf6 DCE vendor
invalid-input invalid invalid invalid
return value: 0
diff --git a/tests/ts/uuid/uuidparse b/tests/ts/uuid/uuidparse
index 2903ce56d..f131986ba 100755
--- a/tests/ts/uuid/uuidparse
+++ b/tests/ts/uuid/uuidparse
@@ -56,6 +56,9 @@ echo '00000000-0000-0000-0000-000000000000
9b274c46-544a-11e7-a972-00037f500001
1ec9414c-232a-6b00-b3c8-9f6bdeced846
017f22e2-79b2-7cc3-98c4-dc0c0c07398f
+bf2eb110-d788-1003-aa59-ce1e9e293641
+f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+01234567-89ab-1def-8000-123456789abc
5c146b14-3c52-8afd-938a-375d0df1fbf6
invalid-input' | $TS_CMD_UUIDPARSE >> $TS_OUTPUT 2>> $TS_ERRLOG
--
2.47.3
^ permalink raw reply related
* [PATCH v4 3/4] libuuid: fix timestamp overflow for pre-1970 dates
From: Kiran Rangoon @ 2025-12-23 18:04 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <9c4332f5-7aad-4804-b8f5-783e06572533@t-8ch.de>
Use int64_t arithmetic to correctly handle timestamps before Unix epoch.
This fixes the overflow that was causing UUID timestamps from 1582 to
appear as far-future dates. Update test expectations accordingly.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 2 +-
tests/expected/uuid/uuidparse | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index 2f7c6652c..63179fd76 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -63,7 +63,7 @@ time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
const uint64_t offset = 0x01B21DD213814000ULL;
- uint64_t clock_reg = ts - offset;
+ int64_t clock_reg = (int64_t)(ts - offset);
tv->tv_sec = clock_reg / 10000000;
tv->tv_usec = (clock_reg % 10000000) / 10;
}
diff --git a/tests/expected/uuid/uuidparse b/tests/expected/uuid/uuidparse
index 9edb05e4e..e44964b30 100644
--- a/tests/expected/uuid/uuidparse
+++ b/tests/expected/uuid/uuidparse
@@ -11,7 +11,7 @@ UUID VARIANT TYPE TIME
00000000-0000-3000-8000-000000000000 DCE name-based
00000000-0000-4000-8000-000000000000 DCE random
00000000-0000-5000-8000-000000000000 DCE sha1-based
-00000000-0000-6000-8000-000000000000 DCE time-v6 60038-03-11 05:36:10,955161+00:00
+00000000-0000-6000-8000-000000000000 DCE time-v6 1582-10-15 00:00:00,000000+00:00
00000000-0000-0000-d000-000000000000 Microsoft
00000000-0000-1000-d000-000000000000 Microsoft
00000000-0000-2000-d000-000000000000 Microsoft
--
2.47.3
^ permalink raw reply related
* [PATCH v4 1/4] libuuid: simplify gregorian-to-unix offset calculation
From: Kiran Rangoon @ 2025-12-23 18:03 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <20251223180055.2396-1-kiranrangoon0@gmail.com>
Replace complex bit-shift offset calculation with a simple constant
definition for better readability and maintainability.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index c7516152b..e2b991d74 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -62,7 +62,8 @@ time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
static uint64_t gregorian_to_unix(uint64_t ts)
{
- return ts - ((((uint64_t) 0x01B21DD2) << 32) + 0x13814000);
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ return ts - offset;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related
* [PATCH v4 2/4] libuuid: refactor gregorian_to_unix to populate timeval directly
From: Kiran Rangoon @ 2025-12-23 18:00 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <20251223180055.2396-1-kiranrangoon0@gmail.com>
Change function signature to take struct timeval pointer and populate
it directly, eliminating duplicate conversion code in callers.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index e2b991d74..2f7c6652c 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -60,10 +60,12 @@
/* prototype to make compiler happy */
time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
-static uint64_t gregorian_to_unix(uint64_t ts)
+static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
const uint64_t offset = 0x01B21DD213814000ULL;
- return ts - offset;
+ uint64_t clock_reg = ts - offset;
+ tv->tv_sec = clock_reg / 10000000;
+ tv->tv_usec = (clock_reg % 10000000) / 10;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
@@ -74,9 +76,7 @@ static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
high = uuid->time_mid | ((uuid->time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid->time_low | ((uint64_t) high << 32);
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
@@ -89,9 +89,7 @@ static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
clock_reg <<= 12;
clock_reg |= uuid->time_hi_and_version & 0xFFF;
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v7(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related
* [PATCH v4 1/4] libuuid: simplify gregorian-to-unix offset calculation
From: Kiran Rangoon @ 2025-12-23 18:00 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <20251223180055.2396-1-kiranrangoon0@gmail.com>
Replace complex bit-shift offset calculation with a simple constant
definition for better readability and maintainability.
Signed-off-by: Kiran Rangoon <kiranrangoon0@gmail.com>
---
libuuid/src/uuid_time.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index c7516152b..e2b991d74 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -62,7 +62,8 @@ time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
static uint64_t gregorian_to_unix(uint64_t ts)
{
- return ts - ((((uint64_t) 0x01B21DD2) << 32) + 0x13814000);
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ return ts - offset;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related
* [PATCH v4 0/4] libuuid: Fix pre-1970 UUID timestamp overflow
From: Kiran Rangoon @ 2025-12-23 18:00 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <9c4332f5-7aad-4804-b8f5-783e06572533@t-8ch.de>
> On 2025-12-18 16:31:21-0500, Kiran Rangoon wrote:
> > I revised the code in response to your feedback.
> Thanks!
> > > Looking at this more closely: __uuid_time() is directly exposed to users
> > > of libuuid as uuid_time(). This means that any change of the function's
> > > contract would break all external users and should be avoided at all
> > > costs.
> >
> > Reversed the change there.
>
> Your new revision is based on top of your old series.
> Instead it should always be based on upstream code.
> In this case the util-linux master branch.
Fixed in v4: I rebased directly on origin/master instead of building
on my previous patch series.
>
> > > Fortunately it turns out that the timestamps embedded in UUIDs
> > > only use 60 bits. This means that the calculation can be performed in an
> > > int64_t without any risk of over- or underflow. Please try to implement
> > > it that way instead.
> >
> > I'm using signed int64_t here as suggested.
> >
> > > It might be useful to change the signature of gregorian_to_unix() to
> > > "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
> >
> > I revised the code to use a struct timeval now.
>
> That looks good. However that refactoring should be in its own commit.
> More on that below.
Fixed in v4: The refactoring is now in its own dedicated commit (patch 2/4).
>
> > > Also please perform each logical step in a dedicated commit.
> >
> > > I made two commits, one for the code change and the other for tests, but
> > > if there is a way you would perfer me to do it I could change it.
> >
> The test is a bad candidate to split out. After each commit the
> repository needs to be in a consistent state, which means that the code
> builds and the tests pass. As the code change breaks the existing test,
> the test needs to be adapted in lockstep.
Understood. In v4, the test updates are included with the code changes
that require them, maintaining repository consistency at each commit.
>
> I see the following commits:
>
> 1) Switch to the simpler constant definition
> 2) Pass 'struct timeval' to gregorian_to_unix()
> 3) Fix the overflow, adapt the existing test
> 4) Add a hand full of additional testcases.
Implemented exactly as suggested in v4.
> Also this patch now lost its useful commit message which got replaced by
> our discussion. This should not happen. Each commit should explain why
> it is being done.
Fixed in v4: All commits now have proper descriptive messages explaining
the rationale for each change.
>
> > + const uint64_t offset = 0x01B21DD213814000ULL;
> > + int64_t t = (int64_t) ts - (int64_t) offset;
>
> Whitespace corruption?
Fixed in v4: Proper tab indentation is used throughout.
---
This v4 patch series addresses all the feedback points above:
Kiran Rangoon (4):
libuuid: simplify gregorian-to-unix offset calculation
libuuid: refactor gregorian_to_unix to populate timeval directly
libuuid: fix timestamp overflow for pre-1970 dates
tests: correct UUID timestamp test expectations
libuuid/src/uuid_time.c | 15 +++++++--------
tests/expected/uuid/uuidparse | 5 ++++-
tests/ts/uuid/uuidparse | 3 +++
3 files changed, 14 insertions(+), 9 deletions(-)
--
2.47.3
^ permalink raw reply
* Re: [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates
From: Thomas Weißschuh @ 2025-12-19 11:40 UTC (permalink / raw)
To: Kiran Rangoon; +Cc: util-linux
In-Reply-To: <20251218213121.4961-1-kiranrangoon0@gmail.com>
Hi Kiran,
On 2025-12-18 16:31:21-0500, Kiran Rangoon wrote:
> I revised the code in response to your feedback.
Thanks!
> > Looking at this more closely: __uuid_time() is directly exposed to users
> > of libuuid as uuid_time(). This means that any change of the function's
> > contract would break all external users and should be avoided at all
> > costs.
>
> Reversed the change there.
Your new revision is based on top of your old series.
Instead it should always be based on upstream code.
In this case the util-linux master branch.
> > Fortunately it turns out that the timestamps embedded in UUIDs
> > only use 60 bits. This means that the calculation can be performed in an
> > int64_t without any risk of over- or underflow. Please try to implement
> > it that way instead.
>
> I'm using signed int64_t here as suggested.
>
> > It might be useful to change the signature of gregorian_to_unix() to
> > "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
>
> I revised the code to use a struct timeval now.
That looks good. However that refactoring should be in its own commit.
More on that below.
> > Also please perform each logical step in a dedicated commit.
>
> I made two commits, one for the code change and the other for tests, but
> if there is a way you would perfer me to do it I could change it.
The test is a bad candidate to split out. After each commit the
repository needs to be in a consistent state, which means that the code
builds and the tests pass. As the code change breaks the existing test,
the test needs to be adapted in lockstep.
I see the following commits:
1) Switch to the simpler constant definition
2) Pass 'struct timeval' to gregorian_to_unix()
3) Fix the overflow, adapt the existing test
4) Add a hand full of additional testcases.
Also this patch now lost its useful commit message which got replaced by
our discussion. This should not happen. Each commit should explain why
it is being done.
> ---
> libuuid/src/uuid_time.c | 25 +++++++++----------------
> 1 file changed, 9 insertions(+), 16 deletions(-)
>
> diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
> index f0d2c8f36..293fc7e68 100644
> --- a/libuuid/src/uuid_time.c
> +++ b/libuuid/src/uuid_time.c
> @@ -60,34 +60,29 @@
> /* prototype to make compiler happy */
> time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
>
> -static int64_t gregorian_to_unix(uint64_t ts)
> +static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
> {
> - const uint64_t offset = 0x01B21DD213814000ULL;
> + const uint64_t offset = 0x01B21DD213814000ULL;
> + int64_t t = (int64_t) ts - (int64_t) offset;
Whitespace corruption?
> - if (ts < offset) {
> - errno = EOVERFLOW;
> - return -1;
> - }
> -
> - return ts - offset;
> + tv->tv_sec = t / 10000000;
> + tv->tv_usec = (t % 10000000) / 10;
> }
(...)
Thomas
^ permalink raw reply
* [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates
From: Kiran Rangoon @ 2025-12-18 21:31 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <9dc90e33-30e2-48c3-8602-00fce280f9ef@t-8ch.de>
I revised the code in response to your feedback.
> Looking at this more closely: __uuid_time() is directly exposed to users
> of libuuid as uuid_time(). This means that any change of the function's
> contract would break all external users and should be avoided at all
> costs.
Reversed the change there.
> Fortunately it turns out that the timestamps embedded in UUIDs
> only use 60 bits. This means that the calculation can be performed in an
> int64_t without any risk of over- or underflow. Please try to implement
> it that way instead.
I'm using signed int64_t here as suggested.
> It might be useful to change the signature of gregorian_to_unix() to
> "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
I revised the code to use a struct timeval now.
> Also please perform each logical step in a dedicated commit.
I made two commits, one for the code change and the other for tests, but
if there is a way you would perfer me to do it I could change it.
---
libuuid/src/uuid_time.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index f0d2c8f36..293fc7e68 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -60,34 +60,29 @@
/* prototype to make compiler happy */
time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
-static int64_t gregorian_to_unix(uint64_t ts)
+static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
- const uint64_t offset = 0x01B21DD213814000ULL;
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ int64_t t = (int64_t) ts - (int64_t) offset;
- if (ts < offset) {
- errno = EOVERFLOW;
- return -1;
- }
-
- return ts - offset;
+ tv->tv_sec = t / 10000000;
+ tv->tv_usec = (t % 10000000) / 10;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
{
uint32_t high;
- int64_t clock_reg;
+ uint64_t clock_reg;
high = uuid->time_mid | ((uuid->time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid->time_low | ((uint64_t) high << 32);
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
{
- int64_t clock_reg;
+ uint64_t clock_reg;
clock_reg = uuid->time_low;
clock_reg <<= 16;
@@ -95,9 +90,7 @@ static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
clock_reg <<= 12;
clock_reg |= uuid->time_hi_and_version & 0xFFF;
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v7(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related
* Inconsistent results from script test case
From: Paul Barker @ 2025-12-18 20:20 UTC (permalink / raw)
To: util-linux
[-- Attachment #1: Type: text/plain, Size: 2088 bytes --]
Hi,
On the Yocto Project autobuilder we have seen occasional failures of the
util-linux test suite over the past year or so.
After investigating this, the failing test is the "size" subtest in
tests/ts/script/options. Occasionally, fewer characters than expected
are read from the pty and the test output doesn't match the expected
output.
Running the tested command in a loop locally, with heavy background load
on the CPUs, showed inconsistent results.
for i in $(seq 0 4095); do \
SCRIPT_TEST_SECOND_SINCE_EPOCH=1432489398 TZ=GMT \
../util-linux/test_script --output-limit 9 --command "echo 1:1234567890" test$i > /dev/null < /dev/null 2>&1 ; \
done
This generated 3849 runs with the expected output, where there is a
blank line after the echo command output (94%):
Script started on 2015-05-24 17:43:18+00:00 [COMMAND="echo 1:1234567890" <not executed on terminal>]
1:1234567890
Script done on 2015-05-24 17:43:18+00:00 [<max output size exceeded>]
And 247 runs without the blank line (6%):
Script started on 2015-05-24 17:43:18+00:00 [COMMAND="echo 1:1234567890" <not executed on terminal>]
1:1234567890
Script done on 2015-05-24 17:43:18+00:00 [<max output size exceeded>]
This test was performed on the current HEAD of util-linux, commit
e4656fa9765f ("zramctl: Add note about column descriptions").
I see two possible ways to fix this flaky test:
1) Modify `script` to never print more characters than the requested
output limit. This will ensure that the generated output is always
consistent, regardless of the influence of I/O buffering.
2) Modify the test case to accept both of the above possible output
variants.
We would like some input from folks more familiar with util-linux on
which of those options is preferred. For option (1) I should be able to
send a patch, for option (2) more invasive changes to the test framework
may be needed to allow for multiple expected outputs so I may not be
able to contribute that change myself.
Best regards,
--
Paul Barker
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
^ permalink raw reply
* [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates
From: Kiran Rangoon @ 2025-12-17 20:59 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <9dc90e33-30e2-48c3-8602-00fce280f9ef@t-8ch.de>
I revised the code in response to your feedback.
> Looking at this more closely: __uuid_time() is directly exposed to users
> of libuuid as uuid_time(). This means that any change of the function's
> contract would break all external users and should be avoided at all
> costs.
Reversed the change there.
> Fortunately it turns out that the timestamps embedded in UUIDs
> only use 60 bits. This means that the calculation can be performed in an
> int64_t without any risk of over- or underflow. Please try to implement
> it that way instead.
I'm using signed int64_t here as suggested.
> It might be useful to change the signature of gregorian_to_unix() to
> "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
I revised the code to use a struct timeval now.
> Also please perform each logical step in a dedicated commit.
I made two commits, one for the code change and the other for tests, but
if there is a way you would perfer me to do it I could change it.
---
libuuid/src/uuid_time.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index f0d2c8f36..293fc7e68 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -60,34 +60,29 @@
/* prototype to make compiler happy */
time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
-static int64_t gregorian_to_unix(uint64_t ts)
+static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
- const uint64_t offset = 0x01B21DD213814000ULL;
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ int64_t t = (int64_t) ts - (int64_t) offset;
- if (ts < offset) {
- errno = EOVERFLOW;
- return -1;
- }
-
- return ts - offset;
+ tv->tv_sec = t / 10000000;
+ tv->tv_usec = (t % 10000000) / 10;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
{
uint32_t high;
- int64_t clock_reg;
+ uint64_t clock_reg;
high = uuid->time_mid | ((uuid->time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid->time_low | ((uint64_t) high << 32);
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
{
- int64_t clock_reg;
+ uint64_t clock_reg;
clock_reg = uuid->time_low;
clock_reg <<= 16;
@@ -95,9 +90,7 @@ static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
clock_reg <<= 12;
clock_reg |= uuid->time_hi_and_version & 0xFFF;
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v7(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related
* [PATCH v3 1/2] libuuid: Refactor UUID time conversion for pre-epoch dates
From: Kiran Rangoon @ 2025-12-17 20:42 UTC (permalink / raw)
To: util-linux; +Cc: thomas, Kiran Rangoon
In-Reply-To: <9dc90e33-30e2-48c3-8602-00fce280f9ef@t-8ch.de>
I revised the code in response to your feedback.
> Looking at this more closely: __uuid_time() is directly exposed to users
> of libuuid as uuid_time(). This means that any change of the function's
> contract would break all external users and should be avoided at all
> costs.
Reversed the change there.
> Fortunately it turns out that the timestamps embedded in UUIDs
> only use 60 bits. This means that the calculation can be performed in an
> int64_t without any risk of over- or underflow. Please try to implement
> it that way instead.
I'm using signed int64_t here as suggested.
> It might be useful to change the signature of gregorian_to_unix() to
> "static void gregorian_to_unix(uint64_t ts, struct timeval *tv)".
I revised the code to use a struct timeval now.
> Also please perform each logical step in a dedicated commit.
I made two commits, one for the code change and the other for tests, but
if there is a way you would perfer me to do it I could change it.
---
libuuid/src/uuid_time.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/libuuid/src/uuid_time.c b/libuuid/src/uuid_time.c
index f0d2c8f36..293fc7e68 100644
--- a/libuuid/src/uuid_time.c
+++ b/libuuid/src/uuid_time.c
@@ -60,34 +60,29 @@
/* prototype to make compiler happy */
time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
-static int64_t gregorian_to_unix(uint64_t ts)
+static void gregorian_to_unix(uint64_t ts, struct timeval *tv)
{
- const uint64_t offset = 0x01B21DD213814000ULL;
+ const uint64_t offset = 0x01B21DD213814000ULL;
+ int64_t t = (int64_t) ts - (int64_t) offset;
- if (ts < offset) {
- errno = EOVERFLOW;
- return -1;
- }
-
- return ts - offset;
+ tv->tv_sec = t / 10000000;
+ tv->tv_usec = (t % 10000000) / 10;
}
static void uuid_time_v1(const struct uuid *uuid, struct timeval *tv)
{
uint32_t high;
- int64_t clock_reg;
+ uint64_t clock_reg;
high = uuid->time_mid | ((uuid->time_hi_and_version & 0xFFF) << 16);
clock_reg = uuid->time_low | ((uint64_t) high << 32);
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
{
- int64_t clock_reg;
+ uint64_t clock_reg;
clock_reg = uuid->time_low;
clock_reg <<= 16;
@@ -95,9 +90,7 @@ static void uuid_time_v6(const struct uuid *uuid, struct timeval *tv)
clock_reg <<= 12;
clock_reg |= uuid->time_hi_and_version & 0xFFF;
- clock_reg = gregorian_to_unix(clock_reg);
- tv->tv_sec = clock_reg / 10000000;
- tv->tv_usec = (clock_reg % 10000000) / 10;
+ gregorian_to_unix(clock_reg, tv);
}
static void uuid_time_v7(const struct uuid *uuid, struct timeval *tv)
--
2.47.3
^ permalink raw reply related
* Re: [PATCH 3/3] blkpr: add read-reservation command
From: Stefan Hajnoczi @ 2025-12-17 18:26 UTC (permalink / raw)
To: Karel Zak; +Cc: util-linux
In-Reply-To: <ce5rsy5oycyuyfke6kcyrqokgim3cctjewhuv4gw2ptbkev7zh@ehw77wgurx7y>
[-- Attachment #1: Type: text/plain, Size: 1141 bytes --]
On Wed, Dec 17, 2025 at 11:53:46AM +0100, Karel Zak wrote:
> On Thu, Dec 11, 2025 at 11:09:56AM -0500, Stefan Hajnoczi wrote:
> >
> > diff --git a/meson.build b/meson.build
> > index 47b43c2af..b759e992f 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -768,6 +768,9 @@ conf.set('HAVE_DECL_PR_REP_CAPACITY', have ? 1 : false)
> > have = cc.has_header_symbol('linux/pr.h', 'IOC_PR_READ_KEYS')
> > conf.set('HAVE_DECL_IOC_PR_READ_KEYS', have ? 1 : false)
> >
> > +have = cc.has_header_symbol('linux/pr.h', 'IOC_PR_READ_RESERVATION')
> > +conf.set('HAVE_DECL_IOC_PR_READ_RESERVATION', have ? 1 : false)
>
> It seems you do not need to define HAVE_DECL_IOC_PR_READ_RESERVATION
> and care about this in meson.build or configure.ac.
>
> > +#if HAVE_DECL_IOC_PR_READ_RESERVATION
> > + {IOC_PR_READ_RESERVATION, "read-reservation",
> > + " * read-reservation: This command shows the current reservation.\n"},
> > +#endif
>
> I think you can use directly
>
> #ifdef IOC_PR_READ_RESERVATION
>
> #endif
>
> as IOC_PR_READ_RESERVATION is macro in linux/pr.h
Will fix in v2.
Stefan
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [PATCH v2 1/3] blkpr: prepare for _IOR() ioctls
From: Stefan Hajnoczi @ 2025-12-17 18:26 UTC (permalink / raw)
To: util-linux; +Cc: kwolf, hare, Karel Zak, pizhenwei, Stefan Hajnoczi
In-Reply-To: <20251217182607.179232-1-stefanha@redhat.com>
parse_pr_command() returns the ioctl command constant for a given
command or -1 when the command is unknown. Up until now all ioctl
command constants were positive, so the following check worked:
if (command < 0)
err(EXIT_FAILURE, _("unknown command"));
The top two bits of ioctl command constants encode the direction (_IO,
_IOR, _IOW, _IOWR). ioctl commands defined with _IOR have negative ioctl
command constants.
Explicitly check for -1 to differentiate "unknown command" from valid
ioctls commands. Later commits will add ioctl commands that use _IOR.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
sys-utils/blkpr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sys-utils/blkpr.c b/sys-utils/blkpr.c
index 03ca9f7e5..c6b030def 100644
--- a/sys-utils/blkpr.c
+++ b/sys-utils/blkpr.c
@@ -276,7 +276,7 @@ int main(int argc, char **argv)
break;
case 'c':
command = parse_pr_command(optarg);
- if (command < 0)
+ if (command == -1)
err(EXIT_FAILURE, _("unknown command"));
break;
case 't':
--
2.52.0
^ permalink raw reply related
* [PATCH v2 2/3] blkpr: add read-keys command
From: Stefan Hajnoczi @ 2025-12-17 18:26 UTC (permalink / raw)
To: util-linux; +Cc: kwolf, hare, Karel Zak, pizhenwei, Stefan Hajnoczi
In-Reply-To: <20251217182607.179232-1-stefanha@redhat.com>
The new IOC_PR_READ_KEYS ioctl lists registered keys on a device. Add a
command so that users can inspect keys. This is useful both for
troubleshooting and for recovery scenarios.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
sys-utils/blkpr.c | 46 ++++++++++++++++++++++++++++++++++++++++++
sys-utils/blkpr.8.adoc | 3 ++-
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/sys-utils/blkpr.c b/sys-utils/blkpr.c
index c6b030def..84e736e9f 100644
--- a/sys-utils/blkpr.c
+++ b/sys-utils/blkpr.c
@@ -103,6 +103,12 @@ static const struct type_string pr_command[] = {
{IOC_PR_CLEAR, "clear",
" * clear: This command unregisters both key and any other reservation\n"
" key registered with the device and drops any existing reservation.\n"},
+
+#ifdef IOC_PR_READ_KEYS
+ {IOC_PR_READ_KEYS, "read-keys",
+ " * read-keys: This command lists reservation keys currently registered\n"
+ " with the device.\n"},
+#endif
};
static const struct type_string pr_flag[] = {
@@ -151,6 +157,41 @@ PARSE(pr_type)
PARSE(pr_command)
PARSE(pr_flag)
+#ifdef IOC_PR_READ_KEYS
+static int do_pr_read_keys(int fd)
+{
+ struct pr_read_keys pr_rk;
+ uint32_t num_keys = 8;
+ uint64_t *keys = NULL;
+ int ret;
+
+ /* Loop to grow keys[] until it is large enough */
+ do {
+ num_keys *= 2;
+ keys = xreallocarray(keys, num_keys, sizeof(keys[0]));
+
+ pr_rk.keys_ptr = (uintptr_t)keys;
+ pr_rk.num_keys = num_keys;
+
+ ret = ioctl(fd, IOC_PR_READ_KEYS, &pr_rk);
+ if (ret)
+ goto out;
+ } while (pr_rk.num_keys > num_keys);
+
+ if (pr_rk.num_keys) {
+ for (uint32_t i = 0; i < pr_rk.num_keys; i++) {
+ printf(_("%#" PRIx64 "\n"), (uint64_t)keys[i]);
+ }
+ } else {
+ printf(_("No registered keys\n"));
+ }
+
+out:
+ free(keys);
+ return ret;
+}
+#endif /* IOC_PR_READ_KEYS */
+
static int do_pr(char *path, uint64_t key, uint64_t oldkey, int op, int type, int flag)
{
struct pr_registration pr_reg;
@@ -190,6 +231,11 @@ static int do_pr(char *path, uint64_t key, uint64_t oldkey, int op, int type, in
pr_clr.flags = flag;
ret = ioctl(fd, op, &pr_clr);
break;
+#ifdef IOC_PR_READ_KEYS
+ case IOC_PR_READ_KEYS:
+ ret = do_pr_read_keys(fd);
+ break;
+#endif
default:
errno = EINVAL;
err(EXIT_FAILURE, _("unknown command"));
diff --git a/sys-utils/blkpr.8.adoc b/sys-utils/blkpr.8.adoc
index 98983b779..3a157af38 100644
--- a/sys-utils/blkpr.8.adoc
+++ b/sys-utils/blkpr.8.adoc
@@ -25,7 +25,8 @@ The _device_ argument is the pathname of the block device.
*-c*, *--command* _command_::
The command for managing persistent reservations. Supported commands are:
-*register*, *reserve*, *release*, *preempt*, *preempt-abort*, and *clear*.
+*register*, *reserve*, *release*, *preempt*, *preempt-abort*, *clear*, and
+*read-keys*.
*-k*, *--key* _key_::
The key the command should operate on.
--
2.52.0
^ permalink raw reply related
* [PATCH v2 3/3] blkpr: add read-reservation command
From: Stefan Hajnoczi @ 2025-12-17 18:26 UTC (permalink / raw)
To: util-linux; +Cc: kwolf, hare, Karel Zak, pizhenwei, Stefan Hajnoczi
In-Reply-To: <20251217182607.179232-1-stefanha@redhat.com>
The new IOC_PR_READ_RESERVATION ioctl reports the current reservation on
a device. Add a command so that users can inspect the current
reservation. This is useful both for troubleshooting and for recovery
scenarios.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
sys-utils/blkpr.c | 60 +++++++++++++++++++++++++++++++++++++-----
sys-utils/blkpr.8.adoc | 4 +--
2 files changed, 55 insertions(+), 9 deletions(-)
diff --git a/sys-utils/blkpr.c b/sys-utils/blkpr.c
index 84e736e9f..e2e67b3f1 100644
--- a/sys-utils/blkpr.c
+++ b/sys-utils/blkpr.c
@@ -73,7 +73,7 @@ static const struct type_string pr_type[] = {
};
static const struct type_string pr_command[] = {
- {IOC_PR_REGISTER, "register",
+ {IOC_PR_REGISTER, "register",
" * register: This command registers a new reservation if the key argument\n"
" is non-null. If no existing reservation exists oldkey must be zero, if\n"
" an existing reservation should be replaced oldkey must contain the old\n"
@@ -81,34 +81,39 @@ static const struct type_string pr_command[] = {
" reservation passed in oldkey.\n"
},
- {IOC_PR_RESERVE, "reserve",
+ {IOC_PR_RESERVE, "reserve",
" * reserve: This command reserves the device and thus restricts access for\n"
" other devices based on the type argument. The key argument must be\n"
" the existing reservation key for the device as acquired by the register,\n"
" preempt, preempt-abort commands.\n"},
- {IOC_PR_RELEASE, "release",
+ {IOC_PR_RELEASE, "release",
" * release: This command releases the reservation specified by key and flags\n"
" and thus removes any access restriction implied by it.\n"},
- {IOC_PR_PREEMPT, "preempt",
+ {IOC_PR_PREEMPT, "preempt",
" * preempt: This command releases the existing reservation referred to by\n"
" old_key and replaces it with a new reservation of type for the\n"
" reservation key key.\n"},
- {IOC_PR_PREEMPT_ABORT, "preempt-abort",
+ {IOC_PR_PREEMPT_ABORT, "preempt-abort",
" * preempt-abort: This command works like preempt except that it also aborts\n"
" any outstanding command sent over a connection identified by oldkey.\n"},
- {IOC_PR_CLEAR, "clear",
+ {IOC_PR_CLEAR, "clear",
" * clear: This command unregisters both key and any other reservation\n"
" key registered with the device and drops any existing reservation.\n"},
#ifdef IOC_PR_READ_KEYS
- {IOC_PR_READ_KEYS, "read-keys",
+ {IOC_PR_READ_KEYS, "read-keys",
" * read-keys: This command lists reservation keys currently registered\n"
" with the device.\n"},
#endif
+
+#ifdef IOC_PR_READ_RESERVATION
+ {IOC_PR_READ_RESERVATION, "read-reservation",
+ " * read-reservation: This command shows the current reservation.\n"},
+#endif
};
static const struct type_string pr_flag[] = {
@@ -140,6 +145,18 @@ static int parse_type_by_str(const struct type_string *ts, int nmem, char *patte
return -1;
}
+static inline const char *type_to_str(const struct type_string *ts, int nmem,
+ int type)
+{
+ int i;
+
+ for (i = 0; i < nmem; i++) {
+ if (ts[i].type == type)
+ return ts[i].str;
+ }
+ return "unknown type";
+}
+
#define PRINT_SUPPORTED(XX) \
static void print_##XX(FILE *out) \
@@ -192,6 +209,30 @@ out:
}
#endif /* IOC_PR_READ_KEYS */
+#ifdef IOC_PR_READ_RESERVATION
+static int do_pr_read_reservation(int fd)
+{
+ struct pr_read_reservation pr_rr;
+ const char *type_str;
+ int ret;
+
+ ret = ioctl(fd, IOC_PR_READ_RESERVATION, &pr_rr);
+ if (ret)
+ return ret;
+
+ type_str = type_to_str(pr_type, ARRAY_SIZE(pr_type), pr_rr.type);
+
+ if (pr_rr.key) {
+ printf(_("Key: %#" PRIx64 "\n"), (uint64_t)pr_rr.key);
+ printf(_("Generation: %#x\n"), pr_rr.generation);
+ printf(_("Type: %s\n"), type_str);
+ } else {
+ printf(_("No reservation\n"));
+ }
+ return 0;
+}
+#endif /* IOC_PR_READ_RESERVATION */
+
static int do_pr(char *path, uint64_t key, uint64_t oldkey, int op, int type, int flag)
{
struct pr_registration pr_reg;
@@ -235,6 +276,11 @@ static int do_pr(char *path, uint64_t key, uint64_t oldkey, int op, int type, in
case IOC_PR_READ_KEYS:
ret = do_pr_read_keys(fd);
break;
+#endif
+#ifdef IOC_PR_READ_RESERVATION
+ case IOC_PR_READ_RESERVATION:
+ ret = do_pr_read_reservation(fd);
+ break;
#endif
default:
errno = EINVAL;
diff --git a/sys-utils/blkpr.8.adoc b/sys-utils/blkpr.8.adoc
index 3a157af38..630bafb92 100644
--- a/sys-utils/blkpr.8.adoc
+++ b/sys-utils/blkpr.8.adoc
@@ -25,8 +25,8 @@ The _device_ argument is the pathname of the block device.
*-c*, *--command* _command_::
The command for managing persistent reservations. Supported commands are:
-*register*, *reserve*, *release*, *preempt*, *preempt-abort*, *clear*, and
-*read-keys*.
+*register*, *reserve*, *release*, *preempt*, *preempt-abort*, *clear*,
+*read-keys*, and *read-reservation*.
*-k*, *--key* _key_::
The key the command should operate on.
--
2.52.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox