sd-network: expose global operational state
This commit is contained in:
parent
e0e5ce237b
commit
bbf7c04821
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue