X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fcli.c;h=98d57c6ccb0547f4c1d55daa7d795c8f29534381;hb=refs%2Fchanges%2F76%2F40476%2F2;hp=db82dede1521ae6def319a141998f645f1ce552a;hpb=b2c31b685fd2cf28436ca32bc93e23eb24c74878;p=vpp.git diff --git a/src/vlib/cli.c b/src/vlib/cli.c index db82dede152..98d57c6ccb0 100644 --- a/src/vlib/cli.c +++ b/src/vlib/cli.c @@ -38,6 +38,7 @@ */ #include +#include #include #include #include @@ -54,36 +55,28 @@ int vl_api_get_elog_trace_api_messages (void); static void *current_traced_heap; /* Root of all show commands. */ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (vlib_cli_show_command, static) = { .path = "show", .short_help = "Show commands", }; -/* *INDENT-ON* */ /* Root of all clear commands. */ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (vlib_cli_clear_command, static) = { .path = "clear", .short_help = "Clear commands", }; -/* *INDENT-ON* */ /* Root of all set commands. */ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (vlib_cli_set_command, static) = { .path = "set", .short_help = "Set commands", }; -/* *INDENT-ON* */ /* Root of all test commands. */ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (vlib_cli_test_command, static) = { .path = "test", .short_help = "Test commands", }; -/* *INDENT-ON* */ /* Returns bitmap of commands which match key. */ static uword * @@ -158,6 +151,64 @@ done: return match; } +uword +unformat_vlib_cli_line (unformat_input_t *i, va_list *va) +{ + unformat_input_t *result = va_arg (*va, unformat_input_t *); + u8 *line = 0; + uword c; + int skip; + +next_line: + skip = 0; + + /* skip leading whitespace if any */ + unformat_skip_white_space (i); + + if (unformat_is_eof (i)) + return 0; + + while ((c = unformat_get_input (i)) != UNFORMAT_END_OF_INPUT) + { + if (c == '\\') + { + c = unformat_get_input (i); + + if (c == '\n') + { + if (!skip) + vec_add1 (line, '\n'); + skip = 0; + continue; + } + + if (!skip) + vec_add1 (line, '\\'); + + if (c == UNFORMAT_END_OF_INPUT) + break; + + if (!skip) + vec_add1 (line, c); + continue; + } + + if (c == '#') + skip = 1; + else if (c == '\n') + break; + + if (!skip) + vec_add1 (line, c); + } + + if (line == 0) + goto next_line; + + unformat_init_vector (result, line); + return 1; +} + /* Looks for string based sub-input formatted { SUB-INPUT }. */ uword unformat_vlib_cli_sub_input (unformat_input_t * i, va_list * args) @@ -205,10 +256,11 @@ get_sub_command (vlib_cli_main_t * cm, vlib_cli_command_t * parent, u32 si) static uword unformat_vlib_cli_sub_command (unformat_input_t * i, va_list * args) { - vlib_main_t *vm = va_arg (*args, vlib_main_t *); + vlib_main_t __clib_unused *vm = va_arg (*args, vlib_main_t *); + vlib_global_main_t *vgm = vlib_get_global_main (); vlib_cli_command_t *c = va_arg (*args, vlib_cli_command_t *); vlib_cli_command_t **result = va_arg (*args, vlib_cli_command_t **); - vlib_cli_main_t *cm = &vm->cli_main; + vlib_cli_main_t *cm = &vgm->cli_main; uword *match_bitmap, is_unique, index; match_bitmap = vlib_cli_sub_command_match (c, i); @@ -238,8 +290,8 @@ vlib_cli_get_possible_completions (u8 * str) { vlib_cli_command_t *c; vlib_cli_sub_command_t *sc; - vlib_main_t *vm = vlib_get_main (); - vlib_cli_main_t *vcm = &vm->cli_main; + vlib_global_main_t *vgm = vlib_get_global_main (); + vlib_cli_main_t *vcm = &vgm->cli_main; uword *match_bitmap = 0; uword index, is_unique, help_next_level; u8 **result = 0; @@ -303,8 +355,7 @@ vlib_cli_get_possible_completions (u8 * str) /* if we have a space at the end of input, and a unique match, * autocomplete the next level of subcommands */ help_next_level = (vec_len (str) == 0) || isspace (str[vec_len (str) - 1]); - /* *INDENT-OFF* */ - clib_bitmap_foreach(index, match_bitmap, { + clib_bitmap_foreach (index, match_bitmap) { if (help_next_level && is_unique) { c = get_sub_command (vcm, c, index); vec_foreach (sc, c->sub_commands) { @@ -314,8 +365,7 @@ vlib_cli_get_possible_completions (u8 * str) } sc = &c->sub_commands[index]; vec_add1(result, (u8*) sc->name); - }); - /* *INDENT-ON* */ + } done: clib_bitmap_free (match_bitmap); @@ -388,11 +438,12 @@ vlib_cli_dispatch_sub_commands (vlib_main_t * vm, unformat_input_t * input, uword parent_command_index) { + vlib_global_main_t *vgm = vlib_get_global_main (); vlib_cli_command_t *parent, *c; clib_error_t *error = 0; unformat_input_t sub_input; u8 *string; - uword is_main_dispatch = cm == &vm->cli_main; + uword is_main_dispatch = cm == &vgm->cli_main; parent = vec_elt_at_index (cm->commands, parent_command_index); if (is_main_dispatch && unformat (input, "help")) @@ -472,6 +523,23 @@ vlib_cli_dispatch_sub_commands (vlib_main_t * vm, vec_free (string); } + else if (unformat (input, "vpplog %v", &string)) + { + int i; + /* + * Delete leading whitespace, so "vpplog { this and that }" + * and "vpplog this" line up nicely. + */ + for (i = 0; i < vec_len (string); i++) + if (string[i] != ' ') + break; + if (i > 0) + vec_delete (string, i, 0); + + vlib_log_notice (cm->log, "CLI: %v", string); + vec_free (string); + } + else if (unformat (input, "uncomment %U", unformat_vlib_cli_sub_input, &sub_input)) { @@ -547,19 +615,17 @@ vlib_cli_dispatch_sub_commands (vlib_main_t * vm, { if (PREDICT_FALSE (vm->elog_trace_cli_commands)) { - /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = { .format = "cli-cmd: %s", .format_args = "T4", }; - /* *INDENT-ON* */ struct { u32 c; } *ed; - ed = ELOG_DATA (&vm->elog_main, e); - ed->c = elog_string (&vm->elog_main, "%v", c->path); + ed = ELOG_DATA (vlib_get_elog_main (), e); + ed->c = elog_string (vlib_get_elog_main (), "%v", c->path); } if (!c->is_mp_safe) @@ -579,28 +645,26 @@ vlib_cli_dispatch_sub_commands (vlib_main_t * vm, if (PREDICT_FALSE (vm->elog_trace_cli_commands)) { - /* *INDENT-OFF* */ ELOG_TYPE_DECLARE (e) = { .format = "cli-cmd: %s %s", .format_args = "T4T4", }; - /* *INDENT-ON* */ struct { u32 c, err; } *ed; - ed = ELOG_DATA (&vm->elog_main, e); - ed->c = elog_string (&vm->elog_main, "%v", c->path); + ed = ELOG_DATA (vlib_get_elog_main (), e); + ed->c = elog_string (vlib_get_elog_main (), "%v", c->path); if (c_error) { vec_add1 (c_error->what, 0); - ed->err = - elog_string (&vm->elog_main, (char *) c_error->what); - _vec_len (c_error->what) -= 1; + ed->err = elog_string (vlib_get_elog_main (), + (char *) c_error->what); + vec_dec_len (c_error->what, 1); } else - ed->err = elog_string (&vm->elog_main, "OK"); + ed->err = elog_string (vlib_get_elog_main (), "OK"); } if (c_error) @@ -657,6 +721,7 @@ vlib_cli_input (vlib_main_t * vm, unformat_input_t * input, vlib_cli_output_function_t * function, uword function_arg) { + vlib_global_main_t *vgm = vlib_get_global_main (); vlib_process_t *cp = vlib_get_current_process (vm); clib_error_t *error; vlib_cli_output_function_t *save_function; @@ -671,7 +736,7 @@ vlib_cli_input (vlib_main_t * vm, do { - error = vlib_cli_dispatch_sub_commands (vm, &vm->cli_main, input, + error = vlib_cli_dispatch_sub_commands (vm, &vgm->cli_main, input, /* parent */ 0); } while (!error && !unformat (input, "%U", unformat_eof)); @@ -733,13 +798,6 @@ vl_msg_pop_heap (void *oldheap) { } -void *vlib_stats_push_heap (void *) __attribute__ ((weak)); -void * -vlib_stats_push_heap (void *notused) -{ - return 0; -} - static clib_error_t * show_memory_usage (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) @@ -800,14 +858,14 @@ show_memory_usage (vlib_main_t * vm, } if (stats_segment) { - void *oldheap = vlib_stats_push_heap (0); + void *oldheap = vlib_stats_set_heap (); was_enabled = clib_mem_trace_enable_disable (0); u8 *s_in_svm = format (0, "%U\n", format_clib_mem_heap, 0, 1); if (oldheap) clib_mem_set_heap (oldheap); u8 *s = vec_dup (s_in_svm); - oldheap = vlib_stats_push_heap (0); + oldheap = vlib_stats_set_heap (); vec_free (s_in_svm); if (oldheap) { @@ -829,17 +887,14 @@ show_memory_usage (vlib_main_t * vm, */ was_enabled = clib_mem_trace_enable_disable (0); - /* *INDENT-OFF* */ - foreach_vlib_main ( - ({ - vlib_cli_output (vm, "%sThread %d %s\n", index ? "\n":"", index, - vlib_worker_threads[index].name); - vlib_cli_output (vm, " %U\n", format_clib_mem_heap, - mm->per_cpu_mheaps[index], - verbose); - index++; - })); - /* *INDENT-ON* */ + foreach_vlib_main () + { + vlib_cli_output (vm, "%sThread %d %s\n", index ? "\n" : "", index, + vlib_worker_threads[index].name); + vlib_cli_output (vm, " %U\n", format_clib_mem_heap, + mm->per_cpu_mheaps[index], verbose); + index++; + } /* Restore the trace flag */ clib_mem_trace_enable_disable (was_enabled); @@ -908,14 +963,12 @@ show_memory_usage (vlib_main_t * vm, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_memory_usage_command, static) = { .path = "show memory", .short_help = "show memory [api-segment][stats-segment][verbose]\n" - " [numa-heaps][map]", + " [numa-heaps][map][main-heap]", .function = show_memory_usage, }; -/* *INDENT-ON* */ static clib_error_t * show_cpu (vlib_main_t * vm, unformat_input_t * input, @@ -942,13 +995,11 @@ show_cpu (vlib_main_t * vm, unformat_input_t * input, * Base Frequency: 3.20 GHz * @cliexend ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_cpu_command, static) = { .path = "show cpu", .short_help = "Show cpu information", .function = show_cpu, }; -/* *INDENT-ON* */ static clib_error_t * enable_disable_memory_trace (vlib_main_t * vm, @@ -1021,7 +1072,7 @@ enable_disable_memory_trace (vlib_main_t * vm, /* Stats segment */ if (stats_segment) { - oldheap = vlib_stats_push_heap (0); + oldheap = vlib_stats_set_heap (); current_traced_heap = clib_mem_get_heap (); clib_mem_trace (stats_segment); /* We don't want to call vlib_stats_pop_heap... */ @@ -1056,19 +1107,18 @@ enable_disable_memory_trace (vlib_main_t * vm, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (enable_disable_memory_trace_command, static) = { .path = "memory-trace", .short_help = "memory-trace on|off [api-segment][stats-segment][main-heap]\n" " [numa-heap ]\n", .function = enable_disable_memory_trace, }; -/* *INDENT-ON* */ static clib_error_t * restart_cmd_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { + vlib_global_main_t *vgm = vlib_get_global_main (); clib_file_main_t *fm = &file_main; clib_file_t *f; @@ -1076,27 +1126,23 @@ restart_cmd_fn (vlib_main_t * vm, unformat_input_t * input, extern char **environ; /* Close all known open files */ - /* *INDENT-OFF* */ pool_foreach (f, fm->file_pool) { if (f->file_descriptor > 2) close(f->file_descriptor); } - /* *INDENT-ON* */ /* Exec ourself */ - execve (vm->name, (char **) vm->argv, environ); + execve (vgm->name, (char **) vgm->argv, environ); return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (restart_cmd,static) = { .path = "restart", .short_help = "restart process", .function = restart_cmd_fn, }; -/* *INDENT-ON* */ #ifdef TEST_CODE /* @@ -1122,13 +1168,11 @@ sleep_ten_seconds (vlib_main_t * vm, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (ping_command, static) = { .path = "test sleep", .function = sleep_ten_seconds, .short_help = "Sleep for 10 seconds", }; -/* *INDENT-ON* */ #endif /* ifdef TEST_CODE */ static uword @@ -1167,7 +1211,7 @@ vlib_cli_normalize_path (char *input, char **result) /* Remove any extra space at end. */ if (l > 0 && s[l - 1] == ' ') - _vec_len (s) -= 1; + vec_dec_len (s, 1); *result = s; return index_of_last_space; @@ -1206,6 +1250,9 @@ add_sub_command (vlib_cli_main_t * cm, uword parent_index, uword child_index) vec_add (sub_name, c->path + l + 1, vec_len (c->path) - (l + 1)); } + /* "Can't happen," check mainly to shut up coverity */ + ALWAYS_ASSERT (sub_name != 0); + if (sub_name[0] == '%') { uword *q; @@ -1335,7 +1382,8 @@ vlib_cli_command_is_empty (vlib_cli_command_t * c) clib_error_t * vlib_cli_register (vlib_main_t * vm, vlib_cli_command_t * c) { - vlib_cli_main_t *cm = &vm->cli_main; + vlib_global_main_t *vgm = vlib_get_global_main (); + vlib_cli_main_t *cm = &vgm->cli_main; clib_error_t *error = 0; uword ci, *p; char *normalized_path; @@ -1530,7 +1578,7 @@ event_logger_trace_command_fn (vlib_main_t * vm, */ if (dispatch || circuit) { - elog_main_t *em = &vm->elog_main; + elog_main_t *em = &vlib_global_main.elog_main; em->n_total_events_disable_limit = em->n_total_events + vec_len (em->event_ring); @@ -1575,7 +1623,6 @@ print_status: * @cliend * @cliexcmd{event-logger trace [api][cli][barrier][disable]} ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (event_logger_trace_command, static) = { .path = "event-logger trace", @@ -1583,7 +1630,6 @@ VLIB_CLI_COMMAND (event_logger_trace_command, static) = "[circuit-node e.g. ethernet-input][disable]", .function = event_logger_trace_command_fn, }; -/* *INDENT-ON* */ static clib_error_t * suspend_command_fn (vlib_main_t * vm, @@ -1593,7 +1639,6 @@ suspend_command_fn (vlib_main_t * vm, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (suspend_command, static) = { .path = "suspend", @@ -1601,7 +1646,6 @@ VLIB_CLI_COMMAND (suspend_command, static) = .function = suspend_command_fn, .is_mp_safe = 1, }; -/* *INDENT-ON* */ static int @@ -1609,8 +1653,8 @@ sort_cmds_by_path (void *a1, void *a2) { u32 *index1 = a1; u32 *index2 = a2; - vlib_main_t *vm = vlib_get_main (); - vlib_cli_main_t *cm = &vm->cli_main; + vlib_global_main_t *vgm = vlib_get_global_main (); + vlib_cli_main_t *cm = &vgm->cli_main; vlib_cli_command_t *c1, *c2; int i, lmin; @@ -1720,6 +1764,7 @@ static clib_error_t * show_cli_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { + vlib_global_main_t *vgm = vlib_get_global_main (); int show_mp_safe = 0; int show_not_mp_safe = 0; int show_hit = 0; @@ -1743,8 +1788,8 @@ show_cli_command_fn (vlib_main_t * vm, if (clear_hit == 0 && (show_mp_safe + show_not_mp_safe) == 0) show_mp_safe = show_not_mp_safe = 1; - vlib_cli_output (vm, "%U", format_mp_safe, &vm->cli_main, - show_mp_safe, show_not_mp_safe, show_hit, clear_hit); + vlib_cli_output (vm, "%U", format_mp_safe, &vgm->cli_main, show_mp_safe, + show_not_mp_safe, show_hit, clear_hit); if (clear_hit) vlib_cli_output (vm, "hit counters cleared..."); @@ -1791,7 +1836,6 @@ show_cli_command_fn (vlib_main_t * vm, * @cliexend ?*/ -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_cli_command, static) = { .path = "show cli", @@ -1799,12 +1843,12 @@ VLIB_CLI_COMMAND (show_cli_command, static) = .function = show_cli_command_fn, .is_mp_safe = 1, }; -/* *INDENT-ON* */ static clib_error_t * vlib_cli_init (vlib_main_t * vm) { - vlib_cli_main_t *cm = &vm->cli_main; + vlib_global_main_t *vgm = vlib_get_global_main (); + vlib_cli_main_t *cm = &vgm->cli_main; clib_error_t *error = 0; vlib_cli_command_t *cmd; @@ -1817,6 +1861,9 @@ vlib_cli_init (vlib_main_t * vm) return error; cmd = cmd->next_cli_command; } + + cm->log = vlib_log_register_class_rate_limit ( + "cli", "log", 0x7FFFFFFF /* aka no rate limit */); return error; }