dpif: New function dpif_create_and_open().
[sliver-openvswitch.git] / lib / dpif.c
index 14b424e..793eaa1 100644 (file)
@@ -95,9 +95,9 @@ dp_wait(void)
     }
 }
 
-/* Initializes 'all_dps' and enumerates the names of all known created
- * datapaths, where possible, into it.  Returns 0 if successful, otherwise a
- * positive errno value.
+/* Clears 'all_dps' and enumerates the names of all known created datapaths, 
+ * where possible, into it.  The caller must first initialize 'all_dps'.
+ * Returns 0 if successful, otherwise a positive errno value.
  *
  * Some kinds of datapaths might not be practically enumerable.  This is not
  * considered an error. */
@@ -107,7 +107,7 @@ dp_enumerate(struct svec *all_dps)
     int error;
     int i;
 
-    svec_init(all_dps);
+    svec_clear(all_dps);
     error = 0;
     for (i = 0; i < N_DPIF_CLASSES; i++) {
         const struct dpif_class *class = dpif_classes[i];
@@ -169,13 +169,35 @@ dpif_open(const char *name, struct dpif **dpifp)
 /* Tries to create and open a new datapath with the given 'name'.  Will fail if
  * a datapath named 'name' already exists.  Returns 0 if successful, otherwise
  * a positive errno value.  On success stores a pointer to the datapath in
- * '*dpifp', otherwise a null pointer.*/
+ * '*dpifp', otherwise a null pointer. */
 int
 dpif_create(const char *name, struct dpif **dpifp)
 {
     return do_open(name, true, dpifp);
 }
 
+/* Tries to open a datapath with the given 'name', creating it if it does not
+ * exist.  Returns 0 if successful, otherwise a positive errno value.  On
+ * success stores a pointer to the datapath in '*dpifp', otherwise a null
+ * pointer. */
+int
+dpif_create_and_open(const char *name, struct dpif **dpifp)
+{
+    int error;
+
+    error = dpif_create(name, dpifp);
+    if (error == EEXIST || error == EBUSY) {
+        error = dpif_open(name, dpifp);
+        if (error) {
+            VLOG_WARN("datapath %s already exists but cannot be opened: %s",
+                      name, strerror(error));
+        }
+    } else if (error) {
+        VLOG_WARN("failed to create datapath %s: %s", name, strerror(error));
+    }
+    return error;
+}
+
 /* Closes and frees the connection to 'dpif'.  Does not destroy the datapath
  * itself; call dpif_delete() first, instead, if that is desirable. */
 void
@@ -397,7 +419,7 @@ dpif_port_list(const struct dpif *dpif,
                struct odp_port **portsp, size_t *n_portsp)
 {
     struct odp_port *ports;
-    size_t n_ports;
+    size_t n_ports = 0;
     int error;
 
     for (;;) {