* [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands
@ 2025-12-17 18:26 Stefan Hajnoczi
2025-12-17 18:26 ` [PATCH v2 1/3] blkpr: prepare for _IOR() ioctls Stefan Hajnoczi
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2025-12-17 18:26 UTC (permalink / raw)
To: util-linux; +Cc: kwolf, hare, Karel Zak, pizhenwei, Stefan Hajnoczi
v2:
- Use #ifdef IOC_PR_... instead of autoconf/meson because it's simpler [Karel]
New <linux/pr.h> ioctls make it possible to fetch the list of registered keys
and the details of the current reservation from a block device. The relevant
Linux commits are:
3e2cb9ee76c27 block: add IOC_PR_READ_RESERVATION ioctl
22a1ffea5f805 block: add IOC_PR_READ_KEYS ioctl
Add the appropriate commands to blkpr. Users can use these for troubleshooting
and cluster management tools may use them to query the state of persistent
reservations during recovery.
Stefan Hajnoczi (3):
blkpr: prepare for _IOR() ioctls
blkpr: add read-keys command
blkpr: add read-reservation command
sys-utils/blkpr.c | 106 ++++++++++++++++++++++++++++++++++++++---
sys-utils/blkpr.8.adoc | 3 +-
2 files changed, 101 insertions(+), 8 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/3] blkpr: prepare for _IOR() ioctls
2025-12-17 18:26 [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands Stefan Hajnoczi
@ 2025-12-17 18:26 ` Stefan Hajnoczi
2025-12-17 18:26 ` [PATCH v2 2/3] blkpr: add read-keys command Stefan Hajnoczi
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2025-12-17 18:26 UTC (permalink / raw)
To: util-linux; +Cc: kwolf, hare, Karel Zak, pizhenwei, Stefan Hajnoczi
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 [flat|nested] 5+ messages in thread
* [PATCH v2 2/3] blkpr: add read-keys command
2025-12-17 18:26 [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands Stefan Hajnoczi
2025-12-17 18:26 ` [PATCH v2 1/3] blkpr: prepare for _IOR() ioctls Stefan Hajnoczi
@ 2025-12-17 18:26 ` Stefan Hajnoczi
2025-12-17 18:26 ` [PATCH v2 3/3] blkpr: add read-reservation command Stefan Hajnoczi
2026-01-14 9:30 ` [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands Karel Zak
3 siblings, 0 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2025-12-17 18:26 UTC (permalink / raw)
To: util-linux; +Cc: kwolf, hare, Karel Zak, pizhenwei, Stefan Hajnoczi
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 [flat|nested] 5+ messages in thread
* [PATCH v2 3/3] blkpr: add read-reservation command
2025-12-17 18:26 [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands Stefan Hajnoczi
2025-12-17 18:26 ` [PATCH v2 1/3] blkpr: prepare for _IOR() ioctls Stefan Hajnoczi
2025-12-17 18:26 ` [PATCH v2 2/3] blkpr: add read-keys command Stefan Hajnoczi
@ 2025-12-17 18:26 ` Stefan Hajnoczi
2026-01-14 9:30 ` [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands Karel Zak
3 siblings, 0 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2025-12-17 18:26 UTC (permalink / raw)
To: util-linux; +Cc: kwolf, hare, Karel Zak, pizhenwei, Stefan Hajnoczi
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 [flat|nested] 5+ messages in thread
* Re: [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands
2025-12-17 18:26 [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands Stefan Hajnoczi
` (2 preceding siblings ...)
2025-12-17 18:26 ` [PATCH v2 3/3] blkpr: add read-reservation command Stefan Hajnoczi
@ 2026-01-14 9:30 ` Karel Zak
3 siblings, 0 replies; 5+ messages in thread
From: Karel Zak @ 2026-01-14 9:30 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: util-linux, kwolf, hare, pizhenwei
On Wed, Dec 17, 2025 at 01:26:04PM -0500, Stefan Hajnoczi wrote:
> sys-utils/blkpr.c | 106 ++++++++++++++++++++++++++++++++++++++---
> sys-utils/blkpr.8.adoc | 3 +-
> 2 files changed, 101 insertions(+), 8 deletions(-)
Applied, thanks.
https://github.com/util-linux/util-linux/pull/3965
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-01-14 9:31 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-17 18:26 [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands Stefan Hajnoczi
2025-12-17 18:26 ` [PATCH v2 1/3] blkpr: prepare for _IOR() ioctls Stefan Hajnoczi
2025-12-17 18:26 ` [PATCH v2 2/3] blkpr: add read-keys command Stefan Hajnoczi
2025-12-17 18:26 ` [PATCH v2 3/3] blkpr: add read-reservation command Stefan Hajnoczi
2026-01-14 9:30 ` [PATCH v2 0/3] blkpr: add read-keys and read-reservations commands Karel Zak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox