Adds a new column "console" to Open_vSwitch table which gets synced with a list of console messages in bridge_run(). The log is cleared whenever the bridges get reconfigured.
A sequence number is used to avoid uneeded database updates. Signed-off-by: Thomas Graf <tg...@redhat.com> --- vswitchd/bridge.c | 109 +++++++++++++++++++++++++++++++++++++++++++++ vswitchd/vswitch.ovsschema | 7 ++- vswitchd/vswitch.xml | 4 ++ 3 files changed, 118 insertions(+), 2 deletions(-) diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index e9a1616..59b3562 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -112,6 +112,13 @@ struct port { struct list ifaces; /* List of "struct iface"s. */ }; +struct logmsg { + struct list list_node; + unsigned int msg_num; + enum vlog_level lvl; + char *text; +}; + struct bridge { struct hmap_node node; /* In 'all_bridges'. */ char *name; /* User-specified arbitrary name. */ @@ -267,6 +274,98 @@ static void add_vlan_splinter_ports(struct bridge *, const unsigned long int *splinter_vlans, struct shash *ports); +/* + * List of log messages, synced to the database with sync_console() + */ +static struct list console_log = LIST_INITIALIZER(&console_log); +static unsigned int console_seq; + +static void +logmsg_free(struct logmsg *lm) +{ + if (!lm) + return; + + free(lm->text); + free(lm); +} + +static void +clear_console(void) +{ + struct logmsg *lm, *next_lm; + + LIST_FOR_EACH_SAFE (lm, next_lm, list_node, &console_log) { + list_remove(&lm->list_node); + logmsg_free(lm); + } + + console_seq++; +} + +/* Synchronize console_log to database. + * + * Format: + * key value + * <cur_cfg:seq> <log text> + */ +static void +sync_console(struct ovsdb_idl_txn *reuse_txn, + const struct ovsrec_open_vswitch *cfg) +{ + static struct ovsdb_idl_txn *txn = NULL; + static unsigned int synced_seq = 0; + + if (reuse_txn || !txn) { + struct logmsg *lm; + struct smap log; + + /* only sync if console was modified */ + if (synced_seq == console_seq) + return; + + smap_init(&log); + + LIST_FOR_EACH (lm, list_node, &console_log) { + char key[32]; + + snprintf(key, sizeof(key), "%04ld:%05u", + cfg ? cfg->cur_cfg : 0, lm->msg_num); + smap_add_format(&log, key, "%s", lm->text); + } + + if (!reuse_txn) + txn = ovsdb_idl_txn_create(idl); + + ovsrec_open_vswitch_set_console(cfg, &log); + synced_seq = console_seq; + smap_destroy(&log); + } + + if (!reuse_txn) { + if (ovsdb_idl_txn_commit(txn) != TXN_INCOMPLETE) { + ovsdb_idl_txn_destroy(txn); + txn = NULL; + } + } +} + +static void +bridge_log(enum vlog_level lvl, unsigned int msg_num, + const char *text) +{ + struct logmsg *lm; + + lm = xcalloc(1, sizeof(*lm)); + lm->text = xstrdup(text); + lm->msg_num = msg_num; + lm->lvl = lvl; + + list_push_back(&console_log, &lm->list_node); + + console_seq++; +} + static void bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg) { @@ -318,6 +417,8 @@ bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg) void bridge_init(const char *remote) { + vlog_register_cb(&bridge_log); + /* Create connection to database. */ idl = ovsdb_idl_create(remote, &ovsrec_idl_class, true); idl_seqno = ovsdb_idl_get_seqno(idl); @@ -326,6 +427,7 @@ bridge_init(const char *remote) ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_cur_cfg); ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_statistics); + ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_console); ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_external_ids); ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_ovs_version); ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_db_version); @@ -403,6 +505,8 @@ bridge_exit(void) HMAP_FOR_EACH_SAFE (br, next_br, node, &all_bridges) { bridge_destroy(br); } + + clear_console(); ovsdb_idl_destroy(idl); } @@ -473,6 +577,9 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) assert(!reconfiguring); reconfiguring = true; + /* clear console log as any errors may have become obsolete */ + clear_console(); + /* Destroy "struct bridge"s, "struct port"s, and "struct iface"s according * to 'ovs_cfg' while update the "if_cfg_queue", with only very minimal * configuration otherwise. @@ -2206,6 +2313,7 @@ bridge_run(void) reconf_txn = ovsdb_idl_txn_create(idl); } if (bridge_reconfigure_continue(cfg)) { + sync_console(reconf_txn, cfg); ovsrec_open_vswitch_set_cur_cfg(cfg, cfg->next_cfg); } } else { @@ -2253,6 +2361,7 @@ bridge_run(void) run_system_stats(); refresh_instant_stats(); + sync_console(NULL, cfg); } void diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema index 293a11b..b1dc8a5 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,6 +1,6 @@ {"name": "Open_vSwitch", - "version": "6.11.2", - "cksum": "2033079075 17296", + "version": "6.11.3", + "cksum": "2937511270 17430", "tables": { "Open_vSwitch": { "columns": { @@ -16,6 +16,9 @@ "type": {"key": {"type": "uuid", "refTable": "SSL"}, "min": 0, "max": 1}}, + "console": { + "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}, + "ephemeral": true}, "other_config": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}, "external_ids": { diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index c2786a5..8133e1b 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -60,6 +60,10 @@ SSL used globally by the daemon. </column> + <column name="console"> + Messages console used by the daemon. + </column> + <column name="external_ids" key="system-id"> A unique identifier for the Open vSwitch's physical host. The form of the identifier depends on the type of the host. -- 1.7.11.7 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev