* [PATCH] blkpr: add block persistent reservations command
@ 2021-09-16 3:29 zhenwei pi
2021-09-23 2:18 ` PING: " zhenwei pi
2022-04-05 7:14 ` Christoph Hellwig
0 siblings, 2 replies; 7+ messages in thread
From: zhenwei pi @ 2021-09-16 3:29 UTC (permalink / raw)
To: kzak; +Cc: util-linux, pizhenwei
Linux kernel block layer supports PR (persistent reservations) ioctl
on a block device. Typically SCSI and NVMe disk support PR feature,
and blkpr could operation on them.
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
---
configure.ac | 11 ++
sys-utils/Makemodule.am | 8 ++
sys-utils/blkpr.8.adoc | 64 ++++++++++
sys-utils/blkpr.c | 277 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 360 insertions(+)
create mode 100644 sys-utils/blkpr.8.adoc
create mode 100644 sys-utils/blkpr.c
diff --git a/configure.ac b/configure.ac
index 60e63592b..ae47a5c6c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -310,6 +310,7 @@ AC_CHECK_HEADERS([ \
linux/fiemap.h \
linux/net_namespace.h \
linux/nsfs.h \
+ linux/pr.h \
linux/raw.h \
linux/securebits.h \
linux/tiocl.h \
@@ -387,6 +388,10 @@ AC_CHECK_DECLS([BLK_ZONE_REP_CAPACITY], [], [], [
#include <linux/blkzoned.h>
])
+AC_CHECK_DECLS([PR_REP_CAPACITY], [], [], [
+ #include <linux/pr.h>
+])
+
AC_CHECK_HEADERS([security/openpam.h], [], [], [
#ifdef HAVE_SECURITY_PAM_APPL_H
#include <security/pam_appl.h>
@@ -454,6 +459,7 @@ dnl
have_linux_blkzoned_h=$ac_cv_header_linux_blkzoned_h
have_linux_btrfs_h=$ac_cv_header_linux_btrfs_h
have_linux_capability_h=$ac_cv_header_linux_capability_h
+have_linux_pr_h=$ac_cv_header_linux_pr_h
have_linux_raw_h=$ac_cv_header_linux_raw_h
have_linux_securebits_h=$ac_cv_header_linux_securebits_h
have_linux_version_h=$ac_cv_header_linux_version_h
@@ -1905,6 +1911,11 @@ UL_REQUIRES_LINUX([blkzone])
UL_REQUIRES_HAVE([blkzone], [linux_blkzoned_h], [linux/blkzoned.h header])
AM_CONDITIONAL([BUILD_BLKZONE], [test "x$build_blkzone" = xyes])
+UL_BUILD_INIT([blkpr], [check])
+UL_REQUIRES_LINUX([blkpr])
+UL_REQUIRES_HAVE([blkpr], [linux_pr_h], [linux/pr.h header])
+AM_CONDITIONAL([BUILD_BLKPR], [test "x$build_blkpr" = xyes])
+
UL_BUILD_INIT([ldattach], [check])
UL_REQUIRES_LINUX([ldattach])
AM_CONDITIONAL([BUILD_LDATTACH], [test "x$build_ldattach" = xyes])
diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
index e55363484..22047d9bd 100644
--- a/sys-utils/Makemodule.am
+++ b/sys-utils/Makemodule.am
@@ -202,6 +202,14 @@ blkzone_SOURCES = sys-utils/blkzone.c
blkzone_LDADD = $(LDADD) libcommon.la
endif
+if BUILD_BLKPR
+sbin_PROGRAMS += blkpr
+MANPAGES += sys-utils/blkpr.8
+dist_noinst_DATA += sys-utils/blkpr.8.adoc
+blkpr_SOURCES = sys-utils/blkpr.c
+blkpr_LDADD = $(LDADD) libcommon.la
+endif
+
if BUILD_LDATTACH
usrsbin_exec_PROGRAMS += ldattach
MANPAGES += sys-utils/ldattach.8
diff --git a/sys-utils/blkpr.8.adoc b/sys-utils/blkpr.8.adoc
new file mode 100644
index 000000000..dc8bb3893
--- /dev/null
+++ b/sys-utils/blkpr.8.adoc
@@ -0,0 +1,64 @@
+//po4a: entry man manual
+= blkpr(8)
+:doctype: manpage
+:man manual: System Administration
+:man source: util-linux {release-version}
+:page-layout: base
+:command: blkpr
+
+== NAME
+
+blkpr - run persistent reservations command on a device
+
+== SYNOPSIS
+
+*blkpr* [options] _device_
+
+== DESCRIPTION
+
+*blkpr* is used to run persistent reservations command on device that supports Persistent Reservations feature.
+
+The _device_ argument is the pathname of the block device.
+
+== OPTIONS
+
+*-o*, *--operation* _operation_::
+The operation of persistent reservations, supported [register|reserve|release|preempt|preempt-abort|clear].
+
+*-k*, *--key* _key_::
+The key the operation should operate on.
+
+*-K*, *--oldkey* _oldkey_::
+The old key the operation should operate on.
+
+*-f*, *--flag* _flag_::
+Supported flag [ignore-key].
+
+*-t*, *--type*::
+Supported type [write-exclusive|exclusive-access|write-exclusive-reg-only|exclusive-access-reg-only|write-exclusive-all-regs|exclusive-access-all-regs]
+
+*-V*, *--version*::
+Display version information and exit.
+
+*-h*, *--help*::
+Display help text and exit.
+
+== AUTHORS
+
+mailto:pizhenwei@bytedance.com[zhenwei pi]
+
+== SEE ALSO
+
+*sg_persist*(8)
+
+Linux documentation at: <https://www.kernel.org/doc/Documentation/block/pr.txt>
+iSCSI specification at: <https://datatracker.ietf.org/doc/html/rfc3720>
+NVMe-oF specification at: <https://nvmexpress.org/nvme-over-fabrics-part-two/>
+
+include::man-common/bugreports.adoc[]
+
+include::man-common/footer.adoc[]
+
+ifdef::translation[]
+include::man-common/translation.adoc[]
+endif::[]
diff --git a/sys-utils/blkpr.c b/sys-utils/blkpr.c
new file mode 100644
index 000000000..3f8c19343
--- /dev/null
+++ b/sys-utils/blkpr.c
@@ -0,0 +1,277 @@
+/*
+ * blkpr.c -- persistent reservations on a block device.
+ *
+ * Copyright (C) 2021 zhenwei pi <pizhenwei@bytedance.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This program uses IOC_PR_XXX ioctl to do persistent reservations
+ * operation on a block device if the device supports it.
+ */
+
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <locale.h>
+#include <sys/ioctl.h>
+#include <linux/pr.h>
+
+#include "nls.h"
+#include "c.h"
+#include "closestream.h"
+#include "strutils.h"
+#include "xalloc.h"
+
+struct type_string {
+ int type;
+ char *str;
+};
+
+/* This array should keep align with enum pr_type of linux/types.h */
+static struct type_string pr_type[] = {
+ {PR_WRITE_EXCLUSIVE, "write-exclusive"},
+ {PR_EXCLUSIVE_ACCESS, "exclusive-access"},
+ {PR_WRITE_EXCLUSIVE_REG_ONLY, "write-exclusive-reg-only"},
+ {PR_EXCLUSIVE_ACCESS_REG_ONLY, "exclusive-access-reg-only"},
+ {PR_WRITE_EXCLUSIVE_ALL_REGS, "write-exclusive-all-regs"},
+ {PR_EXCLUSIVE_ACCESS_ALL_REGS, "exclusive-access-all-regs"}
+};
+
+static struct type_string pr_operation[] = {
+ {IOC_PR_REGISTER, "register"},
+ {IOC_PR_RESERVE, "reserve"},
+ {IOC_PR_RELEASE, "release"},
+ {IOC_PR_PREEMPT, "preempt"},
+ {IOC_PR_PREEMPT_ABORT, "preempt-abort"},
+ {IOC_PR_CLEAR, "clear"},
+};
+
+static struct type_string pr_flag[] = {
+ {PR_FL_IGNORE_KEY, "ignore-key"}
+};
+
+static char *all_type_string(struct type_string *ts, int nmem)
+{
+ char *prtypes, *tmp;
+ size_t total = 0, length;
+ int i;
+
+ for (i = 0; i < nmem; i++) {
+ total += (strlen(ts[i].str) + 1);
+ }
+
+ tmp = prtypes = xmalloc(total);
+ for (i = 0; i < nmem; i++) {
+ strcpy(tmp, ts[i].str);
+ length = strlen(ts[i].str);
+
+ tmp[length++] = '|';
+ tmp += length;
+ }
+
+ /* strip the last '|' */
+ prtypes[total - 1] = '\0';
+
+ return prtypes;
+}
+
+static int parse_type_by_str(struct type_string *ts, int nmem, char *pattern)
+{
+ int i;
+
+ for (i = 0; i < nmem; i++) {
+ if (!strcmp(ts[i].str, pattern)) {
+ return ts[i].type;
+ }
+ }
+
+ return -1;
+}
+
+#define SUPPORTED(XX) \
+ static char *supported_##XX(void) \
+ { return all_type_string(XX, ARRAY_SIZE(XX)); }
+
+#define PARSE(XX) \
+ static int parse_##XX(char *pattern) \
+ { return parse_type_by_str(XX, ARRAY_SIZE(XX), pattern); }
+
+SUPPORTED(pr_type);
+SUPPORTED(pr_operation);
+SUPPORTED(pr_flag);
+
+PARSE(pr_type);
+PARSE(pr_operation);
+PARSE(pr_flag);
+
+static int do_pr(char *path, uint64_t key, uint64_t oldkey, int op, int type, int flag)
+{
+ struct pr_registration pr_reg;
+ struct pr_reservation pr_res;
+ struct pr_preempt pr_prt;
+ struct pr_clear pr_clr;
+ int fd, ret;
+
+ fd = open(path, O_RDWR);
+ if (fd < 0) {
+ err(EXIT_FAILURE, _("cannot open %s"), path);
+ }
+
+ switch (op) {
+ case IOC_PR_REGISTER:
+ pr_reg.old_key = oldkey;
+ pr_reg.new_key = key;
+ pr_reg.flags = flag;
+ ret = ioctl(fd, op, &pr_reg);
+ break;
+ case IOC_PR_RESERVE:
+ case IOC_PR_RELEASE:
+ pr_res.key = key;
+ pr_res.type = type;
+ pr_res.flags = flag;
+ ret = ioctl(fd, op, &pr_res);
+ break;
+ case IOC_PR_PREEMPT:
+ case IOC_PR_PREEMPT_ABORT:
+ pr_prt.old_key = oldkey;
+ pr_prt.new_key = key;
+ pr_prt.type = type;
+ pr_prt.flags = flag;
+ ret = ioctl(fd, op, &pr_prt);
+ break;
+ case IOC_PR_CLEAR:
+ pr_clr.key = key;
+ pr_clr.flags = flag;
+ ret = ioctl(fd, op, &pr_clr);
+ break;
+ default:
+ errno = EINVAL;
+ err(EXIT_FAILURE, _("unknown operation"));
+ }
+
+ close(fd);
+ if (ret < 0) {
+ err(EXIT_FAILURE, _("pr ioctl failed"));
+ } else if (ret > 0) {
+ errx(EXIT_FAILURE, _("error code 0x%x, for more detailed information see specification of device model."), ret);
+ }
+
+ return ret;
+}
+
+static void __attribute__((__noreturn__)) usage(void)
+{
+ FILE *out = stdout;
+ fputs(USAGE_HEADER, out);
+ fprintf(out,
+ _(" %s [options] <device>\n"), program_invocation_short_name);
+
+ fputs(USAGE_SEPARATOR, out);
+ fputs(_("Persistent reservations on a device.\n"), out);
+
+ fputs(USAGE_OPTIONS, out);
+ fprintf(out, _(" -o, --operation <string> supported operation [%s]\n"), supported_pr_operation());
+ fputs(_(" -k, --key <num> key to operate\n"), out);
+ fputs(_(" -K, --oldkey <num> old key to operate\n"), out);
+ fprintf(out, _(" -f, --flag <string> supported flag [%s]\n"), supported_pr_flag());
+ fprintf(out, _(" -t, --type <string> supported type [%s]\n"), supported_pr_type());
+
+ fputs(USAGE_SEPARATOR, out);
+ printf(USAGE_HELP_OPTIONS(21));
+
+ fputs(USAGE_ARGUMENTS, out);
+
+ printf(USAGE_MAN_TAIL("blkpr(8)"));
+ exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+ char c;
+ char *path;
+ uint64_t key = 0, oldkey = 0;
+ int operation = -1, type = -1, flag = 0;
+
+ static const struct option longopts[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'V' },
+ { "operation", required_argument, NULL, 'o' },
+ { "key", required_argument, NULL, 'k' },
+ { "oldkey", required_argument, NULL, 'K' },
+ { "flag", required_argument, NULL, 'f' },
+ { "type", required_argument, NULL, 't' },
+ { NULL, 0, NULL, 0 }
+ };
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ close_stdout_atexit();
+
+ errno = EINVAL;
+ while ((c = getopt_long(argc, argv, "hVo:k:K:f:t:", longopts, NULL)) != -1) {
+ switch(c) {
+ case 'k':
+ key = strtosize_or_err(optarg,
+ _("failed to parse key"));
+ break;
+ case 'K':
+ oldkey = strtosize_or_err(optarg,
+ _("failed to parse old key"));
+ break;
+ case 'o':
+ operation = parse_pr_operation(optarg);
+ if (operation < 0) {
+ err(EXIT_FAILURE, _("unknown operation"));
+ }
+ break;
+ case 't':
+ type = parse_pr_type(optarg);
+ if (type < 0) {
+ err(EXIT_FAILURE, _("unknown type"));
+ }
+ break;
+ case 'f':
+ flag = parse_pr_flag(optarg);
+ if (flag < 0) {
+ err(EXIT_FAILURE, _("unknown flag"));
+ }
+ break;
+
+ case 'h':
+ usage();
+ case 'V':
+ print_version(EXIT_SUCCESS);
+ default:
+ errtryhelp(EXIT_FAILURE);
+ }
+ }
+
+ if (optind == argc) {
+ errx(EXIT_FAILURE, _("no device specified"));
+ }
+
+ path = argv[optind++];
+ if (optind != argc) {
+ warnx(_("unexpected number of arguments"));
+ errtryhelp(EXIT_FAILURE);
+ }
+
+ do_pr(path, key, oldkey, operation, type, flag);
+
+ return EXIT_SUCCESS;
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* PING: [PATCH] blkpr: add block persistent reservations command
2021-09-16 3:29 [PATCH] blkpr: add block persistent reservations command zhenwei pi
@ 2021-09-23 2:18 ` zhenwei pi
2022-04-05 7:14 ` Christoph Hellwig
1 sibling, 0 replies; 7+ messages in thread
From: zhenwei pi @ 2021-09-23 2:18 UTC (permalink / raw)
To: kzak; +Cc: util-linux
PING!
On 9/16/21 11:29 AM, zhenwei pi wrote:
> Linux kernel block layer supports PR (persistent reservations) ioctl
> on a block device. Typically SCSI and NVMe disk support PR feature,
> and blkpr could operation on them.
>
> Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
> ---
> configure.ac | 11 ++
> sys-utils/Makemodule.am | 8 ++
> sys-utils/blkpr.8.adoc | 64 ++++++++++
> sys-utils/blkpr.c | 277 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 360 insertions(+)
> create mode 100644 sys-utils/blkpr.8.adoc
> create mode 100644 sys-utils/blkpr.c
>
> diff --git a/configure.ac b/configure.ac
> index 60e63592b..ae47a5c6c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -310,6 +310,7 @@ AC_CHECK_HEADERS([ \
> linux/fiemap.h \
> linux/net_namespace.h \
> linux/nsfs.h \
> + linux/pr.h \
> linux/raw.h \
> linux/securebits.h \
> linux/tiocl.h \
> @@ -387,6 +388,10 @@ AC_CHECK_DECLS([BLK_ZONE_REP_CAPACITY], [], [], [
> #include <linux/blkzoned.h>
> ])
>
> +AC_CHECK_DECLS([PR_REP_CAPACITY], [], [], [
> + #include <linux/pr.h>
> +])
> +
> AC_CHECK_HEADERS([security/openpam.h], [], [], [
> #ifdef HAVE_SECURITY_PAM_APPL_H
> #include <security/pam_appl.h>
> @@ -454,6 +459,7 @@ dnl
> have_linux_blkzoned_h=$ac_cv_header_linux_blkzoned_h
> have_linux_btrfs_h=$ac_cv_header_linux_btrfs_h
> have_linux_capability_h=$ac_cv_header_linux_capability_h
> +have_linux_pr_h=$ac_cv_header_linux_pr_h
> have_linux_raw_h=$ac_cv_header_linux_raw_h
> have_linux_securebits_h=$ac_cv_header_linux_securebits_h
> have_linux_version_h=$ac_cv_header_linux_version_h
> @@ -1905,6 +1911,11 @@ UL_REQUIRES_LINUX([blkzone])
> UL_REQUIRES_HAVE([blkzone], [linux_blkzoned_h], [linux/blkzoned.h header])
> AM_CONDITIONAL([BUILD_BLKZONE], [test "x$build_blkzone" = xyes])
>
> +UL_BUILD_INIT([blkpr], [check])
> +UL_REQUIRES_LINUX([blkpr])
> +UL_REQUIRES_HAVE([blkpr], [linux_pr_h], [linux/pr.h header])
> +AM_CONDITIONAL([BUILD_BLKPR], [test "x$build_blkpr" = xyes])
> +
> UL_BUILD_INIT([ldattach], [check])
> UL_REQUIRES_LINUX([ldattach])
> AM_CONDITIONAL([BUILD_LDATTACH], [test "x$build_ldattach" = xyes])
> diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
> index e55363484..22047d9bd 100644
> --- a/sys-utils/Makemodule.am
> +++ b/sys-utils/Makemodule.am
> @@ -202,6 +202,14 @@ blkzone_SOURCES = sys-utils/blkzone.c
> blkzone_LDADD = $(LDADD) libcommon.la
> endif
>
> +if BUILD_BLKPR
> +sbin_PROGRAMS += blkpr
> +MANPAGES += sys-utils/blkpr.8
> +dist_noinst_DATA += sys-utils/blkpr.8.adoc
> +blkpr_SOURCES = sys-utils/blkpr.c
> +blkpr_LDADD = $(LDADD) libcommon.la
> +endif
> +
> if BUILD_LDATTACH
> usrsbin_exec_PROGRAMS += ldattach
> MANPAGES += sys-utils/ldattach.8
> diff --git a/sys-utils/blkpr.8.adoc b/sys-utils/blkpr.8.adoc
> new file mode 100644
> index 000000000..dc8bb3893
> --- /dev/null
> +++ b/sys-utils/blkpr.8.adoc
> @@ -0,0 +1,64 @@
> +//po4a: entry man manual
> += blkpr(8)
> +:doctype: manpage
> +:man manual: System Administration
> +:man source: util-linux {release-version}
> +:page-layout: base
> +:command: blkpr
> +
> +== NAME
> +
> +blkpr - run persistent reservations command on a device
> +
> +== SYNOPSIS
> +
> +*blkpr* [options] _device_
> +
> +== DESCRIPTION
> +
> +*blkpr* is used to run persistent reservations command on device that supports Persistent Reservations feature.
> +
> +The _device_ argument is the pathname of the block device.
> +
> +== OPTIONS
> +
> +*-o*, *--operation* _operation_::
> +The operation of persistent reservations, supported [register|reserve|release|preempt|preempt-abort|clear].
> +
> +*-k*, *--key* _key_::
> +The key the operation should operate on.
> +
> +*-K*, *--oldkey* _oldkey_::
> +The old key the operation should operate on.
> +
> +*-f*, *--flag* _flag_::
> +Supported flag [ignore-key].
> +
> +*-t*, *--type*::
> +Supported type [write-exclusive|exclusive-access|write-exclusive-reg-only|exclusive-access-reg-only|write-exclusive-all-regs|exclusive-access-all-regs]
> +
> +*-V*, *--version*::
> +Display version information and exit.
> +
> +*-h*, *--help*::
> +Display help text and exit.
> +
> +== AUTHORS
> +
> +mailto:pizhenwei@bytedance.com[zhenwei pi]
> +
> +== SEE ALSO
> +
> +*sg_persist*(8)
> +
> +Linux documentation at: <https://www.kernel.org/doc/Documentation/block/pr.txt>
> +iSCSI specification at: <https://datatracker.ietf.org/doc/html/rfc3720>
> +NVMe-oF specification at: <https://nvmexpress.org/nvme-over-fabrics-part-two/>
> +
> +include::man-common/bugreports.adoc[]
> +
> +include::man-common/footer.adoc[]
> +
> +ifdef::translation[]
> +include::man-common/translation.adoc[]
> +endif::[]
> diff --git a/sys-utils/blkpr.c b/sys-utils/blkpr.c
> new file mode 100644
> index 000000000..3f8c19343
> --- /dev/null
> +++ b/sys-utils/blkpr.c
> @@ -0,0 +1,277 @@
> +/*
> + * blkpr.c -- persistent reservations on a block device.
> + *
> + * Copyright (C) 2021 zhenwei pi <pizhenwei@bytedance.com>
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * This program uses IOC_PR_XXX ioctl to do persistent reservations
> + * operation on a block device if the device supports it.
> + */
> +
> +
> +#include <string.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <getopt.h>
> +#include <locale.h>
> +#include <sys/ioctl.h>
> +#include <linux/pr.h>
> +
> +#include "nls.h"
> +#include "c.h"
> +#include "closestream.h"
> +#include "strutils.h"
> +#include "xalloc.h"
> +
> +struct type_string {
> + int type;
> + char *str;
> +};
> +
> +/* This array should keep align with enum pr_type of linux/types.h */
> +static struct type_string pr_type[] = {
> + {PR_WRITE_EXCLUSIVE, "write-exclusive"},
> + {PR_EXCLUSIVE_ACCESS, "exclusive-access"},
> + {PR_WRITE_EXCLUSIVE_REG_ONLY, "write-exclusive-reg-only"},
> + {PR_EXCLUSIVE_ACCESS_REG_ONLY, "exclusive-access-reg-only"},
> + {PR_WRITE_EXCLUSIVE_ALL_REGS, "write-exclusive-all-regs"},
> + {PR_EXCLUSIVE_ACCESS_ALL_REGS, "exclusive-access-all-regs"}
> +};
> +
> +static struct type_string pr_operation[] = {
> + {IOC_PR_REGISTER, "register"},
> + {IOC_PR_RESERVE, "reserve"},
> + {IOC_PR_RELEASE, "release"},
> + {IOC_PR_PREEMPT, "preempt"},
> + {IOC_PR_PREEMPT_ABORT, "preempt-abort"},
> + {IOC_PR_CLEAR, "clear"},
> +};
> +
> +static struct type_string pr_flag[] = {
> + {PR_FL_IGNORE_KEY, "ignore-key"}
> +};
> +
> +static char *all_type_string(struct type_string *ts, int nmem)
> +{
> + char *prtypes, *tmp;
> + size_t total = 0, length;
> + int i;
> +
> + for (i = 0; i < nmem; i++) {
> + total += (strlen(ts[i].str) + 1);
> + }
> +
> + tmp = prtypes = xmalloc(total);
> + for (i = 0; i < nmem; i++) {
> + strcpy(tmp, ts[i].str);
> + length = strlen(ts[i].str);
> +
> + tmp[length++] = '|';
> + tmp += length;
> + }
> +
> + /* strip the last '|' */
> + prtypes[total - 1] = '\0';
> +
> + return prtypes;
> +}
> +
> +static int parse_type_by_str(struct type_string *ts, int nmem, char *pattern)
> +{
> + int i;
> +
> + for (i = 0; i < nmem; i++) {
> + if (!strcmp(ts[i].str, pattern)) {
> + return ts[i].type;
> + }
> + }
> +
> + return -1;
> +}
> +
> +#define SUPPORTED(XX) \
> + static char *supported_##XX(void) \
> + { return all_type_string(XX, ARRAY_SIZE(XX)); }
> +
> +#define PARSE(XX) \
> + static int parse_##XX(char *pattern) \
> + { return parse_type_by_str(XX, ARRAY_SIZE(XX), pattern); }
> +
> +SUPPORTED(pr_type);
> +SUPPORTED(pr_operation);
> +SUPPORTED(pr_flag);
> +
> +PARSE(pr_type);
> +PARSE(pr_operation);
> +PARSE(pr_flag);
> +
> +static int do_pr(char *path, uint64_t key, uint64_t oldkey, int op, int type, int flag)
> +{
> + struct pr_registration pr_reg;
> + struct pr_reservation pr_res;
> + struct pr_preempt pr_prt;
> + struct pr_clear pr_clr;
> + int fd, ret;
> +
> + fd = open(path, O_RDWR);
> + if (fd < 0) {
> + err(EXIT_FAILURE, _("cannot open %s"), path);
> + }
> +
> + switch (op) {
> + case IOC_PR_REGISTER:
> + pr_reg.old_key = oldkey;
> + pr_reg.new_key = key;
> + pr_reg.flags = flag;
> + ret = ioctl(fd, op, &pr_reg);
> + break;
> + case IOC_PR_RESERVE:
> + case IOC_PR_RELEASE:
> + pr_res.key = key;
> + pr_res.type = type;
> + pr_res.flags = flag;
> + ret = ioctl(fd, op, &pr_res);
> + break;
> + case IOC_PR_PREEMPT:
> + case IOC_PR_PREEMPT_ABORT:
> + pr_prt.old_key = oldkey;
> + pr_prt.new_key = key;
> + pr_prt.type = type;
> + pr_prt.flags = flag;
> + ret = ioctl(fd, op, &pr_prt);
> + break;
> + case IOC_PR_CLEAR:
> + pr_clr.key = key;
> + pr_clr.flags = flag;
> + ret = ioctl(fd, op, &pr_clr);
> + break;
> + default:
> + errno = EINVAL;
> + err(EXIT_FAILURE, _("unknown operation"));
> + }
> +
> + close(fd);
> + if (ret < 0) {
> + err(EXIT_FAILURE, _("pr ioctl failed"));
> + } else if (ret > 0) {
> + errx(EXIT_FAILURE, _("error code 0x%x, for more detailed information see specification of device model."), ret);
> + }
> +
> + return ret;
> +}
> +
> +static void __attribute__((__noreturn__)) usage(void)
> +{
> + FILE *out = stdout;
> + fputs(USAGE_HEADER, out);
> + fprintf(out,
> + _(" %s [options] <device>\n"), program_invocation_short_name);
> +
> + fputs(USAGE_SEPARATOR, out);
> + fputs(_("Persistent reservations on a device.\n"), out);
> +
> + fputs(USAGE_OPTIONS, out);
> + fprintf(out, _(" -o, --operation <string> supported operation [%s]\n"), supported_pr_operation());
> + fputs(_(" -k, --key <num> key to operate\n"), out);
> + fputs(_(" -K, --oldkey <num> old key to operate\n"), out);
> + fprintf(out, _(" -f, --flag <string> supported flag [%s]\n"), supported_pr_flag());
> + fprintf(out, _(" -t, --type <string> supported type [%s]\n"), supported_pr_type());
> +
> + fputs(USAGE_SEPARATOR, out);
> + printf(USAGE_HELP_OPTIONS(21));
> +
> + fputs(USAGE_ARGUMENTS, out);
> +
> + printf(USAGE_MAN_TAIL("blkpr(8)"));
> + exit(EXIT_SUCCESS);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + char c;
> + char *path;
> + uint64_t key = 0, oldkey = 0;
> + int operation = -1, type = -1, flag = 0;
> +
> + static const struct option longopts[] = {
> + { "help", no_argument, NULL, 'h' },
> + { "version", no_argument, NULL, 'V' },
> + { "operation", required_argument, NULL, 'o' },
> + { "key", required_argument, NULL, 'k' },
> + { "oldkey", required_argument, NULL, 'K' },
> + { "flag", required_argument, NULL, 'f' },
> + { "type", required_argument, NULL, 't' },
> + { NULL, 0, NULL, 0 }
> + };
> +
> + setlocale(LC_ALL, "");
> + bindtextdomain(PACKAGE, LOCALEDIR);
> + textdomain(PACKAGE);
> + close_stdout_atexit();
> +
> + errno = EINVAL;
> + while ((c = getopt_long(argc, argv, "hVo:k:K:f:t:", longopts, NULL)) != -1) {
> + switch(c) {
> + case 'k':
> + key = strtosize_or_err(optarg,
> + _("failed to parse key"));
> + break;
> + case 'K':
> + oldkey = strtosize_or_err(optarg,
> + _("failed to parse old key"));
> + break;
> + case 'o':
> + operation = parse_pr_operation(optarg);
> + if (operation < 0) {
> + err(EXIT_FAILURE, _("unknown operation"));
> + }
> + break;
> + case 't':
> + type = parse_pr_type(optarg);
> + if (type < 0) {
> + err(EXIT_FAILURE, _("unknown type"));
> + }
> + break;
> + case 'f':
> + flag = parse_pr_flag(optarg);
> + if (flag < 0) {
> + err(EXIT_FAILURE, _("unknown flag"));
> + }
> + break;
> +
> + case 'h':
> + usage();
> + case 'V':
> + print_version(EXIT_SUCCESS);
> + default:
> + errtryhelp(EXIT_FAILURE);
> + }
> + }
> +
> + if (optind == argc) {
> + errx(EXIT_FAILURE, _("no device specified"));
> + }
> +
> + path = argv[optind++];
> + if (optind != argc) {
> + warnx(_("unexpected number of arguments"));
> + errtryhelp(EXIT_FAILURE);
> + }
> +
> + do_pr(path, key, oldkey, operation, type, flag);
> +
> + return EXIT_SUCCESS;
> +}
>
--
zhenwei pi
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] blkpr: add block persistent reservations command
2021-09-16 3:29 [PATCH] blkpr: add block persistent reservations command zhenwei pi
2021-09-23 2:18 ` PING: " zhenwei pi
@ 2022-04-05 7:14 ` Christoph Hellwig
2022-04-06 2:13 ` zhenwei pi
1 sibling, 1 reply; 7+ messages in thread
From: Christoph Hellwig @ 2022-04-05 7:14 UTC (permalink / raw)
To: zhenwei pi; +Cc: kzak, util-linux
Any reason this never got picked up or commented on?
On Thu, Sep 16, 2021 at 11:29:01AM +0800, zhenwei pi wrote:
> Linux kernel block layer supports PR (persistent reservations) ioctl
> on a block device. Typically SCSI and NVMe disk support PR feature,
> and blkpr could operation on them.
>
> Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
> ---
> configure.ac | 11 ++
> sys-utils/Makemodule.am | 8 ++
> sys-utils/blkpr.8.adoc | 64 ++++++++++
> sys-utils/blkpr.c | 277 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 360 insertions(+)
> create mode 100644 sys-utils/blkpr.8.adoc
> create mode 100644 sys-utils/blkpr.c
>
> diff --git a/configure.ac b/configure.ac
> index 60e63592b..ae47a5c6c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -310,6 +310,7 @@ AC_CHECK_HEADERS([ \
> linux/fiemap.h \
> linux/net_namespace.h \
> linux/nsfs.h \
> + linux/pr.h \
> linux/raw.h \
> linux/securebits.h \
> linux/tiocl.h \
> @@ -387,6 +388,10 @@ AC_CHECK_DECLS([BLK_ZONE_REP_CAPACITY], [], [], [
> #include <linux/blkzoned.h>
> ])
>
> +AC_CHECK_DECLS([PR_REP_CAPACITY], [], [], [
> + #include <linux/pr.h>
> +])
> +
> AC_CHECK_HEADERS([security/openpam.h], [], [], [
> #ifdef HAVE_SECURITY_PAM_APPL_H
> #include <security/pam_appl.h>
> @@ -454,6 +459,7 @@ dnl
> have_linux_blkzoned_h=$ac_cv_header_linux_blkzoned_h
> have_linux_btrfs_h=$ac_cv_header_linux_btrfs_h
> have_linux_capability_h=$ac_cv_header_linux_capability_h
> +have_linux_pr_h=$ac_cv_header_linux_pr_h
> have_linux_raw_h=$ac_cv_header_linux_raw_h
> have_linux_securebits_h=$ac_cv_header_linux_securebits_h
> have_linux_version_h=$ac_cv_header_linux_version_h
> @@ -1905,6 +1911,11 @@ UL_REQUIRES_LINUX([blkzone])
> UL_REQUIRES_HAVE([blkzone], [linux_blkzoned_h], [linux/blkzoned.h header])
> AM_CONDITIONAL([BUILD_BLKZONE], [test "x$build_blkzone" = xyes])
>
> +UL_BUILD_INIT([blkpr], [check])
> +UL_REQUIRES_LINUX([blkpr])
> +UL_REQUIRES_HAVE([blkpr], [linux_pr_h], [linux/pr.h header])
> +AM_CONDITIONAL([BUILD_BLKPR], [test "x$build_blkpr" = xyes])
> +
> UL_BUILD_INIT([ldattach], [check])
> UL_REQUIRES_LINUX([ldattach])
> AM_CONDITIONAL([BUILD_LDATTACH], [test "x$build_ldattach" = xyes])
> diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
> index e55363484..22047d9bd 100644
> --- a/sys-utils/Makemodule.am
> +++ b/sys-utils/Makemodule.am
> @@ -202,6 +202,14 @@ blkzone_SOURCES = sys-utils/blkzone.c
> blkzone_LDADD = $(LDADD) libcommon.la
> endif
>
> +if BUILD_BLKPR
> +sbin_PROGRAMS += blkpr
> +MANPAGES += sys-utils/blkpr.8
> +dist_noinst_DATA += sys-utils/blkpr.8.adoc
> +blkpr_SOURCES = sys-utils/blkpr.c
> +blkpr_LDADD = $(LDADD) libcommon.la
> +endif
> +
> if BUILD_LDATTACH
> usrsbin_exec_PROGRAMS += ldattach
> MANPAGES += sys-utils/ldattach.8
> diff --git a/sys-utils/blkpr.8.adoc b/sys-utils/blkpr.8.adoc
> new file mode 100644
> index 000000000..dc8bb3893
> --- /dev/null
> +++ b/sys-utils/blkpr.8.adoc
> @@ -0,0 +1,64 @@
> +//po4a: entry man manual
> += blkpr(8)
> +:doctype: manpage
> +:man manual: System Administration
> +:man source: util-linux {release-version}
> +:page-layout: base
> +:command: blkpr
> +
> +== NAME
> +
> +blkpr - run persistent reservations command on a device
> +
> +== SYNOPSIS
> +
> +*blkpr* [options] _device_
> +
> +== DESCRIPTION
> +
> +*blkpr* is used to run persistent reservations command on device that supports Persistent Reservations feature.
> +
> +The _device_ argument is the pathname of the block device.
> +
> +== OPTIONS
> +
> +*-o*, *--operation* _operation_::
> +The operation of persistent reservations, supported [register|reserve|release|preempt|preempt-abort|clear].
> +
> +*-k*, *--key* _key_::
> +The key the operation should operate on.
> +
> +*-K*, *--oldkey* _oldkey_::
> +The old key the operation should operate on.
> +
> +*-f*, *--flag* _flag_::
> +Supported flag [ignore-key].
> +
> +*-t*, *--type*::
> +Supported type [write-exclusive|exclusive-access|write-exclusive-reg-only|exclusive-access-reg-only|write-exclusive-all-regs|exclusive-access-all-regs]
> +
> +*-V*, *--version*::
> +Display version information and exit.
> +
> +*-h*, *--help*::
> +Display help text and exit.
> +
> +== AUTHORS
> +
> +mailto:pizhenwei@bytedance.com[zhenwei pi]
> +
> +== SEE ALSO
> +
> +*sg_persist*(8)
> +
> +Linux documentation at: <https://www.kernel.org/doc/Documentation/block/pr.txt>
> +iSCSI specification at: <https://datatracker.ietf.org/doc/html/rfc3720>
> +NVMe-oF specification at: <https://nvmexpress.org/nvme-over-fabrics-part-two/>
> +
> +include::man-common/bugreports.adoc[]
> +
> +include::man-common/footer.adoc[]
> +
> +ifdef::translation[]
> +include::man-common/translation.adoc[]
> +endif::[]
> diff --git a/sys-utils/blkpr.c b/sys-utils/blkpr.c
> new file mode 100644
> index 000000000..3f8c19343
> --- /dev/null
> +++ b/sys-utils/blkpr.c
> @@ -0,0 +1,277 @@
> +/*
> + * blkpr.c -- persistent reservations on a block device.
> + *
> + * Copyright (C) 2021 zhenwei pi <pizhenwei@bytedance.com>
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * This program uses IOC_PR_XXX ioctl to do persistent reservations
> + * operation on a block device if the device supports it.
> + */
> +
> +
> +#include <string.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <getopt.h>
> +#include <locale.h>
> +#include <sys/ioctl.h>
> +#include <linux/pr.h>
> +
> +#include "nls.h"
> +#include "c.h"
> +#include "closestream.h"
> +#include "strutils.h"
> +#include "xalloc.h"
> +
> +struct type_string {
> + int type;
> + char *str;
> +};
> +
> +/* This array should keep align with enum pr_type of linux/types.h */
> +static struct type_string pr_type[] = {
> + {PR_WRITE_EXCLUSIVE, "write-exclusive"},
> + {PR_EXCLUSIVE_ACCESS, "exclusive-access"},
> + {PR_WRITE_EXCLUSIVE_REG_ONLY, "write-exclusive-reg-only"},
> + {PR_EXCLUSIVE_ACCESS_REG_ONLY, "exclusive-access-reg-only"},
> + {PR_WRITE_EXCLUSIVE_ALL_REGS, "write-exclusive-all-regs"},
> + {PR_EXCLUSIVE_ACCESS_ALL_REGS, "exclusive-access-all-regs"}
> +};
> +
> +static struct type_string pr_operation[] = {
> + {IOC_PR_REGISTER, "register"},
> + {IOC_PR_RESERVE, "reserve"},
> + {IOC_PR_RELEASE, "release"},
> + {IOC_PR_PREEMPT, "preempt"},
> + {IOC_PR_PREEMPT_ABORT, "preempt-abort"},
> + {IOC_PR_CLEAR, "clear"},
> +};
> +
> +static struct type_string pr_flag[] = {
> + {PR_FL_IGNORE_KEY, "ignore-key"}
> +};
> +
> +static char *all_type_string(struct type_string *ts, int nmem)
> +{
> + char *prtypes, *tmp;
> + size_t total = 0, length;
> + int i;
> +
> + for (i = 0; i < nmem; i++) {
> + total += (strlen(ts[i].str) + 1);
> + }
> +
> + tmp = prtypes = xmalloc(total);
> + for (i = 0; i < nmem; i++) {
> + strcpy(tmp, ts[i].str);
> + length = strlen(ts[i].str);
> +
> + tmp[length++] = '|';
> + tmp += length;
> + }
> +
> + /* strip the last '|' */
> + prtypes[total - 1] = '\0';
> +
> + return prtypes;
> +}
> +
> +static int parse_type_by_str(struct type_string *ts, int nmem, char *pattern)
> +{
> + int i;
> +
> + for (i = 0; i < nmem; i++) {
> + if (!strcmp(ts[i].str, pattern)) {
> + return ts[i].type;
> + }
> + }
> +
> + return -1;
> +}
> +
> +#define SUPPORTED(XX) \
> + static char *supported_##XX(void) \
> + { return all_type_string(XX, ARRAY_SIZE(XX)); }
> +
> +#define PARSE(XX) \
> + static int parse_##XX(char *pattern) \
> + { return parse_type_by_str(XX, ARRAY_SIZE(XX), pattern); }
> +
> +SUPPORTED(pr_type);
> +SUPPORTED(pr_operation);
> +SUPPORTED(pr_flag);
> +
> +PARSE(pr_type);
> +PARSE(pr_operation);
> +PARSE(pr_flag);
> +
> +static int do_pr(char *path, uint64_t key, uint64_t oldkey, int op, int type, int flag)
> +{
> + struct pr_registration pr_reg;
> + struct pr_reservation pr_res;
> + struct pr_preempt pr_prt;
> + struct pr_clear pr_clr;
> + int fd, ret;
> +
> + fd = open(path, O_RDWR);
> + if (fd < 0) {
> + err(EXIT_FAILURE, _("cannot open %s"), path);
> + }
> +
> + switch (op) {
> + case IOC_PR_REGISTER:
> + pr_reg.old_key = oldkey;
> + pr_reg.new_key = key;
> + pr_reg.flags = flag;
> + ret = ioctl(fd, op, &pr_reg);
> + break;
> + case IOC_PR_RESERVE:
> + case IOC_PR_RELEASE:
> + pr_res.key = key;
> + pr_res.type = type;
> + pr_res.flags = flag;
> + ret = ioctl(fd, op, &pr_res);
> + break;
> + case IOC_PR_PREEMPT:
> + case IOC_PR_PREEMPT_ABORT:
> + pr_prt.old_key = oldkey;
> + pr_prt.new_key = key;
> + pr_prt.type = type;
> + pr_prt.flags = flag;
> + ret = ioctl(fd, op, &pr_prt);
> + break;
> + case IOC_PR_CLEAR:
> + pr_clr.key = key;
> + pr_clr.flags = flag;
> + ret = ioctl(fd, op, &pr_clr);
> + break;
> + default:
> + errno = EINVAL;
> + err(EXIT_FAILURE, _("unknown operation"));
> + }
> +
> + close(fd);
> + if (ret < 0) {
> + err(EXIT_FAILURE, _("pr ioctl failed"));
> + } else if (ret > 0) {
> + errx(EXIT_FAILURE, _("error code 0x%x, for more detailed information see specification of device model."), ret);
> + }
> +
> + return ret;
> +}
> +
> +static void __attribute__((__noreturn__)) usage(void)
> +{
> + FILE *out = stdout;
> + fputs(USAGE_HEADER, out);
> + fprintf(out,
> + _(" %s [options] <device>\n"), program_invocation_short_name);
> +
> + fputs(USAGE_SEPARATOR, out);
> + fputs(_("Persistent reservations on a device.\n"), out);
> +
> + fputs(USAGE_OPTIONS, out);
> + fprintf(out, _(" -o, --operation <string> supported operation [%s]\n"), supported_pr_operation());
> + fputs(_(" -k, --key <num> key to operate\n"), out);
> + fputs(_(" -K, --oldkey <num> old key to operate\n"), out);
> + fprintf(out, _(" -f, --flag <string> supported flag [%s]\n"), supported_pr_flag());
> + fprintf(out, _(" -t, --type <string> supported type [%s]\n"), supported_pr_type());
> +
> + fputs(USAGE_SEPARATOR, out);
> + printf(USAGE_HELP_OPTIONS(21));
> +
> + fputs(USAGE_ARGUMENTS, out);
> +
> + printf(USAGE_MAN_TAIL("blkpr(8)"));
> + exit(EXIT_SUCCESS);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + char c;
> + char *path;
> + uint64_t key = 0, oldkey = 0;
> + int operation = -1, type = -1, flag = 0;
> +
> + static const struct option longopts[] = {
> + { "help", no_argument, NULL, 'h' },
> + { "version", no_argument, NULL, 'V' },
> + { "operation", required_argument, NULL, 'o' },
> + { "key", required_argument, NULL, 'k' },
> + { "oldkey", required_argument, NULL, 'K' },
> + { "flag", required_argument, NULL, 'f' },
> + { "type", required_argument, NULL, 't' },
> + { NULL, 0, NULL, 0 }
> + };
> +
> + setlocale(LC_ALL, "");
> + bindtextdomain(PACKAGE, LOCALEDIR);
> + textdomain(PACKAGE);
> + close_stdout_atexit();
> +
> + errno = EINVAL;
> + while ((c = getopt_long(argc, argv, "hVo:k:K:f:t:", longopts, NULL)) != -1) {
> + switch(c) {
> + case 'k':
> + key = strtosize_or_err(optarg,
> + _("failed to parse key"));
> + break;
> + case 'K':
> + oldkey = strtosize_or_err(optarg,
> + _("failed to parse old key"));
> + break;
> + case 'o':
> + operation = parse_pr_operation(optarg);
> + if (operation < 0) {
> + err(EXIT_FAILURE, _("unknown operation"));
> + }
> + break;
> + case 't':
> + type = parse_pr_type(optarg);
> + if (type < 0) {
> + err(EXIT_FAILURE, _("unknown type"));
> + }
> + break;
> + case 'f':
> + flag = parse_pr_flag(optarg);
> + if (flag < 0) {
> + err(EXIT_FAILURE, _("unknown flag"));
> + }
> + break;
> +
> + case 'h':
> + usage();
> + case 'V':
> + print_version(EXIT_SUCCESS);
> + default:
> + errtryhelp(EXIT_FAILURE);
> + }
> + }
> +
> + if (optind == argc) {
> + errx(EXIT_FAILURE, _("no device specified"));
> + }
> +
> + path = argv[optind++];
> + if (optind != argc) {
> + warnx(_("unexpected number of arguments"));
> + errtryhelp(EXIT_FAILURE);
> + }
> +
> + do_pr(path, key, oldkey, operation, type, flag);
> +
> + return EXIT_SUCCESS;
> +}
> --
> 2.25.1
>
---end quoted text---
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Re: [PATCH] blkpr: add block persistent reservations command
2022-04-05 7:14 ` Christoph Hellwig
@ 2022-04-06 2:13 ` zhenwei pi
2022-04-06 8:55 ` Karel Zak
0 siblings, 1 reply; 7+ messages in thread
From: zhenwei pi @ 2022-04-06 2:13 UTC (permalink / raw)
To: Christoph Hellwig, kzak; +Cc: util-linux
On 4/5/22 15:14, Christoph Hellwig wrote:
> Any reason this never got picked up or commented on?
>This seems to have been ignored.
Hi Karel,
Could you please give me any hint?
> On Thu, Sep 16, 2021 at 11:29:01AM +0800, zhenwei pi wrote:
>> Linux kernel block layer supports PR (persistent reservations) ioctl
>> on a block device. Typically SCSI and NVMe disk support PR feature,
>> and blkpr could operation on them.
>>
>> Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
>> ---
>> configure.ac | 11 ++
>> sys-utils/Makemodule.am | 8 ++
>> sys-utils/blkpr.8.adoc | 64 ++++++++++
>> sys-utils/blkpr.c | 277 ++++++++++++++++++++++++++++++++++++++++
>> 4 files changed, 360 insertions(+)
>> create mode 100644 sys-utils/blkpr.8.adoc
>> create mode 100644 sys-utils/blkpr.c
--
zhenwei pi
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] blkpr: add block persistent reservations command
2022-04-06 2:13 ` zhenwei pi
@ 2022-04-06 8:55 ` Karel Zak
2022-04-06 10:27 ` Karel Zak
0 siblings, 1 reply; 7+ messages in thread
From: Karel Zak @ 2022-04-06 8:55 UTC (permalink / raw)
To: zhenwei pi; +Cc: Christoph Hellwig, util-linux
On Wed, Apr 06, 2022 at 10:13:00AM +0800, zhenwei pi wrote:
> On 4/5/22 15:14, Christoph Hellwig wrote:
> > Any reason this never got picked up or commented on?
> > This seems to have been ignored.
>
> Hi Karel,
> Could you please give me any hint?
Frankly, I see this first time and I cannot found 'blkpr' in my
emails ... but I see it in mailing list archive(s) now, for example
https://lore.kernel.org/all/20210916032901.2189336-1-pizhenwei@bytedance.com/,
so it's probably my mistake. Sorry for this ;-(
At first glance it seems like something I can merge.
Karel
> > On Thu, Sep 16, 2021 at 11:29:01AM +0800, zhenwei pi wrote:
> > > Linux kernel block layer supports PR (persistent reservations) ioctl
> > > on a block device. Typically SCSI and NVMe disk support PR feature,
> > > and blkpr could operation on them.
> > >
> > > Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
> > > ---
> > > configure.ac | 11 ++
> > > sys-utils/Makemodule.am | 8 ++
> > > sys-utils/blkpr.8.adoc | 64 ++++++++++
> > > sys-utils/blkpr.c | 277 ++++++++++++++++++++++++++++++++++++++++
> > > 4 files changed, 360 insertions(+)
> > > create mode 100644 sys-utils/blkpr.8.adoc
> > > create mode 100644 sys-utils/blkpr.c
> --
> zhenwei pi
>
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] blkpr: add block persistent reservations command
2022-04-06 8:55 ` Karel Zak
@ 2022-04-06 10:27 ` Karel Zak
2022-04-07 3:51 ` zhenwei pi
0 siblings, 1 reply; 7+ messages in thread
From: Karel Zak @ 2022-04-06 10:27 UTC (permalink / raw)
To: zhenwei pi; +Cc: Christoph Hellwig, util-linux
On Wed, Apr 06, 2022 at 10:55:24AM +0200, Karel Zak wrote:
> At first glance it seems like something I can merge.
Merged. I did some minor changes to the code and man-page.
It would be nice to have some short description for the operations and
the types. Something what we can use in --help output.
register, reserve, release, preempt, preempt-abort, and clear
write-exclusive, exclusive-access, write-exclusive-reg-only, exclusive-access-reg-only, write-exclusive-all-regs, and exclusive-access-all-regs
I'm not sure if for example "preempt" or "write-exclusive-reg-only" is
obvious enough for end-users.
The next question, what about to rename --operation to --command? The
man-page describes blkpr as "run persistent reservations command on a
device".
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Re: [PATCH] blkpr: add block persistent reservations command
2022-04-06 10:27 ` Karel Zak
@ 2022-04-07 3:51 ` zhenwei pi
0 siblings, 0 replies; 7+ messages in thread
From: zhenwei pi @ 2022-04-07 3:51 UTC (permalink / raw)
To: Karel Zak; +Cc: Christoph Hellwig, util-linux
On 4/6/22 18:27, Karel Zak wrote:
> On Wed, Apr 06, 2022 at 10:55:24AM +0200, Karel Zak wrote:
>> At first glance it seems like something I can merge.
>
> Merged. I did some minor changes to the code and man-page.
>
> It would be nice to have some short description for the operations and
> the types. Something what we can use in --help output.
>
> register, reserve, release, preempt, preempt-abort, and clear
>
> write-exclusive, exclusive-access, write-exclusive-reg-only, exclusive-access-reg-only, write-exclusive-all-regs, and exclusive-access-all-regs
>
> I'm not sure if for example "preempt" or "write-exclusive-reg-only" is
> obvious enough for end-users.
>
> The next question, what about to rename --operation to --command? The
> man-page describes blkpr as "run persistent reservations command on a
> device".
>
> Karel
>
Thanks! Rename 'operation' to 'command', also add description for
arguments in another two patches.
--
zhenwei pi
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-04-07 3:55 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-16 3:29 [PATCH] blkpr: add block persistent reservations command zhenwei pi
2021-09-23 2:18 ` PING: " zhenwei pi
2022-04-05 7:14 ` Christoph Hellwig
2022-04-06 2:13 ` zhenwei pi
2022-04-06 8:55 ` Karel Zak
2022-04-06 10:27 ` Karel Zak
2022-04-07 3:51 ` zhenwei pi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).