Skip to content

Commit

Permalink
ovn-controller: Add a generic way to check if the daemon started rece…
Browse files Browse the repository at this point in the history
…ntly.

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 <[email protected]>
Signed-off-by: Han Zhou <[email protected]>
Acked-by: Dumitru Ceara <[email protected]>
  • Loading branch information
hzhou8 committed Aug 19, 2022
1 parent 50b3af8 commit 5d733bb
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 3 deletions.
7 changes: 7 additions & 0 deletions TODO.rst
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,10 @@ OVN To-do List
* Multi-threaded logical flow computation was optimized for the case
when datapath groups are disabled. Datpath groups are always enabled
now so northd parallel processing should be revisited.

* ovn-controller daemon module

* Dumitru Ceara: Add a new module e.g. ovn/lib/daemon-ovn.c that wraps
OVS' daemonize_start() call and initializes the additional things, like
the unixctl commands. Or, we should move the APIs such as
daemon_started_recently() to OVS's lib/daemon.
22 changes: 19 additions & 3 deletions controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,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"
Expand Down Expand Up @@ -866,11 +867,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,
Expand Down Expand Up @@ -3858,6 +3860,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;
Expand All @@ -3879,7 +3884,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();
Expand Down Expand Up @@ -4059,6 +4063,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) {
Expand Down Expand Up @@ -4221,7 +4229,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 =
Expand Down Expand Up @@ -4698,3 +4706,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);
}
11 changes: 11 additions & 0 deletions lib/inc-proc-eng.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
4 changes: 4 additions & 0 deletions lib/inc-proc-eng.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
52 changes: 52 additions & 0 deletions lib/ovn-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -883,3 +883,55 @@ 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;

/* Used by debug command only, for tests. */
static bool ignore_startup_delay = false;

OVS_CONSTRUCTOR(startup_ts_initializer) {
startup_ts = time_wall_msec();
}

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;
}
4 changes: 4 additions & 0 deletions lib/ovn-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit 5d733bb

Please sign in to comment.