[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