netdev: Make netdev_from_name() take a reference to its returned netdev.
authorBen Pfaff <blp@nicira.com>
Fri, 26 Jul 2013 00:05:46 +0000 (17:05 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 8 Aug 2013 06:52:43 +0000 (23:52 -0700)
This API change is necessary for thread safety, to be added in an upcoming
commit.  Otherwise, the client would not be able to safely use the returned
netdev because it could already have been destroyed.

Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Andy Zhou <azhou@nicira.com>
lib/netdev-linux.c
lib/netdev.c

index 5bbaf63..c59f590 100644 (file)
@@ -541,6 +541,7 @@ netdev_linux_cache_cb(const struct rtnetlink_link_change *change,
         struct netdev *base_dev = netdev_from_name(change->ifname);
         if (base_dev && is_netdev_linux_class(netdev_get_class(base_dev))) {
             netdev_linux_update(netdev_linux_cast(base_dev), change);
+            netdev_close(base_dev);
         }
     } else {
         struct shash device_shash;
index 2561538..30c44a2 100644 (file)
@@ -1386,11 +1386,18 @@ netdev_get_class(const struct netdev *netdev)
 
 /* Returns the netdev with 'name' or NULL if there is none.
  *
- * The caller must not free the returned value. */
+ * The caller must free the returned netdev with netdev_close(). */
 struct netdev *
 netdev_from_name(const char *name)
 {
-    return shash_find_data(&netdev_shash, name);
+    struct netdev *netdev;
+
+    netdev = shash_find_data(&netdev_shash, name);
+    if (netdev) {
+        netdev_ref(netdev);
+    }
+
+    return netdev;
 }
 
 /* Fills 'device_list' with devices that match 'netdev_class'.
@@ -1415,8 +1422,10 @@ netdev_get_devices(const struct netdev_class *netdev_class,
 const char *
 netdev_get_type_from_name(const char *name)
 {
-    const struct netdev *dev = netdev_from_name(name);
-    return dev ? netdev_get_type(dev) : NULL;
+    struct netdev *dev = netdev_from_name(name);
+    const char *type = dev ? netdev_get_type(dev) : NULL;
+    netdev_close(dev);
+    return type;
 }
 \f
 void