* [ndctl PATCH 0/8] dimm label space initialization support
@ 2016-10-19 16:47 ` Dan Williams
0 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:47 UTC (permalink / raw)
To: linux-nvdimm; +Cc: qemu-devel
The 4.9 kernel added support for sub-dividing PMEM. With this kernel
patch [1] on top of that baseline, the PMEM-sub-division support can be
enabled for QEMU-KVM and any other platforms that advertise both un-aliased
PMEM regions and support for the label DSM commands [2].
Given this increasing need to perform a label management operation
across a set of DIMMs this update also adds glob(3) support. For
example you can now write commands like:
ndctl zero-labels nmem[2-4]
...as a shorthand for:
ndctl zero-labels nmem2 nmem3 nmem4
This support extends to all the commands that take an undecorated dimm /
nmem device as a parameter:
disable-dimm
enable-dimm
read-labels
zero-labels
init-labels
check-labels
The patch "libndctl: fix error returns for unsigned apis" was something
noticed while developing "init-labels", but is otherwise unrelated to
the rest of the set.
[1]: https://patchwork.kernel.org/patch/9384741/
[2]: http://pmem.io/documents/NVDIMM_DSM_Interface_Example-V1.2.pdf
---
Dan Williams (8):
libndctl: fix error returns for unsigned apis
ndctl: consolidate label commands into a single file
ndctl: glob support for label commands
ndctl: merge {enable,disable}-dimm with label commands
libndctl: add ndctl_cmd_cfg_read_get_size()
ndctl: provide a read_labels() helper
ndctl: init-labels command
ndctl: check-labels command
Documentation/Makefile.am | 2
Documentation/ndctl-check-labels.txt | 25 +
Documentation/ndctl-init-labels.txt | 83 +++
ndctl/Makefile.am | 4
ndctl/builtin-dimm.c | 975 ++++++++++++++++++++++++++++++++++
ndctl/builtin-read-labels.c | 412 --------------
ndctl/builtin-xable-dimm.c | 115 ----
ndctl/builtin-zero-labels.c | 92 ---
ndctl/builtin.h | 2
ndctl/lib/libndctl.c | 17 -
ndctl/lib/libndctl.sym | 1
ndctl/libndctl.h.in | 1
ndctl/ndctl.c | 2
13 files changed, 1105 insertions(+), 626 deletions(-)
create mode 100644 Documentation/ndctl-check-labels.txt
create mode 100644 Documentation/ndctl-init-labels.txt
create mode 100644 ndctl/builtin-dimm.c
delete mode 100644 ndctl/builtin-read-labels.c
delete mode 100644 ndctl/builtin-xable-dimm.c
delete mode 100644 ndctl/builtin-zero-labels.c
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 25+ messages in thread
* [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
@ 2016-10-19 16:47 ` Dan Williams
0 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:47 UTC (permalink / raw)
To: linux-nvdimm; +Cc: vishal.l.verma, qemu-devel
The 4.9 kernel added support for sub-dividing PMEM. With this kernel
patch [1] on top of that baseline, the PMEM-sub-division support can be
enabled for QEMU-KVM and any other platforms that advertise both un-aliased
PMEM regions and support for the label DSM commands [2].
Given this increasing need to perform a label management operation
across a set of DIMMs this update also adds glob(3) support. For
example you can now write commands like:
ndctl zero-labels nmem[2-4]
...as a shorthand for:
ndctl zero-labels nmem2 nmem3 nmem4
This support extends to all the commands that take an undecorated dimm /
nmem device as a parameter:
disable-dimm
enable-dimm
read-labels
zero-labels
init-labels
check-labels
The patch "libndctl: fix error returns for unsigned apis" was something
noticed while developing "init-labels", but is otherwise unrelated to
the rest of the set.
[1]: https://patchwork.kernel.org/patch/9384741/
[2]: http://pmem.io/documents/NVDIMM_DSM_Interface_Example-V1.2.pdf
---
Dan Williams (8):
libndctl: fix error returns for unsigned apis
ndctl: consolidate label commands into a single file
ndctl: glob support for label commands
ndctl: merge {enable,disable}-dimm with label commands
libndctl: add ndctl_cmd_cfg_read_get_size()
ndctl: provide a read_labels() helper
ndctl: init-labels command
ndctl: check-labels command
Documentation/Makefile.am | 2
Documentation/ndctl-check-labels.txt | 25 +
Documentation/ndctl-init-labels.txt | 83 +++
ndctl/Makefile.am | 4
ndctl/builtin-dimm.c | 975 ++++++++++++++++++++++++++++++++++
ndctl/builtin-read-labels.c | 412 --------------
ndctl/builtin-xable-dimm.c | 115 ----
ndctl/builtin-zero-labels.c | 92 ---
ndctl/builtin.h | 2
ndctl/lib/libndctl.c | 17 -
ndctl/lib/libndctl.sym | 1
ndctl/libndctl.h.in | 1
ndctl/ndctl.c | 2
13 files changed, 1105 insertions(+), 626 deletions(-)
create mode 100644 Documentation/ndctl-check-labels.txt
create mode 100644 Documentation/ndctl-init-labels.txt
create mode 100644 ndctl/builtin-dimm.c
delete mode 100644 ndctl/builtin-read-labels.c
delete mode 100644 ndctl/builtin-xable-dimm.c
delete mode 100644 ndctl/builtin-zero-labels.c
^ permalink raw reply [flat|nested] 25+ messages in thread
* [ndctl PATCH 1/8] libndctl: fix error returns for unsigned apis
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
(?)
@ 2016-10-19 16:47 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:47 UTC (permalink / raw)
To: linux-nvdimm
For unsigned attributes the library inconsistently returns ULLONG_MAX /
ULONG_MAX as an error return. Fix up ndctl_region_get_available_size()
and ndctl_dimm_get_available_labels() to indicate errors following this
scheme.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/libndctl.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 02524501db16..7d870b082cd4 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -1707,11 +1707,11 @@ NDCTL_EXPORT unsigned long long ndctl_region_get_available_size(
if (snprintf(path, len, "%s/available_size", region->region_path) >= len) {
err(ctx, "%s: buffer too small!\n",
ndctl_region_get_devname(region));
- return -ENOMEM;
+ return ULLONG_MAX;
}
if (sysfs_read_attr(ctx, path, buf) < 0)
- return -ENXIO;
+ return ULLONG_MAX;
return strtoull(buf, NULL, 0);
}
@@ -2519,11 +2519,11 @@ NDCTL_EXPORT unsigned long ndctl_dimm_get_available_labels(
if (snprintf(path, len, "%s/available_slots", dimm->dimm_path) >= len) {
err(ctx, "%s: buffer too small!\n",
ndctl_dimm_get_devname(dimm));
- return -ENOMEM;
+ return ULONG_MAX;
}
if (sysfs_read_attr(ctx, path, buf) < 0)
- return 0;
+ return ULONG_MAX;
return strtoul(buf, NULL, 0);
}
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [ndctl PATCH 2/8] ndctl: consolidate label commands into a single file
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
(?)
(?)
@ 2016-10-19 16:47 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:47 UTC (permalink / raw)
To: linux-nvdimm
Merge ndctl/builtin-zero-labels.c and ndctl/builtin-read-labels.c into a
single file, but no functional change.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/Makefile.am | 3 -
ndctl/builtin-labels.c | 84 +++++++++++++++++++++++++++++++++++++++
ndctl/builtin-zero-labels.c | 92 -------------------------------------------
3 files changed, 84 insertions(+), 95 deletions(-)
rename ndctl/{builtin-read-labels.c => builtin-labels.c} (83%)
delete mode 100644 ndctl/builtin-zero-labels.c
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index 29237b76713a..dc990988ed43 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -10,8 +10,7 @@ ndctl_SOURCES = ndctl.c \
builtin-list.c \
builtin-test.c \
builtin-help.c \
- builtin-zero-labels.c \
- builtin-read-labels.c \
+ builtin-labels.c \
util/json.c
if ENABLE_SMART
diff --git a/ndctl/builtin-read-labels.c b/ndctl/builtin-labels.c
similarity index 83%
rename from ndctl/builtin-read-labels.c
rename to ndctl/builtin-labels.c
index 207d44ce7f68..c85069d97655 100644
--- a/ndctl/builtin-read-labels.c
+++ b/ndctl/builtin-labels.c
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2016, Intel Corporation.
*
@@ -64,6 +63,89 @@ struct namespace_label {
le32 unused;
};
+static int do_zero_dimm(struct ndctl_dimm *dimm, const char **argv, int argc,
+ bool verbose)
+{
+ struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+ int i, rc, log;
+
+ for (i = 0; i < argc; i++)
+ if (util_dimm_filter(dimm, argv[i]))
+ break;
+ if (i >= argc)
+ return -ENODEV;
+
+ log = ndctl_get_log_priority(ctx);
+ if (verbose)
+ ndctl_set_log_priority(ctx, LOG_DEBUG);
+ rc = ndctl_dimm_zero_labels(dimm);
+ ndctl_set_log_priority(ctx, log);
+
+ return rc;
+}
+
+int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
+{
+ const char *nmem_bus = NULL;
+ bool verbose = false;
+ const struct option nmem_options[] = {
+ OPT_STRING('b', "bus", &nmem_bus, "bus-id",
+ "<nmem> must be on a bus with an id/provider of <bus-id>"),
+ OPT_BOOLEAN('v',"verbose", &verbose, "turn on debug"),
+ OPT_END(),
+ };
+ const char * const u[] = {
+ "ndctl zero-labels <nmem0> [<nmem1>..<nmemN>] [<options>]",
+ NULL
+ };
+ struct ndctl_dimm *dimm;
+ struct ndctl_bus *bus;
+ int i, rc, count, err = 0;
+
+ argc = parse_options(argc, argv, nmem_options, u, 0);
+
+ if (argc == 0)
+ usage_with_options(u, nmem_options);
+ for (i = 0; i < argc; i++) {
+ unsigned long id;
+
+ if (strcmp(argv[i], "all") == 0)
+ continue;
+ if (sscanf(argv[i], "nmem%lu", &id) != 1) {
+ fprintf(stderr, "unknown extra parameter \"%s\"\n",
+ argv[i]);
+ usage_with_options(u, nmem_options);
+ }
+ }
+
+ count = 0;
+ ndctl_bus_foreach(ctx, bus) {
+ if (!util_bus_filter(bus, nmem_bus))
+ continue;
+
+ ndctl_dimm_foreach(bus, dimm) {
+ rc = do_zero_dimm(dimm, argv, argc, verbose);
+ if (rc == 0)
+ count++;
+ else if (rc && !err)
+ err = rc;
+ }
+ }
+ rc = err;
+
+ fprintf(stderr, "zeroed %d nmem%s\n", count, count > 1 ? "s" : "");
+
+ /*
+ * 0 if all dimms zeroed, count if at least 1 dimm zeroed, < 0
+ * if all errors
+ */
+ if (rc == 0)
+ return 0;
+ if (count)
+ return count;
+ return rc;
+}
+
static struct json_object *dump_label_json(struct ndctl_cmd *cmd_read, ssize_t size)
{
struct json_object *jarray = json_object_new_array();
diff --git a/ndctl/builtin-zero-labels.c b/ndctl/builtin-zero-labels.c
deleted file mode 100644
index 2fe466e6ba34..000000000000
--- a/ndctl/builtin-zero-labels.c
+++ /dev/null
@@ -1,92 +0,0 @@
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-#include <syslog.h>
-#include <util/filter.h>
-#include <util/parse-options.h>
-#include <ndctl/libndctl.h>
-
-static int do_zero_dimm(struct ndctl_dimm *dimm, const char **argv, int argc,
- bool verbose)
-{
- struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
- int i, rc, log;
-
- for (i = 0; i < argc; i++)
- if (util_dimm_filter(dimm, argv[i]))
- break;
- if (i >= argc)
- return -ENODEV;
-
- log = ndctl_get_log_priority(ctx);
- if (verbose)
- ndctl_set_log_priority(ctx, LOG_DEBUG);
- rc = ndctl_dimm_zero_labels(dimm);
- ndctl_set_log_priority(ctx, log);
-
- return rc;
-}
-
-int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
-{
- const char *nmem_bus = NULL;
- bool verbose = false;
- const struct option nmem_options[] = {
- OPT_STRING('b', "bus", &nmem_bus, "bus-id",
- "<nmem> must be on a bus with an id/provider of <bus-id>"),
- OPT_BOOLEAN('v',"verbose", &verbose, "turn on debug"),
- OPT_END(),
- };
- const char * const u[] = {
- "ndctl zero-labels <nmem0> [<nmem1>..<nmemN>] [<options>]",
- NULL
- };
- struct ndctl_dimm *dimm;
- struct ndctl_bus *bus;
- int i, rc, count, err = 0;
-
- argc = parse_options(argc, argv, nmem_options, u, 0);
-
- if (argc == 0)
- usage_with_options(u, nmem_options);
- for (i = 0; i < argc; i++) {
- unsigned long id;
-
- if (strcmp(argv[i], "all") == 0)
- continue;
- if (sscanf(argv[i], "nmem%lu", &id) != 1) {
- fprintf(stderr, "unknown extra parameter \"%s\"\n",
- argv[i]);
- usage_with_options(u, nmem_options);
- }
- }
-
- count = 0;
- ndctl_bus_foreach(ctx, bus) {
- if (!util_bus_filter(bus, nmem_bus))
- continue;
-
- ndctl_dimm_foreach(bus, dimm) {
- rc = do_zero_dimm(dimm, argv, argc, verbose);
- if (rc == 0)
- count++;
- else if (rc && !err)
- err = rc;
- }
- }
- rc = err;
-
- fprintf(stderr, "zeroed %d nmem%s\n", count, count > 1 ? "s" : "");
-
- /*
- * 0 if all dimms zeroed, count if at least 1 dimm zeroed, < 0
- * if all errors
- */
- if (rc == 0)
- return 0;
- if (count)
- return count;
- return rc;
-}
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [ndctl PATCH 3/8] ndctl: glob support for label commands
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
` (2 preceding siblings ...)
(?)
@ 2016-10-19 16:48 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:48 UTC (permalink / raw)
To: linux-nvdimm
Permit a shell glob of dimm names to be passed to {read,zero}-labels.
For example:
ndctl zero-labels nmem[0-3]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/builtin-labels.c | 329 +++++++++++++++++++++++++-----------------------
1 file changed, 170 insertions(+), 159 deletions(-)
diff --git a/ndctl/builtin-labels.c b/ndctl/builtin-labels.c
index c85069d97655..ddd3eb578341 100644
--- a/ndctl/builtin-labels.c
+++ b/ndctl/builtin-labels.c
@@ -10,6 +10,7 @@
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*/
+#include <glob.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
@@ -25,6 +26,7 @@
#include <ccan/minmax/minmax.h>
#define CCAN_SHORT_TYPES_H
#include <ccan/endian/endian.h>
+#include <ccan/array_size/array_size.h>
enum {
NSINDEX_SIG_LEN = 16,
@@ -63,87 +65,14 @@ struct namespace_label {
le32 unused;
};
-static int do_zero_dimm(struct ndctl_dimm *dimm, const char **argv, int argc,
- bool verbose)
-{
- struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
- int i, rc, log;
-
- for (i = 0; i < argc; i++)
- if (util_dimm_filter(dimm, argv[i]))
- break;
- if (i >= argc)
- return -ENODEV;
-
- log = ndctl_get_log_priority(ctx);
- if (verbose)
- ndctl_set_log_priority(ctx, LOG_DEBUG);
- rc = ndctl_dimm_zero_labels(dimm);
- ndctl_set_log_priority(ctx, log);
-
- return rc;
-}
+struct action_context {
+ struct json_object *jdimms;
+ FILE *f_out;
+};
-int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
+static int action_zero(struct ndctl_dimm *dimm, struct action_context *actx)
{
- const char *nmem_bus = NULL;
- bool verbose = false;
- const struct option nmem_options[] = {
- OPT_STRING('b', "bus", &nmem_bus, "bus-id",
- "<nmem> must be on a bus with an id/provider of <bus-id>"),
- OPT_BOOLEAN('v',"verbose", &verbose, "turn on debug"),
- OPT_END(),
- };
- const char * const u[] = {
- "ndctl zero-labels <nmem0> [<nmem1>..<nmemN>] [<options>]",
- NULL
- };
- struct ndctl_dimm *dimm;
- struct ndctl_bus *bus;
- int i, rc, count, err = 0;
-
- argc = parse_options(argc, argv, nmem_options, u, 0);
-
- if (argc == 0)
- usage_with_options(u, nmem_options);
- for (i = 0; i < argc; i++) {
- unsigned long id;
-
- if (strcmp(argv[i], "all") == 0)
- continue;
- if (sscanf(argv[i], "nmem%lu", &id) != 1) {
- fprintf(stderr, "unknown extra parameter \"%s\"\n",
- argv[i]);
- usage_with_options(u, nmem_options);
- }
- }
-
- count = 0;
- ndctl_bus_foreach(ctx, bus) {
- if (!util_bus_filter(bus, nmem_bus))
- continue;
-
- ndctl_dimm_foreach(bus, dimm) {
- rc = do_zero_dimm(dimm, argv, argc, verbose);
- if (rc == 0)
- count++;
- else if (rc && !err)
- err = rc;
- }
- }
- rc = err;
-
- fprintf(stderr, "zeroed %d nmem%s\n", count, count > 1 ? "s" : "");
-
- /*
- * 0 if all dimms zeroed, count if at least 1 dimm zeroed, < 0
- * if all errors
- */
- if (rc == 0)
- return 0;
- if (count)
- return count;
- return rc;
+ return ndctl_dimm_zero_labels(dimm);
}
static struct json_object *dump_label_json(struct ndctl_cmd *cmd_read, ssize_t size)
@@ -339,28 +268,16 @@ static int dump_bin(FILE *f_out, struct ndctl_cmd *cmd_read, ssize_t size)
return 0;
}
-static int do_read_dimm(FILE *f_out, struct ndctl_dimm *dimm, const char **argv,
- int argc, bool verbose, struct json_object *jdimms)
+static int action_read(struct ndctl_dimm *dimm, struct action_context *actx)
{
- struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm);
struct ndctl_cmd *cmd_size, *cmd_read;
ssize_t size;
- int i, rc, log;
-
- for (i = 0; i < argc; i++)
- if (util_dimm_filter(dimm, argv[i]))
- break;
- if (i >= argc)
- return -ENODEV;
-
- log = ndctl_get_log_priority(ctx);
- if (verbose)
- ndctl_set_log_priority(ctx, LOG_DEBUG);
+ int rc;
rc = ndctl_bus_wait_probe(bus);
if (rc < 0)
- goto out;
+ return rc;
cmd_size = ndctl_dimm_cmd_new_cfg_size(dimm);
if (!cmd_size)
@@ -379,116 +296,210 @@ static int do_read_dimm(FILE *f_out, struct ndctl_dimm *dimm, const char **argv,
goto out_read;
size = ndctl_cmd_cfg_size_get_size(cmd_size);
- if (jdimms) {
+ if (actx->jdimms) {
struct json_object *jdimm = dump_json(dimm, cmd_read, size);
if (!jdimm)
return -ENOMEM;
- json_object_array_add(jdimms, jdimm);
+ json_object_array_add(actx->jdimms, jdimm);
} else
- rc = dump_bin(f_out, cmd_read, size);
+ rc = dump_bin(actx->f_out, cmd_read, size);
out_read:
ndctl_cmd_unref(cmd_read);
out_size:
ndctl_cmd_unref(cmd_size);
- out:
- ndctl_set_log_priority(ctx, log);
return rc;
}
-int cmd_read_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
+static struct parameters {
+ const char *bus;
+ const char *outfile;
+ bool json;
+ bool verbose;
+} param;
+
+#define BASE_OPTIONS() \
+OPT_STRING('b', "bus", ¶m.bus, "bus-id", \
+ "<nmem> must be on a bus with an id/provider of <bus-id>"), \
+OPT_BOOLEAN('v',"verbose", ¶m.verbose, "turn on debug")
+
+#define READ_OPTIONS() \
+OPT_STRING('o', NULL, ¶m.outfile, "output-file", \
+ "filename to write label area contents"), \
+OPT_BOOLEAN('j', "json", ¶m.json, "parse label data into json")
+
+static const struct option read_options[] = {
+ BASE_OPTIONS(),
+ READ_OPTIONS(),
+ OPT_END(),
+};
+
+static const struct option zero_options[] = {
+ BASE_OPTIONS(),
+ OPT_END(),
+};
+
+static int dimm_action(int argc, const char **argv, struct ndctl_ctx *ctx,
+ int (*action)(struct ndctl_dimm *dimm, struct action_context *actx),
+ const struct option *options, const char *usage)
{
- const char *nmem_bus = NULL, *output = NULL;
- bool verbose = false, json = false;
- const struct option nmem_options[] = {
- OPT_STRING('b', "bus", &nmem_bus, "bus-id",
- "<nmem> must be on a bus with an id/provider of <bus-id>"),
- OPT_STRING('o', NULL, &output, "output-file",
- "filename to write label area contents"),
- OPT_BOOLEAN('j', "json", &json, "parse label data into json"),
- OPT_BOOLEAN('v',"verbose", &verbose, "turn on debug"),
- OPT_END(),
- };
+ int rc = 0, count, err = 0, glob_cnt = 0;
+ struct action_context actx = { NULL, NULL };
const char * const u[] = {
- "ndctl read-labels <nmem0> [<nmem1>..<nmemN>] [-o <filename>]",
+ usage,
NULL
};
- struct json_object *jdimms = NULL;
- struct ndctl_dimm *dimm;
- struct ndctl_bus *bus;
- int i, rc, count = 0, err = 0;
- FILE *f_out = NULL;
+ char *all[] = { "all " };
+ glob_t glob_buf;
+ size_t i;
- argc = parse_options(argc, argv, nmem_options, u, 0);
+ argc = parse_options(argc, argv, options, u, 0);
if (argc == 0)
- usage_with_options(u, nmem_options);
- for (i = 0; i < argc; i++) {
+ usage_with_options(u, options);
+ for (i = 0; i < (size_t) argc; i++) {
+ char *path;
+
+ if (strcmp(argv[i], "all") == 0) {
+ argv[0] = "all";
+ argc = 1;
+ glob_cnt = 0;
+ break;
+ }
+ rc = asprintf(&path, "/sys/bus/nd/devices/%s", argv[i]);
+ if (rc < 0) {
+ fprintf(stderr, "failed to parse %s\n", argv[i]);
+ usage_with_options(u, options);
+ }
+
+ rc = glob(path, glob_cnt++ ? GLOB_APPEND : 0, NULL, &glob_buf);
+ switch (rc) {
+ case GLOB_NOSPACE:
+ case GLOB_ABORTED:
+ fprintf(stderr, "failed to parse %s\n", argv[i]);
+ usage_with_options(u, options);
+ break;
+ case GLOB_NOMATCH:
+ case 0:
+ break;
+ }
+ free(path);
+ }
+
+ if (!glob_cnt)
+ glob_buf.gl_pathc = 0;
+ count = 0;
+ for (i = 0; i < glob_buf.gl_pathc; i++) {
+ char *dimm_name = strrchr(glob_buf.gl_pathv[i], '/');
unsigned long id;
- if (strcmp(argv[i], "all") == 0)
+ if (!dimm_name++)
continue;
- if (sscanf(argv[i], "nmem%lu", &id) != 1) {
- fprintf(stderr, "unknown extra parameter \"%s\"\n",
- argv[i]);
- usage_with_options(u, nmem_options);
- }
+ if (sscanf(dimm_name, "nmem%lu", &id) == 1)
+ count++;
+ }
+
+ if (strcmp(argv[0], "all") == 0) {
+ glob_buf.gl_pathc = ARRAY_SIZE(all);
+ glob_buf.gl_pathv = all;
+ } else if (!count) {
+ fprintf(stderr, "Error: ' ");
+ for (i = 0; i < (size_t) argc; i++)
+ fprintf(stderr, "%s ", argv[i]);
+ fprintf(stderr, "' does not specify any present devices\n");
+ fprintf(stderr, "See 'ndctl list -D'\n");
+ usage_with_options(u, options);
}
- if (json) {
- jdimms = json_object_new_array();
- if (!jdimms)
+ if (param.json) {
+ actx.jdimms = json_object_new_array();
+ if (!actx.jdimms)
return -ENOMEM;
}
- if (!output)
- f_out = stdout;
+ if (!param.outfile)
+ actx.f_out = stdout;
else {
- f_out = fopen(output, "w+");
- if (!f_out) {
+ actx.f_out = fopen(param.outfile, "w+");
+ if (!actx.f_out) {
fprintf(stderr, "failed to open: %s: (%s)\n",
- output, strerror(errno));
+ param.outfile, strerror(errno));
rc = -errno;
goto out;
}
}
- ndctl_bus_foreach(ctx, bus) {
- if (!util_bus_filter(bus, nmem_bus))
+ if (param.verbose)
+ ndctl_set_log_priority(ctx, LOG_DEBUG);
+
+ rc = 0;
+ count = 0;
+ for (i = 0; i < glob_buf.gl_pathc; i++) {
+ char *dimm_name = strrchr(glob_buf.gl_pathv[i], '/');
+ struct ndctl_dimm *dimm;
+ struct ndctl_bus *bus;
+ unsigned long id;
+
+ if (!dimm_name++)
+ continue;
+ if (sscanf(dimm_name, "nmem%lu", &id) != 1)
continue;
- ndctl_dimm_foreach(bus, dimm) {
- rc = do_read_dimm(f_out, dimm, argv, argc, verbose,
- jdimms);
- if (rc == 0)
- count++;
- else if (rc && !err)
- err = rc;
+ ndctl_bus_foreach(ctx, bus) {
+ if (!util_bus_filter(bus, param.bus))
+ continue;
+ ndctl_dimm_foreach(bus, dimm) {
+ if (!util_dimm_filter(dimm, dimm_name))
+ continue;
+ rc = action(dimm, &actx);
+ if (rc == 0)
+ count++;
+ else if (rc && !err)
+ err = rc;
+ }
}
}
rc = err;
- if (jdimms)
+ if (actx.jdimms) {
+ util_display_json_array(actx.f_out, actx.jdimms,
+ JSON_C_TO_STRING_PRETTY);
+ json_object_put(actx.jdimms);
+ }
- fprintf(stderr, "read %d nmem%s\n", count, count > 1 ? "s" : "");
+ if (actx.f_out != stdout)
+ fclose(actx.f_out);
out:
- if (jdimms) {
- util_display_json_array(f_out, jdimms, JSON_C_TO_STRING_PRETTY);
- json_object_put(jdimms);
- }
-
- if (f_out != stdout)
- fclose(f_out);
+ if (glob_cnt)
+ globfree(&glob_buf);
/*
- * 0 if all dimms zeroed, count if at least 1 dimm zeroed, < 0
- * if all errors
+ * count if some actions succeeded, 0 if none were attempted,
+ * negative error code otherwise.
*/
- if (rc == 0)
- return 0;
- if (count)
- return count;
- return rc;
+ if (rc < 0)
+ return rc;
+ return count;
+}
+
+int cmd_read_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
+{
+ int count = dimm_action(argc, argv, ctx, action_read, read_options,
+ "ndctl read-labels <nmem0> [<nmem1>..<nmemN>] [-o <filename>]");
+
+ fprintf(stderr, "read %d nmem%s\n", count >= 0 ? count : 0,
+ count > 1 ? "s" : "");
+ return count >= 0 ? 0 : EXIT_FAILURE;
+}
+
+int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
+{
+ int count = dimm_action(argc, argv, ctx, action_zero, zero_options,
+ "ndctl zero-labels <nmem0> [<nmem1>..<nmemN>] [<options>]");
+
+ fprintf(stderr, "zeroed %d nmem%s\n", count >= 0 ? count : 0,
+ count > 1 ? "s" : "");
+ return count >= 0 ? 0 : EXIT_FAILURE;
}
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [ndctl PATCH 4/8] ndctl: merge {enable, disable}-dimm with label commands
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
` (3 preceding siblings ...)
(?)
@ 2016-10-19 16:48 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:48 UTC (permalink / raw)
To: linux-nvdimm
Combine builtin-xable-dimm.c and builtin-label.c into builtin-dimm.c to
give glob support to the enable-dimm and disable-dimm commands. The
command calling conventions already share a <DIMM> argument, so for
consistency enable glob support across the set.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/Makefile.am | 3 -
ndctl/builtin-dimm.c | 40 +++++++++++++++
ndctl/builtin-xable-dimm.c | 115 --------------------------------------------
3 files changed, 39 insertions(+), 119 deletions(-)
rename ndctl/{builtin-labels.c => builtin-dimm.c} (90%)
delete mode 100644 ndctl/builtin-xable-dimm.c
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index dc990988ed43..263a8c4337dd 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -6,11 +6,10 @@ ndctl_SOURCES = ndctl.c \
builtin-create-nfit.c \
builtin-xaction-namespace.c \
builtin-xable-region.c \
- builtin-xable-dimm.c \
+ builtin-dimm.c \
builtin-list.c \
builtin-test.c \
builtin-help.c \
- builtin-labels.c \
util/json.c
if ENABLE_SMART
diff --git a/ndctl/builtin-labels.c b/ndctl/builtin-dimm.c
similarity index 90%
rename from ndctl/builtin-labels.c
rename to ndctl/builtin-dimm.c
index ddd3eb578341..6d0c343a29e3 100644
--- a/ndctl/builtin-labels.c
+++ b/ndctl/builtin-dimm.c
@@ -70,6 +70,22 @@ struct action_context {
FILE *f_out;
};
+static int action_disable(struct ndctl_dimm *dimm, struct action_context *actx)
+{
+ if (ndctl_dimm_is_active(dimm)) {
+ fprintf(stderr, "%s is active, skipping...\n",
+ ndctl_dimm_get_devname(dimm));
+ return -EBUSY;
+ }
+
+ return ndctl_dimm_disable(dimm);
+}
+
+static int action_enable(struct ndctl_dimm *dimm, struct action_context *actx)
+{
+ return ndctl_dimm_enable(dimm);
+}
+
static int action_zero(struct ndctl_dimm *dimm, struct action_context *actx)
{
return ndctl_dimm_zero_labels(dimm);
@@ -335,7 +351,7 @@ static const struct option read_options[] = {
OPT_END(),
};
-static const struct option zero_options[] = {
+static const struct option base_options[] = {
BASE_OPTIONS(),
OPT_END(),
};
@@ -496,10 +512,30 @@ int cmd_read_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
{
- int count = dimm_action(argc, argv, ctx, action_zero, zero_options,
+ int count = dimm_action(argc, argv, ctx, action_zero, base_options,
"ndctl zero-labels <nmem0> [<nmem1>..<nmemN>] [<options>]");
fprintf(stderr, "zeroed %d nmem%s\n", count >= 0 ? count : 0,
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
}
+
+int cmd_disable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx)
+{
+ int count = dimm_action(argc, argv, ctx, action_disable, base_options,
+ "ndctl disable-dimm <nmem0> [<nmem1>..<nmemN>] [<options>]");
+
+ fprintf(stderr, "disabled %d nmem%s\n", count >= 0 ? count : 0,
+ count > 1 ? "s" : "");
+ return count >= 0 ? 0 : EXIT_FAILURE;
+}
+
+int cmd_enable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx)
+{
+ int count = dimm_action(argc, argv, ctx, action_enable, base_options,
+ "ndctl enable-dimm <nmem0> [<nmem1>..<nmemN>] [<options>]");
+
+ fprintf(stderr, "enabled %d nmem%s\n", count >= 0 ? count : 0,
+ count > 1 ? "s" : "");
+ return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/builtin-xable-dimm.c b/ndctl/builtin-xable-dimm.c
deleted file mode 100644
index f0d298837aeb..000000000000
--- a/ndctl/builtin-xable-dimm.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <util/filter.h>
-#include <util/parse-options.h>
-#include <ndctl/libndctl.h>
-
-static const char *dimm_bus;
-
-static const struct option dimm_options[] = {
- OPT_STRING('b', "bus", &dimm_bus, "bus-id",
- "<dimm> must be on a bus with an id/provider of <bus-id>"),
- OPT_END(),
-};
-
-static const char *parse_dimm_options(int argc, const char **argv,
- char *xable_usage)
-{
- const char * const u[] = {
- xable_usage,
- NULL
- };
- int i;
-
- argc = parse_options(argc, argv, dimm_options, u, 0);
-
- if (argc == 0)
- error("specify a dimm to disable, or \"all\"\n");
- for (i = 1; i < argc; i++)
- error("unknown extra parameter \"%s\"\n", argv[i]);
- if (argc == 0 || argc > 1) {
- usage_with_options(u, dimm_options);
- return NULL; /* we won't return from usage_with_options() */
- }
- return argv[0];
-}
-
-static int do_xable_dimm(const char *dimm_arg,
- int (*xable_fn)(struct ndctl_dimm *), struct ndctl_ctx *ctx)
-{
- int rc = -ENXIO, skip = 0, success = 0;
- struct ndctl_dimm *dimm;
- struct ndctl_bus *bus;
-
- if (!dimm_arg)
- goto out;
-
- ndctl_bus_foreach(ctx, bus) {
- if (!util_bus_filter(bus, dimm_bus))
- continue;
-
- ndctl_dimm_foreach(bus, dimm) {
- if (!util_dimm_filter(dimm, dimm_arg))
- continue;
- if (xable_fn == ndctl_dimm_disable
- && ndctl_dimm_is_active(dimm)) {
- fprintf(stderr, "%s is active, skipping...\n",
- ndctl_dimm_get_devname(dimm));
- skip++;
- continue;
- }
- if (xable_fn(dimm) == 0)
- success++;
- }
- }
-
- rc = success;
- if (!success && skip)
- rc = -EBUSY;
- out:
- dimm_bus = NULL;
- return rc;
-}
-
-int cmd_disable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx)
-{
- char *xable_usage = "ndctl disable-dimm <dimm> [<options>]";
- const char *dimm = parse_dimm_options(argc, argv, xable_usage);
- int disabled = do_xable_dimm(dimm, ndctl_dimm_disable,
- ctx);
-
- if (disabled < 0) {
- fprintf(stderr, "error disabling dimms: %s\n",
- strerror(-disabled));
- return disabled;
- } else if (disabled == 0) {
- fprintf(stderr, "disabled 0 dimms\n");
- return 0;
- } else {
- fprintf(stderr, "disabled %d dimm%s\n", disabled,
- disabled > 1 ? "s" : "");
- return 0;
- }
-}
-
-int cmd_enable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx)
-{
- char *xable_usage = "ndctl enable-dimm <dimm> [<options>]";
- const char *dimm = parse_dimm_options(argc, argv, xable_usage);
- int enabled = do_xable_dimm(dimm, ndctl_dimm_enable, ctx);
-
- if (enabled < 0) {
- fprintf(stderr, "error enabling dimms: %s\n",
- strerror(-enabled));
- return enabled;
- } else if (enabled == 0) {
- fprintf(stderr, "enabled 0 dimms\n");
- return 0;
- } else {
- fprintf(stderr, "enabled %d dimm%s\n", enabled,
- enabled > 1 ? "s" : "");
- return 0;
- }
-}
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [ndctl PATCH 5/8] libndctl: add ndctl_cmd_cfg_read_get_size()
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
` (4 preceding siblings ...)
(?)
@ 2016-10-19 16:48 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:48 UTC (permalink / raw)
To: linux-nvdimm
Allow the size of the configuration label region to be retrieved from
the cfg_read command. This lets applications pass around a successful
cfg_read command object and not need access to the original cfg_size
command.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/lib/libndctl.c | 9 +++++++++
ndctl/lib/libndctl.sym | 1 +
ndctl/libndctl.h.in | 1 +
3 files changed, 11 insertions(+)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 7d870b082cd4..82b11a0d3ac9 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -2057,6 +2057,15 @@ NDCTL_EXPORT ssize_t ndctl_cmd_cfg_read_get_data(struct ndctl_cmd *cfg_read,
return len;
}
+NDCTL_EXPORT ssize_t ndctl_cmd_cfg_read_get_size(struct ndctl_cmd *cfg_read)
+{
+ if (cfg_read->type != ND_CMD_GET_CONFIG_DATA || cfg_read->status > 0)
+ return -EINVAL;
+ if (cfg_read->status < 0)
+ return cfg_read->status;
+ return cfg_read->iter.total_xfer;
+}
+
NDCTL_EXPORT ssize_t ndctl_cmd_cfg_write_set_data(struct ndctl_cmd *cfg_write,
void *buf, unsigned int len, unsigned int offset)
{
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index dfc44ae51362..6bd032ea7526 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -210,6 +210,7 @@ global:
ndctl_btt_is_configured;
ndctl_cmd_cfg_size_get_size;
ndctl_cmd_cfg_read_get_data;
+ ndctl_cmd_cfg_read_get_size;
ndctl_cmd_cfg_write_set_data;
ndctl_cmd_cfg_write_zero_data;
ndctl_cmd_unref;
diff --git a/ndctl/libndctl.h.in b/ndctl/libndctl.h.in
index 803368bc1acd..d3379f76e1f9 100644
--- a/ndctl/libndctl.h.in
+++ b/ndctl/libndctl.h.in
@@ -356,6 +356,7 @@ unsigned long ndctl_dimm_get_available_labels(struct ndctl_dimm *dimm);
unsigned int ndctl_cmd_cfg_size_get_size(struct ndctl_cmd *cfg_size);
ssize_t ndctl_cmd_cfg_read_get_data(struct ndctl_cmd *cfg_read, void *buf,
unsigned int len, unsigned int offset);
+ssize_t ndctl_cmd_cfg_read_get_size(struct ndctl_cmd *cfg_read);
ssize_t ndctl_cmd_cfg_write_set_data(struct ndctl_cmd *cfg_write, void *buf,
unsigned int len, unsigned int offset);
ssize_t ndctl_cmd_cfg_write_zero_data(struct ndctl_cmd *cfg_write);
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [ndctl PATCH 6/8] ndctl: provide a read_labels() helper
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
` (5 preceding siblings ...)
(?)
@ 2016-10-19 16:48 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:48 UTC (permalink / raw)
To: linux-nvdimm
In preparation for adding an 'init-labels' command, factor out the
common portion of reading the label space from a dimm.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
ndctl/builtin-dimm.c | 44 ++++++++++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/ndctl/builtin-dimm.c b/ndctl/builtin-dimm.c
index 6d0c343a29e3..34ad1d9b47e7 100644
--- a/ndctl/builtin-dimm.c
+++ b/ndctl/builtin-dimm.c
@@ -284,46 +284,62 @@ static int dump_bin(FILE *f_out, struct ndctl_cmd *cmd_read, ssize_t size)
return 0;
}
-static int action_read(struct ndctl_dimm *dimm, struct action_context *actx)
+static struct ndctl_cmd *read_labels(struct ndctl_dimm *dimm)
{
struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm);
struct ndctl_cmd *cmd_size, *cmd_read;
- ssize_t size;
int rc;
rc = ndctl_bus_wait_probe(bus);
if (rc < 0)
- return rc;
+ return NULL;
cmd_size = ndctl_dimm_cmd_new_cfg_size(dimm);
if (!cmd_size)
- return -ENOTTY;
+ return NULL;
rc = ndctl_cmd_submit(cmd_size);
if (rc || ndctl_cmd_get_firmware_status(cmd_size))
goto out_size;
cmd_read = ndctl_dimm_cmd_new_cfg_read(cmd_size);
- if (!cmd_read) {
- rc = -ENOTTY;
+ if (!cmd_read)
goto out_size;
- }
rc = ndctl_cmd_submit(cmd_read);
if (rc || ndctl_cmd_get_firmware_status(cmd_read))
goto out_read;
- size = ndctl_cmd_cfg_size_get_size(cmd_size);
+ ndctl_cmd_unref(cmd_size);
+ return cmd_read;
+
+ out_read:
+ ndctl_cmd_unref(cmd_read);
+ out_size:
+ ndctl_cmd_unref(cmd_size);
+ return NULL;
+}
+
+static int action_read(struct ndctl_dimm *dimm, struct action_context *actx)
+{
+ struct ndctl_cmd *cmd_read;
+ ssize_t size;
+ int rc = 0;
+
+ cmd_read = read_labels(dimm);
+ if (!cmd_read)
+ return -ENXIO;
+
+ size = ndctl_cmd_cfg_read_get_size(cmd_read);
if (actx->jdimms) {
struct json_object *jdimm = dump_json(dimm, cmd_read, size);
- if (!jdimm)
- return -ENOMEM;
- json_object_array_add(actx->jdimms, jdimm);
+
+ if (jdimm)
+ json_object_array_add(actx->jdimms, jdimm);
+ else
+ rc = -ENOMEM;
} else
rc = dump_bin(actx->f_out, cmd_read, size);
- out_read:
ndctl_cmd_unref(cmd_read);
- out_size:
- ndctl_cmd_unref(cmd_size);
return rc;
}
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [ndctl PATCH 7/8] ndctl: init-labels command
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
@ 2016-10-19 16:48 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:48 UTC (permalink / raw)
To: linux-nvdimm; +Cc: qemu-devel
For environments like QEMU that have label support, but do not have
aliased BLK capacity the kernel by default will ignore labels and
produce a namespace that matches the boundaries defined in the NFIT.
Kernels starting with v4.10 enabled pmem-subdivision support to be
enabled if the DIMM has a valid namespace label index block.
The 'ndctl init-labels' command writes an empty namespace label index
block to convert the pmem region to labelled mode, or otherwise repair a
label area.
Cc: <qemu-devel@nongnu.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
Documentation/Makefile.am | 1
Documentation/ndctl-init-labels.txt | 83 +++++++
ndctl/builtin-dimm.c | 395 +++++++++++++++++++++++++++++++++++
ndctl/builtin.h | 1
ndctl/ndctl.c | 1
5 files changed, 479 insertions(+), 2 deletions(-)
create mode 100644 Documentation/ndctl-init-labels.txt
diff --git a/Documentation/Makefile.am b/Documentation/Makefile.am
index 63ef1ce7f2d7..4448064dd1b9 100644
--- a/Documentation/Makefile.am
+++ b/Documentation/Makefile.am
@@ -2,6 +2,7 @@ man1_MANS = \
ndctl.1 \
ndctl-zero-labels.1 \
ndctl-read-labels.1 \
+ ndctl-init-labels.1 \
ndctl-enable-region.1 \
ndctl-disable-region.1 \
ndctl-enable-dimm.1 \
diff --git a/Documentation/ndctl-init-labels.txt b/Documentation/ndctl-init-labels.txt
new file mode 100644
index 000000000000..c01f31b0532a
--- /dev/null
+++ b/Documentation/ndctl-init-labels.txt
@@ -0,0 +1,83 @@
+ndctl-init-labels(1)
+====================
+
+NAME
+----
+ndctl-init-labels - initialize the label data area on a dimm or set of dimms
+
+SYNOPSIS
+--------
+[verse]
+'ndctl init-labels' <nmem0> [<nmem1>..<nmemN>] [<options>]
+
+include::labels-description.txt[]
+By default, and in kernels prior to v4.10, the kernel only honors labels
+when a DIMM aliases PMEM and BLK capacity. Starting with v4.10 the
+kernel will honor labels for sub-dividing PMEM if all the DIMMs in an
+interleave set / region have a valid namespace index block.
+
+This command can be used to initialize the namespace index block if it
+is missing or reinitialize it if it is damaged. Note that
+reinitialization effectively destroys all existing namespace labels on
+the DIMM.
+
+EXAMPLE
+-------
+Find the DIMMs that comprise a given region:
+[verse]
+# ndctl list -RD --region=region1
+{
+ "dimms":[
+ {
+ "dev":"nmem0",
+ "id":"8680-56341200"
+ }
+ ],
+ "regions":[
+ {
+ "dev":"region1",
+ "size":268435456,
+ "available_size":0,
+ "type":"pmem",
+ "mappings":[
+ {
+ "dimm":"nmem0",
+ "offset":13958643712,
+ "length":268435456
+ }
+ ]
+ }
+ ]
+}
+
+Disable that region so the DIMM label area can be written from
+userspace:
+[verse]
+# ndctl disable-region region1
+
+Initialize labels:
+[verse]
+# ndctl init-labels nmem0
+
+Re-enable the region:
+[verse]
+# ndctl enable-region region1
+
+Create a namespace in that region:
+[verse]
+# ndctl create-namespace --region=region1
+
+OPTIONS
+-------
+include::labels-options.txt[]
+-o::
+ output file
+-f::
+--force::
+ parse the label data into json assuming the 'NVDIMM Namespace
+ Specification' format.
+
+SEE ALSO
+--------
+http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf[NVDIMM Namespace
+Specification]
diff --git a/ndctl/builtin-dimm.c b/ndctl/builtin-dimm.c
index 34ad1d9b47e7..399f0c32b816 100644
--- a/ndctl/builtin-dimm.c
+++ b/ndctl/builtin-dimm.c
@@ -17,14 +17,15 @@
#include <unistd.h>
#include <limits.h>
#include <syslog.h>
+#include <util/log.h>
#include <uuid/uuid.h>
-#include <util/filter.h>
#include <util/json.h>
+#include <util/filter.h>
#include <json-c/json.h>
#include <ndctl/libndctl.h>
#include <util/parse-options.h>
#include <ccan/minmax/minmax.h>
-#define CCAN_SHORT_TYPES_H
+#include <ccan/short_types/short_types.h>
#include <ccan/endian/endian.h>
#include <ccan/array_size/array_size.h>
@@ -65,6 +66,8 @@ struct namespace_label {
le32 unused;
};
+static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
+
struct action_context {
struct json_object *jdimms;
FILE *f_out;
@@ -344,13 +347,381 @@ static int action_read(struct ndctl_dimm *dimm, struct action_context *actx)
return rc;
}
+struct nvdimm_data {
+ struct ndctl_dimm *dimm;
+ struct ndctl_cmd *cmd_read;
+ unsigned long config_size;
+ struct log_ctx ctx;
+ void *data;
+ int nsindex_size;
+ int ns_current, ns_next;
+};
+
+/*
+ * Note, best_seq(), inc_seq(), fletcher64(), sizeof_namespace_index()
+ * nvdimm_num_label_slots(), label_validate(), and label_write_index()
+ * are copied from drivers/nvdimm/label.c in the Linux kernel with the
+ * following modifications:
+ * 1/ s,nd_,,gc
+ * 2/ s,ndd->nsarea.config_size,ndd->config_size,gc
+ * 3/ s,dev_dbg(dev,dbg(ndd,gc
+ * 4/ s,__le,le,gc
+ * 5/ s,__cpu_to,cpu_to,gc
+ * 6/ remove flags argument to label_write_index
+ * 7/ dropped clear_bit_le() usage in label_write_index
+ */
+
+static u64 fletcher64(void *addr, size_t len, bool le)
+{
+ u32 *buf = addr;
+ u32 lo32 = 0;
+ u64 hi32 = 0;
+ size_t i;
+
+ for (i = 0; i < len / sizeof(u32); i++) {
+ lo32 += le ? le32_to_cpu((le32) buf[i]) : buf[i];
+ hi32 += lo32;
+ }
+
+ return hi32 << 32 | lo32;
+}
+
+static unsigned inc_seq(unsigned seq)
+{
+ static const unsigned next[] = { 0, 2, 3, 1 };
+
+ return next[seq & 3];
+}
+
+static u32 best_seq(u32 a, u32 b)
+{
+ a &= NSINDEX_SEQ_MASK;
+ b &= NSINDEX_SEQ_MASK;
+
+ if (a == 0 || a == b)
+ return b;
+ else if (b == 0)
+ return a;
+ else if (inc_seq(a) == b)
+ return b;
+ else
+ return a;
+}
+
+static size_t sizeof_namespace_index(struct nvdimm_data *ndd)
+{
+ u32 index_span;
+
+ if (ndd->nsindex_size)
+ return ndd->nsindex_size;
+
+ /*
+ * The minimum index space is 512 bytes, with that amount of
+ * index we can describe ~1400 labels which is less than a byte
+ * of overhead per label. Round up to a byte of overhead per
+ * label and determine the size of the index region. Yes, this
+ * starts to waste space at larger config_sizes, but it's
+ * unlikely we'll ever see anything but 128K.
+ */
+ index_span = ndd->config_size / 129;
+ index_span /= NSINDEX_ALIGN * 2;
+ ndd->nsindex_size = index_span * NSINDEX_ALIGN;
+
+ return ndd->nsindex_size;
+}
+
+static int nvdimm_num_label_slots(struct nvdimm_data *ndd)
+{
+ return ndd->config_size / 129;
+}
+
+static struct namespace_index *to_namespace_index(struct nvdimm_data *ndd,
+ int i)
+{
+ char *index;
+
+ if (i < 0)
+ return NULL;
+
+ index = (char *) ndd->data + sizeof_namespace_index(ndd) * i;
+ return (struct namespace_index *) index;
+}
+
+static int label_validate(struct nvdimm_data *ndd)
+{
+ /*
+ * On media label format consists of two index blocks followed
+ * by an array of labels. None of these structures are ever
+ * updated in place. A sequence number tracks the current
+ * active index and the next one to write, while labels are
+ * written to free slots.
+ *
+ * +------------+
+ * | |
+ * | nsindex0 |
+ * | |
+ * +------------+
+ * | |
+ * | nsindex1 |
+ * | |
+ * +------------+
+ * | label0 |
+ * +------------+
+ * | label1 |
+ * +------------+
+ * | |
+ * ....nslot...
+ * | |
+ * +------------+
+ * | labelN |
+ * +------------+
+ */
+ struct namespace_index *nsindex[] = {
+ to_namespace_index(ndd, 0),
+ to_namespace_index(ndd, 1),
+ };
+ const int num_index = ARRAY_SIZE(nsindex);
+ bool valid[2] = { 0 };
+ int i, num_valid = 0;
+ u32 seq;
+
+ for (i = 0; i < num_index; i++) {
+ u32 nslot;
+ u8 sig[NSINDEX_SIG_LEN];
+ u64 sum_save, sum, size;
+
+ memcpy(sig, nsindex[i]->sig, NSINDEX_SIG_LEN);
+ if (memcmp(sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN) != 0) {
+ dbg(ndd, "nsindex%d signature invalid\n", i);
+ continue;
+ }
+ sum_save = le64_to_cpu(nsindex[i]->checksum);
+ nsindex[i]->checksum = cpu_to_le64(0);
+ sum = fletcher64(nsindex[i], sizeof_namespace_index(ndd), 1);
+ nsindex[i]->checksum = cpu_to_le64(sum_save);
+ if (sum != sum_save) {
+ dbg(ndd, "nsindex%d checksum invalid\n", i);
+ continue;
+ }
+
+ seq = le32_to_cpu(nsindex[i]->seq);
+ if ((seq & NSINDEX_SEQ_MASK) == 0) {
+ dbg(ndd, "nsindex%d sequence: %#x invalid\n", i, seq);
+ continue;
+ }
+
+ /* sanity check the index against expected values */
+ if (le64_to_cpu(nsindex[i]->myoff)
+ != i * sizeof_namespace_index(ndd)) {
+ dbg(ndd, "nsindex%d myoff: %#llx invalid\n",
+ i, (unsigned long long)
+ le64_to_cpu(nsindex[i]->myoff));
+ continue;
+ }
+ if (le64_to_cpu(nsindex[i]->otheroff)
+ != (!i) * sizeof_namespace_index(ndd)) {
+ dbg(ndd, "nsindex%d otheroff: %#llx invalid\n",
+ i, (unsigned long long)
+ le64_to_cpu(nsindex[i]->otheroff));
+ continue;
+ }
+
+ size = le64_to_cpu(nsindex[i]->mysize);
+ if (size > sizeof_namespace_index(ndd)
+ || size < sizeof(struct namespace_index)) {
+ dbg(ndd, "nsindex%d mysize: %#zx invalid\n", i, size);
+ continue;
+ }
+
+ nslot = le32_to_cpu(nsindex[i]->nslot);
+ if (nslot * sizeof(struct namespace_label)
+ + 2 * sizeof_namespace_index(ndd)
+ > ndd->config_size) {
+ dbg(ndd, "nsindex%d nslot: %u invalid, config_size: %#zx\n",
+ i, nslot, ndd->config_size);
+ continue;
+ }
+ valid[i] = true;
+ num_valid++;
+ }
+
+ switch (num_valid) {
+ case 0:
+ break;
+ case 1:
+ for (i = 0; i < num_index; i++)
+ if (valid[i])
+ return i;
+ /* can't have num_valid > 0 but valid[] = { false, false } */
+ err(ndd, "unexpected index-block parse error\n");
+ break;
+ default:
+ /* pick the best index... */
+ seq = best_seq(le32_to_cpu(nsindex[0]->seq),
+ le32_to_cpu(nsindex[1]->seq));
+ if (seq == (le32_to_cpu(nsindex[1]->seq) & NSINDEX_SEQ_MASK))
+ return 1;
+ else
+ return 0;
+ break;
+ }
+
+ return -1;
+}
+
+static int nvdimm_set_config_data(struct nvdimm_data *ndd, size_t offset,
+ void *buf, size_t len)
+{
+ struct ndctl_cmd *cmd_write;
+ int rc;
+
+ cmd_write = ndctl_dimm_cmd_new_cfg_write(ndd->cmd_read);
+ if (!cmd_write)
+ return -ENXIO;
+
+ rc = ndctl_cmd_cfg_write_set_data(cmd_write, buf, len, offset);
+ if (rc < 0)
+ goto out;
+
+ rc = ndctl_cmd_submit(cmd_write);
+ if (rc || ndctl_cmd_get_firmware_status(cmd_write))
+ rc = -ENXIO;
+ out:
+ ndctl_cmd_unref(cmd_write);
+ return rc;
+}
+
+static int label_next_nsindex(int index)
+{
+ if (index < 0)
+ return -1;
+ return (index + 1) % 2;
+}
+
+static struct namespace_label *label_base(struct nvdimm_data *ndd)
+{
+ char *base = (char *) to_namespace_index(ndd, 0);
+
+ base += 2 * sizeof_namespace_index(ndd);
+ return (struct namespace_label *) base;
+}
+
+#define ALIGN(x, a) ((((unsigned long long) x) + (a - 1)) & ~(a - 1))
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
+static int label_write_index(struct nvdimm_data *ndd, int index, u32 seq)
+{
+ struct namespace_index *nsindex;
+ unsigned long offset;
+ u64 checksum;
+ u32 nslot;
+
+ nsindex = to_namespace_index(ndd, index);
+ nslot = nvdimm_num_label_slots(ndd);
+
+ memcpy(nsindex->sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN);
+ nsindex->flags = cpu_to_le32(0);
+ nsindex->seq = cpu_to_le32(seq);
+ offset = (unsigned long) nsindex
+ - (unsigned long) to_namespace_index(ndd, 0);
+ nsindex->myoff = cpu_to_le64(offset);
+ nsindex->mysize = cpu_to_le64(sizeof_namespace_index(ndd));
+ offset = (unsigned long) to_namespace_index(ndd,
+ label_next_nsindex(index))
+ - (unsigned long) to_namespace_index(ndd, 0);
+ nsindex->otheroff = cpu_to_le64(offset);
+ offset = (unsigned long) label_base(ndd)
+ - (unsigned long) to_namespace_index(ndd, 0);
+ nsindex->labeloff = cpu_to_le64(offset);
+ nsindex->nslot = cpu_to_le32(nslot);
+ nsindex->major = cpu_to_le16(1);
+ nsindex->minor = cpu_to_le16(1);
+ nsindex->checksum = cpu_to_le64(0);
+ /* init label bitmap */
+ memset(nsindex->free, 0xff, ALIGN(nslot, BITS_PER_LONG) / 8);
+ checksum = fletcher64(nsindex, sizeof_namespace_index(ndd), 1);
+ nsindex->checksum = cpu_to_le64(checksum);
+ return nvdimm_set_config_data(ndd, le64_to_cpu(nsindex->myoff),
+ nsindex, sizeof_namespace_index(ndd));
+}
+
static struct parameters {
const char *bus;
const char *outfile;
+ bool force;
bool json;
bool verbose;
} param;
+static int action_init(struct ndctl_dimm *dimm, struct action_context *actx)
+{
+ struct nvdimm_data __ndd, *ndd = &__ndd;
+ struct ndctl_cmd *cmd_read;
+ int rc = 0, i;
+ ssize_t size;
+
+ cmd_read = read_labels(dimm);
+ if (!cmd_read)
+ return -ENXIO;
+
+ size = ndctl_cmd_cfg_read_get_size(cmd_read);
+ ndd->data = malloc(size);
+ if (!ndd->data)
+ return -ENOMEM;
+ rc = ndctl_cmd_cfg_read_get_data(cmd_read, ndd->data, size, 0);
+ if (rc < 0)
+ goto out;
+
+ ndd->dimm = dimm;
+ ndd->cmd_read = cmd_read;
+ ndd->config_size = size;
+ ndd->nsindex_size = 0;
+ ndd->ns_current = -1;
+ ndd->ns_next = -1;
+ log_init(&ndd->ctx, ndctl_dimm_get_devname(dimm), "NDCTL_INIT_LABELS");
+ if (param.verbose)
+ ndd->ctx.log_priority = LOG_DEBUG;
+
+ /*
+ * If the region goes active after this point, i.e. we're racing
+ * another administrative action, the kernel will fail writes to
+ * the label area.
+ */
+ if (ndctl_dimm_is_active(dimm)) {
+ err(ndd, "regions active, abort label write\n");
+ rc = -EBUSY;
+ goto out;
+ }
+
+ if (label_validate(ndd) >= 0 && !param.force) {
+ err(ndd, "error: labels already initialized\n");
+ rc = -EBUSY;
+ goto out;
+ }
+
+ for (i = 0; i < 2; i++) {
+ rc = label_write_index(ndd, i, i*2);
+ if (rc)
+ goto out;
+ }
+
+ /*
+ * If the dimm is already disabled the kernel is not holding a cached
+ * copy of the label space.
+ */
+ if (!ndctl_dimm_is_enabled(dimm))
+ goto out;
+
+ rc = ndctl_dimm_disable(dimm);
+ if (rc)
+ goto out;
+ rc = ndctl_dimm_enable(dimm);
+
+ out:
+ ndctl_cmd_unref(cmd_read);
+ free(ndd->data);
+ return rc;
+}
+
#define BASE_OPTIONS() \
OPT_STRING('b', "bus", ¶m.bus, "bus-id", \
"<nmem> must be on a bus with an id/provider of <bus-id>"), \
@@ -361,6 +732,10 @@ OPT_STRING('o', NULL, ¶m.outfile, "output-file", \
"filename to write label area contents"), \
OPT_BOOLEAN('j', "json", ¶m.json, "parse label data into json")
+#define INIT_OPTIONS() \
+OPT_BOOLEAN('f', "force", ¶m.force, \
+ "force initialization even if existing index-block present")
+
static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -372,6 +747,12 @@ static const struct option base_options[] = {
OPT_END(),
};
+static const struct option init_options[] = {
+ BASE_OPTIONS(),
+ INIT_OPTIONS(),
+ OPT_END(),
+};
+
static int dimm_action(int argc, const char **argv, struct ndctl_ctx *ctx,
int (*action)(struct ndctl_dimm *dimm, struct action_context *actx),
const struct option *options, const char *usage)
@@ -536,6 +917,16 @@ int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
return count >= 0 ? 0 : EXIT_FAILURE;
}
+int cmd_init_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
+{
+ int count = dimm_action(argc, argv, ctx, action_init, init_options,
+ "ndctl init-labels <nmem0> [<nmem1>..<nmemN>] [<options>]");
+
+ fprintf(stderr, "initialized %d nmem%s\n", count >= 0 ? count : 0,
+ count > 1 ? "s" : "");
+ return count >= 0 ? 0 : EXIT_FAILURE;
+}
+
int cmd_disable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx)
{
int count = dimm_action(argc, argv, ctx, action_disable, base_options,
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index ec55865ecea8..efa90c0146ee 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -20,6 +20,7 @@ int cmd_enable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_disable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_read_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_init_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_list(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_help(int argc, const char **argv, struct ndctl_ctx *ctx);
#ifdef ENABLE_TEST
diff --git a/ndctl/ndctl.c b/ndctl/ndctl.c
index aaeb3f7c2bec..bdb17226f834 100644
--- a/ndctl/ndctl.c
+++ b/ndctl/ndctl.c
@@ -36,6 +36,7 @@ static struct cmd_struct commands[] = {
{ "disable-dimm", cmd_disable_dimm },
{ "zero-labels", cmd_zero_labels },
{ "read-labels", cmd_read_labels },
+ { "init-labels", cmd_init_labels },
{ "list", cmd_list },
{ "help", cmd_help },
#ifdef ENABLE_TEST
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [Qemu-devel] [ndctl PATCH 7/8] ndctl: init-labels command
@ 2016-10-19 16:48 ` Dan Williams
0 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:48 UTC (permalink / raw)
To: linux-nvdimm; +Cc: vishal.l.verma, qemu-devel
For environments like QEMU that have label support, but do not have
aliased BLK capacity the kernel by default will ignore labels and
produce a namespace that matches the boundaries defined in the NFIT.
Kernels starting with v4.10 enabled pmem-subdivision support to be
enabled if the DIMM has a valid namespace label index block.
The 'ndctl init-labels' command writes an empty namespace label index
block to convert the pmem region to labelled mode, or otherwise repair a
label area.
Cc: <qemu-devel@nongnu.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
Documentation/Makefile.am | 1
Documentation/ndctl-init-labels.txt | 83 +++++++
ndctl/builtin-dimm.c | 395 +++++++++++++++++++++++++++++++++++
ndctl/builtin.h | 1
ndctl/ndctl.c | 1
5 files changed, 479 insertions(+), 2 deletions(-)
create mode 100644 Documentation/ndctl-init-labels.txt
diff --git a/Documentation/Makefile.am b/Documentation/Makefile.am
index 63ef1ce7f2d7..4448064dd1b9 100644
--- a/Documentation/Makefile.am
+++ b/Documentation/Makefile.am
@@ -2,6 +2,7 @@ man1_MANS = \
ndctl.1 \
ndctl-zero-labels.1 \
ndctl-read-labels.1 \
+ ndctl-init-labels.1 \
ndctl-enable-region.1 \
ndctl-disable-region.1 \
ndctl-enable-dimm.1 \
diff --git a/Documentation/ndctl-init-labels.txt b/Documentation/ndctl-init-labels.txt
new file mode 100644
index 000000000000..c01f31b0532a
--- /dev/null
+++ b/Documentation/ndctl-init-labels.txt
@@ -0,0 +1,83 @@
+ndctl-init-labels(1)
+====================
+
+NAME
+----
+ndctl-init-labels - initialize the label data area on a dimm or set of dimms
+
+SYNOPSIS
+--------
+[verse]
+'ndctl init-labels' <nmem0> [<nmem1>..<nmemN>] [<options>]
+
+include::labels-description.txt[]
+By default, and in kernels prior to v4.10, the kernel only honors labels
+when a DIMM aliases PMEM and BLK capacity. Starting with v4.10 the
+kernel will honor labels for sub-dividing PMEM if all the DIMMs in an
+interleave set / region have a valid namespace index block.
+
+This command can be used to initialize the namespace index block if it
+is missing or reinitialize it if it is damaged. Note that
+reinitialization effectively destroys all existing namespace labels on
+the DIMM.
+
+EXAMPLE
+-------
+Find the DIMMs that comprise a given region:
+[verse]
+# ndctl list -RD --region=region1
+{
+ "dimms":[
+ {
+ "dev":"nmem0",
+ "id":"8680-56341200"
+ }
+ ],
+ "regions":[
+ {
+ "dev":"region1",
+ "size":268435456,
+ "available_size":0,
+ "type":"pmem",
+ "mappings":[
+ {
+ "dimm":"nmem0",
+ "offset":13958643712,
+ "length":268435456
+ }
+ ]
+ }
+ ]
+}
+
+Disable that region so the DIMM label area can be written from
+userspace:
+[verse]
+# ndctl disable-region region1
+
+Initialize labels:
+[verse]
+# ndctl init-labels nmem0
+
+Re-enable the region:
+[verse]
+# ndctl enable-region region1
+
+Create a namespace in that region:
+[verse]
+# ndctl create-namespace --region=region1
+
+OPTIONS
+-------
+include::labels-options.txt[]
+-o::
+ output file
+-f::
+--force::
+ parse the label data into json assuming the 'NVDIMM Namespace
+ Specification' format.
+
+SEE ALSO
+--------
+http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf[NVDIMM Namespace
+Specification]
diff --git a/ndctl/builtin-dimm.c b/ndctl/builtin-dimm.c
index 34ad1d9b47e7..399f0c32b816 100644
--- a/ndctl/builtin-dimm.c
+++ b/ndctl/builtin-dimm.c
@@ -17,14 +17,15 @@
#include <unistd.h>
#include <limits.h>
#include <syslog.h>
+#include <util/log.h>
#include <uuid/uuid.h>
-#include <util/filter.h>
#include <util/json.h>
+#include <util/filter.h>
#include <json-c/json.h>
#include <ndctl/libndctl.h>
#include <util/parse-options.h>
#include <ccan/minmax/minmax.h>
-#define CCAN_SHORT_TYPES_H
+#include <ccan/short_types/short_types.h>
#include <ccan/endian/endian.h>
#include <ccan/array_size/array_size.h>
@@ -65,6 +66,8 @@ struct namespace_label {
le32 unused;
};
+static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
+
struct action_context {
struct json_object *jdimms;
FILE *f_out;
@@ -344,13 +347,381 @@ static int action_read(struct ndctl_dimm *dimm, struct action_context *actx)
return rc;
}
+struct nvdimm_data {
+ struct ndctl_dimm *dimm;
+ struct ndctl_cmd *cmd_read;
+ unsigned long config_size;
+ struct log_ctx ctx;
+ void *data;
+ int nsindex_size;
+ int ns_current, ns_next;
+};
+
+/*
+ * Note, best_seq(), inc_seq(), fletcher64(), sizeof_namespace_index()
+ * nvdimm_num_label_slots(), label_validate(), and label_write_index()
+ * are copied from drivers/nvdimm/label.c in the Linux kernel with the
+ * following modifications:
+ * 1/ s,nd_,,gc
+ * 2/ s,ndd->nsarea.config_size,ndd->config_size,gc
+ * 3/ s,dev_dbg(dev,dbg(ndd,gc
+ * 4/ s,__le,le,gc
+ * 5/ s,__cpu_to,cpu_to,gc
+ * 6/ remove flags argument to label_write_index
+ * 7/ dropped clear_bit_le() usage in label_write_index
+ */
+
+static u64 fletcher64(void *addr, size_t len, bool le)
+{
+ u32 *buf = addr;
+ u32 lo32 = 0;
+ u64 hi32 = 0;
+ size_t i;
+
+ for (i = 0; i < len / sizeof(u32); i++) {
+ lo32 += le ? le32_to_cpu((le32) buf[i]) : buf[i];
+ hi32 += lo32;
+ }
+
+ return hi32 << 32 | lo32;
+}
+
+static unsigned inc_seq(unsigned seq)
+{
+ static const unsigned next[] = { 0, 2, 3, 1 };
+
+ return next[seq & 3];
+}
+
+static u32 best_seq(u32 a, u32 b)
+{
+ a &= NSINDEX_SEQ_MASK;
+ b &= NSINDEX_SEQ_MASK;
+
+ if (a == 0 || a == b)
+ return b;
+ else if (b == 0)
+ return a;
+ else if (inc_seq(a) == b)
+ return b;
+ else
+ return a;
+}
+
+static size_t sizeof_namespace_index(struct nvdimm_data *ndd)
+{
+ u32 index_span;
+
+ if (ndd->nsindex_size)
+ return ndd->nsindex_size;
+
+ /*
+ * The minimum index space is 512 bytes, with that amount of
+ * index we can describe ~1400 labels which is less than a byte
+ * of overhead per label. Round up to a byte of overhead per
+ * label and determine the size of the index region. Yes, this
+ * starts to waste space at larger config_sizes, but it's
+ * unlikely we'll ever see anything but 128K.
+ */
+ index_span = ndd->config_size / 129;
+ index_span /= NSINDEX_ALIGN * 2;
+ ndd->nsindex_size = index_span * NSINDEX_ALIGN;
+
+ return ndd->nsindex_size;
+}
+
+static int nvdimm_num_label_slots(struct nvdimm_data *ndd)
+{
+ return ndd->config_size / 129;
+}
+
+static struct namespace_index *to_namespace_index(struct nvdimm_data *ndd,
+ int i)
+{
+ char *index;
+
+ if (i < 0)
+ return NULL;
+
+ index = (char *) ndd->data + sizeof_namespace_index(ndd) * i;
+ return (struct namespace_index *) index;
+}
+
+static int label_validate(struct nvdimm_data *ndd)
+{
+ /*
+ * On media label format consists of two index blocks followed
+ * by an array of labels. None of these structures are ever
+ * updated in place. A sequence number tracks the current
+ * active index and the next one to write, while labels are
+ * written to free slots.
+ *
+ * +------------+
+ * | |
+ * | nsindex0 |
+ * | |
+ * +------------+
+ * | |
+ * | nsindex1 |
+ * | |
+ * +------------+
+ * | label0 |
+ * +------------+
+ * | label1 |
+ * +------------+
+ * | |
+ * ....nslot...
+ * | |
+ * +------------+
+ * | labelN |
+ * +------------+
+ */
+ struct namespace_index *nsindex[] = {
+ to_namespace_index(ndd, 0),
+ to_namespace_index(ndd, 1),
+ };
+ const int num_index = ARRAY_SIZE(nsindex);
+ bool valid[2] = { 0 };
+ int i, num_valid = 0;
+ u32 seq;
+
+ for (i = 0; i < num_index; i++) {
+ u32 nslot;
+ u8 sig[NSINDEX_SIG_LEN];
+ u64 sum_save, sum, size;
+
+ memcpy(sig, nsindex[i]->sig, NSINDEX_SIG_LEN);
+ if (memcmp(sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN) != 0) {
+ dbg(ndd, "nsindex%d signature invalid\n", i);
+ continue;
+ }
+ sum_save = le64_to_cpu(nsindex[i]->checksum);
+ nsindex[i]->checksum = cpu_to_le64(0);
+ sum = fletcher64(nsindex[i], sizeof_namespace_index(ndd), 1);
+ nsindex[i]->checksum = cpu_to_le64(sum_save);
+ if (sum != sum_save) {
+ dbg(ndd, "nsindex%d checksum invalid\n", i);
+ continue;
+ }
+
+ seq = le32_to_cpu(nsindex[i]->seq);
+ if ((seq & NSINDEX_SEQ_MASK) == 0) {
+ dbg(ndd, "nsindex%d sequence: %#x invalid\n", i, seq);
+ continue;
+ }
+
+ /* sanity check the index against expected values */
+ if (le64_to_cpu(nsindex[i]->myoff)
+ != i * sizeof_namespace_index(ndd)) {
+ dbg(ndd, "nsindex%d myoff: %#llx invalid\n",
+ i, (unsigned long long)
+ le64_to_cpu(nsindex[i]->myoff));
+ continue;
+ }
+ if (le64_to_cpu(nsindex[i]->otheroff)
+ != (!i) * sizeof_namespace_index(ndd)) {
+ dbg(ndd, "nsindex%d otheroff: %#llx invalid\n",
+ i, (unsigned long long)
+ le64_to_cpu(nsindex[i]->otheroff));
+ continue;
+ }
+
+ size = le64_to_cpu(nsindex[i]->mysize);
+ if (size > sizeof_namespace_index(ndd)
+ || size < sizeof(struct namespace_index)) {
+ dbg(ndd, "nsindex%d mysize: %#zx invalid\n", i, size);
+ continue;
+ }
+
+ nslot = le32_to_cpu(nsindex[i]->nslot);
+ if (nslot * sizeof(struct namespace_label)
+ + 2 * sizeof_namespace_index(ndd)
+ > ndd->config_size) {
+ dbg(ndd, "nsindex%d nslot: %u invalid, config_size: %#zx\n",
+ i, nslot, ndd->config_size);
+ continue;
+ }
+ valid[i] = true;
+ num_valid++;
+ }
+
+ switch (num_valid) {
+ case 0:
+ break;
+ case 1:
+ for (i = 0; i < num_index; i++)
+ if (valid[i])
+ return i;
+ /* can't have num_valid > 0 but valid[] = { false, false } */
+ err(ndd, "unexpected index-block parse error\n");
+ break;
+ default:
+ /* pick the best index... */
+ seq = best_seq(le32_to_cpu(nsindex[0]->seq),
+ le32_to_cpu(nsindex[1]->seq));
+ if (seq == (le32_to_cpu(nsindex[1]->seq) & NSINDEX_SEQ_MASK))
+ return 1;
+ else
+ return 0;
+ break;
+ }
+
+ return -1;
+}
+
+static int nvdimm_set_config_data(struct nvdimm_data *ndd, size_t offset,
+ void *buf, size_t len)
+{
+ struct ndctl_cmd *cmd_write;
+ int rc;
+
+ cmd_write = ndctl_dimm_cmd_new_cfg_write(ndd->cmd_read);
+ if (!cmd_write)
+ return -ENXIO;
+
+ rc = ndctl_cmd_cfg_write_set_data(cmd_write, buf, len, offset);
+ if (rc < 0)
+ goto out;
+
+ rc = ndctl_cmd_submit(cmd_write);
+ if (rc || ndctl_cmd_get_firmware_status(cmd_write))
+ rc = -ENXIO;
+ out:
+ ndctl_cmd_unref(cmd_write);
+ return rc;
+}
+
+static int label_next_nsindex(int index)
+{
+ if (index < 0)
+ return -1;
+ return (index + 1) % 2;
+}
+
+static struct namespace_label *label_base(struct nvdimm_data *ndd)
+{
+ char *base = (char *) to_namespace_index(ndd, 0);
+
+ base += 2 * sizeof_namespace_index(ndd);
+ return (struct namespace_label *) base;
+}
+
+#define ALIGN(x, a) ((((unsigned long long) x) + (a - 1)) & ~(a - 1))
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
+static int label_write_index(struct nvdimm_data *ndd, int index, u32 seq)
+{
+ struct namespace_index *nsindex;
+ unsigned long offset;
+ u64 checksum;
+ u32 nslot;
+
+ nsindex = to_namespace_index(ndd, index);
+ nslot = nvdimm_num_label_slots(ndd);
+
+ memcpy(nsindex->sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN);
+ nsindex->flags = cpu_to_le32(0);
+ nsindex->seq = cpu_to_le32(seq);
+ offset = (unsigned long) nsindex
+ - (unsigned long) to_namespace_index(ndd, 0);
+ nsindex->myoff = cpu_to_le64(offset);
+ nsindex->mysize = cpu_to_le64(sizeof_namespace_index(ndd));
+ offset = (unsigned long) to_namespace_index(ndd,
+ label_next_nsindex(index))
+ - (unsigned long) to_namespace_index(ndd, 0);
+ nsindex->otheroff = cpu_to_le64(offset);
+ offset = (unsigned long) label_base(ndd)
+ - (unsigned long) to_namespace_index(ndd, 0);
+ nsindex->labeloff = cpu_to_le64(offset);
+ nsindex->nslot = cpu_to_le32(nslot);
+ nsindex->major = cpu_to_le16(1);
+ nsindex->minor = cpu_to_le16(1);
+ nsindex->checksum = cpu_to_le64(0);
+ /* init label bitmap */
+ memset(nsindex->free, 0xff, ALIGN(nslot, BITS_PER_LONG) / 8);
+ checksum = fletcher64(nsindex, sizeof_namespace_index(ndd), 1);
+ nsindex->checksum = cpu_to_le64(checksum);
+ return nvdimm_set_config_data(ndd, le64_to_cpu(nsindex->myoff),
+ nsindex, sizeof_namespace_index(ndd));
+}
+
static struct parameters {
const char *bus;
const char *outfile;
+ bool force;
bool json;
bool verbose;
} param;
+static int action_init(struct ndctl_dimm *dimm, struct action_context *actx)
+{
+ struct nvdimm_data __ndd, *ndd = &__ndd;
+ struct ndctl_cmd *cmd_read;
+ int rc = 0, i;
+ ssize_t size;
+
+ cmd_read = read_labels(dimm);
+ if (!cmd_read)
+ return -ENXIO;
+
+ size = ndctl_cmd_cfg_read_get_size(cmd_read);
+ ndd->data = malloc(size);
+ if (!ndd->data)
+ return -ENOMEM;
+ rc = ndctl_cmd_cfg_read_get_data(cmd_read, ndd->data, size, 0);
+ if (rc < 0)
+ goto out;
+
+ ndd->dimm = dimm;
+ ndd->cmd_read = cmd_read;
+ ndd->config_size = size;
+ ndd->nsindex_size = 0;
+ ndd->ns_current = -1;
+ ndd->ns_next = -1;
+ log_init(&ndd->ctx, ndctl_dimm_get_devname(dimm), "NDCTL_INIT_LABELS");
+ if (param.verbose)
+ ndd->ctx.log_priority = LOG_DEBUG;
+
+ /*
+ * If the region goes active after this point, i.e. we're racing
+ * another administrative action, the kernel will fail writes to
+ * the label area.
+ */
+ if (ndctl_dimm_is_active(dimm)) {
+ err(ndd, "regions active, abort label write\n");
+ rc = -EBUSY;
+ goto out;
+ }
+
+ if (label_validate(ndd) >= 0 && !param.force) {
+ err(ndd, "error: labels already initialized\n");
+ rc = -EBUSY;
+ goto out;
+ }
+
+ for (i = 0; i < 2; i++) {
+ rc = label_write_index(ndd, i, i*2);
+ if (rc)
+ goto out;
+ }
+
+ /*
+ * If the dimm is already disabled the kernel is not holding a cached
+ * copy of the label space.
+ */
+ if (!ndctl_dimm_is_enabled(dimm))
+ goto out;
+
+ rc = ndctl_dimm_disable(dimm);
+ if (rc)
+ goto out;
+ rc = ndctl_dimm_enable(dimm);
+
+ out:
+ ndctl_cmd_unref(cmd_read);
+ free(ndd->data);
+ return rc;
+}
+
#define BASE_OPTIONS() \
OPT_STRING('b', "bus", ¶m.bus, "bus-id", \
"<nmem> must be on a bus with an id/provider of <bus-id>"), \
@@ -361,6 +732,10 @@ OPT_STRING('o', NULL, ¶m.outfile, "output-file", \
"filename to write label area contents"), \
OPT_BOOLEAN('j', "json", ¶m.json, "parse label data into json")
+#define INIT_OPTIONS() \
+OPT_BOOLEAN('f', "force", ¶m.force, \
+ "force initialization even if existing index-block present")
+
static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -372,6 +747,12 @@ static const struct option base_options[] = {
OPT_END(),
};
+static const struct option init_options[] = {
+ BASE_OPTIONS(),
+ INIT_OPTIONS(),
+ OPT_END(),
+};
+
static int dimm_action(int argc, const char **argv, struct ndctl_ctx *ctx,
int (*action)(struct ndctl_dimm *dimm, struct action_context *actx),
const struct option *options, const char *usage)
@@ -536,6 +917,16 @@ int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
return count >= 0 ? 0 : EXIT_FAILURE;
}
+int cmd_init_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
+{
+ int count = dimm_action(argc, argv, ctx, action_init, init_options,
+ "ndctl init-labels <nmem0> [<nmem1>..<nmemN>] [<options>]");
+
+ fprintf(stderr, "initialized %d nmem%s\n", count >= 0 ? count : 0,
+ count > 1 ? "s" : "");
+ return count >= 0 ? 0 : EXIT_FAILURE;
+}
+
int cmd_disable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx)
{
int count = dimm_action(argc, argv, ctx, action_disable, base_options,
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index ec55865ecea8..efa90c0146ee 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -20,6 +20,7 @@ int cmd_enable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_disable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_read_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_init_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_list(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_help(int argc, const char **argv, struct ndctl_ctx *ctx);
#ifdef ENABLE_TEST
diff --git a/ndctl/ndctl.c b/ndctl/ndctl.c
index aaeb3f7c2bec..bdb17226f834 100644
--- a/ndctl/ndctl.c
+++ b/ndctl/ndctl.c
@@ -36,6 +36,7 @@ static struct cmd_struct commands[] = {
{ "disable-dimm", cmd_disable_dimm },
{ "zero-labels", cmd_zero_labels },
{ "read-labels", cmd_read_labels },
+ { "init-labels", cmd_init_labels },
{ "list", cmd_list },
{ "help", cmd_help },
#ifdef ENABLE_TEST
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [ndctl PATCH 8/8] ndctl: check-labels command
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
` (7 preceding siblings ...)
(?)
@ 2016-10-19 16:48 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 16:48 UTC (permalink / raw)
To: linux-nvdimm
Attempt to parse the namespace index block on a DIMM and return success
if it validates.
Running this command in verbose mode will report errors in the index
block.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
Documentation/Makefile.am | 1 +
Documentation/ndctl-check-labels.txt | 25 +++++++++++++++++++++++++
ndctl/builtin-dimm.c | 33 ++++++++++++++++++++++++++++++---
ndctl/builtin.h | 1 +
ndctl/ndctl.c | 1 +
5 files changed, 58 insertions(+), 3 deletions(-)
create mode 100644 Documentation/ndctl-check-labels.txt
diff --git a/Documentation/Makefile.am b/Documentation/Makefile.am
index 4448064dd1b9..adcc9e7dde8e 100644
--- a/Documentation/Makefile.am
+++ b/Documentation/Makefile.am
@@ -3,6 +3,7 @@ man1_MANS = \
ndctl-zero-labels.1 \
ndctl-read-labels.1 \
ndctl-init-labels.1 \
+ ndctl-check-labels.1 \
ndctl-enable-region.1 \
ndctl-disable-region.1 \
ndctl-enable-dimm.1 \
diff --git a/Documentation/ndctl-check-labels.txt b/Documentation/ndctl-check-labels.txt
new file mode 100644
index 000000000000..22d219cc9afd
--- /dev/null
+++ b/Documentation/ndctl-check-labels.txt
@@ -0,0 +1,25 @@
+ndctl-check-labels(1)
+====================
+
+NAME
+----
+ndctl-check-labels - determine if the given dimms have a valid namespace index block
+
+SYNOPSIS
+--------
+[verse]
+'ndctl check-labels' <nmem0> [<nmem1>..<nmemN>] [<options>]
+
+include::labels-description.txt[]
+In addition to checking if a label area has a valid index block, running
+this command in verbose mode reports the reason the index block is
+deemed invalid.
+
+OPTIONS
+-------
+include::labels-options.txt[]
+
+SEE ALSO
+--------
+http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf[NVDIMM Namespace
+Specification]
diff --git a/ndctl/builtin-dimm.c b/ndctl/builtin-dimm.c
index 399f0c32b816..304bd83a33da 100644
--- a/ndctl/builtin-dimm.c
+++ b/ndctl/builtin-dimm.c
@@ -652,7 +652,7 @@ static struct parameters {
bool verbose;
} param;
-static int action_init(struct ndctl_dimm *dimm, struct action_context *actx)
+static int __action_init(struct ndctl_dimm *dimm, int chk_only)
{
struct nvdimm_data __ndd, *ndd = &__ndd;
struct ndctl_cmd *cmd_read;
@@ -686,13 +686,19 @@ static int action_init(struct ndctl_dimm *dimm, struct action_context *actx)
* another administrative action, the kernel will fail writes to
* the label area.
*/
- if (ndctl_dimm_is_active(dimm)) {
+ if (!chk_only && ndctl_dimm_is_active(dimm)) {
err(ndd, "regions active, abort label write\n");
rc = -EBUSY;
goto out;
}
- if (label_validate(ndd) >= 0 && !param.force) {
+ rc = label_validate(ndd);
+ if (chk_only) {
+ rc = rc >= 0 ? 0 : -ENXIO;
+ goto out;
+ }
+
+ if (rc >= 0 && !param.force) {
err(ndd, "error: labels already initialized\n");
rc = -EBUSY;
goto out;
@@ -722,6 +728,17 @@ static int action_init(struct ndctl_dimm *dimm, struct action_context *actx)
return rc;
}
+static int action_init(struct ndctl_dimm *dimm, struct action_context *actx)
+{
+ return __action_init(dimm, 0);
+}
+
+static int action_check(struct ndctl_dimm *dimm, struct action_context *actx)
+{
+ return __action_init(dimm, 1);
+}
+
+
#define BASE_OPTIONS() \
OPT_STRING('b', "bus", ¶m.bus, "bus-id", \
"<nmem> must be on a bus with an id/provider of <bus-id>"), \
@@ -927,6 +944,16 @@ int cmd_init_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
return count >= 0 ? 0 : EXIT_FAILURE;
}
+int cmd_check_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
+{
+ int count = dimm_action(argc, argv, ctx, action_check, base_options,
+ "ndctl check-labels <nmem0> [<nmem1>..<nmemN>] [<options>]");
+
+ fprintf(stderr, "successfully verified %d nmem%s\n",
+ count >= 0 ? count : 0, count > 1 ? "s" : "");
+ return count >= 0 ? 0 : EXIT_FAILURE;
+}
+
int cmd_disable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx)
{
int count = dimm_action(argc, argv, ctx, action_disable, base_options,
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index efa90c0146ee..0293335c127e 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -21,6 +21,7 @@ int cmd_disable_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_read_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_init_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_check_labels(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_list(int argc, const char **argv, struct ndctl_ctx *ctx);
int cmd_help(int argc, const char **argv, struct ndctl_ctx *ctx);
#ifdef ENABLE_TEST
diff --git a/ndctl/ndctl.c b/ndctl/ndctl.c
index bdb17226f834..4f000fe51fae 100644
--- a/ndctl/ndctl.c
+++ b/ndctl/ndctl.c
@@ -37,6 +37,7 @@ static struct cmd_struct commands[] = {
{ "zero-labels", cmd_zero_labels },
{ "read-labels", cmd_read_labels },
{ "init-labels", cmd_init_labels },
+ { "check-labels", cmd_check_labels },
{ "list", cmd_list },
{ "help", cmd_help },
#ifdef ENABLE_TEST
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [ndctl PATCH 0/8] dimm label space initialization support
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
@ 2016-10-19 18:42 ` Eric Blake
-1 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2016-10-19 18:42 UTC (permalink / raw)
To: Dan Williams, linux-nvdimm; +Cc: vishal.l.verma, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1269 bytes --]
On 10/19/2016 11:47 AM, Dan Williams wrote:
> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
> patch [1] on top of that baseline, the PMEM-sub-division support can be
> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
> PMEM regions and support for the label DSM commands [2].
>
> Given this increasing need to perform a label management operation
> across a set of DIMMs this update also adds glob(3) support. For
> example you can now write commands like:
>
> ndctl zero-labels nmem[2-4]
This is slightly scary, as it depends on the user not having any file
named nmem2, nmem3, or nmem4 in the current working directory. Your
example should probably encourage proper shell quoting, as in:
ndctl zero-labels 'nmem[2-4]'
>
> ...as a shorthand for:
>
> ndctl zero-labels nmem2 nmem3 nmem4
By the way, depending on the user's shell, they can already have
shorthand as in:
ndctl zero-labels nmem{2,3,4}
where the shell does the expansion instead of you having to do a glob
after the fact. Which makes me wonder if this syntactic sugar is worth
maintaining.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
@ 2016-10-19 18:42 ` Eric Blake
0 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2016-10-19 18:42 UTC (permalink / raw)
To: Dan Williams, linux-nvdimm; +Cc: vishal.l.verma, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1269 bytes --]
On 10/19/2016 11:47 AM, Dan Williams wrote:
> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
> patch [1] on top of that baseline, the PMEM-sub-division support can be
> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
> PMEM regions and support for the label DSM commands [2].
>
> Given this increasing need to perform a label management operation
> across a set of DIMMs this update also adds glob(3) support. For
> example you can now write commands like:
>
> ndctl zero-labels nmem[2-4]
This is slightly scary, as it depends on the user not having any file
named nmem2, nmem3, or nmem4 in the current working directory. Your
example should probably encourage proper shell quoting, as in:
ndctl zero-labels 'nmem[2-4]'
>
> ...as a shorthand for:
>
> ndctl zero-labels nmem2 nmem3 nmem4
By the way, depending on the user's shell, they can already have
shorthand as in:
ndctl zero-labels nmem{2,3,4}
where the shell does the expansion instead of you having to do a glob
after the fact. Which makes me wonder if this syntactic sugar is worth
maintaining.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
2016-10-19 18:42 ` [Qemu-devel] " Eric Blake
@ 2016-10-19 19:41 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 19:41 UTC (permalink / raw)
To: Eric Blake; +Cc: linux-nvdimm, qemu-devel-qX2TKyscuCcdnm+yROfE0A
On Wed, Oct 19, 2016 at 11:42 AM, Eric Blake <eblake-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On 10/19/2016 11:47 AM, Dan Williams wrote:
>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>> PMEM regions and support for the label DSM commands [2].
>>
>> Given this increasing need to perform a label management operation
>> across a set of DIMMs this update also adds glob(3) support. For
>> example you can now write commands like:
>>
>> ndctl zero-labels nmem[2-4]
>
> This is slightly scary, as it depends on the user not having any file
> named nmem2, nmem3, or nmem4 in the current working directory. Your
> example should probably encourage proper shell quoting, as in:
>
> ndctl zero-labels 'nmem[2-4]'
True. Although, the glob is run against the list of present device
names in the system, so local files named nmem should change the
operation of the command.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
@ 2016-10-19 19:41 ` Dan Williams
0 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 19:41 UTC (permalink / raw)
To: Eric Blake; +Cc: linux-nvdimm, Vishal L Verma, qemu-devel
On Wed, Oct 19, 2016 at 11:42 AM, Eric Blake <eblake@redhat.com> wrote:
> On 10/19/2016 11:47 AM, Dan Williams wrote:
>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>> PMEM regions and support for the label DSM commands [2].
>>
>> Given this increasing need to perform a label management operation
>> across a set of DIMMs this update also adds glob(3) support. For
>> example you can now write commands like:
>>
>> ndctl zero-labels nmem[2-4]
>
> This is slightly scary, as it depends on the user not having any file
> named nmem2, nmem3, or nmem4 in the current working directory. Your
> example should probably encourage proper shell quoting, as in:
>
> ndctl zero-labels 'nmem[2-4]'
True. Although, the glob is run against the list of present device
names in the system, so local files named nmem should change the
operation of the command.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
2016-10-19 19:41 ` Dan Williams
@ 2016-10-19 21:29 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 21:29 UTC (permalink / raw)
To: Eric Blake; +Cc: linux-nvdimm, qemu-devel-qX2TKyscuCcdnm+yROfE0A
On Wed, Oct 19, 2016 at 12:41 PM, Dan Williams <dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> wrote:
> On Wed, Oct 19, 2016 at 11:42 AM, Eric Blake <eblake-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>> On 10/19/2016 11:47 AM, Dan Williams wrote:
>>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>>> PMEM regions and support for the label DSM commands [2].
>>>
>>> Given this increasing need to perform a label management operation
>>> across a set of DIMMs this update also adds glob(3) support. For
>>> example you can now write commands like:
>>>
>>> ndctl zero-labels nmem[2-4]
>>
>> This is slightly scary, as it depends on the user not having any file
>> named nmem2, nmem3, or nmem4 in the current working directory. Your
>> example should probably encourage proper shell quoting, as in:
>>
>> ndctl zero-labels 'nmem[2-4]'
>
> True. Although, the glob is run against the list of present device
> names in the system, so local files named nmem should change the
> operation of the command.
s/should/shouldn't/
In any event I don't see the danger in leaving it in, and my fingers
default to [2-4] vs {2..4}.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
@ 2016-10-19 21:29 ` Dan Williams
0 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 21:29 UTC (permalink / raw)
To: Eric Blake; +Cc: linux-nvdimm, Vishal L Verma, qemu-devel
On Wed, Oct 19, 2016 at 12:41 PM, Dan Williams <dan.j.williams@intel.com> wrote:
> On Wed, Oct 19, 2016 at 11:42 AM, Eric Blake <eblake@redhat.com> wrote:
>> On 10/19/2016 11:47 AM, Dan Williams wrote:
>>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>>> PMEM regions and support for the label DSM commands [2].
>>>
>>> Given this increasing need to perform a label management operation
>>> across a set of DIMMs this update also adds glob(3) support. For
>>> example you can now write commands like:
>>>
>>> ndctl zero-labels nmem[2-4]
>>
>> This is slightly scary, as it depends on the user not having any file
>> named nmem2, nmem3, or nmem4 in the current working directory. Your
>> example should probably encourage proper shell quoting, as in:
>>
>> ndctl zero-labels 'nmem[2-4]'
>
> True. Although, the glob is run against the list of present device
> names in the system, so local files named nmem should change the
> operation of the command.
s/should/shouldn't/
In any event I don't see the danger in leaving it in, and my fingers
default to [2-4] vs {2..4}.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [ndctl PATCH 0/8] dimm label space initialization support
2016-10-19 21:29 ` Dan Williams
@ 2016-10-19 23:46 ` Eric Blake
-1 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2016-10-19 23:46 UTC (permalink / raw)
To: Dan Williams; +Cc: linux-nvdimm, qemu-devel, Vishal L Verma
[-- Attachment #1: Type: text/plain, Size: 2297 bytes --]
On 10/19/2016 04:29 PM, Dan Williams wrote:
> On Wed, Oct 19, 2016 at 12:41 PM, Dan Williams <dan.j.williams@intel.com> wrote:
>> On Wed, Oct 19, 2016 at 11:42 AM, Eric Blake <eblake@redhat.com> wrote:
>>> On 10/19/2016 11:47 AM, Dan Williams wrote:
>>>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>>>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>>>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>>>> PMEM regions and support for the label DSM commands [2].
>>>>
>>>> Given this increasing need to perform a label management operation
>>>> across a set of DIMMs this update also adds glob(3) support. For
>>>> example you can now write commands like:
>>>>
>>>> ndctl zero-labels nmem[2-4]
>>>
>>> This is slightly scary, as it depends on the user not having any file
>>> named nmem2, nmem3, or nmem4 in the current working directory. Your
>>> example should probably encourage proper shell quoting, as in:
>>>
>>> ndctl zero-labels 'nmem[2-4]'
>>
>> True. Although, the glob is run against the list of present device
>> names in the system, so local files named nmem should change the
>> operation of the command.
>
> s/should/shouldn't/
You didn't get my complaint. So let me demonstrate, using echo instead
of ndctl:
$ mkdir /tmp/foo
$ cd /tmp/foo
$ echo nmem[2-4]
nmem[2-4]
$ touch nmem3 nmem4
$ echo nmem[2-4]
nmem3 nmem4
$ echo 'nmem[2-4]'
nmem[2-4]
The problem is that the glob is liable to pre-expansion by the shell
UNLESS the user quotes the glob; meaning that the current working
directory controls whether ndctl even sees a glob in the first place.
If you are going to support globbing in ndctl out of laziness (since it
is indeed fewer characters to type [2-4] than it is to type {2..4}, plus
{2..4} is not supported by all shells), then you HAVE to document that
the user is responsible for quoting (omitting quoting usually does what
you want). But by the time you quote to get the glob down to ndctl,
'[2-4]' is more typing than {2..4} expanded by the shell, at which point
were you really being lazy by adding globbing?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
@ 2016-10-19 23:46 ` Eric Blake
0 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2016-10-19 23:46 UTC (permalink / raw)
To: Dan Williams; +Cc: linux-nvdimm, Vishal L Verma, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2297 bytes --]
On 10/19/2016 04:29 PM, Dan Williams wrote:
> On Wed, Oct 19, 2016 at 12:41 PM, Dan Williams <dan.j.williams@intel.com> wrote:
>> On Wed, Oct 19, 2016 at 11:42 AM, Eric Blake <eblake@redhat.com> wrote:
>>> On 10/19/2016 11:47 AM, Dan Williams wrote:
>>>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>>>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>>>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>>>> PMEM regions and support for the label DSM commands [2].
>>>>
>>>> Given this increasing need to perform a label management operation
>>>> across a set of DIMMs this update also adds glob(3) support. For
>>>> example you can now write commands like:
>>>>
>>>> ndctl zero-labels nmem[2-4]
>>>
>>> This is slightly scary, as it depends on the user not having any file
>>> named nmem2, nmem3, or nmem4 in the current working directory. Your
>>> example should probably encourage proper shell quoting, as in:
>>>
>>> ndctl zero-labels 'nmem[2-4]'
>>
>> True. Although, the glob is run against the list of present device
>> names in the system, so local files named nmem should change the
>> operation of the command.
>
> s/should/shouldn't/
You didn't get my complaint. So let me demonstrate, using echo instead
of ndctl:
$ mkdir /tmp/foo
$ cd /tmp/foo
$ echo nmem[2-4]
nmem[2-4]
$ touch nmem3 nmem4
$ echo nmem[2-4]
nmem3 nmem4
$ echo 'nmem[2-4]'
nmem[2-4]
The problem is that the glob is liable to pre-expansion by the shell
UNLESS the user quotes the glob; meaning that the current working
directory controls whether ndctl even sees a glob in the first place.
If you are going to support globbing in ndctl out of laziness (since it
is indeed fewer characters to type [2-4] than it is to type {2..4}, plus
{2..4} is not supported by all shells), then you HAVE to document that
the user is responsible for quoting (omitting quoting usually does what
you want). But by the time you quote to get the glob down to ndctl,
'[2-4]' is more typing than {2..4} expanded by the shell, at which point
were you really being lazy by adding globbing?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
2016-10-19 23:46 ` [Qemu-devel] " Eric Blake
@ 2016-10-19 23:56 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 23:56 UTC (permalink / raw)
To: Eric Blake; +Cc: linux-nvdimm, qemu-devel-qX2TKyscuCcdnm+yROfE0A
On Wed, Oct 19, 2016 at 4:46 PM, Eric Blake <eblake-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On 10/19/2016 04:29 PM, Dan Williams wrote:
>> On Wed, Oct 19, 2016 at 12:41 PM, Dan Williams <dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> wrote:
>>> On Wed, Oct 19, 2016 at 11:42 AM, Eric Blake <eblake-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>>> On 10/19/2016 11:47 AM, Dan Williams wrote:
>>>>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>>>>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>>>>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>>>>> PMEM regions and support for the label DSM commands [2].
>>>>>
>>>>> Given this increasing need to perform a label management operation
>>>>> across a set of DIMMs this update also adds glob(3) support. For
>>>>> example you can now write commands like:
>>>>>
>>>>> ndctl zero-labels nmem[2-4]
>>>>
>>>> This is slightly scary, as it depends on the user not having any file
>>>> named nmem2, nmem3, or nmem4 in the current working directory. Your
>>>> example should probably encourage proper shell quoting, as in:
>>>>
>>>> ndctl zero-labels 'nmem[2-4]'
>>>
>>> True. Although, the glob is run against the list of present device
>>> names in the system, so local files named nmem should change the
>>> operation of the command.
>>
>> s/should/shouldn't/
>
> You didn't get my complaint. So let me demonstrate, using echo instead
> of ndctl:
>
> $ mkdir /tmp/foo
> $ cd /tmp/foo
> $ echo nmem[2-4]
> nmem[2-4]
> $ touch nmem3 nmem4
> $ echo nmem[2-4]
> nmem3 nmem4
> $ echo 'nmem[2-4]'
> nmem[2-4]
>
> The problem is that the glob is liable to pre-expansion by the shell
> UNLESS the user quotes the glob; meaning that the current working
> directory controls whether ndctl even sees a glob in the first place.
> If you are going to support globbing in ndctl out of laziness (since it
> is indeed fewer characters to type [2-4] than it is to type {2..4}, plus
> {2..4} is not supported by all shells), then you HAVE to document that
> the user is responsible for quoting (omitting quoting usually does what
> you want). But by the time you quote to get the glob down to ndctl,
> '[2-4]' is more typing than {2..4} expanded by the shell, at which point
> were you really being lazy by adding globbing?
Ah true, and I agree not worth it to document the need to add quoting
versus just relying on shells to do expansion.
Thanks for the feedback, I'll rip that glob support out.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
@ 2016-10-19 23:56 ` Dan Williams
0 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-19 23:56 UTC (permalink / raw)
To: Eric Blake; +Cc: linux-nvdimm, Vishal L Verma, qemu-devel
On Wed, Oct 19, 2016 at 4:46 PM, Eric Blake <eblake@redhat.com> wrote:
> On 10/19/2016 04:29 PM, Dan Williams wrote:
>> On Wed, Oct 19, 2016 at 12:41 PM, Dan Williams <dan.j.williams@intel.com> wrote:
>>> On Wed, Oct 19, 2016 at 11:42 AM, Eric Blake <eblake@redhat.com> wrote:
>>>> On 10/19/2016 11:47 AM, Dan Williams wrote:
>>>>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>>>>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>>>>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>>>>> PMEM regions and support for the label DSM commands [2].
>>>>>
>>>>> Given this increasing need to perform a label management operation
>>>>> across a set of DIMMs this update also adds glob(3) support. For
>>>>> example you can now write commands like:
>>>>>
>>>>> ndctl zero-labels nmem[2-4]
>>>>
>>>> This is slightly scary, as it depends on the user not having any file
>>>> named nmem2, nmem3, or nmem4 in the current working directory. Your
>>>> example should probably encourage proper shell quoting, as in:
>>>>
>>>> ndctl zero-labels 'nmem[2-4]'
>>>
>>> True. Although, the glob is run against the list of present device
>>> names in the system, so local files named nmem should change the
>>> operation of the command.
>>
>> s/should/shouldn't/
>
> You didn't get my complaint. So let me demonstrate, using echo instead
> of ndctl:
>
> $ mkdir /tmp/foo
> $ cd /tmp/foo
> $ echo nmem[2-4]
> nmem[2-4]
> $ touch nmem3 nmem4
> $ echo nmem[2-4]
> nmem3 nmem4
> $ echo 'nmem[2-4]'
> nmem[2-4]
>
> The problem is that the glob is liable to pre-expansion by the shell
> UNLESS the user quotes the glob; meaning that the current working
> directory controls whether ndctl even sees a glob in the first place.
> If you are going to support globbing in ndctl out of laziness (since it
> is indeed fewer characters to type [2-4] than it is to type {2..4}, plus
> {2..4} is not supported by all shells), then you HAVE to document that
> the user is responsible for quoting (omitting quoting usually does what
> you want). But by the time you quote to get the glob down to ndctl,
> '[2-4]' is more typing than {2..4} expanded by the shell, at which point
> were you really being lazy by adding globbing?
Ah true, and I agree not worth it to document the need to add quoting
versus just relying on shells to do expansion.
Thanks for the feedback, I'll rip that glob support out.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [ndctl PATCH 0/8] dimm label space initialization support
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
@ 2016-10-20 19:32 ` Vishal Verma
-1 siblings, 0 replies; 25+ messages in thread
From: Vishal Verma @ 2016-10-20 19:32 UTC (permalink / raw)
To: Dan Williams; +Cc: qemu-devel, linux-nvdimm
On 10/19, Dan Williams wrote:
> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
> patch [1] on top of that baseline, the PMEM-sub-division support can be
> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
> PMEM regions and support for the label DSM commands [2].
>
> Given this increasing need to perform a label management operation
> across a set of DIMMs this update also adds glob(3) support. For
> example you can now write commands like:
>
> ndctl zero-labels nmem[2-4]
>
> ...as a shorthand for:
>
> ndctl zero-labels nmem2 nmem3 nmem4
>
> This support extends to all the commands that take an undecorated dimm /
> nmem device as a parameter:
>
> disable-dimm
> enable-dimm
> read-labels
> zero-labels
> init-labels
> check-labels
>
> The patch "libndctl: fix error returns for unsigned apis" was something
> noticed while developing "init-labels", but is otherwise unrelated to
> the rest of the set.
>
> [1]: https://patchwork.kernel.org/patch/9384741/
> [2]: http://pmem.io/documents/NVDIMM_DSM_Interface_Example-V1.2.pdf
>
> ---
>
> Dan Williams (8):
> libndctl: fix error returns for unsigned apis
> ndctl: consolidate label commands into a single file
> ndctl: glob support for label commands
> ndctl: merge {enable,disable}-dimm with label commands
> libndctl: add ndctl_cmd_cfg_read_get_size()
> ndctl: provide a read_labels() helper
> ndctl: init-labels command
> ndctl: check-labels command
>
Hi Dan,
Here is the bash completion patch for the new commands:
8<-----
>From 53e3090ecd124562540bb25948783c33d9390112 Mon Sep 17 00:00:00 2001
From: Vishal Verma <vishal.l.verma@intel.com>
Date: Thu, 20 Oct 2016 13:29:03 -0600
Subject: [PATCH] ndctl: bash completion for {init, check}-labels
Add bash completion for the new init-labels and check-labels commands.
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
contrib/ndctl | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/contrib/ndctl b/contrib/ndctl
index 2c04504..ea7303c 100755
--- a/contrib/ndctl
+++ b/contrib/ndctl
@@ -206,6 +206,10 @@ __ndctl_comp_non_option_args()
disable-dimm)
opts="$(__ndctl_get_dimms) all"
;;
+ init-labels)
+ ;&
+ check-labels)
+ ;&
read-labels)
;&
zero-labels)
--
2.7.4
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
@ 2016-10-20 19:32 ` Vishal Verma
0 siblings, 0 replies; 25+ messages in thread
From: Vishal Verma @ 2016-10-20 19:32 UTC (permalink / raw)
To: Dan Williams; +Cc: linux-nvdimm, qemu-devel
On 10/19, Dan Williams wrote:
> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
> patch [1] on top of that baseline, the PMEM-sub-division support can be
> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
> PMEM regions and support for the label DSM commands [2].
>
> Given this increasing need to perform a label management operation
> across a set of DIMMs this update also adds glob(3) support. For
> example you can now write commands like:
>
> ndctl zero-labels nmem[2-4]
>
> ...as a shorthand for:
>
> ndctl zero-labels nmem2 nmem3 nmem4
>
> This support extends to all the commands that take an undecorated dimm /
> nmem device as a parameter:
>
> disable-dimm
> enable-dimm
> read-labels
> zero-labels
> init-labels
> check-labels
>
> The patch "libndctl: fix error returns for unsigned apis" was something
> noticed while developing "init-labels", but is otherwise unrelated to
> the rest of the set.
>
> [1]: https://patchwork.kernel.org/patch/9384741/
> [2]: http://pmem.io/documents/NVDIMM_DSM_Interface_Example-V1.2.pdf
>
> ---
>
> Dan Williams (8):
> libndctl: fix error returns for unsigned apis
> ndctl: consolidate label commands into a single file
> ndctl: glob support for label commands
> ndctl: merge {enable,disable}-dimm with label commands
> libndctl: add ndctl_cmd_cfg_read_get_size()
> ndctl: provide a read_labels() helper
> ndctl: init-labels command
> ndctl: check-labels command
>
Hi Dan,
Here is the bash completion patch for the new commands:
8<-----
>From 53e3090ecd124562540bb25948783c33d9390112 Mon Sep 17 00:00:00 2001
From: Vishal Verma <vishal.l.verma@intel.com>
Date: Thu, 20 Oct 2016 13:29:03 -0600
Subject: [PATCH] ndctl: bash completion for {init, check}-labels
Add bash completion for the new init-labels and check-labels commands.
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
contrib/ndctl | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/contrib/ndctl b/contrib/ndctl
index 2c04504..ea7303c 100755
--- a/contrib/ndctl
+++ b/contrib/ndctl
@@ -206,6 +206,10 @@ __ndctl_comp_non_option_args()
disable-dimm)
opts="$(__ndctl_get_dimms) all"
;;
+ init-labels)
+ ;&
+ check-labels)
+ ;&
read-labels)
;&
zero-labels)
--
2.7.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [ndctl PATCH 0/8] dimm label space initialization support
2016-10-20 19:32 ` [Qemu-devel] " Vishal Verma
@ 2016-10-20 20:06 ` Dan Williams
-1 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-20 20:06 UTC (permalink / raw)
To: Vishal Verma; +Cc: qemu-devel, linux-nvdimm@lists.01.org
On Thu, Oct 20, 2016 at 12:32 PM, Vishal Verma <vishal.l.verma@intel.com> wrote:
> On 10/19, Dan Williams wrote:
>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>> PMEM regions and support for the label DSM commands [2].
>>
>> Given this increasing need to perform a label management operation
>> across a set of DIMMs this update also adds glob(3) support. For
>> example you can now write commands like:
>>
>> ndctl zero-labels nmem[2-4]
>>
>> ...as a shorthand for:
>>
>> ndctl zero-labels nmem2 nmem3 nmem4
>>
>> This support extends to all the commands that take an undecorated dimm /
>> nmem device as a parameter:
>>
>> disable-dimm
>> enable-dimm
>> read-labels
>> zero-labels
>> init-labels
>> check-labels
>>
>> The patch "libndctl: fix error returns for unsigned apis" was something
>> noticed while developing "init-labels", but is otherwise unrelated to
>> the rest of the set.
>>
>> [1]: https://patchwork.kernel.org/patch/9384741/
>> [2]: http://pmem.io/documents/NVDIMM_DSM_Interface_Example-V1.2.pdf
>>
>> ---
>>
>> Dan Williams (8):
>> libndctl: fix error returns for unsigned apis
>> ndctl: consolidate label commands into a single file
>> ndctl: glob support for label commands
>> ndctl: merge {enable,disable}-dimm with label commands
>> libndctl: add ndctl_cmd_cfg_read_get_size()
>> ndctl: provide a read_labels() helper
>> ndctl: init-labels command
>> ndctl: check-labels command
>>
>
> Hi Dan,
>
> Here is the bash completion patch for the new commands:
>
> 8<-----
>
>
> From 53e3090ecd124562540bb25948783c33d9390112 Mon Sep 17 00:00:00 2001
> From: Vishal Verma <vishal.l.verma@intel.com>
> Date: Thu, 20 Oct 2016 13:29:03 -0600
> Subject: [PATCH] ndctl: bash completion for {init, check}-labels
>
> Add bash completion for the new init-labels and check-labels commands.
>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
> ---
> contrib/ndctl | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/contrib/ndctl b/contrib/ndctl
> index 2c04504..ea7303c 100755
> --- a/contrib/ndctl
> +++ b/contrib/ndctl
> @@ -206,6 +206,10 @@ __ndctl_comp_non_option_args()
> disable-dimm)
> opts="$(__ndctl_get_dimms) all"
> ;;
> + init-labels)
> + ;&
> + check-labels)
> + ;&
> read-labels)
> ;&
> zero-labels)
Thanks, applied.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [Qemu-devel] [ndctl PATCH 0/8] dimm label space initialization support
@ 2016-10-20 20:06 ` Dan Williams
0 siblings, 0 replies; 25+ messages in thread
From: Dan Williams @ 2016-10-20 20:06 UTC (permalink / raw)
To: Vishal Verma; +Cc: linux-nvdimm@lists.01.org, qemu-devel
On Thu, Oct 20, 2016 at 12:32 PM, Vishal Verma <vishal.l.verma@intel.com> wrote:
> On 10/19, Dan Williams wrote:
>> The 4.9 kernel added support for sub-dividing PMEM. With this kernel
>> patch [1] on top of that baseline, the PMEM-sub-division support can be
>> enabled for QEMU-KVM and any other platforms that advertise both un-aliased
>> PMEM regions and support for the label DSM commands [2].
>>
>> Given this increasing need to perform a label management operation
>> across a set of DIMMs this update also adds glob(3) support. For
>> example you can now write commands like:
>>
>> ndctl zero-labels nmem[2-4]
>>
>> ...as a shorthand for:
>>
>> ndctl zero-labels nmem2 nmem3 nmem4
>>
>> This support extends to all the commands that take an undecorated dimm /
>> nmem device as a parameter:
>>
>> disable-dimm
>> enable-dimm
>> read-labels
>> zero-labels
>> init-labels
>> check-labels
>>
>> The patch "libndctl: fix error returns for unsigned apis" was something
>> noticed while developing "init-labels", but is otherwise unrelated to
>> the rest of the set.
>>
>> [1]: https://patchwork.kernel.org/patch/9384741/
>> [2]: http://pmem.io/documents/NVDIMM_DSM_Interface_Example-V1.2.pdf
>>
>> ---
>>
>> Dan Williams (8):
>> libndctl: fix error returns for unsigned apis
>> ndctl: consolidate label commands into a single file
>> ndctl: glob support for label commands
>> ndctl: merge {enable,disable}-dimm with label commands
>> libndctl: add ndctl_cmd_cfg_read_get_size()
>> ndctl: provide a read_labels() helper
>> ndctl: init-labels command
>> ndctl: check-labels command
>>
>
> Hi Dan,
>
> Here is the bash completion patch for the new commands:
>
> 8<-----
>
>
> From 53e3090ecd124562540bb25948783c33d9390112 Mon Sep 17 00:00:00 2001
> From: Vishal Verma <vishal.l.verma@intel.com>
> Date: Thu, 20 Oct 2016 13:29:03 -0600
> Subject: [PATCH] ndctl: bash completion for {init, check}-labels
>
> Add bash completion for the new init-labels and check-labels commands.
>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
> ---
> contrib/ndctl | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/contrib/ndctl b/contrib/ndctl
> index 2c04504..ea7303c 100755
> --- a/contrib/ndctl
> +++ b/contrib/ndctl
> @@ -206,6 +206,10 @@ __ndctl_comp_non_option_args()
> disable-dimm)
> opts="$(__ndctl_get_dimms) all"
> ;;
> + init-labels)
> + ;&
> + check-labels)
> + ;&
> read-labels)
> ;&
> zero-labels)
Thanks, applied.
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2016-10-20 20:07 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-10-19 16:47 [ndctl PATCH 0/8] dimm label space initialization support Dan Williams
2016-10-19 16:47 ` [Qemu-devel] " Dan Williams
2016-10-19 16:47 ` [ndctl PATCH 1/8] libndctl: fix error returns for unsigned apis Dan Williams
2016-10-19 16:47 ` [ndctl PATCH 2/8] ndctl: consolidate label commands into a single file Dan Williams
2016-10-19 16:48 ` [ndctl PATCH 3/8] ndctl: glob support for label commands Dan Williams
2016-10-19 16:48 ` [ndctl PATCH 4/8] ndctl: merge {enable, disable}-dimm with " Dan Williams
2016-10-19 16:48 ` [ndctl PATCH 5/8] libndctl: add ndctl_cmd_cfg_read_get_size() Dan Williams
2016-10-19 16:48 ` [ndctl PATCH 6/8] ndctl: provide a read_labels() helper Dan Williams
2016-10-19 16:48 ` [ndctl PATCH 7/8] ndctl: init-labels command Dan Williams
2016-10-19 16:48 ` [Qemu-devel] " Dan Williams
2016-10-19 16:48 ` [ndctl PATCH 8/8] ndctl: check-labels command Dan Williams
2016-10-19 18:42 ` [ndctl PATCH 0/8] dimm label space initialization support Eric Blake
2016-10-19 18:42 ` [Qemu-devel] " Eric Blake
[not found] ` <6ceb7075-71fc-b725-8a1c-a7d8c727770e-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-19 19:41 ` Dan Williams
2016-10-19 19:41 ` Dan Williams
[not found] ` <CAPcyv4gbRE-ALJM6EHv6fM3Kq02HeZFMLF5T63J5qaJmHWvQCg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-10-19 21:29 ` Dan Williams
2016-10-19 21:29 ` Dan Williams
2016-10-19 23:46 ` Eric Blake
2016-10-19 23:46 ` [Qemu-devel] " Eric Blake
[not found] ` <708947f5-dfdc-d6c9-4523-7436959119f3-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-19 23:56 ` Dan Williams
2016-10-19 23:56 ` Dan Williams
2016-10-20 19:32 ` Vishal Verma
2016-10-20 19:32 ` [Qemu-devel] " Vishal Verma
2016-10-20 20:06 ` Dan Williams
2016-10-20 20:06 ` [Qemu-devel] " Dan Williams
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.