};
const char *output_format = "Output format: normal|json|binary";
+const char *namespace_id = "Identifier of desired namespace";
/* Name of file to output log pages in their raw format */
static char *raw;
static int get_endurance_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- struct nvme_endurance_group_log log;
const char *desc = "Retrieves endurance groups log page and prints the log.";
const char *group_id = "The endurance group identifier";
+
+ struct nvme_endurance_group_log log;
enum nvme_print_flags flags;
int err, fd;
static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- struct nvme_ns_list ns_list;
- const char *desc = "Retrieve Changed Namespaces log for the given device "\
- "in either decoded format "\
- "(default) or binary.";
+ const char *desc = "Retrieve Changed Namespaces log for the given device";
const char *raw = "output in binary format";
+
+ struct nvme_ns_list ns_list;
enum nvme_print_flags flags;
int err, fd;
{
const char *desc = "For the specified controller handle, show the "\
"namespace list in the associated NVMe subsystem, optionally starting with a given nsid.";
- const char *namespace_id = "first nsid returned list should start from";
+ const char *namespace_id = "list's first nsid should start from";
const char *all = "show all namespaces in the subsystem, whether attached or inactive";
enum nvme_print_flags flags;
int err, fd;
"given device, returns the namespace identification descriptors "\
"of the specific namespace in either human-readable or binary format.";
const char *raw = "show descriptors in binary format";
- const char *namespace_id = "identifier of desired namespace";
enum nvme_print_flags flags;
void *nsdescs;
int err, fd;
const char *vendor_specific = "dump binary vendor fields";
const char *raw = "show identify in binary format";
const char *human_readable = "show identify in readable format";
- const char *namespace_id = "identifier of desired namespace";
enum nvme_print_flags flags;
struct nvme_id_ns ns;
{
const char *desc = "Implementing the device self-test feature"\
" which provides the necessary log to determine the state of the device";
- const char *namespace_id = "Indicate the namespace in which the device self-test"\
- " has to be carried out";
+ const char *namespace_id = "Indicate the namespace the for the device self-test";
const char * self_test_code = "This field specifies the action taken by the device self-test command : "\
"\n1h Start a short device self-test operation\n"\
"2h Start a extended device self-test operation\n"\
const char *desc = "Retrieve the self-test log for the given device and given test "\
"(or optionally a namespace) in either decoded format "\
"(default) or binary.";
- const char *namespace_id = "Indicate the namespace from which the self-test "\
- "log has to be obtained";
+ const char *namespace_id = "The namespace for the self-test log namespace";
const char *verbose = "Increase output verbosity";
struct nvme_self_test_log log;
"are vendor-specific and not changeable. Use set-feature to "\
"change saveable Features.";
const char *raw = "show feature in binary format";
- const char *namespace_id = "identifier of desired namespace";
const char *feature_id = "feature identifier";
const char *sel = "[0-3]: current/default/saved/supported";
const char *data_len = "buffer len if data is returned through host memory buffer";
"given device. Can erase all data in namespace (user "\
"data erase) or delete data encryption key if specified. "\
"Can also be used to change LBAF to change the namespaces reported physical block format.";
- const char *namespace_id = "identifier of desired namespace";
const char *lbaf = "LBA format to apply (required)";
const char *ses = "[0-2]: secure erase";
const char *pil = "[0-1]: protection info location last/first 8 bytes of metadata";
"for each Feature are vendor-specific and may not be modified."\
"Use get-feature to determine which Features are supported by "\
"the controller and are saveable/changeable.";
- const char *namespace_id = "desired namespace";
const char *feature_id = "feature identifier (required)";
const char *data_len = "buffer length if data required";
const char *data = "optional file for feature data (default stdin)";
const char *secp = "security protocol (cf. SPC-4)";
const char *spsp = "security-protocol-specific (cf. SPC-4)";
const char *tl = "transfer length (cf. SPC-4)";
- const char *namespace_id = "desired namespace";
const char *nssf = "NVMe Security Specific Field";
int err, fd, sec_fd = -1;
void *sec_buf;
const char *desc = "Set directive parameters of the "\
"specified directive type.";
const char *raw = "show directive in binary format";
- const char *namespace_id = "identifier of desired namespace";
const char *data_len = "buffer len (if) data is returned";
const char *dtype = "directive type";
const char *dspec = "directive specification associated with directive type";
int err, fd;
const char *desc = "The Write Uncorrectable command is used to set a "\
"range of logical blocks to invalid.";
- const char *namespace_id = "desired namespace";
const char *start_block = "64-bit LBA of first block to access";
const char *block_count = "number of blocks (zeroes based) on device to access";
__u16 control = 0;
const char *desc = "The Write Zeroes command is used to set a "\
"range of logical blocks to zero.";
- const char *namespace_id = "desired namespace";
const char *start_block = "64-bit LBA of first block to access";
const char *block_count = "number of blocks (zeroes based) on device to access";
const char *limited_retry = "limit media access attempts";
"indicate attributes for ranges of logical blocks. This includes attributes "\
"for discarding unused blocks, data read and write frequency, access size, and other "\
"information that may be used to optimize performance and reliability.";
- const char *namespace_id = "identifier of desired namespace";
const char *blocks = "Comma separated list of the number of blocks in each range";
const char *starting_blocks = "Comma separated list of the starting block in each range";
const char *context_attrs = "Comma separated list of the context attributes in each range";
"finished before the flush was submitted. Additional data may also be "\
"flushed by the controller, from any namespace, depending on controller and "\
"associated namespace status.";
- const char *namespace_id = "identifier of desired namespace";
int err, fd;
struct config {
"with that namespace. Namespace reservation will abort with "\
"status Reservation Conflict if the given namespace is "\
"already reserved.";
- const char *namespace_id = "identifier of desired namespace";
const char *crkey = "current reservation key";
const char *prkey = "pre-empt reservation key";
const char *rtype = "reservation type";
const char *desc = "Register, de-register, or "\
"replace a controller's reservation on a given namespace. "\
"Only one reservation at a time is allowed on any namespace.";
- const char *namespace_id = "identifier of desired namespace";
const char *crkey = "current reservation key";
const char *iekey = "ignore existing res. key";
const char *nrkey = "new reservation key";
"effect. If the reservation type is not Write Exclusive or "\
"Exclusive Access, all registrants on the namespace except "\
"the issuing controller are notified.";
- const char *namespace_id = "desired namespace";
const char *crkey = "current reservation key";
const char *iekey = "ignore existing res. key";
const char *rtype = "reservation type";
"status of a given namespace. Namespace Reservation Status "\
"depends on the number of controllers registered for that "\
"namespace.";
- const char *namespace_id = "identifier of desired namespace";
const char *s = "number of bytes to transfer";
const char *eds = "request extended data structure";
const char *raw = "dump output in binary format";
const char *dtype = "directive type (for write-only)";
const char *dspec = "directive specific (for write-only)";
const char *dsm = "dataset management attributes (lower 16 bits)";
- const char *namespace_id = "desired namespace";
struct config {
__u64 start_block;
int err, fd;
__u16 control = 0;
const char *desc = "Verify specified logical blocks on the given device.";
- const char *namespace_id = "desired namespace";
const char *start_block = "64-bit LBA of first block to access";
const char *block_count = "number of blocks (zeroes based) on device to access";
const char *limited_retry = "limit media access attempts";
const char *spsp = "security-protocol-specific (cf. SPC-4)";
const char *al = "allocation length (cf. SPC-4)";
const char *raw = "dump output in binary format";
- const char *namespace_id = "desired namespace";
const char *nssf = "NVMe Security Specific Field";
int err, fd;
void *sec_buf = NULL;
const char *desc = "Read directive parameters of the "\
"specified directive type.";
const char *raw = "show directive in binary format";
- const char *namespace_id = "identifier of desired namespace";
const char *data_len = "buffer len (if) data is returned";
const char *dtype = "directive type";
const char *dspec = "directive specification associated with directive type";
const char *opcode = "opcode (required)";
const char *flags = "command flags";
const char *rsvd = "value for reserved field";
- const char *namespace_id = "desired namespace";
const char *data_len = "data I/O length (bytes)";
const char *metadata_len = "metadata seg. length (bytes)";
const char *timeout = "timeout value, in milliseconds";
#define VERBOSE (NVME_JSON_DECODE_COMPLEX|NVME_JSON_HUMAN)
extern const char *output_format;
+extern const char *namespace_id;
void register_extension(struct plugin *plugin);
int parse_and_open(int argc, char **argv, const char *desc,
const char *desc = "Send ZNS specific Identify Namespace command to "\
"the given device and report information about the specified "\
"namespace in varios formats.";
- const char *namespace_id = "identifier of desired namespace";
const char *verbose = "verbosely decode fields";
enum nvme_print_flags flags;
const char *desc, enum nvme_zns_send_action zsa)
{
const char *zslba = "starting lba of the zone for this command";
- const char *namespace_id = "identifier of desired namespace";
const char *select_all = "send command to all zones";
int err, fd;
{
const char *desc = "Zone Management Send";
const char *zslba = "starting lba of the zone for this command";
- const char *namespace_id = "identifier of desired namespace";
const char *select_all = "send command to all zones";
const char *zsa = "zone send action";
const char *data_len = "buffer length if data required";
{
const char *desc = "Set Zone Descriptor Extension\n";
const char *zslba = "starting lba of the zone for this command";
- const char *namespace_id = "identifier of desired namespace";
const char *data = "optional file for zone extention data (default stdin)";
int fd, ffd = STDIN_FILENO, err;
goto close_fd;
}
- buf = malloc(data_len);
+ buf = calloc(1, data_len);
if (!buf) {
err = -1;
goto close_fd;
static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- return 0;
+ const char *desc = "Zone Management Receive";
+
+ enum nvme_print_flags flags;
+ int fd, err = -1;
+ void *data = NULL;
+
+ struct config {
+ char *output_format;
+ __u64 zslba;
+ __u32 namespace_id;
+ __u16 zra;
+ __u16 zrasf;
+ bool zrass;
+ __u32 data_len;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
+
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
+
+ fd = parse_and_open(argc, argv, desc, opts);
+ if (fd < 0)
+ return errno;
+
+ flags = validate_output_format(cfg.output_format);
+ if (flags < 0)
+ goto close_fd;
+
+ if (!cfg.namespace_id) {
+ err = nvme_get_nsid(fd, &cfg.namespace_id);
+ if (err < 0) {
+ perror("get-namespace-id");
+ goto close_fd;
+ }
+ }
+
+ if (cfg.data_len) {
+ data = calloc(1, cfg.data_len);
+ if (!data) {
+ err = -1;
+ goto close_fd;
+ }
+ }
+
+ err = nvme_zns_mgmt_recv(fd, cfg.namespace_id, cfg.zslba, cfg.zra,
+ cfg.zrasf, cfg.zrass, cfg.data_len, data);
+ if (!err)
+ printf("zone-mgmt-recv: Success, action:%d zone:%"PRIx64" nsid:%d\n",
+ cfg.zra, (uint64_t)cfg.zslba, cfg.namespace_id);
+ else
+ nvme_show_status("zone-mgmt-recv", err);
+
+ if (data)
+ free(data);
+close_fd:
+ close(fd);
+ return nvme_status_to_errno(err, false);
}
static int get_zdes(int fd, __u32 nsid)
const char *ext = "set to use the extended report zones";
const char *part = "set to use the partial report";
const char *verbose = "verbosely decode fields";
- const char *namespace_id = "identifier of desired namespace";
-
+
enum nvme_print_flags flags;
int fd, zdes = 0, err = -1;
__u32 report_size;
bool extended;
bool partial;
};
-
+
struct config cfg = {
.output_format = "normal",
};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba),
- OPT_UINT("descs", 'd', &cfg.num_descs, num_descs),
- OPT_UINT("state", 'S', &cfg.state, state),
+ OPT_UINT("descs", 'd', &cfg.num_descs, num_descs),
+ OPT_UINT("state", 'S', &cfg.state, state),
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
OPT_FLAG("extended", 'e', &cfg.extended, ext),
report = nvme_alloc(report_size, &huge);
if (!report) {
- perror("malloc");
+ perror("alloc");
err = -1;
goto close_fd;
}
static int change_zone_list(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- return 0;
+ const char *desc = "Retrieve Changed Zone log for the given device";
+ const char *rae = "retain an asynchronous event";
+
+ struct nvme_zns_changed_zone_log log;
+ enum nvme_print_flags flags;
+ int fd, err = -1;
+
+ struct config {
+ char *output_format;
+ __u32 namespace_id;
+ bool rae;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_FLAG("rae", 'r', &cfg.rae, rae),
+ OPT_END()
+ };
+
+ fd = parse_and_open(argc, argv, desc, opts);
+ if (fd < 0)
+ return errno;
+
+ flags = validate_output_format(cfg.output_format);
+ if (flags < 0)
+ goto close_fd;
+
+ if (!cfg.namespace_id) {
+ err = nvme_get_nsid(fd, &cfg.namespace_id);
+ if (err < 0) {
+ perror("get-namespace-id");
+ goto close_fd;
+ }
+ }
+
+ err = nvme_get_log_zns_changed_zones(fd, cfg.namespace_id, cfg.rae, &log);
+ if (!err)
+ nvme_print_object(nvme_zns_changed_to_json(&log, flags));
+ else
+ nvme_show_status("change-zone-log", err);
+
+close_fd:
+ close(fd);
+ return nvme_status_to_errno(err, false);
}
#include <json-c/json.h>
#include <uuid/uuid.h>
+#include <ccan/minmax/minmax.h>
#include <ccan/array_size/array_size.h>
#include "user-types.h"
{
uint16_t i = 0, major = 0, minor = 0, jmajor = 0, jminor = 0;
uint64_t v = json_object_get_int64(o);
-
+
util_split(v, &i, &major, &minor, &jmajor, &jminor);
return sprintbuf(p, "%u.%02u %s (%lu.%03lu %s)", major, minor, iec[i],
jmajor, jminor, jedec[i]);
{
uint64_t v = json_object_get_int64(o);
uint16_t i = 0, major = 0, minor = 0;
-
+
util_split(v, &i, &major, &minor, NULL, NULL);
if (minor)
return sprintbuf(p, "%u.%02u %s", major, minor, iec[i]);
if (i > 1)
char_stack[l] = '|';
- else
+ else
char_stack[l] = ' ';
//printf("%s %d child objects\n", __func__, i);
switch (ips) {
case 1:
break;
- case 2:
+ case 2:
idlp *= 100;
break;
default:
switch (aps) {
case 1:
break;
- case 2:
+ case 2:
actp *= 100;
break;
default:
jlist = nvme_json_new_object(flags);
jarray = nvme_json_new_array();
- for (i = 0; i < 1024; i++) {
+ for (i = 0; i < NVME_ID_NS_LIST_MAX; i++) {
struct json_object *jnsid;
__u32 nsid;
return jlist;
}
+struct json_object *nvme_zns_changed_to_json(
+ struct nvme_zns_changed_zone_log *log, unsigned long flags)
+{
+ struct json_object *jlist, *jarray;
+ uint16_t nrzid;
+ int i;
+
+ if (flags & NVME_JSON_BINARY)
+ return nvme_json_new_str_len_flags(log, sizeof(*log), flags);
+
+ jlist = nvme_json_new_object(flags);
+ jarray = nvme_json_new_array();
+
+ nrzid = le16_to_cpu(log->nrzid);
+
+ nvme_json_add_int(jlist, "nr-zone-ids", nrzid);
+ if (nrzid == 0xffff)
+ return jlist;
+
+ for (i = 0; i < min(nrzid, (uint16_t)NVME_ZNS_CHANGED_ZONES_MAX); i++)
+ json_object_array_add(jarray, nvme_json_new_int64(
+ le64_to_cpu(log->zid[i])));
+
+ json_object_object_add(jlist, "zone-ids", jarray);
+
+ return jlist;
+}
+
struct json_object *nvme_ctrl_list_to_json(
struct nvme_ctrl_list *list, unsigned long flags)
{
struct json_object *nvme_zns_report_zones_to_json(void *report, __u32 descs,
__u8 ext_size, __u32 report_size, unsigned long flags);
+struct json_object *nvme_zns_changed_to_json(
+ struct nvme_zns_changed_zone_log *log, unsigned long flags);
+
struct json_object *nvme_json_new_str_len(const char *v, int len);
struct json_object *nvme_json_new_str_len_flags(const void *v, int len,
unsigned long flags);