[ovs-dev] [PATCH] bridge: Add controller status to Controller table.
Andrew Evans
aevans at nicira.com
Sun Jan 23 02:07:52 UTC 2011
Get status information for controller(s) attached to each bridge and store in
Controller table every 5 seconds.
---
ofproto/ofproto.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
ofproto/ofproto.h | 20 +++++++++++++++
vswitchd/bridge.c | 37 +++++++++++++++++++++++++++++
vswitchd/vswitch.ovsschema | 15 ++++++++++-
vswitchd/vswitch.xml | 33 ++++++++++++++++++++++++++
5 files changed, 159 insertions(+), 2 deletions(-)
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 7df8600..1678892 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -1354,6 +1354,62 @@ ofproto_is_alive(const struct ofproto *p)
return !hmap_is_empty(&p->controllers);
}
+void
+ofproto_get_ofproto_controller_info(const struct ofproto * const ofproto,
+ struct shash *info)
+{
+ const struct ofconn *ofconn;
+
+ shash_init(info);
+
+ HMAP_FOR_EACH (ofconn, hmap_node, &ofproto->controllers) {
+ static const char *keys[] = { "last_error", "state", "time_in_state" };
+ static const size_t n_keys = ARRAY_SIZE(keys);
+ const struct rconn *rconn = ofconn->rconn;
+ const int last_error = rconn_get_last_error(rconn);
+ const char *last_error_str;
+ struct ofproto_controller_info *cinfo = xmalloc(sizeof *cinfo);
+
+ shash_add(info, rconn_get_target(rconn), cinfo);
+
+ cinfo->is_connected = rconn_is_connected(rconn);
+ cinfo->role = ofconn->role;
+
+ cinfo->pairs.keys = keys;
+
+ if (last_error == EOF) {
+ last_error_str = "EOF";
+ } else if (last_error > 0) {
+ last_error_str = strerror(last_error);
+ } else {
+ last_error_str = "";
+ }
+
+ cinfo->pairs.values = xmalloc(sizeof *cinfo->pairs.values * n_keys);
+ cinfo->pairs.values[CONTROLLER_INFO_KEY_LAST_ERROR] = last_error_str;
+ cinfo->pairs.values[CONTROLLER_INFO_KEY_STATE]
+ = rconn_get_state(rconn);
+ cinfo->pairs.values[CONTROLLER_INFO_KEY_TIME_IN_STATE] =
+ xasprintf("%u", rconn_get_state_elapsed(rconn));
+
+ cinfo->pairs.count = n_keys;
+ }
+}
+
+void
+ofproto_free_ofproto_controller_info(struct shash *info)
+{
+ struct shash_node *node;
+
+ SHASH_FOR_EACH (node, info) {
+ struct ofproto_controller_info *cinfo = node->data;
+ free((char *) cinfo->pairs.values[CONTROLLER_INFO_KEY_TIME_IN_STATE]);
+ free(cinfo->pairs.values);
+ free(cinfo);
+ }
+ shash_destroy(info);
+}
+
/* Deletes port number 'odp_port' from the datapath for 'ofproto'.
*
* This is almost the same as calling dpif_port_del() directly on the
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index eeaeb6f..b03ad7e 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -34,8 +34,25 @@ struct cls_rule;
struct nlattr;
struct ofhooks;
struct ofproto;
+struct shash;
struct svec;
+struct ofproto_controller_info {
+ bool is_connected;
+ enum nx_role role;
+ struct {
+ const char **keys;
+ const char **values;
+ size_t count;
+ } pairs;
+};
+
+enum ofproto_controller_info_key_indices {
+ CONTROLLER_INFO_KEY_LAST_ERROR,
+ CONTROLLER_INFO_KEY_STATE,
+ CONTROLLER_INFO_KEY_TIME_IN_STATE
+};
+
struct ofexpired {
struct flow flow;
uint64_t packet_count; /* Packets from subrules. */
@@ -147,6 +164,9 @@ struct ofhooks {
void ofproto_revalidate(struct ofproto *, tag_type);
struct tag_set *ofproto_get_revalidate_set(struct ofproto *);
+void ofproto_get_ofproto_controller_info(const struct ofproto * const, struct shash *);
+void ofproto_free_ofproto_controller_info(struct shash *);
+
#ifdef __cplusplus
}
#endif
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 680c1ad..4b43918 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -1318,6 +1318,42 @@ refresh_system_stats(const struct ovsrec_open_vswitch *cfg)
&datum);
}
+static inline const char *
+nx_role_to_str(enum nx_role role)
+{
+ switch (role) {
+ case NX_ROLE_OTHER:
+ return "other";
+ case NX_ROLE_MASTER:
+ return "master";
+ case NX_ROLE_SLAVE:
+ return "slave";
+ default:
+ return "*** INVALID ROLE ***";
+ }
+}
+
+static void
+bridge_refresh_controller_status(const struct bridge *br)
+{
+ struct shash info;
+ const struct ovsrec_controller *cfg;
+
+ ofproto_get_ofproto_controller_info(br->ofproto, &info);
+
+ OVSREC_CONTROLLER_FOR_EACH(cfg, idl) {
+ struct ofproto_controller_info *cinfo = shash_find_data(&info, cfg->target);
+
+ ovsrec_controller_set_is_connected(cfg, cinfo->is_connected);
+ ovsrec_controller_set_role(cfg, nx_role_to_str(cinfo->role));
+ ovsrec_controller_set_status(cfg, (char **) cinfo->pairs.keys,
+ (char **) cinfo->pairs.values,
+ cinfo->pairs.count);
+ }
+
+ ofproto_free_ofproto_controller_info(&info);
+}
+
void
bridge_run(void)
{
@@ -1393,6 +1429,7 @@ bridge_run(void)
iface_refresh_status(iface);
}
}
+ bridge_refresh_controller_status(br);
}
refresh_system_stats(cfg);
ovsdb_idl_txn_commit(txn);
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index 75c4326..c62353c 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,5 +1,5 @@
{"name": "Open_vSwitch",
- "version": "1.0.6",
+ "version": "99.99.99",
"cksum": "2256400918 14940",
"tables": {
"Open_vSwitch": {
@@ -384,7 +384,18 @@
"min": 0, "max": 1}},
"external_ids": {
"type": {"key": "string", "value": "string",
- "min": 0, "max": "unlimited"}}}},
+ "min": 0, "max": "unlimited"}},
+ "is_connected": {
+ "type": "boolean",
+ "ephemeral": true},
+ "role": {
+ "type": {"key": {"type": "string",
+ "enum": ["set", ["other", "master", "slave"]]},
+ "min": 0, "max": 1},
+ "ephemeral": true},
+ "status": {
+ "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"},
+ "ephemeral": true}}},
"Manager": {
"columns": {
"target": {
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index dfa3f20..0b839c7 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -1844,6 +1844,39 @@
unique. No common key-value pairs are currently defined.
</column>
</group>
+
+ <group title="Controller Status">
+ <column name="is_connected">
+ <code>true</code> if currently connected to this controller,
+ <code>false</code> otherwise.
+ </column>
+
+ <column name="role">
+ The level of authority this controller has on the associated bridge.
+ </column>
+
+ <column name="status">
+ <p>Key-value pairs that report controller status.</p>
+ <dl>
+ <dt><code>state</code></dt>
+ <dd>The state of the connection to the controller. Possible values
+ are: <code>VOID</code>, <code>BACKOFF</code>,
+ <code>CONNECTING</code>, <code>ACTIVE</code> and
+ <code>IDLE</code>.</dd>
+ </dl>
+ <dl>
+ <dt><code>last_error</code></dt>
+ <dd>The last error on this connection, if any, in human-readable
+ form. Possible values are empty, <code>EOF</code> and UNIX system
+ call error strings; i.e. <code>strerror(errno)</code>.</dd>
+ </dl>
+ <dl>
+ <dt><code>time_disconnected</code></dt>
+ <dd>Seconds since disconnecting from controller, if previously
+ connected.</dd>
+ </dl>
+ </column>
+ </group>
</table>
<table name="Manager" title="OVSDB management connection.">
--
1.7.2.3
More information about the dev
mailing list