X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fnode_cli.c;h=58b63c366bf1bdb42b8fdafc19b2c228d7cf8a26;hb=7c8f828ba353472e27369a77574bca532147e458;hp=3dbf672d4414a919d7d04be0717cb9f9dcbb8476;hpb=bdc0e6b7204ea0211d4f7881497e4306586fb9ef;p=vpp.git diff --git a/src/vlib/node_cli.c b/src/vlib/node_cli.c index 3dbf672d441..58b63c366bf 100644 --- a/src/vlib/node_cli.c +++ b/src/vlib/node_cli.c @@ -37,6 +37,9 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include +#include +#include #include #include @@ -88,6 +91,81 @@ VLIB_CLI_COMMAND (show_node_graph_command, static) = { }; /* *INDENT-ON* */ +static clib_error_t * +show_node_graphviz (vlib_main_t * vm, + unformat_input_t * input, vlib_cli_command_t * cmd) +{ + clib_error_t *error = 0; + vlib_node_main_t *nm = &vm->node_main; + u8 *chroot_filename = 0; + int fd; + vlib_node_t **nodes = 0; + uword i, j; + + if (!unformat_user (input, unformat_vlib_tmpfile, &chroot_filename)) + { + fd = -1; + } + else + { + fd = + open ((char *) chroot_filename, O_CREAT | O_TRUNC | O_WRONLY, 0664); + } + +#define format__(vm__, fd__, ...) \ + if ((fd) < 0) \ + { \ + vlib_cli_output((vm__), ## __VA_ARGS__); \ + } \ + else \ + { \ + fdformat((fd__), ## __VA_ARGS__); \ + } + + format__ (vm, fd, "%s", "digraph {\n"); + + nodes = vec_dup (nm->nodes); + vec_sort_with_function (nodes, node_cmp); + + for (i = 0; i < vec_len (nodes); i++) + { + for (j = 0; j < vec_len (nodes[i]->next_nodes); j++) + { + vlib_node_t *x; + + if (nodes[i]->next_nodes[j] == VLIB_INVALID_NODE_INDEX) + continue; + + x = vec_elt (nm->nodes, nodes[i]->next_nodes[j]); + format__ (vm, fd, " \"%v\" -> \"%v\"\n", nodes[i]->name, x->name); + } + } + + format__ (vm, fd, "%s", "}"); + + if (fd >= 0) + { + vlib_cli_output (vm, + "vlib graph dumped into `%s'. Run eg. `fdp -Tsvg -O %s'.", + chroot_filename, chroot_filename); + } + + vec_free (nodes); + vec_free (chroot_filename); + vec_free (nodes); + if (fd >= 0) + close (fd); + return error; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (show_node_graphviz_command, static) = { + .path = "show vlib graphviz", + .short_help = "Dump packet processing node graph as a graphviz dotfile", + .function = show_node_graphviz, +}; +/* *INDENT-ON* */ + static u8 * format_vlib_node_state (u8 * s, va_list * va) { @@ -152,15 +230,16 @@ format_vlib_node_stats (u8 * s, va_list * va) if (!n) { if (max) - return format (s, - "%=30s%=17s%=16s%=16s%=16s%=16s", - "Name", "Max Node Clocks", "Vectors at Max", - "Max Clocks", "Avg Clocks", "Avg Vectors/Call"); + s = format (s, + "%=30s%=17s%=16s%=16s%=16s%=16s", + "Name", "Max Node Clocks", "Vectors at Max", + "Max Clocks", "Avg Clocks", "Avg Vectors/Call"); else - return format (s, - "%=30s%=12s%=16s%=16s%=16s%=16s%=16s", - "Name", "State", "Calls", "Vectors", "Suspends", - "Clocks", "Vectors/Call"); + s = format (s, + "%=30s%=12s%=16s%=16s%=16s%=16s%=16s", + "Name", "State", "Calls", "Vectors", "Suspends", + "Clocks", "Vectors/Call"); + return s; } indent = format_get_indent (s); @@ -345,9 +424,9 @@ show_node_runtime (vlib_main_t * vm, if (j > 0) vlib_cli_output (vm, "---------------"); - if (w->lcore_id > -1) + if (w->cpu_id > -1) vlib_cli_output (vm, "Thread %d %s (lcore %u)", j, w->name, - w->lcore_id); + w->cpu_id); else vlib_cli_output (vm, "Thread %d %s", j, w->name); } @@ -459,27 +538,40 @@ show_node (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = 0; vlib_node_main_t *nm = &vm->node_main; vlib_node_t *n; u8 *s = 0, *s2 = 0; u32 i, node_index = ~0; char *type_str; + u8 valid_node_name = 0; if (!unformat_user (input, unformat_line_input, line_input)) return 0; while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "%U", unformat_vlib_node, vm, &node_index)) - ; - else if (unformat (line_input, "index %u", &node_index)) + if (unformat (line_input, "index %u", &node_index)) ; else - return clib_error_return (0, "unknown input '%U'", - format_unformat_error, line_input); + if (unformat (line_input, "%U", unformat_vlib_node, vm, &node_index)) + valid_node_name = 1; + else if (!valid_node_name) + error = clib_error_return (0, "unknown node name: '%U'", + format_unformat_error, line_input); + else + error = clib_error_return (0, "unknown input '%U'", + format_unformat_error, line_input); + + if (error) + break; } + unformat_free (line_input); + if (error) + return error; + if (node_index >= vec_len (vm->node_main.nodes)) return clib_error_return (0, "please specify valid node");