[ovs-dev] [PATCH 2/4] bridge: add console log to database
Thomas Graf
tgraf at redhat.com
Thu Nov 29 16:31:37 UTC 2012
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 <tgraf at 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
More information about the dev
mailing list