summaryrefslogtreecommitdiffstats
path: root/vlib
diff options
context:
space:
mode:
Diffstat (limited to 'vlib')
-rw-r--r--vlib/vlib/cli.c50
-rw-r--r--vlib/vlib/cli.h6
-rw-r--r--vlib/vlib/node.h19
-rw-r--r--vlib/vlib/unix/cli.c5
4 files changed, 63 insertions, 17 deletions
diff --git a/vlib/vlib/cli.c b/vlib/vlib/cli.c
index 8833f4ac261..5a0867bd0f8 100644
--- a/vlib/vlib/cli.c
+++ b/vlib/vlib/cli.c
@@ -506,16 +506,17 @@ void vlib_cli_input (vlib_main_t * vm,
vlib_cli_output_function_t * function,
uword function_arg)
{
+ vlib_process_t * cp = vlib_get_current_process(vm);
vlib_cli_main_t * cm = &vm->cli_main;
clib_error_t * error;
vlib_cli_output_function_t * save_function;
uword save_function_arg;
- save_function = cm->output_function;
- save_function_arg = cm->output_function_arg;
+ save_function = cp->output_function;
+ save_function_arg = cp->output_function_arg;
- cm->output_function = function;
- cm->output_function_arg = function_arg;
+ cp->output_function = function;
+ cp->output_function_arg = function_arg;
do {
vec_reset_length (cm->parse_rule_data);
@@ -529,14 +530,14 @@ void vlib_cli_input (vlib_main_t * vm,
clib_error_free (error);
}
- cm->output_function = save_function;
- cm->output_function_arg = save_function_arg;
+ cp->output_function = save_function;
+ cp->output_function_arg = save_function_arg;
}
/* Output to current CLI connection. */
void vlib_cli_output (vlib_main_t * vm, char * fmt, ...)
{
- vlib_cli_main_t * cm = &vm->cli_main;
+ vlib_process_t * cp = vlib_get_current_process(vm);
va_list va;
u8 * s;
@@ -548,10 +549,10 @@ void vlib_cli_output (vlib_main_t * vm, char * fmt, ...)
if (vec_len (s) > 0 && s[vec_len (s)-1] != '\n')
vec_add1 (s, '\n');
- if (! cm->output_function)
+ if ((! cp) || (! cp->output_function))
fformat (stdout, "%v", s);
else
- cm->output_function (cm->output_function_arg, s, vec_len (s));
+ cp->output_function (cp->output_function_arg, s, vec_len (s));
vec_free (s);
}
@@ -665,6 +666,37 @@ VLIB_CLI_COMMAND (cmd_test_heap_validate,static) = {
.function = test_heap_validate,
};
+#ifdef TEST_CODE
+/*
+ * A trivial test harness to verify the per-process output_function
+ * is working correcty.
+ */
+
+static clib_error_t *
+sleep_ten_seconds (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ u16 i;
+ u16 my_id = rand();
+
+ vlib_cli_output(vm, "Starting 10 seconds sleep with id %u\n", my_id);
+
+ for(i=0; i<10; i++)
+ {
+ vlib_process_wait_for_event_or_clock(vm, 1.0);
+ vlib_cli_output(vm, "Iteration number %u, my id: %u\n", i, my_id);
+ }
+ vlib_cli_output(vm, "Done with sleep with id %u\n", my_id);
+ return 0;
+}
+
+VLIB_CLI_COMMAND (ping_command, static) = {
+ .path = "test sleep",
+ .function = sleep_ten_seconds,
+ .short_help = "Sleep for 10 seconds",
+};
+#endif /* ifdef TEST_CODE */
static uword vlib_cli_normalize_path (char * input, char ** result)
{
diff --git a/vlib/vlib/cli.h b/vlib/vlib/cli.h
index 8c802475176..22aa22e6342 100644
--- a/vlib/vlib/cli.h
+++ b/vlib/vlib/cli.h
@@ -128,12 +128,6 @@ typedef void (vlib_cli_output_function_t) (uword arg,
u8 * buffer,
uword buffer_bytes);
typedef struct {
- /* Current output function. */
- vlib_cli_output_function_t * output_function;
-
- /* Opaque data for output function. */
- uword output_function_arg;
-
/* Vector of all known commands. */
vlib_cli_command_t * commands;
diff --git a/vlib/vlib/node.h b/vlib/vlib/node.h
index 348ad1f3b8c..2caede6e411 100644
--- a/vlib/vlib/node.h
+++ b/vlib/vlib/node.h
@@ -496,17 +496,32 @@ typedef struct {
/* When suspending saves cpu cycle counter when process is to be resumed. */
u64 resume_cpu_time;
+ /* Default output function and its argument for any CLI outputs
+ within the process. */
+ vlib_cli_output_function_t *output_function;
+ uword output_function_arg;
+
#ifdef CLIB_UNIX
/* Pad to a multiple of the page size so we can mprotect process stacks */
- CLIB_PAD_FROM_TO (0x140, 0x1000);
+#define PAGE_SIZE_MULTIPLE 0x1000
+#define ALIGN_ON_MULTIPLE_PAGE_BOUNDARY_FOR_MPROTECT __attribute__ ((aligned (PAGE_SIZE_MULTIPLE)))
+#else
+#define ALIGN_ON_MULTIPLE_PAGE_BOUNDARY_FOR_MPROTECT
#endif
+
/* Process stack. Starts here and extends 2^log2_n_stack_bytes
bytes. */
#define VLIB_PROCESS_STACK_MAGIC (0xdead7ead)
- u32 stack[0];
+ u32 stack[0] ALIGN_ON_MULTIPLE_PAGE_BOUNDARY_FOR_MPROTECT;
} vlib_process_t __attribute__ ((aligned (CLIB_CACHE_LINE_BYTES)));
+#ifdef CLIB_UNIX
+ /* Ensure that the stack is aligned on the multiple of the page size */
+typedef char assert_process_stack_must_be_aligned_exactly_to_page_size_multiple
+ [(sizeof(vlib_process_t) - PAGE_SIZE_MULTIPLE) == 0 ? 0 : -1];
+#endif
+
typedef struct {
u32 node_index;
diff --git a/vlib/vlib/unix/cli.c b/vlib/vlib/unix/cli.c
index 0aa7f23cbc3..dc9ac2aeea5 100644
--- a/vlib/vlib/unix/cli.c
+++ b/vlib/vlib/unix/cli.c
@@ -1889,6 +1889,11 @@ static u32 unix_cli_file_add (unix_cli_main_t * cm, char * name, int fd)
cf->input_vector = 0;
vlib_start_process (vm, n->runtime_index);
+
+ vlib_process_t * p = vlib_get_process_from_node(vm, n);
+ p->output_function = unix_vlib_cli_output;
+ p->output_function_arg = cf - cm->cli_file_pool;
+
return cf - cm->cli_file_pool;
}