netdev-dpdk: Properly support non pmd threads.
[cascardo/ovs.git] / lib / dpctl.c
index 711b18d..e95483e 100644 (file)
@@ -621,26 +621,28 @@ dps_for_each(struct dpctl_params *dpctl_p, dps_for_each_cb cb)
 {
     struct sset dpif_names = SSET_INITIALIZER(&dpif_names),
                 dpif_types = SSET_INITIALIZER(&dpif_types);
-    int error, lasterror = 0;
+    int error, openerror = 0, enumerror = 0;
     const char *type, *name;
+    bool at_least_one = false;
 
     dp_enumerate_types(&dpif_types);
 
     SSET_FOR_EACH (type, &dpif_types) {
         error = dp_enumerate_names(type, &dpif_names);
         if (error) {
-            lasterror = error;
+            enumerror = error;
         }
 
         SSET_FOR_EACH (name, &dpif_names) {
             struct dpif *dpif;
 
+            at_least_one = true;
             error = dpif_open(name, type, &dpif);
             if (!error) {
                 cb(dpif, dpctl_p);
                 dpif_close(dpif);
             } else {
-                lasterror = error;
+                openerror = error;
                 dpctl_error(dpctl_p, error, "opening datapath %s failed",
                             name);
             }
@@ -650,7 +652,17 @@ dps_for_each(struct dpctl_params *dpctl_p, dps_for_each_cb cb)
     sset_destroy(&dpif_names);
     sset_destroy(&dpif_types);
 
-    return lasterror;
+    /* If there has been an error while opening a datapath it should be
+     * reported.  Otherwise, we want to ignore the errors generated by
+     * dp_enumerate_names() if at least one datapath has been discovered,
+     * because they're not interesting for the user.  This happens, for
+     * example, if OVS is using a userspace datapath and the kernel module
+     * is not loaded. */
+    if (openerror) {
+        return openerror;
+    } else {
+        return at_least_one ? 0 : enumerror;
+    }
 }
 
 static int
@@ -771,6 +783,12 @@ dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
         }
     }
 
+    /* Make sure that these values are different. PMD_ID_NULL means that the
+     * pmd is unspecified (e.g. because the datapath doesn't have different
+     * pmd threads), while NON_PMD_CORE_ID refers to every non pmd threads
+     * in the userspace datapath */
+    BUILD_ASSERT(PMD_ID_NULL != NON_PMD_CORE_ID);
+
     ds_init(&ds);
     flow_dump = dpif_flow_dump_create(dpif, false);
     flow_dump_thread = dpif_flow_dump_thread_create(flow_dump);