|
|
bbaaef |
From 9bb08e772a3ac946466906d89cf460d852e6144d Mon Sep 17 00:00:00 2001
|
|
|
bbaaef |
From: Dumitru Ceara <dceara@redhat.com>
|
|
|
bbaaef |
Date: Wed, 27 Nov 2019 14:15:22 +0100
|
|
|
bbaaef |
Subject: [PATCH ovn 2/4] ovn-controller: Add per node states to I-P engine.
|
|
|
bbaaef |
|
|
|
bbaaef |
This commit transforms the 'changed' field in struct engine_node in a
|
|
|
bbaaef |
'state' field. Possible node states are:
|
|
|
bbaaef |
- "Stale": data in the node is not up to date with the DB.
|
|
|
bbaaef |
- "Updated": data in the node is valid but was updated during
|
|
|
bbaaef |
the last run of the engine.
|
|
|
bbaaef |
- "Valid": data in the node is valid and didn't change during
|
|
|
bbaaef |
the last run of the engine.
|
|
|
bbaaef |
- "Aborted": during the last run, processing was aborted for
|
|
|
bbaaef |
this node.
|
|
|
bbaaef |
|
|
|
bbaaef |
This commit also further refactors the I-P engine:
|
|
|
bbaaef |
- instead of recursively performing all the engine processing a
|
|
|
bbaaef |
preprocessing stage is added (engine_get_nodes()) before the main processing
|
|
|
bbaaef |
loop is executed in order to topologically sort nodes in the engine such
|
|
|
bbaaef |
that all inputs of a given node appear in the sorted array before the node
|
|
|
bbaaef |
itself. This simplifies a bit the code in engine_run().
|
|
|
bbaaef |
- remove the need for using an engine_run_id by using the newly added states.
|
|
|
bbaaef |
- turn the global 'engine_abort_recompute' into an argument to be passed to
|
|
|
bbaaef |
engine_run(). It's relevant only in the current run context anyway as
|
|
|
bbaaef |
we reset it before every call to engine_run().
|
|
|
bbaaef |
|
|
|
bbaaef |
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
|
|
|
bbaaef |
Signed-off-by: Han Zhou <hzhou@ovn.org>
|
|
|
bbaaef |
|
|
|
bbaaef |
(cherry picked from upstream commit 5ed53faecef12c09330ced445418c961cb1f8caf)
|
|
|
bbaaef |
|
|
|
bbaaef |
Change-Id: I9c3322fe8eb51ffcad62797f5f2a7306bb0c53f4
|
|
|
bbaaef |
---
|
|
|
bbaaef |
ovn/controller/ovn-controller.c | 101 +++++++++---------
|
|
|
bbaaef |
ovn/lib/inc-proc-eng.c | 231 ++++++++++++++++++++++++++++------------
|
|
|
bbaaef |
ovn/lib/inc-proc-eng.h | 74 +++++++++----
|
|
|
bbaaef |
3 files changed, 268 insertions(+), 138 deletions(-)
|
|
|
bbaaef |
|
|
|
bbaaef |
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
|
|
|
bbaaef |
index ad5b067..8c474e9 100644
|
|
|
bbaaef |
--- a/ovn/controller/ovn-controller.c
|
|
|
bbaaef |
+++ b/ovn/controller/ovn-controller.c
|
|
|
bbaaef |
@@ -722,10 +722,10 @@ en_ofctrl_is_connected_run(struct engine_node *node)
|
|
|
bbaaef |
(struct ed_type_ofctrl_is_connected *)node->data;
|
|
|
bbaaef |
if (data->connected != ofctrl_is_connected()) {
|
|
|
bbaaef |
data->connected = !data->connected;
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
return;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
- node->changed = false;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_VALID);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
struct ed_type_addr_sets {
|
|
|
bbaaef |
@@ -775,7 +775,7 @@ en_addr_sets_run(struct engine_node *node)
|
|
|
bbaaef |
addr_sets_init(as_table, &as->addr_sets);
|
|
|
bbaaef |
|
|
|
bbaaef |
as->change_tracked = false;
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
static bool
|
|
|
bbaaef |
@@ -794,11 +794,14 @@ addr_sets_sb_address_set_handler(struct engine_node *node)
|
|
|
bbaaef |
addr_sets_update(as_table, &as->addr_sets, &as->new,
|
|
|
bbaaef |
&as->deleted, &as->updated);
|
|
|
bbaaef |
|
|
|
bbaaef |
- node->changed = !sset_is_empty(&as->new) || !sset_is_empty(&as->deleted)
|
|
|
bbaaef |
- || !sset_is_empty(&as->updated);
|
|
|
bbaaef |
+ if (!sset_is_empty(&as->new) || !sset_is_empty(&as->deleted) ||
|
|
|
bbaaef |
+ !sset_is_empty(&as->updated)) {
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
+ } else {
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_VALID);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
|
|
|
bbaaef |
as->change_tracked = true;
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
return true;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
@@ -849,7 +852,7 @@ en_port_groups_run(struct engine_node *node)
|
|
|
bbaaef |
port_groups_init(pg_table, &pg->port_groups);
|
|
|
bbaaef |
|
|
|
bbaaef |
pg->change_tracked = false;
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
static bool
|
|
|
bbaaef |
@@ -868,11 +871,14 @@ port_groups_sb_port_group_handler(struct engine_node *node)
|
|
|
bbaaef |
port_groups_update(pg_table, &pg->port_groups, &pg->new,
|
|
|
bbaaef |
&pg->deleted, &pg->updated);
|
|
|
bbaaef |
|
|
|
bbaaef |
- node->changed = !sset_is_empty(&pg->new) || !sset_is_empty(&pg->deleted)
|
|
|
bbaaef |
- || !sset_is_empty(&pg->updated);
|
|
|
bbaaef |
+ if (!sset_is_empty(&pg->new) || !sset_is_empty(&pg->deleted) ||
|
|
|
bbaaef |
+ !sset_is_empty(&pg->updated)) {
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
+ } else {
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_VALID);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
|
|
|
bbaaef |
pg->change_tracked = true;
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
return true;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
@@ -1053,7 +1059,7 @@ en_runtime_data_run(struct engine_node *node)
|
|
|
bbaaef |
update_ct_zones(local_lports, local_datapaths, ct_zones,
|
|
|
bbaaef |
ct_zone_bitmap, pending_ct_zones);
|
|
|
bbaaef |
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
static bool
|
|
|
bbaaef |
@@ -1119,10 +1125,10 @@ en_mff_ovn_geneve_run(struct engine_node *node)
|
|
|
bbaaef |
enum mf_field_id mff_ovn_geneve = ofctrl_get_mf_field_id();
|
|
|
bbaaef |
if (data->mff_ovn_geneve != mff_ovn_geneve) {
|
|
|
bbaaef |
data->mff_ovn_geneve = mff_ovn_geneve;
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
return;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
- node->changed = false;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_VALID);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
struct ed_type_flow_output {
|
|
|
bbaaef |
@@ -1284,7 +1290,7 @@ en_flow_output_run(struct engine_node *node)
|
|
|
bbaaef |
active_tunnels,
|
|
|
bbaaef |
flow_table);
|
|
|
bbaaef |
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
static bool
|
|
|
bbaaef |
@@ -1366,7 +1372,7 @@ flow_output_sb_logical_flow_handler(struct engine_node *node)
|
|
|
bbaaef |
flow_table, group_table, meter_table, lfrr,
|
|
|
bbaaef |
conj_id_ofs);
|
|
|
bbaaef |
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
return handled;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
@@ -1389,7 +1395,7 @@ flow_output_sb_mac_binding_handler(struct engine_node *node)
|
|
|
bbaaef |
lflow_handle_changed_neighbors(sbrec_port_binding_by_name,
|
|
|
bbaaef |
mac_binding_table, flow_table);
|
|
|
bbaaef |
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
return true;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
@@ -1493,7 +1499,7 @@ flow_output_sb_port_binding_handler(struct engine_node *node)
|
|
|
bbaaef |
chassis, ct_zones, local_datapaths,
|
|
|
bbaaef |
active_tunnels, flow_table);
|
|
|
bbaaef |
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
return true;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
@@ -1542,7 +1548,7 @@ flow_output_sb_multicast_group_handler(struct engine_node *node)
|
|
|
bbaaef |
mff_ovn_geneve, chassis, ct_zones, local_datapaths,
|
|
|
bbaaef |
flow_table);
|
|
|
bbaaef |
|
|
|
bbaaef |
- node->changed = true;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
return true;
|
|
|
bbaaef |
|
|
|
bbaaef |
}
|
|
|
bbaaef |
@@ -1656,7 +1662,9 @@ _flow_output_resource_ref_handler(struct engine_node *node,
|
|
|
bbaaef |
conj_id_ofs, &changed)) {
|
|
|
bbaaef |
return false;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
- node->changed = changed || node->changed;
|
|
|
bbaaef |
+ if (changed) {
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
}
|
|
|
bbaaef |
SSET_FOR_EACH (ref_name, updated) {
|
|
|
bbaaef |
if (!lflow_handle_changed_ref(ref_type, ref_name,
|
|
|
bbaaef |
@@ -1669,7 +1677,9 @@ _flow_output_resource_ref_handler(struct engine_node *node,
|
|
|
bbaaef |
conj_id_ofs, &changed)) {
|
|
|
bbaaef |
return false;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
- node->changed = changed || node->changed;
|
|
|
bbaaef |
+ if (changed) {
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
}
|
|
|
bbaaef |
SSET_FOR_EACH (ref_name, new) {
|
|
|
bbaaef |
if (!lflow_handle_changed_ref(ref_type, ref_name,
|
|
|
bbaaef |
@@ -1682,7 +1692,9 @@ _flow_output_resource_ref_handler(struct engine_node *node,
|
|
|
bbaaef |
conj_id_ofs, &changed)) {
|
|
|
bbaaef |
return false;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
- node->changed = changed || node->changed;
|
|
|
bbaaef |
+ if (changed) {
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
return true;
|
|
|
bbaaef |
@@ -1904,9 +1916,6 @@ main(int argc, char *argv[])
|
|
|
bbaaef |
unixctl_command_register("recompute", "", 0, 0, engine_recompute_cmd,
|
|
|
bbaaef |
NULL);
|
|
|
bbaaef |
|
|
|
bbaaef |
- uint64_t engine_run_id = 0;
|
|
|
bbaaef |
- bool engine_run_done = true;
|
|
|
bbaaef |
-
|
|
|
bbaaef |
unsigned int ovs_cond_seqno = UINT_MAX;
|
|
|
bbaaef |
unsigned int ovnsb_cond_seqno = UINT_MAX;
|
|
|
bbaaef |
|
|
|
bbaaef |
@@ -1914,7 +1923,7 @@ main(int argc, char *argv[])
|
|
|
bbaaef |
exiting = false;
|
|
|
bbaaef |
restart = false;
|
|
|
bbaaef |
while (!exiting) {
|
|
|
bbaaef |
- engine_run_id++;
|
|
|
bbaaef |
+ engine_init_run();
|
|
|
bbaaef |
|
|
|
bbaaef |
update_sb_db(ovs_idl_loop.idl, ovnsb_idl_loop.idl);
|
|
|
bbaaef |
update_ssl_config(ovsrec_ssl_table_get(ovs_idl_loop.idl));
|
|
|
bbaaef |
@@ -2007,15 +2016,9 @@ main(int argc, char *argv[])
|
|
|
bbaaef |
* this round of engine_run and continue processing
|
|
|
bbaaef |
* acculated changes incrementally later when
|
|
|
bbaaef |
* ofctrl_can_put() returns true. */
|
|
|
bbaaef |
- if (engine_run_done) {
|
|
|
bbaaef |
- engine_set_abort_recompute(true);
|
|
|
bbaaef |
- engine_run_done = engine_run(&en_flow_output,
|
|
|
bbaaef |
- engine_run_id);
|
|
|
bbaaef |
- }
|
|
|
bbaaef |
+ engine_run(false);
|
|
|
bbaaef |
} else {
|
|
|
bbaaef |
- engine_set_abort_recompute(false);
|
|
|
bbaaef |
- engine_run_done = true;
|
|
|
bbaaef |
- engine_run(&en_flow_output, engine_run_id);
|
|
|
bbaaef |
+ engine_run(true);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
}
|
|
|
bbaaef |
stopwatch_stop(CONTROLLER_LOOP_STOPWATCH_NAME,
|
|
|
bbaaef |
@@ -2034,7 +2037,7 @@ main(int argc, char *argv[])
|
|
|
bbaaef |
sbrec_meter_table_get(ovnsb_idl_loop.idl),
|
|
|
bbaaef |
get_nb_cfg(sbrec_sb_global_table_get(
|
|
|
bbaaef |
ovnsb_idl_loop.idl)),
|
|
|
bbaaef |
- en_flow_output.changed);
|
|
|
bbaaef |
+ engine_node_changed(&en_flow_output));
|
|
|
bbaaef |
pinctrl_run(ovnsb_idl_txn,
|
|
|
bbaaef |
sbrec_datapath_binding_by_key,
|
|
|
bbaaef |
sbrec_port_binding_by_datapath,
|
|
|
bbaaef |
@@ -2052,7 +2055,7 @@ main(int argc, char *argv[])
|
|
|
bbaaef |
&ed_runtime_data.local_datapaths,
|
|
|
bbaaef |
&ed_runtime_data.active_tunnels);
|
|
|
bbaaef |
|
|
|
bbaaef |
- if (en_runtime_data.changed) {
|
|
|
bbaaef |
+ if (engine_node_changed(&en_runtime_data)) {
|
|
|
bbaaef |
update_sb_monitors(ovnsb_idl_loop.idl, chassis,
|
|
|
bbaaef |
&ed_runtime_data.local_lports,
|
|
|
bbaaef |
&ed_runtime_data.local_datapaths);
|
|
|
bbaaef |
@@ -2060,20 +2063,23 @@ main(int argc, char *argv[])
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
}
|
|
|
bbaaef |
- if (engine_need_run(&en_flow_output, engine_run_id)) {
|
|
|
bbaaef |
- VLOG_DBG("engine did not run, force recompute next time: "
|
|
|
bbaaef |
- "br_int %p, chassis %p", br_int, chassis);
|
|
|
bbaaef |
- engine_set_force_recompute(true);
|
|
|
bbaaef |
- poll_immediate_wake();
|
|
|
bbaaef |
- } else if (!engine_run_done) {
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ if (!engine_has_run()) {
|
|
|
bbaaef |
+ if (engine_need_run()) {
|
|
|
bbaaef |
+ VLOG_DBG("engine did not run, force recompute next time: "
|
|
|
bbaaef |
+ "br_int %p, chassis %p", br_int, chassis);
|
|
|
bbaaef |
+ engine_set_force_recompute(true);
|
|
|
bbaaef |
+ poll_immediate_wake();
|
|
|
bbaaef |
+ } else {
|
|
|
bbaaef |
+ VLOG_DBG("engine did not run, and it was not needed"
|
|
|
bbaaef |
+ " either: br_int %p, chassis %p",
|
|
|
bbaaef |
+ br_int, chassis);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
+ } else if (engine_aborted()) {
|
|
|
bbaaef |
VLOG_DBG("engine was aborted, force recompute next time: "
|
|
|
bbaaef |
"br_int %p, chassis %p", br_int, chassis);
|
|
|
bbaaef |
engine_set_force_recompute(true);
|
|
|
bbaaef |
poll_immediate_wake();
|
|
|
bbaaef |
- } else if (!engine_has_run(&en_flow_output, engine_run_id)) {
|
|
|
bbaaef |
- VLOG_DBG("engine did not run, and it was not needed"
|
|
|
bbaaef |
- " either: br_int %p, chassis %p",
|
|
|
bbaaef |
- br_int, chassis);
|
|
|
bbaaef |
} else {
|
|
|
bbaaef |
engine_set_force_recompute(false);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
@@ -2098,8 +2104,7 @@ main(int argc, char *argv[])
|
|
|
bbaaef |
}
|
|
|
bbaaef |
} else {
|
|
|
bbaaef |
VLOG_DBG("Pending_pkt conn but br_int %p or chassis "
|
|
|
bbaaef |
- "%p not ready. run-id: %"PRIu64, br_int,
|
|
|
bbaaef |
- chassis, engine_run_id);
|
|
|
bbaaef |
+ "%p not ready.", br_int, chassis);
|
|
|
bbaaef |
unixctl_command_reply_error(pending_pkt.conn,
|
|
|
bbaaef |
"ovn-controller not ready.");
|
|
|
bbaaef |
}
|
|
|
bbaaef |
@@ -2148,7 +2153,7 @@ main(int argc, char *argv[])
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
engine_set_context(NULL);
|
|
|
bbaaef |
- engine_cleanup(&en_flow_output);
|
|
|
bbaaef |
+ engine_cleanup();
|
|
|
bbaaef |
|
|
|
bbaaef |
/* It's time to exit. Clean up the databases if we are not restarting */
|
|
|
bbaaef |
if (!restart) {
|
|
|
bbaaef |
diff --git a/ovn/lib/inc-proc-eng.c b/ovn/lib/inc-proc-eng.c
|
|
|
bbaaef |
index ff07ad9..59b5cac 100644
|
|
|
bbaaef |
--- a/ovn/lib/inc-proc-eng.c
|
|
|
bbaaef |
+++ b/ovn/lib/inc-proc-eng.c
|
|
|
bbaaef |
@@ -31,21 +31,25 @@
|
|
|
bbaaef |
VLOG_DEFINE_THIS_MODULE(inc_proc_eng);
|
|
|
bbaaef |
|
|
|
bbaaef |
static bool engine_force_recompute = false;
|
|
|
bbaaef |
-static bool engine_abort_recompute = false;
|
|
|
bbaaef |
+static bool engine_run_aborted = false;
|
|
|
bbaaef |
static const struct engine_context *engine_context;
|
|
|
bbaaef |
|
|
|
bbaaef |
+static struct engine_node **engine_nodes;
|
|
|
bbaaef |
+static size_t engine_n_nodes;
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+static const char *engine_node_state_name[EN_STATE_MAX] = {
|
|
|
bbaaef |
+ [EN_STALE] = "Stale",
|
|
|
bbaaef |
+ [EN_UPDATED] = "Updated",
|
|
|
bbaaef |
+ [EN_VALID] = "Valid",
|
|
|
bbaaef |
+ [EN_ABORTED] = "Aborted",
|
|
|
bbaaef |
+};
|
|
|
bbaaef |
+
|
|
|
bbaaef |
void
|
|
|
bbaaef |
engine_set_force_recompute(bool val)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
engine_force_recompute = val;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
-void
|
|
|
bbaaef |
-engine_set_abort_recompute(bool val)
|
|
|
bbaaef |
-{
|
|
|
bbaaef |
- engine_abort_recompute = val;
|
|
|
bbaaef |
-}
|
|
|
bbaaef |
-
|
|
|
bbaaef |
const struct engine_context *
|
|
|
bbaaef |
engine_get_context(void)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
@@ -58,26 +62,69 @@ engine_set_context(const struct engine_context *ctx)
|
|
|
bbaaef |
engine_context = ctx;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
-void
|
|
|
bbaaef |
-engine_init(struct engine_node *node)
|
|
|
bbaaef |
+/* Builds the topologically sorted 'sorted_nodes' array starting from
|
|
|
bbaaef |
+ * 'node'.
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+static struct engine_node **
|
|
|
bbaaef |
+engine_topo_sort(struct engine_node *node, struct engine_node **sorted_nodes,
|
|
|
bbaaef |
+ size_t *n_count, size_t *n_size)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
+ /* It's not so efficient to walk the array of already sorted nodes but
|
|
|
bbaaef |
+ * we know that sorting is done only once at startup so it's ok for now.
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+ for (size_t i = 0; i < *n_count; i++) {
|
|
|
bbaaef |
+ if (sorted_nodes[i] == node) {
|
|
|
bbaaef |
+ return sorted_nodes;
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
+
|
|
|
bbaaef |
for (size_t i = 0; i < node->n_inputs; i++) {
|
|
|
bbaaef |
- engine_init(node->inputs[i].node);
|
|
|
bbaaef |
+ sorted_nodes = engine_topo_sort(node->inputs[i].node, sorted_nodes,
|
|
|
bbaaef |
+ n_count, n_size);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
- if (node->init) {
|
|
|
bbaaef |
- node->init(node);
|
|
|
bbaaef |
+ if (*n_count == *n_size) {
|
|
|
bbaaef |
+ sorted_nodes = x2nrealloc(sorted_nodes, n_size, sizeof *sorted_nodes);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
+ sorted_nodes[(*n_count)] = node;
|
|
|
bbaaef |
+ (*n_count)++;
|
|
|
bbaaef |
+ return sorted_nodes;
|
|
|
bbaaef |
+}
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+/* Return the array of topologically sorted nodes when starting from
|
|
|
bbaaef |
+ * 'node'. Stores the number of nodes in 'n_count'.
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+static struct engine_node **
|
|
|
bbaaef |
+engine_get_nodes(struct engine_node *node, size_t *n_count)
|
|
|
bbaaef |
+{
|
|
|
bbaaef |
+ size_t n_size = 0;
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ *n_count = 0;
|
|
|
bbaaef |
+ return engine_topo_sort(node, NULL, n_count, &n_size);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
void
|
|
|
bbaaef |
-engine_cleanup(struct engine_node *node)
|
|
|
bbaaef |
+engine_init(struct engine_node *node)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
- for (size_t i = 0; i < node->n_inputs; i++) {
|
|
|
bbaaef |
- engine_cleanup(node->inputs[i].node);
|
|
|
bbaaef |
+ engine_nodes = engine_get_nodes(node, &engine_n_nodes);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ for (size_t i = 0; i < engine_n_nodes; i++) {
|
|
|
bbaaef |
+ if (engine_nodes[i]->init) {
|
|
|
bbaaef |
+ engine_nodes[i]->init(engine_nodes[i]);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
}
|
|
|
bbaaef |
- if (node->cleanup) {
|
|
|
bbaaef |
- node->cleanup(node);
|
|
|
bbaaef |
+}
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+void
|
|
|
bbaaef |
+engine_cleanup(void)
|
|
|
bbaaef |
+{
|
|
|
bbaaef |
+ for (size_t i = 0; i < engine_n_nodes; i++) {
|
|
|
bbaaef |
+ if (engine_nodes[i]->cleanup) {
|
|
|
bbaaef |
+ engine_nodes[i]->cleanup(engine_nodes[i]);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
}
|
|
|
bbaaef |
+ free(engine_nodes);
|
|
|
bbaaef |
+ engine_nodes = NULL;
|
|
|
bbaaef |
+ engine_n_nodes = 0;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
struct engine_node *
|
|
|
bbaaef |
@@ -128,16 +175,59 @@ engine_ovsdb_node_add_index(struct engine_node *node, const char *name,
|
|
|
bbaaef |
ed->n_indexes ++;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
+void
|
|
|
bbaaef |
+engine_set_node_state_at(struct engine_node *node,
|
|
|
bbaaef |
+ enum engine_node_state state,
|
|
|
bbaaef |
+ const char *where)
|
|
|
bbaaef |
+{
|
|
|
bbaaef |
+ if (node->state == state) {
|
|
|
bbaaef |
+ return;
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ VLOG_DBG("%s: node: %s, old_state %s, new_state %s",
|
|
|
bbaaef |
+ where, node->name,
|
|
|
bbaaef |
+ engine_node_state_name[node->state],
|
|
|
bbaaef |
+ engine_node_state_name[state]);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ node->state = state;
|
|
|
bbaaef |
+}
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+bool
|
|
|
bbaaef |
+engine_node_changed(struct engine_node *node)
|
|
|
bbaaef |
+{
|
|
|
bbaaef |
+ return node->state == EN_UPDATED;
|
|
|
bbaaef |
+}
|
|
|
bbaaef |
+
|
|
|
bbaaef |
bool
|
|
|
bbaaef |
-engine_has_run(struct engine_node *node, uint64_t run_id)
|
|
|
bbaaef |
+engine_has_run(void)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
- return node->run_id == run_id;
|
|
|
bbaaef |
+ for (size_t i = 0; i < engine_n_nodes; i++) {
|
|
|
bbaaef |
+ if (engine_nodes[i]->state != EN_STALE) {
|
|
|
bbaaef |
+ return true;
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
+ return false;
|
|
|
bbaaef |
+}
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+bool
|
|
|
bbaaef |
+engine_aborted(void)
|
|
|
bbaaef |
+{
|
|
|
bbaaef |
+ return engine_run_aborted;
|
|
|
bbaaef |
+}
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+void
|
|
|
bbaaef |
+engine_init_run(void)
|
|
|
bbaaef |
+{
|
|
|
bbaaef |
+ VLOG_DBG("Initializing new run");
|
|
|
bbaaef |
+ for (size_t i = 0; i < engine_n_nodes; i++) {
|
|
|
bbaaef |
+ engine_set_node_state(engine_nodes[i], EN_STALE);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
/* Do a full recompute (or at least try). If we're not allowed then
|
|
|
bbaaef |
* mark the node as "aborted".
|
|
|
bbaaef |
*/
|
|
|
bbaaef |
-static bool
|
|
|
bbaaef |
+static void
|
|
|
bbaaef |
engine_recompute(struct engine_node *node, bool forced, bool allowed)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
VLOG_DBG("node: %s, recompute (%s)", node->name,
|
|
|
bbaaef |
@@ -145,12 +235,12 @@ engine_recompute(struct engine_node *node, bool forced, bool allowed)
|
|
|
bbaaef |
|
|
|
bbaaef |
if (!allowed) {
|
|
|
bbaaef |
VLOG_DBG("node: %s, recompute aborted", node->name);
|
|
|
bbaaef |
- return false;
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_ABORTED);
|
|
|
bbaaef |
+ return;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
+ /* Run the node handler which might change state. */
|
|
|
bbaaef |
node->run(node);
|
|
|
bbaaef |
- VLOG_DBG("node: %s, changed: %d", node->name, node->changed);
|
|
|
bbaaef |
- return true;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
/* Return true if the node could be computed, false otherwise. */
|
|
|
bbaaef |
@@ -159,7 +249,7 @@ engine_compute(struct engine_node *node, bool recompute_allowed)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
for (size_t i = 0; i < node->n_inputs; i++) {
|
|
|
bbaaef |
/* If the input node data changed call its change handler. */
|
|
|
bbaaef |
- if (node->inputs[i].node->changed) {
|
|
|
bbaaef |
+ if (node->inputs[i].node->state == EN_UPDATED) {
|
|
|
bbaaef |
VLOG_DBG("node: %s, handle change for input %s",
|
|
|
bbaaef |
node->name, node->inputs[i].node->name);
|
|
|
bbaaef |
|
|
|
bbaaef |
@@ -170,55 +260,40 @@ engine_compute(struct engine_node *node, bool recompute_allowed)
|
|
|
bbaaef |
VLOG_DBG("node: %s, can't handle change for input %s, "
|
|
|
bbaaef |
"fall back to recompute",
|
|
|
bbaaef |
node->name, node->inputs[i].node->name);
|
|
|
bbaaef |
- return engine_recompute(node, false, recompute_allowed);
|
|
|
bbaaef |
+ engine_recompute(node, false, recompute_allowed);
|
|
|
bbaaef |
+ return (node->state != EN_ABORTED);
|
|
|
bbaaef |
}
|
|
|
bbaaef |
}
|
|
|
bbaaef |
}
|
|
|
bbaaef |
-
|
|
|
bbaaef |
return true;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
-bool engine_run(struct engine_node *node, uint64_t run_id)
|
|
|
bbaaef |
+static void
|
|
|
bbaaef |
+engine_run_node(struct engine_node *node, bool recompute_allowed)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
- if (node->run_id == run_id) {
|
|
|
bbaaef |
- /* The node was already updated in this run (could be input for
|
|
|
bbaaef |
- * multiple other nodes). Stop processing.
|
|
|
bbaaef |
- */
|
|
|
bbaaef |
- return true;
|
|
|
bbaaef |
- }
|
|
|
bbaaef |
-
|
|
|
bbaaef |
- /* Initialize the node for this run. */
|
|
|
bbaaef |
- node->run_id = run_id;
|
|
|
bbaaef |
- node->changed = false;
|
|
|
bbaaef |
-
|
|
|
bbaaef |
if (!node->n_inputs) {
|
|
|
bbaaef |
+ /* Run the node handler which might change state. */
|
|
|
bbaaef |
node->run(node);
|
|
|
bbaaef |
- VLOG_DBG("node: %s, changed: %d", node->name, node->changed);
|
|
|
bbaaef |
- return true;
|
|
|
bbaaef |
- }
|
|
|
bbaaef |
-
|
|
|
bbaaef |
- for (size_t i = 0; i < node->n_inputs; i++) {
|
|
|
bbaaef |
- if (!engine_run(node->inputs[i].node, run_id)) {
|
|
|
bbaaef |
- return false;
|
|
|
bbaaef |
- }
|
|
|
bbaaef |
+ return;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
- bool need_compute = false;
|
|
|
bbaaef |
-
|
|
|
bbaaef |
if (engine_force_recompute) {
|
|
|
bbaaef |
- return engine_recompute(node, true, !engine_abort_recompute);
|
|
|
bbaaef |
+ engine_recompute(node, true, recompute_allowed);
|
|
|
bbaaef |
+ return;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
/* If any of the inputs updated data but there is no change_handler, then
|
|
|
bbaaef |
* recompute the current node too.
|
|
|
bbaaef |
*/
|
|
|
bbaaef |
+ bool need_compute = false;
|
|
|
bbaaef |
for (size_t i = 0; i < node->n_inputs; i++) {
|
|
|
bbaaef |
- if (node->inputs[i].node->changed) {
|
|
|
bbaaef |
+ if (node->inputs[i].node->state == EN_UPDATED) {
|
|
|
bbaaef |
need_compute = true;
|
|
|
bbaaef |
|
|
|
bbaaef |
/* Trigger a recompute if we don't have a change handler. */
|
|
|
bbaaef |
if (!node->inputs[i].change_handler) {
|
|
|
bbaaef |
- return engine_recompute(node, false, !engine_abort_recompute);
|
|
|
bbaaef |
+ engine_recompute(node, false, recompute_allowed);
|
|
|
bbaaef |
+ return;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
}
|
|
|
bbaaef |
}
|
|
|
bbaaef |
@@ -227,33 +302,55 @@ bool engine_run(struct engine_node *node, uint64_t run_id)
|
|
|
bbaaef |
/* If we couldn't compute the node we either aborted or triggered
|
|
|
bbaaef |
* a full recompute. In any case, stop processing.
|
|
|
bbaaef |
*/
|
|
|
bbaaef |
- return engine_compute(node, !engine_abort_recompute);
|
|
|
bbaaef |
+ if (!engine_compute(node, recompute_allowed)) {
|
|
|
bbaaef |
+ return;
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
- VLOG_DBG("node: %s, changed: %d", node->name, node->changed);
|
|
|
bbaaef |
- return true;
|
|
|
bbaaef |
+ /* If we reached this point, either the node was updated or its state is
|
|
|
bbaaef |
+ * still valid.
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+ if (!engine_node_changed(node)) {
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_VALID);
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
-bool
|
|
|
bbaaef |
-engine_need_run(struct engine_node *node, uint64_t run_id)
|
|
|
bbaaef |
+void
|
|
|
bbaaef |
+engine_run(bool recompute_allowed)
|
|
|
bbaaef |
{
|
|
|
bbaaef |
- size_t i;
|
|
|
bbaaef |
-
|
|
|
bbaaef |
- if (node->run_id == run_id) {
|
|
|
bbaaef |
- return false;
|
|
|
bbaaef |
+ /* If the last run was aborted skip the incremental run because a
|
|
|
bbaaef |
+ * recompute is needed first.
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+ if (!recompute_allowed && engine_run_aborted) {
|
|
|
bbaaef |
+ return;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
|
|
|
bbaaef |
- if (!node->n_inputs) {
|
|
|
bbaaef |
- node->run(node);
|
|
|
bbaaef |
- VLOG_DBG("input node: %s, changed: %d", node->name, node->changed);
|
|
|
bbaaef |
- return node->changed;
|
|
|
bbaaef |
+ engine_run_aborted = false;
|
|
|
bbaaef |
+ for (size_t i = 0; i < engine_n_nodes; i++) {
|
|
|
bbaaef |
+ engine_run_node(engine_nodes[i], recompute_allowed);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ if (engine_nodes[i]->state == EN_ABORTED) {
|
|
|
bbaaef |
+ engine_run_aborted = true;
|
|
|
bbaaef |
+ return;
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
}
|
|
|
bbaaef |
+}
|
|
|
bbaaef |
|
|
|
bbaaef |
- for (i = 0; i < node->n_inputs; i++) {
|
|
|
bbaaef |
- if (engine_need_run(node->inputs[i].node, run_id)) {
|
|
|
bbaaef |
+bool
|
|
|
bbaaef |
+engine_need_run(void)
|
|
|
bbaaef |
+{
|
|
|
bbaaef |
+ for (size_t i = 0; i < engine_n_nodes; i++) {
|
|
|
bbaaef |
+ /* Check only leaf nodes for updates. */
|
|
|
bbaaef |
+ if (engine_nodes[i]->n_inputs) {
|
|
|
bbaaef |
+ continue;
|
|
|
bbaaef |
+ }
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+ engine_nodes[i]->run(engine_nodes[i]);
|
|
|
bbaaef |
+ VLOG_DBG("input node: %s, state: %s", engine_nodes[i]->name,
|
|
|
bbaaef |
+ engine_node_state_name[engine_nodes[i]->state]);
|
|
|
bbaaef |
+ if (engine_nodes[i]->state == EN_UPDATED) {
|
|
|
bbaaef |
return true;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
}
|
|
|
bbaaef |
-
|
|
|
bbaaef |
return false;
|
|
|
bbaaef |
}
|
|
|
bbaaef |
diff --git a/ovn/lib/inc-proc-eng.h b/ovn/lib/inc-proc-eng.h
|
|
|
bbaaef |
index a4151ca..2f3ff62 100644
|
|
|
bbaaef |
--- a/ovn/lib/inc-proc-eng.h
|
|
|
bbaaef |
+++ b/ovn/lib/inc-proc-eng.h
|
|
|
bbaaef |
@@ -82,10 +82,21 @@ struct engine_node_input {
|
|
|
bbaaef |
bool (*change_handler)(struct engine_node *node);
|
|
|
bbaaef |
};
|
|
|
bbaaef |
|
|
|
bbaaef |
-struct engine_node {
|
|
|
bbaaef |
- /* A unique id to distinguish each iteration of the engine_run(). */
|
|
|
bbaaef |
- uint64_t run_id;
|
|
|
bbaaef |
+enum engine_node_state {
|
|
|
bbaaef |
+ EN_STALE, /* Data in the node is not up to date with the DB. */
|
|
|
bbaaef |
+ EN_UPDATED, /* Data in the node is valid but was updated during the
|
|
|
bbaaef |
+ * last run.
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+ EN_VALID, /* Data in the node is valid and didn't change during the
|
|
|
bbaaef |
+ * last run.
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+ EN_ABORTED, /* During the last run, processing was aborted for
|
|
|
bbaaef |
+ * this node.
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+ EN_STATE_MAX,
|
|
|
bbaaef |
+};
|
|
|
bbaaef |
|
|
|
bbaaef |
+struct engine_node {
|
|
|
bbaaef |
/* A unique name for each node. */
|
|
|
bbaaef |
char *name;
|
|
|
bbaaef |
|
|
|
bbaaef |
@@ -102,8 +113,8 @@ struct engine_node {
|
|
|
bbaaef |
* node. */
|
|
|
bbaaef |
void *data;
|
|
|
bbaaef |
|
|
|
bbaaef |
- /* Whether the data changed in the last engine run. */
|
|
|
bbaaef |
- bool changed;
|
|
|
bbaaef |
+ /* State of the node after the last engine run. */
|
|
|
bbaaef |
+ enum engine_node_state state;
|
|
|
bbaaef |
|
|
|
bbaaef |
/* Method to initialize data. It may be NULL. */
|
|
|
bbaaef |
void (*init)(struct engine_node *);
|
|
|
bbaaef |
@@ -116,23 +127,29 @@ struct engine_node {
|
|
|
bbaaef |
void (*run)(struct engine_node *);
|
|
|
bbaaef |
};
|
|
|
bbaaef |
|
|
|
bbaaef |
-/* Initialize the data for the engine nodes recursively. It calls each node's
|
|
|
bbaaef |
+/* Initialize the data for the engine nodes. It calls each node's
|
|
|
bbaaef |
* init() method if not NULL. It should be called before the main loop. */
|
|
|
bbaaef |
-void engine_init(struct engine_node *);
|
|
|
bbaaef |
+void engine_init(struct engine_node *node);
|
|
|
bbaaef |
|
|
|
bbaaef |
-/* Execute the processing recursively, which should be called in the main
|
|
|
bbaaef |
- * loop. Returns true if the execution is compelte, false if it is aborted,
|
|
|
bbaaef |
- * which could happen when engine_abort_recompute is set. */
|
|
|
bbaaef |
-bool engine_run(struct engine_node *, uint64_t run_id);
|
|
|
bbaaef |
+/* Initialize the engine nodes for a new run. It should be called in the
|
|
|
bbaaef |
+ * main processing loop before every potential engine_run().
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+void engine_init_run(void);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+/* Execute the processing, which should be called in the main loop.
|
|
|
bbaaef |
+ * Updates the engine node's states accordingly. If 'recompute_allowed' is
|
|
|
bbaaef |
+ * false and a recompute is required by the current engine run then the engine
|
|
|
bbaaef |
+ * aborts.
|
|
|
bbaaef |
+ */
|
|
|
bbaaef |
+void engine_run(bool recompute_allowed);
|
|
|
bbaaef |
|
|
|
bbaaef |
-/* Clean up the data for the engine nodes recursively. It calls each node's
|
|
|
bbaaef |
+/* Clean up the data for the engine nodes. It calls each node's
|
|
|
bbaaef |
* cleanup() method if not NULL. It should be called before the program
|
|
|
bbaaef |
* terminates. */
|
|
|
bbaaef |
-void engine_cleanup(struct engine_node *);
|
|
|
bbaaef |
+void engine_cleanup(void);
|
|
|
bbaaef |
|
|
|
bbaaef |
/* Check if engine needs to run but didn't. */
|
|
|
bbaaef |
-bool
|
|
|
bbaaef |
-engine_need_run(struct engine_node *, uint64_t run_id);
|
|
|
bbaaef |
+bool engine_need_run(void);
|
|
|
bbaaef |
|
|
|
bbaaef |
/* Get the input node with <name> for <node> */
|
|
|
bbaaef |
struct engine_node * engine_get_input(const char *input_name,
|
|
|
bbaaef |
@@ -151,16 +168,26 @@ void engine_add_input(struct engine_node *node, struct engine_node *input,
|
|
|
bbaaef |
* iteration, and the change can't be tracked across iterations */
|
|
|
bbaaef |
void engine_set_force_recompute(bool val);
|
|
|
bbaaef |
|
|
|
bbaaef |
-/* Set the flag to cause engine execution to be aborted when there
|
|
|
bbaaef |
- * is any recompute to be triggered in any node. */
|
|
|
bbaaef |
-void engine_set_abort_recompute(bool val);
|
|
|
bbaaef |
-
|
|
|
bbaaef |
const struct engine_context * engine_get_context(void);
|
|
|
bbaaef |
|
|
|
bbaaef |
void engine_set_context(const struct engine_context *);
|
|
|
bbaaef |
|
|
|
bbaaef |
-/* Return true if the engine has run for 'node' in the 'run_id' iteration. */
|
|
|
bbaaef |
-bool engine_has_run(struct engine_node *node, uint64_t run_id);
|
|
|
bbaaef |
+void engine_set_node_state_at(struct engine_node *node,
|
|
|
bbaaef |
+ enum engine_node_state state,
|
|
|
bbaaef |
+ const char *where);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+/* Return true if during the last iteration the node's data was updated. */
|
|
|
bbaaef |
+bool engine_node_changed(struct engine_node *node);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+/* Return true if the engine has run in the last iteration. */
|
|
|
bbaaef |
+bool engine_has_run(void);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+/* Returns true if during the last engine run we had to abort processing. */
|
|
|
bbaaef |
+bool engine_aborted(void);
|
|
|
bbaaef |
+
|
|
|
bbaaef |
+/* Set the state of the node and log changes. */
|
|
|
bbaaef |
+#define engine_set_node_state(node, state) \
|
|
|
bbaaef |
+ engine_set_node_state_at(node, state, OVS_SOURCE_LOCATOR)
|
|
|
bbaaef |
|
|
|
bbaaef |
struct ed_ovsdb_index {
|
|
|
bbaaef |
const char *name;
|
|
|
bbaaef |
@@ -187,6 +214,7 @@ void engine_ovsdb_node_add_index(struct engine_node *, const char *name,
|
|
|
bbaaef |
struct engine_node en_##NAME = { \
|
|
|
bbaaef |
.name = NAME_STR, \
|
|
|
bbaaef |
.data = &ed_##NAME, \
|
|
|
bbaaef |
+ .state = EN_STALE, \
|
|
|
bbaaef |
.init = en_##NAME##_init, \
|
|
|
bbaaef |
.run = en_##NAME##_run, \
|
|
|
bbaaef |
.cleanup = en_##NAME##_cleanup, \
|
|
|
bbaaef |
@@ -201,10 +229,10 @@ en_##DB_NAME##_##TBL_NAME##_run(struct engine_node *node) \
|
|
|
bbaaef |
const struct DB_NAME##rec_##TBL_NAME##_table *table = \
|
|
|
bbaaef |
EN_OVSDB_GET(node); \
|
|
|
bbaaef |
if (DB_NAME##rec_##TBL_NAME##_table_track_get_first(table)) { \
|
|
|
bbaaef |
- node->changed = true; \
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_UPDATED); \
|
|
|
bbaaef |
return; \
|
|
|
bbaaef |
} \
|
|
|
bbaaef |
- node->changed = false; \
|
|
|
bbaaef |
+ engine_set_node_state(node, EN_VALID); \
|
|
|
bbaaef |
} \
|
|
|
bbaaef |
static void (*en_##DB_NAME##_##TBL_NAME##_init)(struct engine_node *node) \
|
|
|
bbaaef |
= NULL; \
|
|
|
bbaaef |
--
|
|
|
bbaaef |
1.8.3.1
|
|
|
bbaaef |
|