Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 12 additions & 21 deletions nvme-print-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,9 @@ static void obj_add_result(struct json_object *o, const char *v, ...)
va_start(ap, v);

if (vasprintf(&value, v, ap) < 0)
value = NULL;
value = alloc_error;

if (value)
obj_add_str(o, "Result", value);
else
obj_add_str(o, "Result", "Could not allocate string");
obj_add_str(o, "Result", value);

va_end(ap);
}
Expand All @@ -138,12 +135,9 @@ static void obj_add_key(struct json_object *o, const char *k, const char *v, ...
va_start(ap, v);

if (vasprintf(&value, v, ap) < 0)
value = NULL;
value = alloc_error;

if (value)
obj_add_str(o, k, value);
else
obj_add_str(o, k, "Could not allocate string");
obj_add_str(o, k, value);

va_end(ap);
}
Expand Down Expand Up @@ -4588,9 +4582,9 @@ static void json_output_error_status(int status, const char *msg, va_list ap)
_cleanup_free_ char *value = NULL;

if (vasprintf(&value, msg, ap) < 0)
value = NULL;
value = alloc_error;

sprintf(json_str, "Error: %s", value ? value : "Could not allocate string");
sprintf(json_str, "Error: %s", value);
r = obj_create(json_str);

if (status < 0) {
Expand Down Expand Up @@ -4628,26 +4622,23 @@ static void json_output_message(bool error, const char *msg, va_list ap)
_cleanup_free_ char *value = NULL;

if (vasprintf(&value, msg, ap) < 0)
value = NULL;
value = alloc_error;

obj_add_str(r, error ? "error" : "result", value ? value : "Could not allocate string");
obj_add_str(r, error ? "error" : "result", value);

obj_print(r);
}

static void json_output_perror(const char *msg)
static void json_output_perror(const char *msg, va_list ap)
{
struct json_object *r = json_create_object();

_cleanup_free_ char *error = NULL;

if (asprintf(&error, "%s: %s", msg, strerror(errno)) < 0)
error = NULL;
if (vasprintf(&error, msg, ap) < 0)
error = alloc_error;

if (error)
obj_add_str(r, "error", error);
else
obj_add_str(r, "error", "Could not allocate string");
obj_add_key(r, "error", "%s: %s", error, strerror(errno));

json_output_object(r);
}
Expand Down
9 changes: 7 additions & 2 deletions nvme-print-stdout.c
Original file line number Diff line number Diff line change
Expand Up @@ -5604,9 +5604,14 @@ static void stdout_message(bool error, const char *msg, va_list ap)
fprintf(error ? stderr : stdout, "\n");
}

static void stdout_perror(const char *msg)
static void stdout_perror(const char *msg, va_list ap)
{
perror(msg);
_cleanup_free_ char *error = NULL;

if (vasprintf(&error, msg, ap) < 0)
error = alloc_error;

perror(error);
}

static void stdout_discovery_log(struct nvmf_discovery_log *log, int numrec)
Expand Down
11 changes: 9 additions & 2 deletions nvme-print.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#define nvme_print_output_format(name, ...) \
nvme_print(name, nvme_is_output_format_json() ? JSON : NORMAL, ##__VA_ARGS__);

char *alloc_error = "Could not allocate string";

static struct print_ops *nvme_print_ops(nvme_print_flags_t flags)
{
struct print_ops *ops = NULL;
Expand Down Expand Up @@ -1460,15 +1462,20 @@ void nvme_show_message(bool error, const char *msg, ...)
va_end(ap);
}

void nvme_show_perror(const char *msg)
void nvme_show_perror(const char *msg, ...)
{
struct print_ops *ops = nvme_print_ops(NORMAL);
va_list ap;

va_start(ap, msg);

if (nvme_is_output_format_json())
ops = nvme_print_ops(JSON);

if (ops && ops->show_perror)
ops->show_perror(msg);
ops->show_perror(msg, ap);

va_end(ap);
}

void nvme_show_discovery_log(struct nvmf_discovery_log *log, uint64_t numrec,
Expand Down
6 changes: 4 additions & 2 deletions nvme-print.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct print_ops {
/* status and error messages */
void (*connect_msg)(nvme_ctrl_t c);
void (*show_message)(bool error, const char *msg, va_list ap);
void (*show_perror)(const char *msg);
void (*show_perror)(const char *msg, va_list ap);
void (*show_status)(int status);
void (*show_error_status)(int status, const char *msg, va_list ap);

Expand Down Expand Up @@ -326,7 +326,7 @@ const char *nvme_pls_mode_to_string(__u8 mode);
void nvme_dev_full_path(nvme_ns_t n, char *path, size_t len);
void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len);
void nvme_show_message(bool error, const char *msg, ...);
void nvme_show_perror(const char *msg);
void nvme_show_perror(const char *msg, ...);
void nvme_show_error_status(int status, const char *msg, ...);
void nvme_show_init(void);
void nvme_show_finish(void);
Expand All @@ -352,4 +352,6 @@ void nvme_show_host_discovery_log(struct nvme_host_discover_log *log, nvme_print
void nvme_show_ave_discovery_log(struct nvme_ave_discover_log *log, nvme_print_flags_t flags);
void nvme_show_pull_model_ddc_req_log(struct nvme_pull_model_ddc_req_log *log,
nvme_print_flags_t flags);

extern char *alloc_error;
#endif /* NVME_PRINT_H */
108 changes: 108 additions & 0 deletions plugins/feat/feat-nvme.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "nvme.h"
#include "plugin.h"
#include "nvme-print.h"

#define CREATE_CMD
#include "feat-nvme.h"

static const char *power_mgmt_feat = "power management feature";
static const char *sel = "[0-3]: current/default/saved/supported";
static const char *save = "Specifies that the controller shall save the attribute";

static int power_mgmt_get(struct nvme_dev *dev, const __u8 fid, __u8 sel)
{
__u32 result;
int err;

struct nvme_get_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = fid,
.sel = sel,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = &result,
};

err = nvme_get_features(&args);
if (!err) {
if (NVME_CHECK(sel, GET_FEATURES_SEL, SUPPORTED))
nvme_show_select_result(fid, result);
else
nvme_feature_show_fields(fid, result, NULL);
} else {
nvme_show_error("Get %s", power_mgmt_feat);
}

return err;
}

static int power_mgmt_set(struct nvme_dev *dev, const __u8 fid, __u8 ps, __u8 wh, bool save)
{
__u32 result;
int err;

struct nvme_set_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = fid,
.cdw11 = NVME_SET(ps, FEAT_PWRMGMT_PS) | NVME_SET(wh, FEAT_PWRMGMT_WH),
.save = save,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = &result,
};

err = nvme_set_features(&args);

nvme_show_init();

if (err > 0) {
nvme_show_status(err);
} else if (err < 0) {
nvme_show_perror("Set %s", power_mgmt_feat);
} else {
nvme_show_result("Set %s: 0x%04x (%s)", power_mgmt_feat, args.cdw11,
save ? "Save" : "Not save");
nvme_feature_show_fields(fid, args.cdw11, NULL);
}

nvme_show_finish();

return err;
}

static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *ps = "power state";
const char *wh = "workload hint";
const __u8 fid = NVME_FEAT_FID_POWER_MGMT;

_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;

struct config {
__u8 ps;
__u8 wh;
bool save;
__u8 sel;
};

struct config cfg = { 0 };

NVME_ARGS(opts,
OPT_BYTE("ps", 'p', &cfg.ps, ps),
OPT_BYTE("wh", 'w', &cfg.wh, wh),
OPT_FLAG("save", 's', &cfg.save, save),
OPT_BYTE("sel", 'S', &cfg.sel, sel));

err = parse_and_open(&dev, argc, argv, POWER_MGMT_DESC, opts);
if (err)
return err;

if (argconfig_parse_seen(opts, "ps"))
err = power_mgmt_set(dev, fid, cfg.ps, cfg.wh, cfg.save);
else
err = power_mgmt_get(dev, fid, cfg.sel);

return err;
}
25 changes: 25 additions & 0 deletions plugins/feat/feat-nvme.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "cmd.h"

#undef CMD_INC_FILE
#define CMD_INC_FILE plugins/feat/feat-nvme

Check failure on line 5 in plugins/feat/feat-nvme.h

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: Macros with complex values should be enclosed in parentheses

#include "define_cmd.h"

#if !defined(FEAT_NVME) || defined(CMD_HEADER_MULTI_READ)
#define FEAT_NVME

#define FEAT_PLUGIN_VERSION "1.0"
#define POWER_MGMT_DESC "Get and set power management feature"

PLUGIN(NAME("feat", "NVMe feature extensions", FEAT_PLUGIN_VERSION),
COMMAND_LIST(
ENTRY("power-mgmt", POWER_MGMT_DESC, feat_power_mgmt)
)
);
#endif /* !FEAT_NVME || CMD_HEADER_MULTI_READ */

#ifndef FEAT_NVME_H
#define FEAT_NVME_H

#endif /* FEAT_NVME_H */
3 changes: 3 additions & 0 deletions plugins/feat/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
sources += [
'plugins/feat/feat-nvme.c',
]
1 change: 1 addition & 0 deletions plugins/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ sources += [
'plugins/zns/zns.c',
]

subdir('feat')
subdir('lm')
subdir('ocp')

Expand Down