[ovs-dev] [PATCH] bridge: Store datapath version into ovsdb
Andy Zhou
azhou at nicira.com
Wed Oct 22 21:18:41 UTC 2014
OVS userspace are backword compatible with older Linux kernel modules.
However, not having the most up-to-date datapath kernel modules can
some times lead to user confusion. Storing the datapath version in
OVSDB allows management software to check and optionally provide
notifications to users.
Signed-off-by: Andy Zhou <azhou at nicira.com>
---
vswitchd/bridge.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++
vswitchd/vswitch.ovsschema | 6 ++--
vswitchd/vswitch.xml | 5 +++
3 files changed, 85 insertions(+), 2 deletions(-)
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 5f6000e..4371dbe 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -69,6 +69,12 @@ VLOG_DEFINE_THIS_MODULE(bridge);
COVERAGE_DEFINE(bridge_reconfigure);
+#define MAX_VERSION_STR_SIZE 80
+#define DATAPATH_VERSION_FILE "/sys/module/openvswitch/version"
+/* A copy ovs_version from OVSDB. This is a default datapath version for
+ * all non-kernel datapathes. */
+static char *ovs_version = NULL;
+
struct iface {
/* These members are always valid.
*
@@ -134,6 +140,10 @@ struct bridge {
struct ovsrec_port synth_local_port;
struct ovsrec_interface synth_local_iface;
struct ovsrec_interface *synth_local_ifacep;
+
+ /* Set true when created. Reset to false after the datpath
+ * information has been stored into ovsdb. */
+ bool embryonic;
};
/* All bridges, indexed by name. */
@@ -315,6 +325,23 @@ static void add_vlan_splinter_ports(struct bridge *,
const unsigned long int *splinter_vlans,
struct shash *ports);
+
+static void
+free_ovs_version(void)
+{
+ free(ovs_version);
+}
+
+static void
+init_ovs_version(const char *version)
+{
+ if (ovs_version) {
+ free_ovs_version();
+ }
+
+ ovs_version = xstrdup(version ? version : VERSION);
+}
+
static void
bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg)
{
@@ -381,6 +408,7 @@ bridge_init(const char *remote)
ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_system_version);
ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_datapath_id);
+ ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_datapath_version);
ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_status);
ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_rstp_status);
ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_stp_enable);
@@ -465,6 +493,7 @@ bridge_exit(void)
bridge_destroy(br);
}
ovsdb_idl_destroy(idl);
+ free_ovs_version();
}
/* Looks at the list of managers in 'ovs_cfg' and extracts their remote IP
@@ -595,6 +624,9 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
ovs_strerror(error));
shash_destroy(&br->wanted_ports);
bridge_destroy(br);
+ } else {
+ br->embryonic = true;
+ seq_change(connectivity_seq_get());
}
}
}
@@ -2320,6 +2352,46 @@ iface_refresh_stats(struct iface *iface)
}
static void
+br_refresh_datapath_info(struct bridge *br)
+{
+ char version[MAX_VERSION_STR_SIZE];
+
+ if (!br->ofproto) {
+ return;
+ }
+
+ if (!br->embryonic) {
+ return;
+ }
+
+ /* Only store the datapath version once. */
+ br->embryonic = false;
+
+ /* For "system" type datapath, record the Linux kenrel modules'
+ * verions number. Other datapath types are assumed to be supplied
+ * by openvswitch itself, thus inherit the same version string. */
+
+ if (!strcmp("system", ofproto_normalize_type(br->cfg->datapath_type))) {
+ FILE *f;
+
+ f = fopen(DATAPATH_VERSION_FILE, "r");
+ if (f) {
+ char *newline;
+
+ fgets(version, MAX_VERSION_STR_SIZE, f);
+ newline = strchr(version, '\n');
+ if (newline) {
+ *newline = '\0';
+ }
+ ovsrec_bridge_set_datapath_version(br->cfg, version);
+ fclose(f);
+ }
+ } else {
+ ovsrec_bridge_set_datapath_version(br->cfg, ovs_version);
+ }
+}
+
+static void
br_refresh_stp_status(struct bridge *br)
{
struct smap smap = SMAP_INITIALIZER(&smap);
@@ -2695,6 +2767,7 @@ run_status_update(void)
br_refresh_stp_status(br);
br_refresh_rstp_status(br);
+ br_refresh_datapath_info(br);
HMAP_FOR_EACH (port, hmap_node, &br->ports) {
struct iface *iface;
@@ -2808,6 +2881,8 @@ bridge_run(void)
}
cfg = ovsrec_open_vswitch_first(idl);
+ init_ovs_version(cfg->ovs_version);
+
/* Initialize the ofproto library. This only needs to run once, but
* it must be done after the configuration is set. If the
* initialization has already occurred, bridge_init_ofproto()
@@ -3054,6 +3129,7 @@ bridge_create(const struct ovsrec_bridge *br_cfg)
br->name = xstrdup(br_cfg->name);
br->type = xstrdup(ofproto_normalize_type(br_cfg->datapath_type));
br->cfg = br_cfg;
+ br->embryonic = true;
/* Derive the default Ethernet address from the bridge's UUID. This should
* be unique and it will be stable between ovs-vswitchd runs. */
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index 1817766..196c33c 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
{"name": "Open_vSwitch",
- "version": "7.10.1",
- "cksum": "2340049037 21461",
+ "version": "7.11.1",
+ "cksum": "1038213587 21518",
"tables": {
"Open_vSwitch": {
"columns": {
@@ -49,6 +49,8 @@
"mutable": false},
"datapath_type": {
"type": "string"},
+ "datapath_version": {
+ "type": "string"},
"datapath_id": {
"type": {"key": "string", "min": 0, "max": 1},
"ephemeral": true},
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index d90f221..0af0637 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -582,6 +582,11 @@
column="other-config" key="datapath-id"/> instead.)
</column>
+ <column name="datapath_version">
+ Reports the OpenFlow datapath version in use. Can be empty if
+ datapath version can not be determined.
+ </column>
+
<column name="other_config" key="datapath-id">
Exactly 16 hex digits to set the OpenFlow datapath ID to a specific
value. May not be all-zero.
--
1.9.1
More information about the dev
mailing list