57 while (*s && *s !=
',')
76 (_vlib_init_function_list_elt_t ** head)
80 u8 **init_f_names = 0;
82 char **these_constraints;
83 char *this_constraint_c;
95 _vlib_init_function_list_elt_t *this_reg = 0;
97 u8 **keys_to_delete = 0;
111 init_f_name =
format (0,
"%s%c", this_reg->name, 0);
116 vec_add1 (init_f_names, init_f_name);
118 these_constraints = this_reg->runs_before;
119 while (these_constraints && these_constraints[0])
121 this_constraint_c = these_constraints[0];
123 constraint_tuple =
format (0,
"%s,%s%c", init_f_name,
124 this_constraint_c, 0);
125 vec_add1 (constraints, constraint_tuple);
129 these_constraints = this_reg->runs_after;
130 while (these_constraints && these_constraints[0])
132 this_constraint_c = these_constraints[0];
134 constraint_tuple =
format (0,
"%s,%s%c",
135 this_constraint_c, init_f_name, 0);
136 vec_add1 (constraints, constraint_tuple);
140 this_reg = this_reg->next_init_function;
150 these_constraints = this_reg->init_order;
154 while (these_constraints && these_constraints[0])
156 this_constraint_c = these_constraints[0];
161 (
"order constraint fcn '%s' not found", this_constraint_c);
168 prev_name = this_constraint_c;
173 constraint_tuple =
format (0,
"%s,%s%c", prev_name,
174 this_constraint_c, 0);
175 vec_add1 (constraints, constraint_tuple);
176 prev_name = this_constraint_c;
179 this_reg = this_reg->next_init_function;
182 n_init_fns =
vec_len (init_f_names);
185 for (i = 0; i <
vec_len (constraints); i++)
187 this_constraint = constraints[
i];
189 if (
comma_split (this_constraint, &a_name, &b_name))
200 clib_warning (
"init function '%s' not found (before '%s')",
209 clib_warning (
"init function '%s' not found (after '%s')",
216 orig[a_index][b_index] = 1;
225 for (i = 0; i < n_init_fns; i++)
227 for (j = 0; j < n_init_fns; j++)
230 goto item_constrained;
235 for (k = 0; k < n_init_fns; k++)
249 if (vec_len (result) != n_init_fns)
251 (0,
"Failed to find a suitable init function order!");
262 for (i = 0; i < n_init_fns; i++)
264 p =
hash_get (reg_by_index, result[i]);
266 this_reg = (_vlib_init_function_list_elt_t *) p[0];
268 this_reg->next_init_function = *head;
280 for (i = 0; i <
vec_len (keys_to_delete); i++)
334 _vlib_init_function_list_elt_t ** headp,
335 int call_once,
int do_sort)
338 _vlib_init_function_list_elt_t *
i;
354 i = i->next_init_function;
361 _vlib_init_function_list_elt_t ** headp,
370 _vlib_init_function_list_elt_t **
371 headp,
int call_once)
382 #define _(f) vlib_##f##_reference (); 444 for (i = 0; i <
vec_len (all); i++)
463 for (i = 0; i <
vec_len (all); i++)
479 _vlib_init_function_list_elt_t *head, *
this;
486 this = this->next_init_function;
498 _vlib_init_function_list_elt_t *head, *
this;
499 uword *index_by_name;
501 u8 **init_f_names = 0;
504 _vlib_init_function_list_elt_t *this_reg = 0;
506 u8 **keys_to_delete = 0;
516 else if (
unformat (input,
"verbose %d", &verbose))
518 else if (
unformat (input,
"verbose"))
546 this = this->next_init_function;
559 init_f_name =
format (0,
"%s%c", this_reg->name, 0);
563 vec_add1 (init_f_names, init_f_name);
565 this_reg = this_reg->next_init_function;
568 for (i = 0; i < n_init_fns; i++)
572 this_reg = (_vlib_init_function_list_elt_t *) p[0];
575 char **runs_before, **runs_after, **init_order;
576 runs_before = this_reg->runs_before;
577 while (runs_before && runs_before[0])
579 _vlib_init_function_list_elt_t *successor;
580 uword successor_index;
584 clib_warning (
"couldn't find successor '%s'", runs_before[0]);
588 successor_index = p[0];
591 successor = (_vlib_init_function_list_elt_t *) p[0];
593 successor->
name, successor_index);
596 runs_after = this_reg->runs_after;
597 while (runs_after && runs_after[0])
599 _vlib_init_function_list_elt_t *predecessor;
600 uword predecessor_index;
609 predecessor_index = p[0];
612 predecessor = (_vlib_init_function_list_elt_t *) p[0];
614 predecessor->
name, predecessor_index);
617 init_order = this_reg->init_order;
618 while (init_order && init_order[0])
620 _vlib_init_function_list_elt_t *inorder;
630 inorder_index = p[0];
633 inorder = (_vlib_init_function_list_elt_t *) p[0];
635 inorder->
name, inorder_index);
647 for (i = 0; i <
vec_len (keys_to_delete); i++)
664 .path =
"show init-function",
665 .short_help =
"show init-function [init | enter | exit][verbose [nn]]",
static clib_error_t * show_init_function_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
clib_error_t * vlib_call_all_main_loop_exit_functions(vlib_main_t *vm)
#define hash_set(h, key, value)
clib_error_t * vlib_call_all_main_loop_enter_functions(vlib_main_t *vm)
_vlib_init_function_list_elt_t * init_function_registrations
_vlib_init_function_list_elt_t * main_loop_exit_function_registrations
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define foreach_vlib_module_reference
#define hash_set_mem(h, key, value)
vlib_config_function_t * function
static vlib_cli_command_t show_init_function
(constructor) VLIB_CLI_COMMAND (show_init_function)
clib_error_t * vlib_sort_init_exit_functions(_vlib_init_function_list_elt_t **head)
Topological sorter for init function chains.
clib_error_t * vlib_call_init_exit_functions(vlib_main_t *vm, _vlib_init_function_list_elt_t **headp, int call_once)
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
clib_error_t * vlib_call_init_exit_functions_no_sort(vlib_main_t *vm, _vlib_init_function_list_elt_t **headp, int call_once)
#define clib_error_return(e, args...)
#define clib_error_create(args...)
#define hash_create_string(elts, value_bytes)
u8 ** clib_ptclosure_alloc(int n)
uword * init_functions_called
**The first form will [most likely] call init_runs_next on the *spot The second form means that init_runs_first runs before possibly much earlier in the sequence **Please DO NOT construct sets of init functions where A before B *actually means A *right before *B It s not necessary simply combine *A and B and it leads to hugely annoying debugging exercises *static clib_error_t * call_init_exit_functions_internal(vlib_main_t *vm, _vlib_init_function_list_elt_t **headp, int call_once, int do_sort)
void clib_ptclosure_free(u8 **ptc)
#define vec_free(V)
Free vector's memory (no header).
#define clib_warning(format, args...)
#define VLIB_CLI_COMMAND(x,...)
#define hash_set1(h, key)
#define hash_create(elts, value_bytes)
_vlib_init_function_list_elt_t * main_loop_enter_function_registrations
static int comma_split(u8 *s, u8 **a, u8 **b)
static vlib_main_t * vlib_get_main(void)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define hash_foreach_pair(p, v, body)
Iterate over hash pairs.
clib_error_t * vlib_call_all_config_functions(vlib_main_t *vm, unformat_input_t *input, int is_early)
u8 ** clib_ptclosure(u8 **orig)
void vlib_init_dump(void)
clib_error_t * vlib_call_all_init_functions(vlib_main_t *vm)
struct vlib_config_function_runtime_t * next_registration
#define hash_get_mem(h, key)
vlib_config_function_runtime_t * config_function_registrations
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)