tipc: JSON support for tipc link printouts

Add json output support for tipc link command

Example output:
$tipc -j -p link list

[ {
        "broadcast-link": "up",
        "1.1.1:bridge-1.1.104:eth0": "up",
        "1.1.1:bridge-1.1.105:eth0": "up",
        "1.1.1:bridge-1.1.106:eth0": "up"
    } ]

--------------------
$tipc -j -p link stat show link broadcast-link

[ {
        "link": "broadcast-link",
        "window": 50,
        "rx packets": {
            "rx packets": 0,
            "fragments": 0,
            "fragmented": 0,
            "bundles": 0,
            "bundled": 0
        },
        "tx packets": {
            "tx packets": 0,
            "fragments": 0,
            "fragmented": 0,
            "bundles": 0,
            "bundled": 0
        },
        "rx naks": {
            "rx naks": 0,
            "defs": 0,
            "dups": 0
        },
        "tx naks": {
            "tx naks": 0,
            "acks": 0,
            "retrans": 0
        },
        "congestion link": 0,
        "send queue max": 0,
        "avg": 0
    } ]

v2:
    Replace variable 'json_flag' by 'json' declared in include/utils.h

v3:
    Update manual page

Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Hoang Le <hoang.h.le@dektech.com.au>
Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
Hoang Le 2018-06-12 09:32:29 +07:00 committed by David Ahern
parent 1304f50a5b
commit a56e0db7e8
2 changed files with 269 additions and 129 deletions

View File

@ -71,6 +71,16 @@ Show help about last valid command. For example
will show link help and
.B tipc --help
will show general help. The position of the option in the string is irrelevant.
.TP
.BR "\-j", " \-json"
Output results in JavaScript Object Notation (JSON).
.TP
.BR "\-p", " \-pretty"
The default JSON format is compact and more efficient to parse but hard for most users to read.
This flag adds indentation for readability.
.SH DESCRIPTION
.SS Link statistics

View File

@ -23,6 +23,11 @@
#include "msg.h"
#include "link.h"
#include "bearer.h"
#include "utils.h"
#define PRIORITY_STR "priority"
#define TOLERANCE_STR "tolerance"
#define WINDOW_STR "window"
static int link_list_cb(const struct nlmsghdr *nlh, void *data)
{
@ -38,13 +43,14 @@ static int link_list_cb(const struct nlmsghdr *nlh, void *data)
if (!attrs[TIPC_NLA_LINK_NAME])
return MNL_CB_ERROR;
printf("%s: ", mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]));
print_string(PRINT_FP, NULL, "%s: ",
mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]));
if (attrs[TIPC_NLA_LINK_UP])
printf("up\n");
print_string(PRINT_ANY,
mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]),"%s\n", "up");
else
printf("down\n");
print_string(PRINT_ANY,
mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]), "%s\n", "down");
return MNL_CB_OK;
}
@ -52,6 +58,7 @@ static int cmd_link_list(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
int err = 0;
if (help_flag) {
fprintf(stderr, "Usage: %s link list\n", cmdl->argv[0]);
@ -64,7 +71,12 @@ static int cmd_link_list(struct nlmsghdr *nlh, const struct cmd *cmd,
return -1;
}
return msg_dumpit(nlh, link_list_cb, NULL);
new_json_obj(json);
open_json_object(NULL);
err = msg_dumpit(nlh, link_list_cb, NULL);
close_json_object();
delete_json_obj();
return err;
}
static int link_get_cb(const struct nlmsghdr *nlh, void *data)
@ -87,8 +99,23 @@ static int link_get_cb(const struct nlmsghdr *nlh, void *data)
if (!props[*prop])
return MNL_CB_ERROR;
printf("%u\n", mnl_attr_get_u32(props[*prop]));
new_json_obj(json);
open_json_object(NULL);
switch (*prop) {
case TIPC_NLA_PROP_PRIO:
print_uint(PRINT_ANY, PRIORITY_STR, "%u\n", mnl_attr_get_u32(props[*prop]));
break;
case TIPC_NLA_PROP_TOL:
print_uint(PRINT_ANY, TOLERANCE_STR, "%u\n", mnl_attr_get_u32(props[*prop]));
break;
case TIPC_NLA_PROP_WIN:
print_uint(PRINT_ANY, WINDOW_STR, "%u\n", mnl_attr_get_u32(props[*prop]));
break;
default:
break;
}
close_json_object();
delete_json_obj();
return MNL_CB_OK;
}
@ -104,11 +131,11 @@ static int cmd_link_get_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
{ NULL }
};
if (strcmp(cmd->cmd, "priority") == 0)
if (strcmp(cmd->cmd, PRIORITY_STR) == 0)
prop = TIPC_NLA_PROP_PRIO;
else if ((strcmp(cmd->cmd, "tolerance") == 0))
else if ((strcmp(cmd->cmd, TOLERANCE_STR) == 0))
prop = TIPC_NLA_PROP_TOL;
else if ((strcmp(cmd->cmd, "window") == 0))
else if ((strcmp(cmd->cmd, WINDOW_STR) == 0))
prop = TIPC_NLA_PROP_WIN;
else
return -EINVAL;
@ -153,9 +180,9 @@ static int cmd_link_get(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
const struct cmd cmds[] = {
{ "priority", cmd_link_get_prop, cmd_link_get_help },
{ "tolerance", cmd_link_get_prop, cmd_link_get_help },
{ "window", cmd_link_get_prop, cmd_link_get_help },
{ PRIORITY_STR, cmd_link_get_prop, cmd_link_get_help },
{ TOLERANCE_STR, cmd_link_get_prop, cmd_link_get_help },
{ WINDOW_STR, cmd_link_get_prop, cmd_link_get_help },
{ NULL }
};
@ -214,109 +241,178 @@ static uint32_t perc(uint32_t count, uint32_t total)
return (count * 100 + (total / 2)) / total;
}
static int _show_link_stat(struct nlattr *attrs[], struct nlattr *prop[],
struct nlattr *stats[])
static int _show_link_stat(const char *name, struct nlattr *attrs[],
struct nlattr *prop[], struct nlattr *stats[])
{
uint32_t proft;
open_json_object(NULL);
print_string(PRINT_ANY, "link", "\nLink <%s>\n", name);
print_string(PRINT_JSON, "state", "", NULL);
open_json_array(PRINT_JSON, NULL);
if (attrs[TIPC_NLA_LINK_ACTIVE])
printf(" ACTIVE");
print_string(PRINT_ANY, NULL, " %s", "ACTIVE");
else if (attrs[TIPC_NLA_LINK_UP])
printf(" STANDBY");
print_string(PRINT_ANY, NULL, " %s", "STANDBY");
else
printf(" DEFUNCT");
print_string(PRINT_ANY, NULL, " %s", "DEFUNCT");
close_json_array(PRINT_JSON, NULL);
printf(" MTU:%u Priority:%u Tolerance:%u ms Window:%u packets\n",
mnl_attr_get_u32(attrs[TIPC_NLA_LINK_MTU]),
mnl_attr_get_u32(prop[TIPC_NLA_PROP_PRIO]),
mnl_attr_get_u32(prop[TIPC_NLA_PROP_TOL]),
mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN]));
print_uint(PRINT_ANY, "mtu", " MTU:%u",
mnl_attr_get_u32(attrs[TIPC_NLA_LINK_MTU]));
print_uint(PRINT_ANY, PRIORITY_STR, " Priority:%u",
mnl_attr_get_u32(prop[TIPC_NLA_PROP_PRIO]));
print_uint(PRINT_ANY, TOLERANCE_STR, " Tolerance:%u ms",
mnl_attr_get_u32(prop[TIPC_NLA_PROP_TOL]));
print_uint(PRINT_ANY, WINDOW_STR, " Window:%u packets\n",
mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN]));
printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
mnl_attr_get_u32(attrs[TIPC_NLA_LINK_RX]) -
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED]));
open_json_object("rx packets");
print_uint(PRINT_ANY, "rx packets", " RX packets:%u",
mnl_attr_get_u32(attrs[TIPC_NLA_LINK_RX]) -
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]));
print_uint(PRINT_ANY, "fragments", " fragments:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]));
print_uint(PRINT_ANY, "fragmented", "/%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]));
print_uint(PRINT_ANY, "bundles", " bundles:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]));
print_uint(PRINT_ANY, "bundled", "/%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED]));
close_json_object();
printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
mnl_attr_get_u32(attrs[TIPC_NLA_LINK_TX]) -
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED]));
open_json_object("tx packets");
print_uint(PRINT_ANY, "tx packets", " TX packets:%u",
mnl_attr_get_u32(attrs[TIPC_NLA_LINK_TX]) -
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]));
print_uint(PRINT_ANY, "fragments", " fragments:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]));
print_uint(PRINT_ANY, "fragmented", "/%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]));
print_uint(PRINT_ANY, "bundles", " bundles:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]));
print_uint(PRINT_ANY, "bundled", "/%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED]));
close_json_object();
proft = mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]);
printf(" TX profile sample:%u packets average:%u octets\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / proft);
print_uint(PRINT_ANY, "tx profile sample", " TX profile sample:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT]));
print_uint(PRINT_ANY, "packets average", " packets average:%u octets\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / proft);
printf(" 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% -16384:%u%% -32768:%u%% -66000:%u%%\n",
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), proft),
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), proft),
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), proft),
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), proft),
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), proft),
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), proft),
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), proft));
print_uint(PRINT_ANY, "0-64", " 0-64:%u%%",
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), proft));
print_uint(PRINT_ANY, "-256", " -256:%u%%",
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), proft));
print_uint(PRINT_ANY, "-1024", " -1024:%u%%",
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), proft));
print_uint(PRINT_ANY, "-4096", " -4096:%u%%",
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), proft));
print_uint(PRINT_ANY, "-16384", " -16384:%u%%",
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), proft));
print_uint(PRINT_ANY, "-32768", " -32768:%u%%",
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), proft));
print_uint(PRINT_ANY, "-66000", " -66000:%u%%\n",
perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), proft));
printf(" RX states:%u probes:%u naks:%u defs:%u dups:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_STATES]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES]));
open_json_object("rx states");
print_uint(PRINT_ANY, "rx states", " RX states:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_STATES]));
print_uint(PRINT_ANY, "probes", " probes:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_PROBES]));
print_uint(PRINT_ANY, "naks", " naks:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]));
print_uint(PRINT_ANY, "defs", " defs:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]));
print_uint(PRINT_ANY, "dups", " dups:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES]));
close_json_object();
printf(" TX states:%u probes:%u naks:%u acks:%u dups:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_STATES]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED]));
open_json_object("tx states");
print_uint(PRINT_ANY, "tx states", " TX states:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_STATES]));
print_uint(PRINT_ANY, "probes", " probes:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_PROBES]));
print_uint(PRINT_ANY, "naks", " naks:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]));
print_uint(PRINT_ANY, "acks", " acks:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]));
print_uint(PRINT_ANY, "retrans", " retrans:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED]));
close_json_object();
printf(" Congestion link:%u Send queue max:%u avg:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE]));
print_uint(PRINT_ANY, "congestion link", " Congestion link:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]));
print_uint(PRINT_ANY, "send queue max", " Send queue max:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]));
print_uint(PRINT_ANY, "avg", " avg:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE]));
close_json_object();
return MNL_CB_OK;
}
static int _show_bc_link_stat(struct nlattr *prop[], struct nlattr *stats[])
static int _show_bc_link_stat(const char *name, struct nlattr *prop[],
struct nlattr *stats[])
{
printf(" Window:%u packets\n",
mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN]));
open_json_object(NULL);
print_string(PRINT_ANY, "link", "Link <%s>\n", name);
print_uint(PRINT_ANY, WINDOW_STR, " Window:%u packets\n",
mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN]));
printf(" RX packets:%u fragments:%u/%u bundles:%u/%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED]));
open_json_object("rx packets");
print_uint(PRINT_ANY, "rx packets", " RX packets:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO]));
print_uint(PRINT_ANY, "fragments", " fragments:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS]));
print_uint(PRINT_ANY, "fragmented", "/%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED]));
print_uint(PRINT_ANY, "bundles", " bundles:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES]));
print_uint(PRINT_ANY, "bundled", "/%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED]));
close_json_object();
printf(" TX packets:%u fragments:%u/%u bundles:%u/%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED]));
open_json_object("tx packets");
print_uint(PRINT_ANY, "tx packets", " TX packets:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO]));
print_uint(PRINT_ANY, "fragments", " fragments:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS]));
print_uint(PRINT_ANY, "fragmented", "/%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED]));
print_uint(PRINT_ANY, "bundles", " bundles:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES]));
print_uint(PRINT_ANY, "bundled", "/%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED]));
close_json_object();
printf(" RX naks:%u defs:%u dups:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES]));
open_json_object("rx naks");
print_uint(PRINT_ANY, "rx naks", " RX naks:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS]));
print_uint(PRINT_ANY, "defs", " defs:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED]));
print_uint(PRINT_ANY, "dups", " dups:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES]));
close_json_object();
printf(" TX naks:%u acks:%u dups:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED]));
open_json_object("tx naks");
print_uint(PRINT_ANY, "tx naks", " TX naks:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS]));
print_uint(PRINT_ANY, "acks", " acks:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS]));
print_uint(PRINT_ANY, "retrans", " retrans:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED]));
close_json_object();
printf(" Congestion link:%u Send queue max:%u avg:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]),
mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE]));
print_uint(PRINT_ANY, "congestion link", " Congestion link:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS]));
print_uint(PRINT_ANY, "send queue max", " Send queue max:%u",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE]));
print_uint(PRINT_ANY, "avg", " avg:%u\n",
mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE]));
close_json_object();
return MNL_CB_OK;
}
@ -350,13 +446,10 @@ static int link_stat_show_cb(const struct nlmsghdr *nlh, void *data)
return MNL_CB_OK;
if (attrs[TIPC_NLA_LINK_BROADCAST]) {
printf("Link <%s>\n", name);
return _show_bc_link_stat(prop, stats);
return _show_bc_link_stat(name, prop, stats);
}
printf("\nLink <%s>\n", name);
return _show_link_stat(attrs, prop, stats);
return _show_link_stat(name, attrs, prop, stats);
}
static void cmd_link_stat_show_help(struct cmdl *cmdl)
@ -375,6 +468,7 @@ static int cmd_link_stat_show(struct nlmsghdr *nlh, const struct cmd *cmd,
{ "link", OPT_KEYVAL, NULL },
{ NULL }
};
int err = 0;
if (help_flag) {
(cmd->help)(cmdl);
@ -394,7 +488,10 @@ static int cmd_link_stat_show(struct nlmsghdr *nlh, const struct cmd *cmd,
if (opt)
link = opt->val;
return msg_dumpit(nlh, link_stat_show_cb, link);
new_json_obj(json);
err = msg_dumpit(nlh, link_stat_show_cb, link);
delete_json_obj();
return err;
}
static void cmd_link_stat_help(struct cmdl *cmdl)
@ -442,11 +539,11 @@ static int cmd_link_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
{ NULL }
};
if (strcmp(cmd->cmd, "priority") == 0)
if (strcmp(cmd->cmd, PRIORITY_STR) == 0)
prop = TIPC_NLA_PROP_PRIO;
else if ((strcmp(cmd->cmd, "tolerance") == 0))
else if ((strcmp(cmd->cmd, TOLERANCE_STR) == 0))
prop = TIPC_NLA_PROP_TOL;
else if ((strcmp(cmd->cmd, "window") == 0))
else if ((strcmp(cmd->cmd, WINDOW_STR) == 0))
prop = TIPC_NLA_PROP_WIN;
else
return -EINVAL;
@ -492,9 +589,9 @@ static int cmd_link_set(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
const struct cmd cmds[] = {
{ "priority", cmd_link_set_prop, cmd_link_set_help },
{ "tolerance", cmd_link_set_prop, cmd_link_set_help },
{ "window", cmd_link_set_prop, cmd_link_set_help },
{ PRIORITY_STR, cmd_link_set_prop, cmd_link_set_help },
{ TOLERANCE_STR, cmd_link_set_prop, cmd_link_set_help },
{ WINDOW_STR, cmd_link_set_prop, cmd_link_set_help },
{ NULL }
};
@ -540,15 +637,17 @@ static int link_mon_summary_cb(const struct nlmsghdr *nlh, void *data)
mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs);
printf("\nbearer %s\n",
open_json_object(NULL);
print_string(PRINT_ANY, "bearer", "\nbearer %s\n",
mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME]));
printf(" table_generation %u\n",
print_uint(PRINT_ANY, "table_generation", " table_generation %u\n",
mnl_attr_get_u32(attrs[TIPC_NLA_MON_LISTGEN]));
printf(" cluster_size %u\n",
print_uint(PRINT_ANY, "cluster_size", " cluster_size %u\n",
mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT]));
printf(" algorithm %s\n",
print_string(PRINT_ANY, "algorithm", " algorithm %s\n",
attrs[TIPC_NLA_MON_ACTIVE] ? "overlapping-ring" : "full-mesh");
close_json_object();
return MNL_CB_OK;
}
@ -557,6 +656,7 @@ static int cmd_link_mon_summary(struct nlmsghdr *nlh, const struct cmd *cmd,
struct cmdl *cmdl, void *data)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
int err = 0;
if (help_flag) {
fprintf(stderr, "Usage: %s monitor summary\n", cmdl->argv[0]);
@ -569,7 +669,11 @@ static int cmd_link_mon_summary(struct nlmsghdr *nlh, const struct cmd *cmd,
return -1;
}
return msg_dumpit(nlh, link_mon_summary_cb, NULL);
new_json_obj(json);
err = msg_dumpit(nlh, link_mon_summary_cb, NULL);
delete_json_obj();
return err;
}
#define STATUS_WIDTH 7
@ -590,16 +694,19 @@ static int map_get(uint64_t up_map, int i)
static void link_mon_print_applied(uint16_t applied, uint64_t up_map)
{
int i;
char state;
open_json_array(PRINT_JSON, "applied_node_status");
for (i = 0; i < applied; i++) {
char state_str[2] = {0};
/* print the delimiter for every -n- entry */
if (i && !(i % APPL_NODE_STATUS_WIDTH))
printf(",");
print_string(PRINT_FP, NULL, "%s", ",");
state = map_get(up_map, i) ? 'U' : 'D';
printf("%c", state);
sprintf(state_str, "%c", map_get(up_map, i) ? 'U' : 'D');
print_string(PRINT_ANY, NULL, "%s", state_str);
}
close_json_array(PRINT_JSON, "applied_node_status");
}
/* print the non applied members, since we dont know
@ -611,19 +718,23 @@ static void link_mon_print_non_applied(uint16_t applied, uint16_t member_cnt,
int i;
char state;
printf(" [");
open_json_array(PRINT_JSON, "[non_applied_node:status]");
print_string(PRINT_FP, NULL, " %s", "[");
for (i = applied; i < member_cnt; i++) {
char addr_str[16];
char full_state[17] = {0};
/* print the delimiter for every entry */
if (i != applied)
printf(",");
print_string(PRINT_FP, NULL, "%s", ",");
sprintf(addr_str, "%x:", members[i]);
state = map_get(up_map, i) ? 'U' : 'D';
printf("%s%c", addr_str, state);
sprintf(full_state, "%s%c", addr_str, state);
print_string(PRINT_ANY, NULL, "%s", full_state);
}
printf("]");
print_string(PRINT_FP, NULL, "%s", "]");
close_json_array(PRINT_JSON, "[non_applied_node:status]");
}
static void link_mon_print_peer_state(const uint32_t addr, const char *status,
@ -634,11 +745,17 @@ static void link_mon_print_peer_state(const uint32_t addr, const char *status,
sprintf(addr_str, "%u.%u.%u", tipc_zone(addr), tipc_cluster(addr),
tipc_node(addr));
printf("%-*s", MAX_NODE_WIDTH, addr_str);
printf("%-*s", STATUS_WIDTH, status);
printf("%-*s", DIRECTLY_MON_WIDTH, monitored);
printf("%-*u", MAX_DOM_GEN_WIDTH, dom_gen);
if (is_json_context()) {
print_string(PRINT_JSON, "node", NULL, addr_str);
print_string(PRINT_JSON, "status", NULL, status);
print_string(PRINT_JSON, "monitored", NULL, monitored);
print_uint(PRINT_JSON, "generation", NULL, dom_gen);
} else {
printf("%-*s", MAX_NODE_WIDTH, addr_str);
printf("%-*s", STATUS_WIDTH, status);
printf("%-*s", DIRECTLY_MON_WIDTH, monitored);
printf("%-*u", MAX_DOM_GEN_WIDTH, dom_gen);
}
}
static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data)
@ -657,6 +774,7 @@ static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data)
if (!info[TIPC_NLA_MON_PEER])
return MNL_CB_ERROR;
open_json_object(NULL);
mnl_attr_parse_nested(info[TIPC_NLA_MON_PEER], parse_attrs, attrs);
(attrs[TIPC_NLA_MON_PEER_LOCAL] || attrs[TIPC_NLA_MON_PEER_HEAD]) ?
@ -691,8 +809,9 @@ static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data)
mnl_attr_get_payload(attrs[TIPC_NLA_MON_PEER_MEMBERS]));
exit:
printf("\n");
print_string(PRINT_FP, NULL, "\n", "");
close_json_object();
return MNL_CB_OK;
}
@ -701,6 +820,7 @@ static int link_mon_peer_list(uint32_t mon_ref)
struct nlmsghdr *nlh;
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlattr *nest;
int err = 0;
nlh = msg_init(buf, TIPC_NL_MON_PEER_GET);
if (!nlh) {
@ -712,7 +832,8 @@ static int link_mon_peer_list(uint32_t mon_ref)
mnl_attr_put_u32(nlh, TIPC_NLA_MON_REF, mon_ref);
mnl_attr_nest_end(nlh, nest);
return msg_dumpit(nlh, link_mon_peer_list_cb, NULL);
err = msg_dumpit(nlh, link_mon_peer_list_cb, NULL);
return err;
}
static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data)
@ -736,12 +857,16 @@ static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data)
if (*req_bearer && (strcmp(req_bearer, bname) != 0))
return MNL_CB_OK;
printf("\nbearer %s\n", bname);
printf("%s\n", title);
open_json_object(NULL);
print_string(PRINT_ANY, "bearer", "\nbearer %s\n", bname);
print_string(PRINT_FP, NULL, "%s\n", title);
open_json_array(PRINT_JSON, bname);
if (mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT]))
link_mon_peer_list(mnl_attr_get_u32(attrs[TIPC_NLA_MON_REF]));
close_json_array(PRINT_JSON, bname);
close_json_object();
return MNL_CB_OK;
}
@ -807,7 +932,10 @@ static int cmd_link_mon_list(struct nlmsghdr *nlh, const struct cmd *cmd,
return -1;
}
return msg_dumpit(nlh, link_mon_list_cb, bname);
new_json_obj(json);
err = msg_dumpit(nlh, link_mon_list_cb, bname);
delete_json_obj();
return err;
}
static void cmd_link_mon_set_help(struct cmdl *cmdl)
@ -851,8 +979,10 @@ static int link_mon_get_cb(const struct nlmsghdr *nlh, void *data)
if (!attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD])
return MNL_CB_ERROR;
printf("%u\n",
mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]));
new_json_obj(json);
print_uint(PRINT_ANY, "threshold", "%u\n",
mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]));
delete_json_obj();
return MNL_CB_OK;
}