[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1595165763-13657-3-git-send-email-moshe@mellanox.com>
Date: Sun, 19 Jul 2020 16:36:02 +0300
From: Moshe Shemesh <moshe@...lanox.com>
To: Stephen Hemminger <stephen@...workplumber.org>,
David Ahern <dsahern@...il.com>
Cc: Jiri Pirko <jiri@...lanox.com>, netdev@...r.kernel.org,
Moshe Shemesh <moshe@...lanox.com>,
Vladyslav Tarasiuk <vladyslavt@...lanox.com>
Subject: [PATCH iproute2-next 2/3] devlink: Add devlink port health command
From: Vladyslav Tarasiuk <vladyslavt@...lanox.com>
Add devlink port health show subcommand which displays information about
specified port reporter or all present port reporters as in the example.
Device and port reporters can be distinguished by a handle being used.
Make other devlink-health subcommands be aliased by devlink port health.
Refactor devlink-health commands for usage of port handles in order to
interact with port reporters.
Change devlink health show output to dump information about both device
and port reporters with correct handles.
Example:
$ devlink health show
pci/0000:00:0b.0:
reporter fw
state healthy error 0 recover 0 auto_dump true
reporter fw_fatal
state healthy error 0 recover 0 grace_period 1200000 auto_recover true auto_dump true
pci/0000:00:0b.0/1:
reporter tx
state healthy error 0 recover 0 grace_period 10000 auto_recover true auto_dump true
reporter rx
state healthy error 0 recover 0 grace_period 10000 auto_recover true auto_dump true
$ devlink health show pci/0000:00:0b.0/1 reporter rx
Which is equivalent to:
$ devlink port health show pci/0000:00:0b.0/1 reporter rx
pci/0000:00:0b.0/1:
reporter rx
state healthy error 0 recover 0 grace_period 10000 auto_recover true auto_dump true
$ devlink port health show pci/0000:00:0b.0/1 reporter rx -j --pretty
{
"health": {
"pci/0000:00:0b.0/1": [ {
"reporter": "rx",
"state": "healthy",
"error": 0,
"recover": 0,
"grace_period": 500,
"auto_recover": true,
"auto_dump": true
} ]
}
}
$ devlink health set pci/0000:00:0b.0/1 reporter rx grace_period 5000
Which is equivalent to:
$ devlink port health set pci/0000:00:0b.0/1 reporter rx grace_period 5000
$ devlink port health show pci/0000:00:0b.0/1 reporter rx
pci/0000:00:0b.0/1:
reporter rx
state healthy error 0 recover 0 grace_period 5000 auto_recover true auto_dump true
Signed-off-by: Vladyslav Tarasiuk <vladyslavt@...lanox.com>
Reviewed-by: Moshe Shemesh <moshe@...lanox.com>
Reviewed-by: Jiri Pirko <jiri@...lanox.com>
---
devlink/devlink.c | 80 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 60 insertions(+), 20 deletions(-)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index bb4588e..7dbe9c7 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -3291,6 +3291,7 @@ static void cmd_port_help(void)
pr_err(" devlink port split DEV/PORT_INDEX count COUNT\n");
pr_err(" devlink port unsplit DEV/PORT_INDEX\n");
pr_err(" devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ]\n");
+ pr_err(" devlink port health show [ DEV/PORT_INDEX reporter REPORTER_NAME ]\n");
}
static const char *port_type_name(uint32_t type)
@@ -3540,6 +3541,9 @@ static int cmd_port_function(struct dl *dl)
return -ENOENT;
}
+static int cmd_health(struct dl *dl);
+static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port);
+
static int cmd_port(struct dl *dl)
{
if (dl_argv_match(dl, "help")) {
@@ -3561,6 +3565,15 @@ static int cmd_port(struct dl *dl)
} else if (dl_argv_match(dl, "function")) {
dl_arg_inc(dl);
return cmd_port_function(dl);
+ } else if (dl_argv_match(dl, "health")) {
+ dl_arg_inc(dl);
+ if (dl_argv_match(dl, "list") || dl_no_arg(dl)
+ || (dl_argv_match(dl, "show") && dl_argc(dl) == 1)) {
+ dl_arg_inc(dl);
+ return __cmd_health_show(dl, false, true);
+ } else {
+ return cmd_health(dl);
+ }
}
pr_err("Command \"%s\" not found\n", dl_argv(dl));
return -ENOENT;
@@ -4493,7 +4506,8 @@ static void pr_out_flash_update(struct dl *dl, struct nlattr **tb)
}
static void pr_out_region(struct dl *dl, struct nlattr **tb);
-static void pr_out_health(struct dl *dl, struct nlattr **tb_health);
+static void pr_out_health(struct dl *dl, struct nlattr **tb_health,
+ bool show_device, bool show_port);
static void pr_out_trap(struct dl *dl, struct nlattr **tb, bool array);
static void pr_out_trap_group(struct dl *dl, struct nlattr **tb, bool array);
static void pr_out_trap_policer(struct dl *dl, struct nlattr **tb, bool array);
@@ -4572,7 +4586,7 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
!tb[DEVLINK_ATTR_HEALTH_REPORTER])
return MNL_CB_ERROR;
pr_out_mon_header(genl->cmd);
- pr_out_health(dl, tb);
+ pr_out_health(dl, tb, true, true);
pr_out_mon_footer();
break;
case DEVLINK_CMD_TRAP_GET: /* fall through */
@@ -6717,7 +6731,7 @@ static int cmd_health_set_params(struct dl *dl)
nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_HEALTH_REPORTER_SET,
NLM_F_REQUEST | NLM_F_ACK);
- err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HEALTH_REPORTER_NAME,
+ err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_HEALTH_REPORTER_NAME,
DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD |
DL_OPT_HEALTH_REPORTER_AUTO_RECOVER |
DL_OPT_HEALTH_REPORTER_AUTO_DUMP);
@@ -6737,7 +6751,8 @@ static int cmd_health_dump_clear(struct dl *dl)
NLM_F_REQUEST | NLM_F_ACK);
err = dl_argv_parse_put(nlh, dl,
- DL_OPT_HANDLE | DL_OPT_HEALTH_REPORTER_NAME, 0);
+ DL_OPT_HANDLE | DL_OPT_HANDLEP |
+ DL_OPT_HEALTH_REPORTER_NAME, 0);
if (err)
return err;
@@ -6984,7 +6999,8 @@ static int cmd_health_object_common(struct dl *dl, uint8_t cmd, uint16_t flags)
nlh = mnlg_msg_prepare(dl->nlg, cmd, flags | NLM_F_REQUEST | NLM_F_ACK);
err = dl_argv_parse_put(nlh, dl,
- DL_OPT_HANDLE | DL_OPT_HEALTH_REPORTER_NAME, 0);
+ DL_OPT_HANDLE | DL_OPT_HANDLEP |
+ DL_OPT_HEALTH_REPORTER_NAME, 0);
if (err)
return err;
@@ -7017,7 +7033,8 @@ static int cmd_health_recover(struct dl *dl)
NLM_F_REQUEST | NLM_F_ACK);
err = dl_argv_parse_put(nlh, dl,
- DL_OPT_HANDLE | DL_OPT_HEALTH_REPORTER_NAME, 0);
+ DL_OPT_HANDLE | DL_OPT_HANDLEP |
+ DL_OPT_HEALTH_REPORTER_NAME, 0);
if (err)
return err;
@@ -7091,7 +7108,8 @@ static void pr_out_dump_report_timestamp(struct dl *dl, const struct nlattr *att
print_string(PRINT_ANY, "last_dump_time", " last_dump_time %s", dump_time);
}
-static void pr_out_health(struct dl *dl, struct nlattr **tb_health)
+static void pr_out_health(struct dl *dl, struct nlattr **tb_health,
+ bool print_device, bool print_port)
{
struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
enum devlink_health_reporter_state state;
@@ -7108,7 +7126,20 @@ static void pr_out_health(struct dl *dl, struct nlattr **tb_health)
!tb[DEVLINK_ATTR_HEALTH_REPORTER_STATE])
return;
- pr_out_handle_start_arr(dl, tb_health);
+ if (!print_device && !print_port)
+ return;
+ if (print_port) {
+ if (!print_device && !tb_health[DEVLINK_ATTR_PORT_INDEX])
+ return;
+ else if (tb_health[DEVLINK_ATTR_PORT_INDEX])
+ pr_out_port_handle_start_arr(dl, tb_health, false);
+ }
+ if (print_device) {
+ if (!print_port && tb_health[DEVLINK_ATTR_PORT_INDEX])
+ return;
+ else if (!tb_health[DEVLINK_ATTR_PORT_INDEX])
+ pr_out_handle_start_arr(dl, tb_health);
+ }
check_indent_newline(dl);
print_string(PRINT_ANY, "reporter", "reporter %s",
@@ -7142,25 +7173,33 @@ static void pr_out_health(struct dl *dl, struct nlattr **tb_health)
pr_out_handle_end(dl);
}
+struct health_ctx {
+ struct dl *dl;
+ bool show_device;
+ bool show_port;
+};
+
static int cmd_health_show_cb(const struct nlmsghdr *nlh, void *data)
{
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
- struct dl *dl = data;
+ struct health_ctx *ctx = data;
+ struct dl *dl = ctx->dl;
mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
!tb[DEVLINK_ATTR_HEALTH_REPORTER])
return MNL_CB_ERROR;
- pr_out_health(dl, tb);
+ pr_out_health(dl, tb, ctx->show_device, ctx->show_port);
return MNL_CB_OK;
}
-static int cmd_health_show(struct dl *dl)
+static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port)
{
struct nlmsghdr *nlh;
+ struct health_ctx ctx = { dl, show_device, show_port };
uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
int err;
@@ -7170,27 +7209,28 @@ static int cmd_health_show(struct dl *dl)
flags);
if (dl_argc(dl) > 0) {
+ ctx.show_port = true;
err = dl_argv_parse_put(nlh, dl,
- DL_OPT_HANDLE |
+ DL_OPT_HANDLE | DL_OPT_HANDLEP |
DL_OPT_HEALTH_REPORTER_NAME, 0);
if (err)
return err;
}
pr_out_section_start(dl, "health");
- err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_health_show_cb, dl);
+ err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_health_show_cb, &ctx);
pr_out_section_end(dl);
return err;
}
static void cmd_health_help(void)
{
- pr_err("Usage: devlink health show [ dev DEV reporter REPORTER_NAME ]\n");
- pr_err(" devlink health recover DEV reporter REPORTER_NAME\n");
- pr_err(" devlink health diagnose DEV reporter REPORTER_NAME\n");
- pr_err(" devlink health dump show DEV reporter REPORTER_NAME\n");
- pr_err(" devlink health dump clear DEV reporter REPORTER_NAME\n");
- pr_err(" devlink health set DEV reporter REPORTER_NAME\n");
+ pr_err("Usage: devlink health show [ { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME ]\n");
+ pr_err(" devlink health recover { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
+ pr_err(" devlink health diagnose { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
+ pr_err(" devlink health dump show { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
+ pr_err(" devlink health dump clear { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
+ pr_err(" devlink health set { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
pr_err(" [ grace_period MSEC ]\n");
pr_err(" [ auto_recover { true | false } ]\n");
pr_err(" [ auto_dump { true | false } ]\n");
@@ -7204,7 +7244,7 @@ static int cmd_health(struct dl *dl)
} else if (dl_argv_match(dl, "show") ||
dl_argv_match(dl, "list") || dl_no_arg(dl)) {
dl_arg_inc(dl);
- return cmd_health_show(dl);
+ return __cmd_health_show(dl, true, true);
} else if (dl_argv_match(dl, "recover")) {
dl_arg_inc(dl);
return cmd_health_recover(dl);
--
1.7.1
Powered by blists - more mailing lists