chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
networkd: reorder bonding and bridging
[elogind.git]
/
src
/
network
/
networkd-link.c
diff --git
a/src/network/networkd-link.c
b/src/network/networkd-link.c
index 74860196a506bb08d753a19ce4cbbddfac07e73d..7cb9ee675418101ac966b5926f0e2bba365434d9 100644
(file)
--- a/
src/network/networkd-link.c
+++ b/
src/network/networkd-link.c
@@
-37,7
+37,7
@@
static int ipv4ll_address_update(Link *link, bool deprecate);
static bool ipv4ll_is_bound(sd_ipv4ll *ll);
static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
static bool ipv4ll_is_bound(sd_ipv4ll *ll);
static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
- _cleanup_link_
free
_ Link *link = NULL;
+ _cleanup_link_
unref
_ Link *link = NULL;
uint16_t type;
char *ifname;
int r, ifindex;
uint16_t type;
char *ifname;
int r, ifindex;
@@
-67,6
+67,7
@@
static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
if (!link)
return -ENOMEM;
if (!link)
return -ENOMEM;
+ link->n_ref = 1;
link->manager = manager;
link->state = LINK_STATE_INITIALIZING;
link->ifindex = ifindex;
link->manager = manager;
link->state = LINK_STATE_INITIALIZING;
link->ifindex = ifindex;
@@
-94,7
+95,7
@@
static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
return 0;
}
return 0;
}
-void link_free(Link *link) {
+
static
void link_free(Link *link) {
if (!link)
return;
if (!link)
return;
@@
-120,6
+121,20
@@
void link_free(Link *link) {
free(link);
}
free(link);
}
+Link *link_unref(Link *link) {
+ if (link && (-- link->n_ref <= 0))
+ link_free(link);
+
+ return NULL;
+}
+
+Link *link_ref(Link *link) {
+ if (link)
+ assert_se(++ link->n_ref >= 2);
+
+ return link;
+}
+
int link_get(Manager *m, int ifindex, Link **ret) {
Link *link;
uint64_t ifindex_64;
int link_get(Manager *m, int ifindex, Link **ret) {
Link *link;
uint64_t ifindex_64;
@@
-139,6
+154,19
@@
int link_get(Manager *m, int ifindex, Link **ret) {
return 0;
}
return 0;
}
+void link_drop(Link *link) {
+ if (!link || link->state == LINK_STATE_LINGER)
+ return;
+
+ link->state = LINK_STATE_LINGER;
+
+ log_debug_link(link, "dropped");
+
+ link_unref(link);
+
+ return;
+}
+
static int link_enter_configured(Link *link) {
assert(link);
assert(link->state == LINK_STATE_SETTING_ROUTES);
static int link_enter_configured(Link *link) {
assert(link);
assert(link->state == LINK_STATE_SETTING_ROUTES);
@@
-198,7
+226,7
@@
static int link_stop_clients(Link *link) {
static void link_enter_failed(Link *link) {
assert(link);
static void link_enter_failed(Link *link) {
assert(link);
- if (
link->state == LINK_STATE_FAILED
)
+ if (
IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)
)
return;
log_warning_link(link, "failed");
return;
log_warning_link(link, "failed");
@@
-215,14
+243,16
@@
static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
int r;
assert(link->route_messages > 0);
int r;
assert(link->route_messages > 0);
- assert(
link->state == LINK_STATE_SETTING_ADDRESSES ||
- link->state == LINK_STATE_SETTING_ROUTES ||
-
link->state == LINK_STATE_FAILED
);
+ assert(
IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
+ LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
+
LINK_STATE_LINGER)
);
link->route_messages --;
link->route_messages --;
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
return 1;
return 1;
+ }
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST)
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST)
@@
-239,6
+269,8
@@
static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
link_enter_configured(link);
}
link_enter_configured(link);
}
+ link_unref(link);
+
return 1;
}
return 1;
}
@@
-253,7
+285,7
@@
static int link_enter_set_routes(Link *link) {
link->state = LINK_STATE_SETTING_ROUTES;
if (!link->network->static_routes && !link->dhcp_lease &&
link->state = LINK_STATE_SETTING_ROUTES;
if (!link->network->static_routes && !link->dhcp_lease &&
-
(!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
+ (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
return link_enter_configured(link);
log_debug_link(link, "setting routes");
return link_enter_configured(link);
log_debug_link(link, "setting routes");
@@
-267,6
+299,7
@@
static int link_enter_set_routes(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
link->route_messages ++;
}
link->route_messages ++;
}
@@
-301,6
+334,7
@@
static int link_enter_set_routes(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
link->route_messages ++;
}
}
link->route_messages ++;
}
}
@@
-346,6
+380,7
@@
static int link_enter_set_routes(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
link->route_messages ++;
route->family = AF_INET;
link->route_messages ++;
route->family = AF_INET;
@@
-359,6
+394,7
@@
static int link_enter_set_routes(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
link->route_messages ++;
}
}
link->route_messages ++;
}
}
@@
-378,8
+414,10
@@
static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata)
assert(link);
assert(link->ifname);
assert(link);
assert(link->ifname);
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
return 1;
return 1;
+ }
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -ENOENT)
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -ENOENT)
@@
-389,6
+427,8
@@
static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata)
"ERRNO=%d", -r,
NULL);
"ERRNO=%d", -r,
NULL);
+ link_unref(link);
+
return 0;
}
return 0;
}
@@
-400,12
+440,15
@@
static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
assert(link);
assert(link->ifname);
assert(link->addr_messages > 0);
assert(link);
assert(link->ifname);
assert(link->addr_messages > 0);
- assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
+ assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
+ LINK_STATE_FAILED, LINK_STATE_LINGER));
link->addr_messages --;
link->addr_messages --;
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
return 1;
return 1;
+ }
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST)
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -EEXIST)
@@
-420,6
+463,8
@@
static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
link_enter_set_routes(link);
}
link_enter_set_routes(link);
}
+ link_unref(link);
+
return 1;
}
return 1;
}
@@
-448,6
+493,7
@@
static int link_enter_set_addresses(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
link->addr_messages ++;
}
link->addr_messages ++;
}
@@
-483,6
+529,7
@@
static int link_enter_set_addresses(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
link->addr_messages ++;
}
}
link->addr_messages ++;
}
}
@@
-529,6
+576,7
@@
static int link_enter_set_addresses(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
link->addr_messages ++;
}
link->addr_messages ++;
}
@@
-543,8
+591,10
@@
static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userd
assert(link);
assert(link->ifname);
assert(link);
assert(link->ifname);
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
return 1;
return 1;
+ }
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -ENOENT)
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -ENOENT)
@@
-554,6
+604,8
@@
static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userd
"ERRNO=%d", -r,
NULL);
"ERRNO=%d", -r,
NULL);
+ link_unref(link);
+
return 0;
}
return 0;
}
@@
-565,8
+617,10
@@
static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdat
assert(link);
assert(link->ifname);
assert(link);
assert(link->ifname);
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
return 1;
return 1;
+ }
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -ENOENT)
r = sd_rtnl_message_get_errno(m);
if (r < 0 && r != -ENOENT)
@@
-576,34
+630,48
@@
static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdat
"ERRNO=%d", -r,
NULL);
"ERRNO=%d", -r,
NULL);
+ link_unref(link);
+
return 0;
}
static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
return 0;
}
static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+ Link *link = userdata;
int r;
int r;
+ assert(link);
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
+ return 1;
+ }
+
r = sd_bus_message_get_errno(m);
if (r < 0)
log_warning("Could not set hostname: %s", strerror(-r));
r = sd_bus_message_get_errno(m);
if (r < 0)
log_warning("Could not set hostname: %s", strerror(-r));
+ link_unref(link);
+
return 1;
}
return 1;
}
-static int
set_hostname(sd_bus *bus
, const char *hostname) {
+static int
link_set_hostname(Link *link
, const char *hostname) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
int r = 0;
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
int r = 0;
+ assert(link);
+ assert(link->manager);
assert(hostname);
assert(hostname);
- log_debug
(
"Setting transient hostname: '%s'", hostname);
+ log_debug
_link(link,
"Setting transient hostname: '%s'", hostname);
- if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
- log_info
(
"Not connected to system bus, ignoring transient hostname.");
+ if (!
link->manager->
bus) { /* TODO: replace by assert when we can rely on kdbus */
+ log_info
_link(link,
"Not connected to system bus, ignoring transient hostname.");
return 0;
}
r = sd_bus_message_new_method_call(
return 0;
}
r = sd_bus_message_new_method_call(
- bus,
+
link->manager->
bus,
&m,
"org.freedesktop.hostname1",
"/org/freedesktop/hostname1",
&m,
"org.freedesktop.hostname1",
"/org/freedesktop/hostname1",
@@
-616,9
+684,11
@@
static int set_hostname(sd_bus *bus, const char *hostname) {
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_bus_call_async(
bus, m, set_hostname_handler, NULL
, 0, NULL);
+ r = sd_bus_call_async(
link->manager->bus, m, set_hostname_handler, link
, 0, NULL);
if (r < 0)
if (r < 0)
- log_error("Could not set transient hostname: %s", strerror(-r));
+ log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
+
+ link_ref(link);
return r;
}
return r;
}
@@
-631,8
+701,10
@@
static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
assert(link);
assert(link->ifname);
assert(link);
assert(link->ifname);
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
return 1;
return 1;
+ }
r = sd_rtnl_message_get_errno(m);
if (r < 0)
r = sd_rtnl_message_get_errno(m);
if (r < 0)
@@
-642,6
+714,8
@@
static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
"ERRNO=%d", -r,
NULL);
"ERRNO=%d", -r,
NULL);
+ link_unref(link);
+
return 1;
}
return 1;
}
@@
-675,6
+749,8
@@
static int link_set_mtu(Link *link, uint32_t mtu) {
return r;
}
return r;
}
+ link_unref(link);
+
return 0;
}
return 0;
}
@@
-705,6
+781,7
@@
static int dhcp_lease_lost(Link *link) {
route_gw->scope = RT_SCOPE_LINK;
route_drop(route_gw, link, &route_drop_handler);
route_gw->scope = RT_SCOPE_LINK;
route_drop(route_gw, link, &route_drop_handler);
+ link_ref(link);
}
r = route_new_dynamic(&route);
}
r = route_new_dynamic(&route);
@@
-713,6
+790,7
@@
static int dhcp_lease_lost(Link *link) {
route->in_addr.in = gateway;
route_drop(route, link, &route_drop_handler);
route->in_addr.in = gateway;
route_drop(route, link, &route_drop_handler);
+ link_ref(link);
}
}
}
}
@@
-725,6
+803,7
@@
static int dhcp_lease_lost(Link *link) {
address->prefixlen = prefixlen;
address_drop(address, link, &address_drop_handler);
address->prefixlen = prefixlen;
address_drop(address, link, &address_drop_handler);
+ link_ref(link);
}
if (link->network->dhcp_mtu) {
}
if (link->network->dhcp_mtu) {
@@
-746,7
+825,7
@@
static int dhcp_lease_lost(Link *link) {
r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
if (r >= 0 && hostname) {
r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
if (r >= 0 && hostname) {
- r =
set_hostname(link->manager->bus
, "");
+ r =
link_set_hostname(link
, "");
if (r < 0)
log_error("Failed to reset transient hostname");
}
if (r < 0)
log_error("Failed to reset transient hostname");
}
@@
-853,7
+932,7
@@
static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
r = sd_dhcp_lease_get_hostname(lease, &hostname);
if (r >= 0) {
r = sd_dhcp_lease_get_hostname(lease, &hostname);
if (r >= 0) {
- r =
set_hostname(link->manager->bus
, hostname);
+ r =
link_set_hostname(link
, hostname);
if (r < 0)
log_error("Failed to set transient hostname "
"to '%s'", hostname);
if (r < 0)
log_error("Failed to set transient hostname "
"to '%s'", hostname);
@@
-873,7
+952,7
@@
static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
assert(link->network);
assert(link->manager);
assert(link->network);
assert(link->manager);
- if (
link->state == LINK_STATE_FAILED
)
+ if (
IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)
)
return;
switch (event) {
return;
switch (event) {
@@
-973,6
+1052,7
@@
static int ipv4ll_address_update(Link *link, bool deprecate) {
address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
address_update(address, link, &address_update_handler);
address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
address_update(address, link, &address_update_handler);
+ link_ref(link);
}
return 0;
}
return 0;
@@
-1005,6
+1085,7
@@
static int ipv4ll_address_lost(Link *link) {
address->scope = RT_SCOPE_LINK;
address_drop(address, link, &address_drop_handler);
address->scope = RT_SCOPE_LINK;
address_drop(address, link, &address_drop_handler);
+ link_ref(link);
r = route_new_dynamic(&route);
if (r < 0) {
r = route_new_dynamic(&route);
if (r < 0) {
@@
-1018,6
+1099,7
@@
static int ipv4ll_address_lost(Link *link) {
route->metrics = 99;
route_drop(route, link, &route_drop_handler);
route->metrics = 99;
route_drop(route, link, &route_drop_handler);
+ link_ref(link);
}
return 0;
}
return 0;
@@
-1065,6
+1147,9
@@
static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
assert(link->network);
assert(link->manager);
assert(link->network);
assert(link->manager);
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return;
+
switch(event) {
case IPV4LL_EVENT_STOP:
case IPV4LL_EVENT_CONFLICT:
switch(event) {
case IPV4LL_EVENT_STOP:
case IPV4LL_EVENT_CONFLICT:
@@
-1272,8
+1357,10
@@
static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
assert(link);
assert(link);
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
return 1;
return 1;
+ }
r = sd_rtnl_message_get_errno(m);
if (r < 0) {
r = sd_rtnl_message_get_errno(m);
if (r < 0) {
@@
-1286,6
+1373,8
@@
static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
NULL);
}
NULL);
}
+ link_unref(link);
+
return 1;
}
return 1;
}
@@
-1319,6
+1408,8
@@
static int link_up(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
+
return 0;
}
return 0;
}
@@
-1348,13
+1439,16
@@
static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
int r;
assert(link);
int r;
assert(link);
- assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
+ assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
+ LINK_STATE_LINGER));
assert(link->network);
link->enslaving --;
assert(link->network);
link->enslaving --;
- if (link->state == LINK_STATE_FAILED)
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
+ link_unref(link);
return 1;
return 1;
+ }
r = sd_rtnl_message_get_errno(m);
if (r < 0) {
r = sd_rtnl_message_get_errno(m);
if (r < 0) {
@@
-1364,6
+1458,7
@@
static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
"ERRNO=%d", -r,
NULL);
link_enter_failed(link);
"ERRNO=%d", -r,
NULL);
link_enter_failed(link);
+ link_unref(link);
return 1;
}
return 1;
}
@@
-1372,6
+1467,8
@@
static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
if (link->enslaving == 0)
link_enslaved(link);
if (link->enslaving == 0)
link_enslaved(link);
+ link_unref(link);
+
return 1;
}
return 1;
}
@@
-1393,45
+1490,47
@@
static int link_enter_enslave(Link *link) {
hashmap_isempty(link->network->macvlans))
return link_enslaved(link);
hashmap_isempty(link->network->macvlans))
return link_enslaved(link);
- if (link->network->b
ridge
) {
+ if (link->network->b
ond
) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%s: enslaving by '%s'",
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%s: enslaving by '%s'",
- link->ifname, link->network->b
ridge
->name,
- NETDEV(link->network->b
ridge
),
+ link->ifname, link->network->b
ond
->name,
+ NETDEV(link->network->b
ond
),
NULL);
NULL);
- r = netdev_enslave(link->network->b
ridge
, link, &enslave_handler);
+ r = netdev_enslave(link->network->b
ond
, link, &enslave_handler);
if (r < 0) {
log_struct_link(LOG_WARNING, link,
"MESSAGE=%s: could not enslave by '%s': %s",
if (r < 0) {
log_struct_link(LOG_WARNING, link,
"MESSAGE=%s: could not enslave by '%s': %s",
- link->ifname, link->network->b
ridge
->name, strerror(-r),
- NETDEV(link->network->b
ridge
),
+ link->ifname, link->network->b
ond
->name, strerror(-r),
+ NETDEV(link->network->b
ond
),
NULL);
link_enter_failed(link);
return r;
}
NULL);
link_enter_failed(link);
return r;
}
+ link_ref(link);
link->enslaving ++;
}
link->enslaving ++;
}
- if (link->network->b
ond
) {
+ if (link->network->b
ridge
) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%s: enslaving by '%s'",
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%s: enslaving by '%s'",
- link->ifname, link->network->b
ond
->name,
- NETDEV(link->network->b
ond
),
+ link->ifname, link->network->b
ridge
->name,
+ NETDEV(link->network->b
ridge
),
NULL);
NULL);
- r = netdev_enslave(link->network->b
ond
, link, &enslave_handler);
+ r = netdev_enslave(link->network->b
ridge
, link, &enslave_handler);
if (r < 0) {
log_struct_link(LOG_WARNING, link,
"MESSAGE=%s: could not enslave by '%s': %s",
if (r < 0) {
log_struct_link(LOG_WARNING, link,
"MESSAGE=%s: could not enslave by '%s': %s",
- link->ifname, link->network->b
ond
->name, strerror(-r),
- NETDEV(link->network->b
ond
),
+ link->ifname, link->network->b
ridge
->name, strerror(-r),
+ NETDEV(link->network->b
ridge
),
NULL);
link_enter_failed(link);
return r;
}
NULL);
link_enter_failed(link);
return r;
}
+ link_ref(link);
link->enslaving ++;
}
link->enslaving ++;
}
@@
-1450,6
+1549,7
@@
static int link_enter_enslave(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
link->enslaving ++;
}
link->enslaving ++;
}
@@
-1468,6
+1568,7
@@
static int link_enter_enslave(Link *link) {
return r;
}
return r;
}
+ link_ref(link);
link->enslaving ++;
}
link->enslaving ++;
}
@@
-1706,6
+1807,11
@@
int link_save(Link *link) {
if (r < 0)
return r;
if (r < 0)
return r;
+ if (link->state == LINK_STATE_LINGER) {
+ unlink(link->state_file);
+ return 0;
+ }
+
admin_state = link_state_to_string(link->state);
assert(admin_state);
admin_state = link_state_to_string(link->state);
assert(admin_state);
@@
-1759,6
+1865,7
@@
static const char* const link_state_table[_LINK_STATE_MAX] = {
[LINK_STATE_CONFIGURED] = "configured",
[LINK_STATE_UNMANAGED] = "unmanaged",
[LINK_STATE_FAILED] = "failed",
[LINK_STATE_CONFIGURED] = "configured",
[LINK_STATE_UNMANAGED] = "unmanaged",
[LINK_STATE_FAILED] = "failed",
+ [LINK_STATE_LINGER] = "linger",
};
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
};
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);