@@ -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);