On Wed, Aug 17, 2022 at 8:27 AM Dumitru Ceara <dce...@redhat.com> wrote: > > On 7/25/22 23:34, Han Zhou wrote: > > In some cases we need to know if ovn-controller started long enough and > > has enough iterations of input processing, primarily to ensure it has > > downloaded and handled a complete initial view of the SB DB (and of > > course the local OVS DB), so that it won't delete things too early by > > mistake based on incomplete data. > > > > The mechanism will be used in follow up patches. > > > > Suggested-by: Dumitru Ceara <dce...@redhat.com> > > Signed-off-by: Han Zhou <hz...@ovn.org> > > --- > > Hi Han, > > > controller/ovn-controller.c | 22 +++++++++++++--- > > lib/inc-proc-eng.c | 11 ++++++++ > > lib/inc-proc-eng.h | 4 +++ > > lib/ovn-util.c | 50 +++++++++++++++++++++++++++++++++++++ > > lib/ovn-util.h | 4 +++ > > 5 files changed, 88 insertions(+), 3 deletions(-) > > > > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c > > index 2e9138036..8fc554201 100644 > > --- a/controller/ovn-controller.c > > +++ b/controller/ovn-controller.c > > @@ -93,6 +93,7 @@ static unixctl_cb_func debug_dump_lflow_conj_ids; > > static unixctl_cb_func lflow_cache_flush_cmd; > > static unixctl_cb_func lflow_cache_show_stats_cmd; > > static unixctl_cb_func debug_delay_nb_cfg_report; > > +static unixctl_cb_func debug_ignore_startup_delay; > > > > #define DEFAULT_BRIDGE_NAME "br-int" > > #define DEFAULT_DATAPATH "system" > > @@ -863,11 +864,12 @@ static void > > store_nb_cfg(struct ovsdb_idl_txn *sb_txn, struct ovsdb_idl_txn *ovs_txn, > > const struct sbrec_chassis_private *chassis, > > const struct ovsrec_bridge *br_int, > > - unsigned int delay_nb_cfg_report, int64_t startup_ts) > > + unsigned int delay_nb_cfg_report) > > { > > struct ofctrl_acked_seqnos *acked_nb_cfg_seqnos = > > ofctrl_acked_seqnos_get(ofctrl_seq_type_nb_cfg); > > uint64_t cur_cfg = acked_nb_cfg_seqnos->last_acked; > > + int64_t startup_ts = daemon_startup_ts(); > > > > if (ovs_txn && br_int > > && startup_ts != smap_get_ullong(&br_int->external_ids, > > @@ -3796,6 +3798,9 @@ main(int argc, char *argv[]) > > debug_dump_lflow_conj_ids, > > &lflow_output_data->conj_ids); > > > > + unixctl_command_register("debug/ignore-startup-delay", "", 0, 0, > > + debug_ignore_startup_delay, NULL); > > + > > unsigned int ovs_cond_seqno = UINT_MAX; > > unsigned int ovnsb_cond_seqno = UINT_MAX; > > unsigned int ovnsb_expected_cond_seqno = UINT_MAX; > > @@ -3817,7 +3822,6 @@ main(int argc, char *argv[]) > > /* Main loop. */ > > exiting = false; > > restart = false; > > - int64_t startup_ts = time_wall_msec(); > > bool sb_monitor_all = false; > > while (!exiting) { > > memory_run(); > > @@ -3997,6 +4001,10 @@ main(int argc, char *argv[]) > > } > > stopwatch_stop(CONTROLLER_LOOP_STOPWATCH_NAME, > > time_msec()); > > + if (engine_has_updated()) { > > + daemon_started_recently_countdown(); > > + } > > + > > ct_zones_data = engine_get_data(&en_ct_zones); > > if (ovs_idl_txn) { > > if (ct_zones_data) { > > @@ -4159,7 +4167,7 @@ main(int argc, char *argv[]) > > } > > > > store_nb_cfg(ovnsb_idl_txn, ovs_idl_txn, chassis_private, > > - br_int, delay_nb_cfg_report, startup_ts); > > + br_int, delay_nb_cfg_report); > > > > if (pending_pkt.conn) { > > struct ed_type_addr_sets *as_data = > > @@ -4633,3 +4641,11 @@ debug_dump_lflow_conj_ids(struct unixctl_conn *conn, int argc OVS_UNUSED, > > unixctl_command_reply(conn, ds_cstr(&conj_ids_dump)); > > ds_destroy(&conj_ids_dump); > > } > > + > > +static void > > +debug_ignore_startup_delay(struct unixctl_conn *conn, int argc OVS_UNUSED, > > + const char *argv[] OVS_UNUSED, void *arg OVS_UNUSED) > > +{ > > + daemon_started_recently_ignore(); > > + unixctl_command_reply(conn, NULL); > > +} > > diff --git a/lib/inc-proc-eng.c b/lib/inc-proc-eng.c > > index 575b774ae..2e2b31033 100644 > > --- a/lib/inc-proc-eng.c > > +++ b/lib/inc-proc-eng.c > > @@ -312,6 +312,17 @@ engine_has_run(void) > > return false; > > } > > > > +bool > > +engine_has_updated(void) > > +{ > > + for (size_t i = 0; i < engine_n_nodes; i++) { > > + if (engine_nodes[i]->state == EN_UPDATED) { > > + return true; > > + } > > + } > > + return false; > > +} > > + > > bool > > engine_aborted(void) > > { > > diff --git a/lib/inc-proc-eng.h b/lib/inc-proc-eng.h > > index 9bfab1f7c..dc365dc18 100644 > > --- a/lib/inc-proc-eng.h > > +++ b/lib/inc-proc-eng.h > > @@ -238,6 +238,10 @@ bool engine_node_changed(struct engine_node *node); > > /* Return true if the engine has run in the last iteration. */ > > bool engine_has_run(void); > > > > +/* Return true if the engine has any update in any node, i.e. any input > > + * has changed; false if nothing has changed. */ > > +bool engine_has_updated(void); > > + > > /* Returns true if during the last engine run we had to abort processing. */ > > bool engine_aborted(void); > > > > diff --git a/lib/ovn-util.c b/lib/ovn-util.c > > index 616999eab..693735841 100644 > > --- a/lib/ovn-util.c > > +++ b/lib/ovn-util.c > > @@ -883,3 +883,53 @@ get_bridge(const struct ovsrec_bridge_table *bridge_table, const char *br_name) > > } > > return NULL; > > } > > + > > +#define DAEMON_STARTUP_DELAY_SEED 20 > > +#define DAEMON_STARTUP_DELAY_MS 10000 > > + > > +static int64_t startup_ts; > > +static int startup_delay = DAEMON_STARTUP_DELAY_SEED; > > +static bool ignore_startup_delay = false; > > + > > +OVS_CONSTRUCTOR(startup_ts_initializer) { > > + startup_ts = time_wall_msec(); > > A bit of a nit, but if we moved the "debug/ignore-startup-delay" unixctl > registration here, we wouldn't need the daemon_started_recently_ignore() > api either.
Maybe, but I'd avoid register unix commands from the util module since it doesn't seem to have a proper "initialize" place to do that. Now that I register the command in main(), we will need an API anyway, either for the command function, or for the current API, so I just left as is. > > I think I would also add a comment specifying that this is needed just > for the sake of making the test reliable. > Ack. I added a comment for the ignore_startup_delay variable in v3. Thanks, Han > > +} > > + > > +int64_t > > +daemon_startup_ts(void) > > +{ > > + return startup_ts; > > +} > > + > > +void > > +daemon_started_recently_countdown(void) > > +{ > > + if (startup_delay > 0) { > > + startup_delay--; > > + } > > +} > > + > > +void > > +daemon_started_recently_ignore(void) > > +{ > > + ignore_startup_delay = true; > > +} > > + > > +bool > > +daemon_started_recently(void) > > +{ > > + if (ignore_startup_delay) { > > + return false; > > + } > > + > > + VLOG_DBG("startup_delay: %d, startup_ts: %"PRId64, startup_delay, > > + startup_ts); > > + > > + /* Ensure that at least an amount of updates has been handled. */ > > + if (startup_delay) { > > + return true; > > + } > > + > > + /* Ensure that at least an amount of time has passed. */ > > + return time_wall_msec() - startup_ts <= DAEMON_STARTUP_DELAY_MS; > > +} > > diff --git a/lib/ovn-util.h b/lib/ovn-util.h > > index b3905ef7b..145f974ed 100644 > > --- a/lib/ovn-util.h > > +++ b/lib/ovn-util.h > > @@ -309,5 +309,9 @@ struct ovsrec_bridge_table; > > const struct ovsrec_bridge *get_bridge(const struct ovsrec_bridge_table *, > > const char *br_name); > > > > +void daemon_started_recently_countdown(void); > > +void daemon_started_recently_ignore(void); > > +bool daemon_started_recently(void); > > +int64_t daemon_startup_ts(void); > > > > #endif /* OVN_UTIL_H */ > > > Thanks, > Dumitru > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev