Wow Paulo, this is fantastic! I think this provides a great jumping-off point for developing further incremental processing in ovn-ic.
Acked-by: Mark Michelson <[email protected]> On Wed, Dec 10, 2025 at 7:28 AM Paulo Guilherme Silva via dev <[email protected]> wrote: > > Initial implementation adds a single node (ic). This single > node executes the ovn-ic processing pipeline but does not do so > incrementally. > > In order to develop incremental processing for ovn-ic, the code > will be organised with a .c/.h file for each I-P node following > the naming convention en-<node name>.c/.h. These files will > contain definition of the node data, the main node processing > functions and change handlers (if any). The purpose of these nodes > will be coordination of the nodes work and implemention of the > relevant interfaces to plug into the I-P framework. The actual > work that will be executed by the node will be organised into > a companion file or files. Ideally this file will follow the > naming convention of the node: e.g. en-<node name>.c is > associated with <node name>.c. > > Initial node topology sees the ic node dependent on all DB > nodes. This structure and approach was heavily influenced > by the way I+P was developed and evolved in the northd daemon. > > Signed-off-by: Paulo Guilherme Silva <[email protected]> > > --- > ic/automake.mk | 7 +- > ic/en-ic.c | 50 +++++ > ic/en-ic.h | 18 ++ > ic/inc-proc-ic.c | 269 +++++++++++++++++++++++++ > ic/inc-proc-ic.h | 48 +++++ > ic/ovn-ic.c | 481 ++++++++++++++++++++++++++------------------- > ic/ovn-ic.h | 61 ++++++ > lib/inc-proc-eng.h | 21 ++ > 8 files changed, 754 insertions(+), 201 deletions(-) > create mode 100644 ic/en-ic.c > create mode 100644 ic/en-ic.h > create mode 100644 ic/inc-proc-ic.c > create mode 100644 ic/inc-proc-ic.h > create mode 100644 ic/ovn-ic.h > > diff --git a/ic/automake.mk b/ic/automake.mk > index 8e71bc334..a69b1030d 100644 > --- a/ic/automake.mk > +++ b/ic/automake.mk > @@ -1,6 +1,11 @@ > # ovn-ic > bin_PROGRAMS += ic/ovn-ic > -ic_ovn_ic_SOURCES = ic/ovn-ic.c > +ic_ovn_ic_SOURCES = ic/ovn-ic.c \ > + ic/ovn-ic.h \ > + ic/en-ic.c \ > + ic/en-ic.h \ > + ic/inc-proc-ic.c \ > + ic/inc-proc-ic.h > ic_ovn_ic_LDADD = \ > lib/libovn.la \ > $(OVSDB_LIBDIR)/libovsdb.la \ > diff --git a/ic/en-ic.c b/ic/en-ic.c > new file mode 100644 > index 000000000..2db9d3b84 > --- /dev/null > +++ b/ic/en-ic.c > @@ -0,0 +1,50 @@ > +/* > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at: > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > +*/ > + > +#include <config.h> > + > +#include <getopt.h> > +#include <stdlib.h> > +#include <stdio.h> > + > +#include "en-ic.h" > +#include "lib/inc-proc-eng.h" > +#include "lib/stopwatch-names.h" > +#include "ovn-ic.h" > +#include "openvswitch/vlog.h" > + > +VLOG_DEFINE_THIS_MODULE(en_ic); > + > +enum engine_node_state > +en_ic_run(struct engine_node *node OVS_UNUSED, void *data OVS_UNUSED) > +{ > + const struct engine_context *eng_ctx = engine_get_context(); > + struct ic_context *ctx = eng_ctx->client_ctx; > + > + ovn_db_run(ctx); > + > + return EN_UPDATED; > +} > + > +void * > +en_ic_init(struct engine_node *node OVS_UNUSED, > + struct engine_arg *arg OVS_UNUSED) > +{ > + return NULL; > +} > + > +void > +en_ic_cleanup(void *data OVS_UNUSED) > +{ > +} > diff --git a/ic/en-ic.h b/ic/en-ic.h > new file mode 100644 > index 000000000..a4b75bb0e > --- /dev/null > +++ b/ic/en-ic.h > @@ -0,0 +1,18 @@ > +#ifndef EN_IC_H > +#define EN_IC_H 1 > + > +#include <config.h> > + > +#include <getopt.h> > +#include <stdlib.h> > +#include <stdio.h> > + > +#include "lib/inc-proc-eng.h" > + > +enum engine_node_state en_ic_run(struct engine_node *node OVS_UNUSED, > + void *data OVS_UNUSED); > +void *en_ic_init(struct engine_node *node OVS_UNUSED, > + struct engine_arg *arg); > +void en_ic_cleanup(void *data); > + > +#endif /* EN_IC_H */ > diff --git a/ic/inc-proc-ic.c b/ic/inc-proc-ic.c > new file mode 100644 > index 000000000..ba9fdeb9e > --- /dev/null > +++ b/ic/inc-proc-ic.c > @@ -0,0 +1,269 @@ > +/* > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at: > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +#include <config.h> > + > +#include <getopt.h> > +#include <stdlib.h> > +#include <stdio.h> > + > +#include "lib/inc-proc-eng.h" > +#include "lib/ovn-nb-idl.h" > +#include "lib/ovn-sb-idl.h" > +#include "lib/ovn-ic-nb-idl.h" > +#include "lib/ovn-ic-sb-idl.h" > +#include "openvswitch/poll-loop.h" > +#include "openvswitch/vlog.h" > +#include "inc-proc-ic.h" > +#include "en-ic.h" > +#include "unixctl.h" > +#include "util.h" > + > +VLOG_DEFINE_THIS_MODULE(inc_proc_ic); > + > +#define NB_NODES \ > + NB_NODE(nb_global, "nb_global") \ > + NB_NODE(logical_router_static_route, "logical_router_static_route") \ > + NB_NODE(logical_router, "logical_router") \ > + NB_NODE(logical_router_port, "logical_router_port") \ > + NB_NODE(logical_switch, "logical_switch") \ > + NB_NODE(logical_switch_port, "logical_switch_port") \ > + NB_NODE(load_balancer, "load_balancer") \ > + NB_NODE(load_balancer_group, "load_balancer_group") > + > + enum nb_engine_node { > +#define NB_NODE(NAME, NAME_STR) NB_##NAME, > + NB_NODES > +#undef NB_NODE > + }; > + > +/* Define engine node functions for nodes that represent NB tables > + * > + * en_nb_<TABLE_NAME>_run() > + * en_nb_<TABLE_NAME>_init() > + * en_nb_<TABLE_NAME>_cleanup() > + */ > +#define NB_NODE(NAME, NAME_STR) ENGINE_FUNC_NB(NAME); > + NB_NODES > +#undef NB_NODE > + > +#define SB_NODES \ > + SB_NODE(sb_global, "sb_global") \ > + SB_NODE(chassis, "chassis") \ > + SB_NODE(encap, "encap") \ > + SB_NODE(datapath_binding, "datapath_binding") \ > + SB_NODE(port_binding, "port_binding") \ > + SB_NODE(service_monitor, "service_monitor") > + > + enum sb_engine_node { > +#define SB_NODE(NAME, NAME_STR) SB_##NAME, > + SB_NODES > +#undef SB_NODE > +}; > + > +/* Define engine node functions for nodes that represent SB tables > + * > + * en_sb_<TABLE_NAME>_run() > + * en_sb_<TABLE_NAME>_init() > + * en_sb_<TABLE_NAME>_cleanup() > + */ > +#define SB_NODE(NAME, NAME_STR) ENGINE_FUNC_SB(NAME); > + SB_NODES > +#undef SB_NODE > + > +#define ICNB_NODES \ > + ICNB_NODE(ic_nb_global, "ic_nb_global") \ > + ICNB_NODE(transit_switch, "transit_switch") \ > + ICNB_NODE(transit_router, "transit_router") \ > + ICNB_NODE(transit_router_port, "transit_router_port") > + > + enum icnb_engine_node { > +#define ICNB_NODE(NAME, NAME_STR) ICNB_##NAME, > + ICNB_NODES > +#undef ICNB_NODE > + }; > + > +/* Define engine node functions for nodes that represent ICNB tables > + * > + * en_icnb_<TABLE_NAME>_run() > + * en_icnb_<TABLE_NAME>_init() > + * en_icnb_<TABLE_NAME>_cleanup() > + */ > +#define ICNB_NODE(NAME, NAME_STR) ENGINE_FUNC_ICNB(NAME); > + ICNB_NODES > +#undef ICNB_NODE > + > +#define ICSB_NODES \ > + ICSB_NODE(ic_sb_global, "ic_sb_global") \ > + ICSB_NODE(availability_zone, "availability_zone") \ > + ICSB_NODE(service_monitor, "service_monitor") \ > + ICSB_NODE(route, "route") \ > + ICSB_NODE(datapath_binding, "datapath_binding") \ > + ICSB_NODE(encap, "encap") \ > + ICSB_NODE(gateway, "gateway") \ > + ICSB_NODE(port_binding, "port_binding") > + > + enum icsb_engine_node { > +#define ICSB_NODE(NAME, NAME_STR) ICSB_##NAME, > + ICSB_NODES > +#undef ICSB_NODE > + }; > + > +/* Define engine node functions for nodes that represent ICSB tables > + * > + * en_icsb_<TABLE_NAME>_run() > + * en_icsb_<TABLE_NAME>_init() > + * en_icsb_<TABLE_NAME>_cleanup() > + */ > +#define ICSB_NODE(NAME, NAME_STR) ENGINE_FUNC_ICSB(NAME); > + ICSB_NODES > +#undef ICSB_NODE > + > +/* Define engine nodes for NB, SB, ICNB and ICSB tables > + * > + * struct engine_node en_nb_<TABLE_NAME> > + * struct engine_node en_sb_<TABLE_NAME> > + * struct engine_node en_icnb_<TABLE_NAME> > + * struct engine_node en_icsb_<TABLE_NAME> > + * > + * Define nodes as static to avoid sparse errors. > + */ > +#define NB_NODE(NAME, NAME_STR) static ENGINE_NODE_NB(NAME); > + NB_NODES > +#undef NB_NODE > + > +#define SB_NODE(NAME, NAME_STR) static ENGINE_NODE_SB(NAME); > + SB_NODES > +#undef SB_NODE > + > +#define ICNB_NODE(NAME, NAME_STR) static ENGINE_NODE_ICNB(NAME); > + ICNB_NODES > +#undef ICNB_NODE > + > +#define ICSB_NODE(NAME, NAME_STR) static ENGINE_NODE_ICSB(NAME); > + ICSB_NODES > +#undef ICSB_NODE > + > +/* Define engine nodes for other nodes. They should be defined as static to > + * avoid sparse errors. */ > +static ENGINE_NODE(ic); > + > +void inc_proc_ic_init(struct ovsdb_idl_loop *nb, > + struct ovsdb_idl_loop *sb, > + struct ovsdb_idl_loop *icnb, > + struct ovsdb_idl_loop *icsb) > +{ > + /* Define relationships between nodes where first argument is dependent > + * on the second argument */ > + engine_add_input(&en_ic, &en_nb_nb_global, NULL); > + engine_add_input(&en_ic, &en_nb_logical_router_static_route, NULL); > + engine_add_input(&en_ic, &en_nb_logical_router, NULL); > + engine_add_input(&en_ic, &en_nb_logical_router_port, NULL); > + engine_add_input(&en_ic, &en_nb_logical_switch, NULL); > + engine_add_input(&en_ic, &en_nb_logical_switch_port, NULL); > + engine_add_input(&en_ic, &en_nb_load_balancer, NULL); > + engine_add_input(&en_ic, &en_nb_load_balancer_group, NULL); > + > + engine_add_input(&en_ic, &en_sb_sb_global, NULL); > + engine_add_input(&en_ic, &en_sb_chassis, NULL); > + engine_add_input(&en_ic, &en_sb_encap, NULL); > + engine_add_input(&en_ic, &en_sb_datapath_binding, NULL); > + engine_add_input(&en_ic, &en_sb_port_binding, NULL); > + engine_add_input(&en_ic, &en_sb_service_monitor, NULL); > + > + engine_add_input(&en_ic, &en_icnb_ic_nb_global, NULL); > + engine_add_input(&en_ic, &en_icnb_transit_switch, NULL); > + engine_add_input(&en_ic, &en_icnb_transit_router, NULL); > + engine_add_input(&en_ic, &en_icnb_transit_router_port, NULL); > + > + engine_add_input(&en_ic, &en_icsb_encap, NULL); > + engine_add_input(&en_ic, &en_icsb_service_monitor, NULL); > + engine_add_input(&en_ic, &en_icsb_ic_sb_global, NULL); > + engine_add_input(&en_ic, &en_icsb_port_binding, NULL); > + engine_add_input(&en_ic, &en_icsb_availability_zone, NULL); > + engine_add_input(&en_ic, &en_icsb_gateway, NULL); > + engine_add_input(&en_ic, &en_icsb_route, NULL); > + engine_add_input(&en_ic, &en_icsb_datapath_binding, NULL); > + > + struct engine_arg engine_arg = { > + .nb_idl = nb->idl, > + .sb_idl = sb->idl, > + .icnb_idl = icnb->idl, > + .icsb_idl = icsb->idl, > + }; > + > + engine_init(&en_ic, &engine_arg); > +} > + > +/* Returns true if the incremental processing ended up updating nodes. */ > +bool > +inc_proc_ic_run(struct ic_context *ctx, > + struct ic_engine_context *ic_eng_ctx) > +{ > + ovs_assert(ctx->ovnnb_txn && ctx->ovnsb_txn && > + ctx->ovninb_txn && ctx->ovnisb_txn); > + > + int64_t start = time_msec(); > + engine_init_run(); > + > + struct engine_context eng_ctx = { > + .client_ctx = ctx, > + }; > + > + engine_set_context(&eng_ctx); > + engine_run(true); > + > + if (!engine_has_run()) { > + if (engine_need_run()) { > + VLOG_DBG("engine did not run, force recompute next time."); > + engine_set_force_recompute_immediate(); > + } else { > + VLOG_DBG("engine did not run, and it was not needed"); > + } > + } else if (engine_canceled()) { > + VLOG_DBG("engine was canceled, force recompute next time."); > + engine_set_force_recompute_immediate(); > + } else { > + engine_clear_force_recompute(); > + } > + > + int64_t now = time_msec(); > + /* Postpone the next run by length of current run with maximum capped > + * by "northd-backoff-interval-ms" interval. */ > + ic_eng_ctx->next_run_ms = now + MIN(now - start, ic_eng_ctx->backoff_ms); > + > + return engine_has_updated(); > +} > + > +void > +inc_proc_ic_cleanup(void) > +{ > + engine_cleanup(); > + engine_set_context(NULL); > +} > + > +bool > +inc_proc_ic_can_run(struct ic_engine_context *ctx) > +{ > + if (engine_get_force_recompute() || time_msec() >= ctx->next_run_ms || > + ctx->nb_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS || > + ctx->sb_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS || > + ctx->inb_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS || > + ctx->isb_idl_duration_ms >= IDL_LOOP_MAX_DURATION_MS) { > + return true; > + } > + > + poll_timer_wait_until(ctx->next_run_ms); > + return false; > +} > diff --git a/ic/inc-proc-ic.h b/ic/inc-proc-ic.h > new file mode 100644 > index 000000000..9af147fb3 > --- /dev/null > +++ b/ic/inc-proc-ic.h > @@ -0,0 +1,48 @@ > +#ifndef INC_PROC_IC_H > +#define INC_PROC_IC_H 1 > + > +#include <config.h> > + > +#include "ovn-ic.h" > +#include "ovsdb-idl.h" > +#include "lib/inc-proc-eng.h" > + > +struct ic_engine_context { > + int64_t next_run_ms; > + uint64_t nb_idl_duration_ms; > + uint64_t sb_idl_duration_ms; > + uint64_t inb_idl_duration_ms; > + uint64_t isb_idl_duration_ms; > + uint32_t backoff_ms; > +}; > + > +void inc_proc_ic_init(struct ovsdb_idl_loop *nb, > + struct ovsdb_idl_loop *sb, > + struct ovsdb_idl_loop *icnb, > + struct ovsdb_idl_loop *icsb); > + > +bool inc_proc_ic_run(struct ic_context *ctx, > + struct ic_engine_context *ic_eng_ctx); > + > +void inc_proc_ic_cleanup(void); > +bool inc_proc_ic_can_run(struct ic_engine_context *ctx); > + > +static inline void > +inc_proc_ic_force_recompute(void) > +{ > + engine_set_force_recompute(); > +} > + > +static inline void > +inc_proc_ic_force_recompute_immediate(void) > +{ > + engine_set_force_recompute_immediate(); > +} > + > +static inline bool > +inc_proc_ic_get_force_recompute(void) > +{ > + return engine_get_force_recompute(); > +} > + > +#endif /* INC_PROC_IC */ > diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c > index 0ef82f3a3..0e8c0953d 100644 > --- a/ic/ovn-ic.c > +++ b/ic/ovn-ic.c > @@ -46,6 +46,8 @@ > #include "uuid.h" > #include "openvswitch/vlog.h" > #include "vec.h" > +#include "inc-proc-ic.h" > +#include "ovn-ic.h" > > VLOG_DEFINE_THIS_MODULE(ovn_ic); > > @@ -55,45 +57,6 @@ static unixctl_cb_func ovn_ic_resume; > static unixctl_cb_func ovn_ic_is_paused; > static unixctl_cb_func ovn_ic_status; > > -struct ic_context { > - struct ovsdb_idl *ovnnb_idl; > - struct ovsdb_idl *ovnsb_idl; > - struct ovsdb_idl *ovninb_idl; > - struct ovsdb_idl *ovnisb_idl; > - struct ovsdb_idl_txn *ovnnb_txn; > - struct ovsdb_idl_txn *ovnsb_txn; > - struct ovsdb_idl_txn *ovninb_txn; > - struct ovsdb_idl_txn *ovnisb_txn; > - const struct icsbrec_availability_zone *runned_az; > - struct ovsdb_idl_index *nbrec_ls_by_name; > - struct ovsdb_idl_index *nbrec_lr_by_name; > - struct ovsdb_idl_index *nbrec_lrp_by_name; > - struct ovsdb_idl_index *nbrec_port_by_name; > - struct ovsdb_idl_index *sbrec_chassis_by_name; > - struct ovsdb_idl_index *sbrec_port_binding_by_name; > - struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type; > - struct ovsdb_idl_index *sbrec_service_monitor_by_ic_learned; > - struct ovsdb_idl_index > *sbrec_service_monitor_by_remote_type_logical_port; > - struct ovsdb_idl_index *icnbrec_transit_switch_by_name; > - struct ovsdb_idl_index *icsbrec_port_binding_by_az; > - struct ovsdb_idl_index *icsbrec_port_binding_by_ts; > - struct ovsdb_idl_index *icsbrec_port_binding_by_ts_az; > - struct ovsdb_idl_index *icsbrec_route_by_az; > - struct ovsdb_idl_index *icsbrec_route_by_ts; > - struct ovsdb_idl_index *icsbrec_route_by_ts_az; > - struct ovsdb_idl_index *icsbrec_service_monitor_by_source_az; > - struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az; > - struct ovsdb_idl_index > *icsbrec_service_monitor_by_target_az_logical_port; > -}; > - > -struct ic_state { > - bool had_lock; > - bool paused; > -}; > - > -enum ic_datapath_type { IC_SWITCH, IC_ROUTER, IC_DATAPATH_MAX }; > -enum ic_port_binding_type { IC_SWITCH_PORT, IC_ROUTER_PORT, IC_PORT_MAX }; > - > static const char *ovnnb_db; > static const char *ovnsb_db; > static const char *ovn_ic_nb_db; > @@ -3091,7 +3054,7 @@ update_sequence_numbers(struct ic_context *ctx, > } > } > > -static void > +void > ovn_db_run(struct ic_context *ctx) > { > struct hmap dp_tnlids = HMAP_INITIALIZER(&dp_tnlids); > @@ -3311,172 +3274,183 @@ main(int argc, char *argv[]) > /* ovn-ic-nb db. */ > struct ovsdb_idl_loop ovninb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( > ovsdb_idl_create(ovn_ic_nb_db, &icnbrec_idl_class, true, true)); > + ovsdb_idl_track_add_all(ovninb_idl_loop.idl); > > /* ovn-ic-sb db. */ > struct ovsdb_idl_loop ovnisb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( > ovsdb_idl_create(ovn_ic_sb_db, &icsbrec_idl_class, true, true)); > + ovsdb_idl_track_add_all(ovnisb_idl_loop.idl); > > /* ovn-nb db. */ > struct ovsdb_idl_loop ovnnb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( > ovsdb_idl_create(ovnnb_db, &nbrec_idl_class, false, true)); > > ovsdb_idl_add_table(ovnnb_idl_loop.idl, &nbrec_table_nb_global); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, &nbrec_nb_global_col_name); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, &nbrec_nb_global_col_options); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_nb_global_col_name); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_nb_global_col_options); > > ovsdb_idl_add_table(ovnnb_idl_loop.idl, > &nbrec_table_logical_router_static_route); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_static_route_col_route_table); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_static_route_col_ip_prefix); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_static_route_col_nexthop); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - > &nbrec_logical_router_static_route_col_external_ids); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_static_route_col_options); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_static_route_col_policy); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_static_route_col_route_table); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_static_route_col_ip_prefix); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_static_route_col_nexthop); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_static_route_col_external_ids); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_static_route_col_options); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_static_route_col_policy); > > ovsdb_idl_add_table(ovnnb_idl_loop.idl, &nbrec_table_logical_router); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_col_name); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_col_static_routes); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_col_ports); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_col_options); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_col_external_ids); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_col_enabled); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_col_load_balancer); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_col_load_balancer_group); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_col_name); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_col_static_routes); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_col_ports); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_col_options); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_col_external_ids); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_col_enabled); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_col_load_balancer); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + > &nbrec_logical_router_col_load_balancer_group); > > ovsdb_idl_add_table(ovnnb_idl_loop.idl, > &nbrec_table_logical_router_port); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_port_col_mac); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_port_col_name); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_port_col_networks); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_port_col_external_ids); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_router_port_col_options); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_port_col_mac); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_port_col_name); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_port_col_networks); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_port_col_external_ids); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_router_port_col_options); > > ovsdb_idl_add_table(ovnnb_idl_loop.idl, &nbrec_table_logical_switch); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_col_name); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_col_ports); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_col_other_config); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_col_external_ids); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_col_name); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_col_ports); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_col_other_config); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_col_external_ids); > > ovsdb_idl_add_table(ovnnb_idl_loop.idl, > &nbrec_table_logical_switch_port); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_port_col_name); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_port_col_addresses); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_port_col_options); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_port_col_type); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_port_col_up); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_port_col_addresses); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_port_col_enabled); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_logical_switch_port_col_external_ids); > - > - ovsdb_idl_add_table(ovnnb_idl_loop.idl, > - &nbrec_table_load_balancer); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_load_balancer_col_vips); > - > - ovsdb_idl_add_table(ovnnb_idl_loop.idl, > - &nbrec_table_load_balancer_group); > - ovsdb_idl_add_column(ovnnb_idl_loop.idl, > - &nbrec_load_balancer_group_col_load_balancer); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_port_col_name); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_port_col_addresses); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_port_col_options); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_port_col_type); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_port_col_up); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_port_col_addresses); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_port_col_enabled); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_logical_switch_port_col_external_ids); > + > + ovsdb_idl_add_table(ovnnb_idl_loop.idl, &nbrec_table_load_balancer); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_load_balancer_col_vips); > + > + ovsdb_idl_add_table(ovnnb_idl_loop.idl, > &nbrec_table_load_balancer_group); > + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > + &nbrec_load_balancer_group_col_load_balancer); > > /* ovn-sb db. */ > struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( > ovsdb_idl_create(ovnsb_db, &sbrec_idl_class, false, true)); > > ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_sb_global); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_sb_global_col_options); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_sb_global_col_options); > > ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_chassis); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_encaps); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_name); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_hostname); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_chassis_col_other_config); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_chassis_col_encaps); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_chassis_col_name); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_chassis_col_hostname); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_chassis_col_other_config); > > ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_encap); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_encap_col_chassis_name); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_encap_col_type); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_encap_col_ip); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_encap_col_options); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_encap_col_chassis_name); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_encap_col_type); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_encap_col_ip); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_encap_col_options); > > ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_datapath_binding); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_datapath_binding_col_type); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_datapath_binding_col_external_ids); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_datapath_binding_col_nb_uuid); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_datapath_binding_col_type); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_datapath_binding_col_external_ids); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_datapath_binding_col_nb_uuid); > > ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_port_binding); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_datapath); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_mac); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_options); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_logical_port); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_external_ids); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_chassis); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_up); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, > - &sbrec_table_service_monitor); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_chassis_name); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_external_ids); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_type); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_ip); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_logical_port); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_port); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_protocol); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_src_ip); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_src_mac); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_remote); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_ic_learned); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_status); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_options); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_datapath); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_mac); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_options); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_logical_port); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_external_ids); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_chassis); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_up); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_service_monitor); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_chassis_name); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_external_ids); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_type); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_ip); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_logical_port); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_port); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_protocol); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_src_ip); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_src_mac); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_remote); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_ic_learned); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_status); > + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_options); > > /* Create IDL indexes */ > struct ovsdb_idl_index *nbrec_ls_by_name > @@ -3497,7 +3471,7 @@ main(int argc, char *argv[]) > = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, > &sbrec_chassis_col_name); > > - struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type > + struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type > = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, > &sbrec_service_monitor_col_remote); > > @@ -3562,10 +3536,22 @@ main(int argc, char *argv[]) > unixctl_command_register("ic-sb-connection-status", "", 0, 0, > ovn_conn_show, ovnisb_idl_loop.idl); > > + /* Initialize incremental processing engine for ovn-northd */ > + inc_proc_ic_init(&ovnnb_idl_loop, &ovnsb_idl_loop, > + &ovninb_idl_loop, &ovnisb_idl_loop); > + > + unsigned int ovnnb_cond_seqno = UINT_MAX; > + unsigned int ovnsb_cond_seqno = UINT_MAX; > + unsigned int ovninb_cond_seqno = UINT_MAX; > + unsigned int ovnisb_cond_seqno = UINT_MAX; > + > /* Main loop. */ > + struct ic_engine_context eng_ctx = {0}; > + > exiting = false; > state.had_lock = false; > state.paused = false; > + > while (!exiting) { > update_ssl_config(); > update_idl_probe_interval(ovnsb_idl_loop.idl, ovnnb_idl_loop.idl, > @@ -3579,6 +3565,7 @@ main(int argc, char *argv[]) > simap_destroy(&usage); > } > > + bool clear_idl_track = true; > if (!state.paused) { > if (!ovsdb_idl_has_lock(ovnsb_idl_loop.idl) && > !ovsdb_idl_is_lock_contended(ovnsb_idl_loop.idl)) > @@ -3590,15 +3577,67 @@ main(int argc, char *argv[]) > ovsdb_idl_set_lock(ovnsb_idl_loop.idl, "ovn_ic"); > } > > + struct ovsdb_idl_txn *ovnnb_txn = > + run_idl_loop(&ovnnb_idl_loop, "OVN_Northbound", > + &eng_ctx.nb_idl_duration_ms); > + unsigned int new_ovnnb_cond_seqno = > + ovsdb_idl_get_condition_seqno(ovnnb_idl_loop.idl); > + if (new_ovnnb_cond_seqno != ovnnb_cond_seqno) { > + if (!new_ovnnb_cond_seqno) { > + VLOG_INFO("OVN NB IDL reconnected, force recompute."); > + inc_proc_ic_force_recompute(); > + } > + ovnnb_cond_seqno = new_ovnnb_cond_seqno; > + } > + > + struct ovsdb_idl_txn *ovnsb_txn = > + run_idl_loop(&ovnsb_idl_loop, "OVN_Southbound", > + &eng_ctx.sb_idl_duration_ms); > + unsigned int new_ovnsb_cond_seqno = > + ovsdb_idl_get_condition_seqno(ovnsb_idl_loop.idl); > + if (new_ovnsb_cond_seqno != ovnsb_cond_seqno) { > + if (!new_ovnsb_cond_seqno) { > + VLOG_INFO("OVN SB IDL reconnected, force recompute."); > + inc_proc_ic_force_recompute(); > + } > + ovnsb_cond_seqno = new_ovnsb_cond_seqno; > + } > + > + struct ovsdb_idl_txn *ovninb_txn = > + run_idl_loop(&ovninb_idl_loop, "OVN_IC_Northbound", > + &eng_ctx.inb_idl_duration_ms); > + unsigned int new_ovninb_cond_seqno = > + ovsdb_idl_get_condition_seqno(ovninb_idl_loop.idl); > + if (new_ovninb_cond_seqno != ovninb_cond_seqno) { > + if (!new_ovninb_cond_seqno) { > + VLOG_INFO("OVN INB IDL reconnected, force recompute."); > + inc_proc_ic_force_recompute(); > + } > + ovninb_cond_seqno = new_ovninb_cond_seqno; > + } > + > + struct ovsdb_idl_txn *ovnisb_txn = > + run_idl_loop(&ovnisb_idl_loop, "OVN_IC_Southbound", > + &eng_ctx.isb_idl_duration_ms); > + unsigned int new_ovnisb_cond_seqno = > + ovsdb_idl_get_condition_seqno(ovnisb_idl_loop.idl); > + if (new_ovnisb_cond_seqno != ovnisb_cond_seqno) { > + if (!new_ovnisb_cond_seqno) { > + VLOG_INFO("OVN ISB IDL reconnected, force recompute."); > + inc_proc_ic_force_recompute(); > + } > + ovnisb_cond_seqno = new_ovnisb_cond_seqno; > + } > + > struct ic_context ctx = { > .ovnnb_idl = ovnnb_idl_loop.idl, > - .ovnnb_txn = ovsdb_idl_loop_run(&ovnnb_idl_loop), > + .ovnnb_txn = ovnnb_txn, > .ovnsb_idl = ovnsb_idl_loop.idl, > - .ovnsb_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop), > + .ovnsb_txn = ovnsb_txn, > .ovninb_idl = ovninb_idl_loop.idl, > - .ovninb_txn = ovsdb_idl_loop_run(&ovninb_idl_loop), > + .ovninb_txn = ovninb_txn, > .ovnisb_idl = ovnisb_idl_loop.idl, > - .ovnisb_txn = ovsdb_idl_loop_run(&ovnisb_idl_loop), > + .ovnisb_txn = ovnisb_txn, > .nbrec_ls_by_name = nbrec_ls_by_name, > .nbrec_lr_by_name = nbrec_lr_by_name, > .nbrec_lrp_by_name = nbrec_lrp_by_name, > @@ -3627,44 +3666,75 @@ main(int argc, char *argv[]) > icsbrec_service_monitor_by_target_az_logical_port, > }; > > - if (!state.had_lock && ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) { > + if (!state.had_lock && ovsdb_idl_has_lock(ctx.ovnsb_idl)) { > VLOG_INFO("ovn-ic lock acquired. " > - "This ovn-ic instance is now active."); > + "This ovn-ic instance is now active."); > state.had_lock = true; > } else if (state.had_lock && > - !ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) { > + !ovsdb_idl_has_lock(ctx.ovnsb_idl)) { > VLOG_INFO("ovn-ic lock lost. " > - "This ovn-ic instance is now on standby."); > + "This ovn-ic instance is now on standby."); > state.had_lock = false; > } > > - if (ovsdb_idl_has_lock(ovnsb_idl_loop.idl) && > + if (ovsdb_idl_has_lock(ctx.ovnsb_idl) && > ovsdb_idl_has_ever_connected(ctx.ovnnb_idl) && > ovsdb_idl_has_ever_connected(ctx.ovnsb_idl) && > ovsdb_idl_has_ever_connected(ctx.ovninb_idl) && > ovsdb_idl_has_ever_connected(ctx.ovnisb_idl)) { > - const struct icsbrec_availability_zone *az = az_run(&ctx); > - VLOG_DBG("Availability zone: %s", az ? az->name : > - "not created yet."); > - if (az) { > - ovn_db_run(&ctx); > - update_sequence_numbers(&ctx, &ovnisb_idl_loop); > + if (ctx.ovnnb_txn && ctx.ovnsb_txn && ctx.ovninb_txn && > + ctx.ovnisb_txn && inc_proc_ic_can_run(&eng_ctx)) { > + ctx.runned_az = az_run(&ctx); > + VLOG_DBG("Availability zone: %s", ctx.runned_az ? > + ctx.runned_az->name : "not created yet."); > + if (ctx.runned_az) { > + (void) inc_proc_ic_run(&ctx, &eng_ctx); > + update_sequence_numbers(&ctx, &ovnisb_idl_loop); > + } > + } else if (!inc_proc_ic_get_force_recompute()) { > + clear_idl_track = false; > + } > + /* If there are any errors, we force a full recompute in > order > + * to ensure we handle all changes. */ > + if (!ovsdb_idl_loop_commit_and_wait(&ovnnb_idl_loop)) { > + VLOG_INFO("OVNNB commit failed, " > + "force recompute next time."); > + inc_proc_ic_force_recompute_immediate(); > } > > - } > + if (!ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop)) { > + VLOG_INFO("OVNSB commit failed, " > + "force recompute next time."); > + inc_proc_ic_force_recompute_immediate(); > + } > + > + if (!ovsdb_idl_loop_commit_and_wait(&ovninb_idl_loop)) { > + VLOG_INFO("OVNINB commit failed, " > + "force recompute next time."); > + inc_proc_ic_force_recompute_immediate(); > + } > > - int rc1 = ovsdb_idl_loop_commit_and_wait(&ovnnb_idl_loop); > - int rc2 = ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop); > - int rc3 = ovsdb_idl_loop_commit_and_wait(&ovninb_idl_loop); > - int rc4 = ovsdb_idl_loop_commit_and_wait(&ovnisb_idl_loop); > - if (!rc1 || !rc2 || !rc3 || !rc4) { > - VLOG_DBG(" a transaction failed in: %s %s %s %s", > - !rc1 ? "nb" : "", !rc2 ? "sb" : "", > - !rc3 ? "ic_nb" : "", !rc4 ? "ic_sb" : ""); > - /* A transaction failed. Wake up immediately to give > - * opportunity to send the proper transaction > - */ > - poll_immediate_wake(); > + if (!ovsdb_idl_loop_commit_and_wait(&ovnisb_idl_loop)) { > + VLOG_INFO("OVNISB commit failed, " > + "force recompute next time."); > + inc_proc_ic_force_recompute_immediate(); > + } > + } else { > + /* Make sure we send any pending requests, e.g., lock. */ > + int rc1 = ovsdb_idl_loop_commit_and_wait(&ovnnb_idl_loop); > + int rc2 = ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop); > + int rc3 = ovsdb_idl_loop_commit_and_wait(&ovninb_idl_loop); > + int rc4 = ovsdb_idl_loop_commit_and_wait(&ovnisb_idl_loop); > + if (!rc1 || !rc2 || !rc3 || !rc4) { > + VLOG_DBG(" a transaction failed in: %s %s %s %s", > + !rc1 ? "nb" : "", !rc2 ? "sb" : "", > + !rc3 ? "ic_nb" : "", !rc4 ? "ic_sb" : ""); > + /* A transaction failed. Wake up immediately to give > + * opportunity to send the proper transaction > + */ > + } > + /* Force a full recompute next time we become active. */ > + inc_proc_ic_force_recompute(); > } > } else { > /* ovn-ic is paused > @@ -3690,6 +3760,16 @@ main(int argc, char *argv[]) > ovsdb_idl_wait(ovnsb_idl_loop.idl); > ovsdb_idl_wait(ovninb_idl_loop.idl); > ovsdb_idl_wait(ovnisb_idl_loop.idl); > + > + /* Force a full recompute next time we become active. */ > + inc_proc_ic_force_recompute_immediate(); > + } > + > + if (clear_idl_track) { > + ovsdb_idl_track_clear(ovnnb_idl_loop.idl); > + ovsdb_idl_track_clear(ovnsb_idl_loop.idl); > + ovsdb_idl_track_clear(ovninb_idl_loop.idl); > + ovsdb_idl_track_clear(ovnisb_idl_loop.idl); > } > > unixctl_server_run(unixctl); > @@ -3704,6 +3784,7 @@ main(int argc, char *argv[]) > exiting = true; > } > } > + inc_proc_ic_cleanup(); > > unixctl_server_destroy(unixctl); > ovsdb_idl_loop_destroy(&ovnnb_idl_loop); > diff --git a/ic/ovn-ic.h b/ic/ovn-ic.h > new file mode 100644 > index 000000000..e8d7a970f > --- /dev/null > +++ b/ic/ovn-ic.h > @@ -0,0 +1,61 @@ > +/* > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at: > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > +#ifndef OVN_IC_H > +#define OVN_IC_H 1 > + > +#include "ovsdb-idl.h" > +#include "unixctl.h" > + > +struct ic_context { > + struct ovsdb_idl *ovnnb_idl; > + struct ovsdb_idl *ovnsb_idl; > + struct ovsdb_idl *ovninb_idl; > + struct ovsdb_idl *ovnisb_idl; > + struct ovsdb_idl_txn *ovnnb_txn; > + struct ovsdb_idl_txn *ovnsb_txn; > + struct ovsdb_idl_txn *ovninb_txn; > + struct ovsdb_idl_txn *ovnisb_txn; > + const struct icsbrec_availability_zone *runned_az; > + struct ovsdb_idl_index *nbrec_ls_by_name; > + struct ovsdb_idl_index *nbrec_lr_by_name; > + struct ovsdb_idl_index *nbrec_lrp_by_name; > + struct ovsdb_idl_index *nbrec_port_by_name; > + struct ovsdb_idl_index *sbrec_chassis_by_name; > + struct ovsdb_idl_index *sbrec_port_binding_by_name; > + struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type; > + struct ovsdb_idl_index *sbrec_service_monitor_by_ic_learned; > + struct ovsdb_idl_index > *sbrec_service_monitor_by_remote_type_logical_port; > + struct ovsdb_idl_index *icnbrec_transit_switch_by_name; > + struct ovsdb_idl_index *icsbrec_port_binding_by_az; > + struct ovsdb_idl_index *icsbrec_port_binding_by_ts; > + struct ovsdb_idl_index *icsbrec_port_binding_by_ts_az; > + struct ovsdb_idl_index *icsbrec_route_by_az; > + struct ovsdb_idl_index *icsbrec_route_by_ts; > + struct ovsdb_idl_index *icsbrec_route_by_ts_az; > + struct ovsdb_idl_index *icsbrec_service_monitor_by_source_az; > + struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az; > + struct ovsdb_idl_index > *icsbrec_service_monitor_by_target_az_logical_port; > +}; > + > +struct ic_state { > + bool had_lock; > + bool paused; > +}; > + > +enum ic_datapath_type { IC_SWITCH, IC_ROUTER, IC_DATAPATH_MAX }; > +enum ic_port_binding_type { IC_SWITCH_PORT, IC_ROUTER_PORT, IC_PORT_MAX }; > + > +void ovn_db_run(struct ic_context *ctx); > + > +#endif /* OVN_IC_H */ > diff --git a/lib/inc-proc-eng.h b/lib/inc-proc-eng.h > index 02eeb46fe..1cb2466b2 100644 > --- a/lib/inc-proc-eng.h > +++ b/lib/inc-proc-eng.h > @@ -158,6 +158,8 @@ struct engine_context { > struct ovsdb_idl_txn *ovnsb_idl_txn; > struct ovsdb_idl_txn *ovnnb_idl_txn; > struct ovsdb_idl_txn *ovnbr_idl_txn; > + struct ovsdb_idl_txn *ovnisb_idl_txn; > + struct ovsdb_idl_txn *ovninb_idl_txn; > > void *client_ctx; > }; > @@ -167,6 +169,8 @@ struct engine_arg { > struct ovsdb_idl *sb_idl; > struct ovsdb_idl *nb_idl; > struct ovsdb_idl *ovnbr_idl; > + struct ovsdb_idl *icsb_idl; > + struct ovsdb_idl *icnb_idl; > struct ovsdb_idl *ovs_idl; > }; > > @@ -547,6 +551,16 @@ en_##DB_NAME##_##TBL_NAME##_compute_failure_info(struct > engine_node *node) \ > #define ENGINE_FUNC_BR(TBL_NAME) \ > ENGINE_FUNC_OVSDB(ovnbr, TBL_NAME) > > +/* Macro to define member functions of an engine node which represents > + * a table of OVN ISB DB */ > +#define ENGINE_FUNC_ICSB(TBL_NAME) \ > + ENGINE_FUNC_OVSDB(icsb, TBL_NAME) > + > +/* Macro to define member functions of an engine node which represents > + * a table of OVN INB DB */ > +#define ENGINE_FUNC_ICNB(TBL_NAME) \ > + ENGINE_FUNC_OVSDB(icnb, TBL_NAME) > + > /* Macro to define member functions of an engine node which represents > * a table of open_vswitch DB */ > #define ENGINE_FUNC_OVS(TBL_NAME) \ > @@ -569,6 +583,13 @@ en_##DB_NAME##_##TBL_NAME##_compute_failure_info(struct > engine_node *node) \ > /* Macro to define an engine node which represents a table of OVN BR DB */ > #define ENGINE_NODE_BR(TBL_NAME) \ > ENGINE_NODE_OVSDB(ovnbr, "BR", TBL_NAME, #TBL_NAME); > +/* Macro to define an engine node which represents a table of OVN ISB DB */ > +#define ENGINE_NODE_ICSB(TBL_NAME) \ > + ENGINE_NODE_OVSDB(icsb, "ICSB", TBL_NAME, #TBL_NAME); > + > +/* Macro to define an engine node which represents a table of OVN INB DB */ > +#define ENGINE_NODE_ICNB(TBL_NAME) \ > + ENGINE_NODE_OVSDB(icnb, "ICNB", TBL_NAME, #TBL_NAME); > > /* Macro to define an engine node which represents a table of open_vswitch > * DB */ > -- > 2.34.1 > > > -- > > > > > _'Esta mensagem é direcionada apenas para os endereços constantes no > cabeçalho inicial. Se você não está listado nos endereços constantes no > cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa > mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas estão > imediatamente anuladas e proibidas'._ > > > * **'Apesar do Magazine Luiza tomar > todas as precauções razoáveis para assegurar que nenhum vírus esteja > presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por > quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.* > > > > _______________________________________________ > dev mailing list > [email protected] > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
