]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/netdev: use hashmap_remove_value() on detaching NetDev from manager
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 9 Sep 2024 06:17:54 +0000 (15:17 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 10 Sep 2024 10:29:05 +0000 (19:29 +0900)
Then, it is not necessary to free NetDev.ifname when a conflicting
.netdev file is already loaded.

This also split out netdev_detach_name() and netdev_detach_impl().

No functional change, just refactoring.

src/network/netdev/netdev.c
src/network/netdev/netdev.h

index f24ec02f7f6ffd72ae64bdc088c2b60aeade7f6b..1b01f7e4533aedca159b20a23c1f71d5ae7adaa1 100644 (file)
@@ -191,12 +191,31 @@ static bool netdev_is_stacked(NetDev *netdev) {
         return true;
 }
 
-static void netdev_detach_from_manager(NetDev *netdev) {
-        if (netdev->ifname && netdev->manager)
-                hashmap_remove(netdev->manager->netdevs, netdev->ifname);
+NetDev* netdev_detach_name(NetDev *netdev, const char *name) {
+        assert(netdev);
+
+        if (!netdev->manager || !name)
+                return NULL; /* Already detached or not attached yet. */
+
+        return hashmap_remove_value(netdev->manager->netdevs, name, netdev);
+}
+
+static NetDev* netdev_detach_impl(NetDev *netdev) {
+        assert(netdev);
+
+        NetDev *n = netdev_detach_name(netdev, netdev->ifname);
+
+        netdev->manager = NULL;
+        return n; /* Return NULL when it is not attached yet, or already detached. */
+}
+
+void netdev_detach(NetDev *netdev) {
+        assert(netdev);
+
+        netdev_unref(netdev_detach_impl(netdev));
 }
 
-static NetDev *netdev_free(NetDev *netdev) {
+static NetDevnetdev_free(NetDev *netdev) {
         assert(netdev);
 
         /* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that
@@ -211,7 +230,7 @@ static NetDev *netdev_free(NetDev *netdev) {
             NETDEV_VTABLE(netdev)->done)
                 NETDEV_VTABLE(netdev)->done(netdev);
 
-        netdev_detach_from_manager(netdev);
+        netdev_detach_impl(netdev);
 
         condition_free_list(netdev->conditions);
         free(netdev->filename);
@@ -245,9 +264,7 @@ void netdev_drop(NetDev *netdev) {
 
         log_netdev_debug(netdev, "netdev removed");
 
-        netdev_detach_from_manager(netdev);
-        netdev_unref(netdev);
-        return;
+        netdev_detach(netdev);
 }
 
 int netdev_get(Manager *manager, const char *name, NetDev **ret) {
@@ -891,9 +908,6 @@ int netdev_load_one(Manager *manager, const char *filename) {
                                                  "Device was already configured by \"%s\", ignoring %s.",
                                                  n->filename, netdev->filename);
 
-                /* Clear ifname before netdev_free() is called. Otherwise, the NetDev object 'n' is
-                 * removed from the hashmap 'manager->netdevs'. */
-                netdev->ifname = mfree(netdev->ifname);
                 return -EEXIST;
         }
         assert(r > 0);
index 3bb4acf6c232884552c2a4c55ffe7757600a91d6..2d19c2f042e03eacb451d82f55056559430c3903 100644 (file)
@@ -195,6 +195,9 @@ extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
 /* For casting the various netdev kinds into a netdev */
 #define NETDEV(n) (&(n)->meta)
 
+NetDev* netdev_detach_name(NetDev *netdev, const char *name);
+void netdev_detach(NetDev *netdev);
+
 int netdev_load(Manager *manager, bool reload);
 int netdev_load_one(Manager *manager, const char *filename);
 void netdev_drop(NetDev *netdev);