chiark / gitweb /
Fix a few return codes in error paths
[elogind.git] / src / network / networkd-manager.c
index 55e5cafd00bcd6a248c2e583903d4cf958706f89..d903d0d60ed4dc02655a7512c4573d90428b759d 100644 (file)
@@ -33,11 +33,43 @@ const char* const network_dirs[] = {
         "/etc/systemd/network",
         "/run/systemd/network",
         "/usr/lib/systemd/network",
-#ifdef HAVE_SPLIT_USER
+#ifdef HAVE_SPLIT_USR
         "/lib/systemd/network",
 #endif
         NULL};
 
+static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
+        Manager *m = userdata;
+
+        assert(m);
+
+        log_received_signal(LOG_INFO, si);
+
+        sd_event_exit(m->event, 0);
+        return 0;
+}
+
+static int setup_signals(Manager *m) {
+        sigset_t mask;
+        int r;
+
+        assert(m);
+
+        assert_se(sigemptyset(&mask) == 0);
+        sigset_add_many(&mask, SIGINT, SIGTERM, -1);
+        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+        r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m);
+        if (r < 0)
+                return r;
+
+        r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 int manager_new(Manager **ret) {
         _cleanup_manager_free_ Manager *m = NULL;
         int r;
@@ -60,6 +92,10 @@ int manager_new(Manager **ret) {
         if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
                 return r;
 
+        r = setup_signals(m);
+        if (r < 0)
+                return r;
+
         m->udev = udev_new();
         if (!m->udev)
                 return -ENOMEM;
@@ -105,15 +141,17 @@ void manager_free(Manager *m) {
         udev_unref(m->udev);
         sd_bus_unref(m->bus);
         sd_event_source_unref(m->udev_event_source);
+        sd_event_source_unref(m->sigterm_event_source);
+        sd_event_source_unref(m->sigint_event_source);
         sd_event_unref(m->event);
 
-        while ((network = m->networks))
-                network_free(network);
-
         while ((link = hashmap_first(m->links)))
                 link_free(link);
         hashmap_free(m->links);
 
+        while ((network = m->networks))
+                network_free(network);
+
         while ((netdev = hashmap_first(m->netdevs)))
                 netdev_free(netdev);
         hashmap_free(m->netdevs);
@@ -265,7 +303,7 @@ int manager_udev_listen(Manager *m) {
 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
         Manager *m = userdata;
         Link *link;
-        const char *name;
+        char *name;
         int r, ifindex;
 
         assert(rtnl);
@@ -274,22 +312,24 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
 
         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
         if (r < 0 || ifindex <= 0) {
-                log_debug("received RTM_NEWLINK message without valid ifindex");
+                log_warning("received RTM_NEWLINK message without valid ifindex");
                 return 0;
         }
 
-        r = rtnl_message_link_get_ifname(message, &name);
+        r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
         if (r < 0)
-                log_debug("received RTM_NEWLINK message without valid IFLA_IFNAME");
+                log_warning("received RTM_NEWLINK message without valid ifname");
         else {
                 NetDev *netdev;
 
                 r = netdev_get(m, name, &netdev);
                 if (r >= 0) {
-                        r = netdev_set_ifindex(netdev, ifindex);
-                        if (r < 0)
-                                log_debug("could not set ifindex of netdev '%s' to %d: %s",
-                                          name, ifindex, strerror(-r));
+                        netdev_set_ifindex(netdev, message);
+                        r = sd_rtnl_message_rewind(message);
+                        if (r < 0) {
+                                log_debug("could not rewind rtnl message");
+                                return 0;
+                        }
                 }
         }
 
@@ -369,10 +409,6 @@ int manager_update_resolv_conf(Manager *m) {
 
         assert(m);
 
-        r = mkdir_safe_label("/run/systemd/network", 0755, 0, 0);
-        if (r < 0)
-                return r;
-
         r = fopen_temporary("/run/systemd/network/resolv.conf", &f, &temp_path);
         if (r < 0)
                 return r;
@@ -408,10 +444,17 @@ int manager_update_resolv_conf(Manager *m) {
                 }
         }
 
-        HASHMAP_FOREACH(link, m->links, i)
-                if (link->network && link->network->dns)
-                        append_dns(f, &link->network->dns->in_addr.in,
-                                   link->network->dns->family, &count);
+        HASHMAP_FOREACH(link, m->links, i) {
+                if (link->network && link->network->dns) {
+                        Address *address;
+                        Iterator j;
+
+                        SET_FOREACH(address, link->network->dns, j) {
+                                append_dns(f, &address->in_addr.in,
+                                           address->family, &count);
+                        }
+                }
+        }
 
         fflush(f);