diff options
| author | Tom Gundersen <teg@jklm.no> | 2014-05-08 17:21:37 +0200 | 
|---|---|---|
| committer | Tom Gundersen <teg@jklm.no> | 2014-05-08 17:21:37 +0200 | 
| commit | bbf7c04821a71fec67eaf0e7a34d17afc5913c13 (patch) | |
| tree | c713e0a13d98e87c2462947c508b025c25dd827c | |
| parent | e0e5ce237b11f2d97189cd7725bf339b4b8a78de (diff) | |
sd-network: expose global operational state
| -rw-r--r-- | src/network/networkd-link.c | 9 | ||||
| -rw-r--r-- | src/network/networkd-manager.c | 59 | ||||
| -rw-r--r-- | src/network/networkd.h | 5 | ||||
| -rw-r--r-- | src/network/sd-network.c | 21 | ||||
| -rw-r--r-- | src/systemd/sd-network.h | 7 | 
5 files changed, 99 insertions, 2 deletions
| diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 04b2265610..ab3158356a 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1117,7 +1117,7 @@ static int link_acquire_conf(Link *link) {          return 0;  } -static bool link_has_carrier(unsigned flags, uint8_t operstate) { +bool link_has_carrier(unsigned flags, uint8_t operstate) {          /* see Documentation/networking/operstates.txt in the kernel sources */          if (operstate == IF_OPER_UP) @@ -1689,6 +1689,11 @@ int link_save(Link *link) {          assert(link);          assert(link->state_file); +        assert(link->manager); + +        r = manager_save(link->manager); +        if (r < 0) +                return r;          admin_state = link_state_to_string(link->state);          assert(admin_state); @@ -1735,7 +1740,7 @@ int link_save(Link *link) {  finish:          if (r < 0) -                log_error("Failed to save link data %s: %s", link->state_file, strerror(-r)); +                log_error("Failed to save link data to %s: %s", link->state_file, strerror(-r));          return r;  } diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 28de7919da..4b29553330 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -20,6 +20,7 @@   ***/  #include <resolv.h> +#include <linux/if.h>  #include "path-util.h"  #include "networkd.h" @@ -80,6 +81,10 @@ int manager_new(Manager **ret) {          if (!m)                  return -ENOMEM; +        m->state_file = strdup("/run/systemd/network/state"); +        if (!m->state_file) +                return -ENOMEM; +          r = sd_event_default(&m->event);          if (r < 0)                  return r; @@ -135,6 +140,8 @@ void manager_free(Manager *m) {          if (!m)                  return; +        free(m->state_file); +          udev_monitor_unref(m->udev_monitor);          udev_unref(m->udev);          sd_bus_unref(m->bus); @@ -457,3 +464,55 @@ int manager_update_resolv_conf(Manager *m) {          return 0;  } + +int manager_save(Manager *m) { +        Link *link; +        Iterator i; +        _cleanup_free_ char *temp_path = NULL; +        _cleanup_fclose_ FILE *f = NULL; +        const char *oper_state = "unknown"; +        bool dormant, carrier; +        int r; + +        assert(m); +        assert(m->state_file); + +        HASHMAP_FOREACH(link, m->links, i) { +                if (link->flags & IFF_LOOPBACK) +                        continue; + +                if (link_has_carrier(link->flags, link->operstate)) +                        carrier = true; +                else if (link->operstate == IF_OPER_DORMANT) +                        dormant = true; +        } + +        if (carrier) +                oper_state = "carrier"; +        else if (dormant) +                oper_state = "dormant"; + +        r = fopen_temporary(m->state_file, &f, &temp_path); +        if (r < 0) +                goto finish; + +        fchmod(fileno(f), 0644); + +        fprintf(f, +                "# This is private data. Do not parse.\n" +                "OPER_STATE=%s\n", oper_state); + +        fflush(f); + +        if (ferror(f) || rename(temp_path, m->state_file) < 0) { +                r = -errno; +                unlink(m->state_file); +                unlink(temp_path); +        } + +finish: +        if (r < 0) +                log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r)); + +        return r; +} diff --git a/src/network/networkd.h b/src/network/networkd.h index d31844aefd..aebb285920 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -232,6 +232,8 @@ struct Manager {          sd_event_source *sigterm_event_source;          sd_event_source *sigint_event_source; +        char *state_file; +          Hashmap *links;          Hashmap *netdevs;          LIST_HEAD(Network, networks); @@ -256,6 +258,7 @@ int manager_udev_listen(Manager *m);  int manager_bus_listen(Manager *m);  int manager_update_resolv_conf(Manager *m); +int manager_save(Manager *m);  DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);  #define _cleanup_manager_free_ _cleanup_(manager_freep) @@ -377,6 +380,8 @@ int link_initialized(Link *link, struct udev_device *device);  int link_save(Link *link); +bool link_has_carrier(unsigned flags, uint8_t operstate); +  const char* link_state_to_string(LinkState s) _const_;  LinkState link_state_from_string(const char *s) _pure_; diff --git a/src/network/sd-network.c b/src/network/sd-network.c index c867812209..492e97c73f 100644 --- a/src/network/sd-network.c +++ b/src/network/sd-network.c @@ -95,6 +95,27 @@ _public_ int sd_network_get_link_state(unsigned index, char **state) {          return 0;  } +_public_ int sd_network_get_operational_state(char **state) { +        _cleanup_free_ char *s = NULL; +        int r; + +        assert_return(state, -EINVAL); + +        r = parse_env_file("/run/systemd/network/state", NEWLINE, "OPER_STATE", +                           &s, NULL); +        if (r == -ENOENT) +                return -ENODATA; +        else if (r < 0) +                return r; +        else if (!s) +                return -EIO; + +        *state = s; +        s = NULL; + +        return 0; +} +  _public_ int sd_network_get_link_operational_state(unsigned index, char **state) {          _cleanup_free_ char *s = NULL, *p = NULL;          int r; diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h index 40bd75a23a..d0b2ea3576 100644 --- a/src/systemd/sd-network.h +++ b/src/systemd/sd-network.h @@ -67,6 +67,13 @@ int sd_network_get_link_state(unsigned index, char **state);   */  int sd_network_get_link_operational_state(unsigned index, char **state); +/* Get overall opeartional state + * Possible states: unknown, dormant, carrier + * Possible return codes: + *   -ENODATA: networkd is not aware of any links + */ +int sd_network_get_operational_state(char **state); +  /* Returns true if link exists and is loopback, and false otherwise */  int sd_network_link_is_loopback(unsigned index); | 
