@@ -222,7 +222,7 @@ void link_dns_settings_clear(Link *link) {
|
||||
link->dnssec_negative_trust_anchors = set_free_free(link->dnssec_negative_trust_anchors);
|
||||
}
|
||||
|
||||
void link_free_engines(Link *link) {
|
||||
static void link_free_engines(Link *link) {
|
||||
if (!link)
|
||||
return;
|
||||
|
||||
|
||||
@@ -253,7 +253,6 @@ int link_ipv6ll_gained(Link *link);
|
||||
bool link_has_ipv6_connectivity(Link *link);
|
||||
|
||||
int link_stop_engines(Link *link, bool may_keep_dhcp);
|
||||
void link_free_engines(Link *link);
|
||||
|
||||
const char* link_state_to_string(LinkState s) _const_;
|
||||
LinkState link_state_from_string(const char *s) _pure_;
|
||||
|
||||
@@ -475,10 +475,8 @@ static int manager_stop(Manager *manager, ManagerState state) {
|
||||
manager->state = state;
|
||||
|
||||
Link *link;
|
||||
HASHMAP_FOREACH(link, manager->links_by_index) {
|
||||
HASHMAP_FOREACH(link, manager->links_by_index)
|
||||
(void) link_stop_engines(link, /* may_keep_dhcp = */ true);
|
||||
link_free_engines(link);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ static int netlabel_command(uint16_t command, const char *label, const Address *
|
||||
assert(address->link->manager->genl);
|
||||
assert(IN_SET(address->family, AF_INET, AF_INET6));
|
||||
|
||||
if (address->link->manager->state == MANAGER_STOPPED)
|
||||
return 0; /* We cannot call link_ref() below. */
|
||||
|
||||
r = sd_genl_message_new(address->link->manager->genl, NETLBL_NLTYPE_UNLABELED_NAME, command, &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -142,6 +142,15 @@ static int request_new(
|
||||
assert(manager);
|
||||
assert(process);
|
||||
|
||||
/* Note, requests will be processed only when the manager is in MANAGER_RUNNING. If a new operation
|
||||
* is requested when the manager is in MANAGER_TERMINATING or MANAGER_RESTARTING, the request will be
|
||||
* successfully queued but will never be processed. Then, here why we refuse new requests when the
|
||||
* manager is in MANAGER_STOPPED? This is because we cannot call link_ref() in that case, as this may
|
||||
* be called during link_free(), that means the reference counter of the link is already 0 and
|
||||
* calling link_ref() below triggers assertion. */
|
||||
if (manager->state == MANAGER_STOPPED)
|
||||
return -EBUSY;
|
||||
|
||||
req = new(Request, 1);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
@@ -426,6 +435,12 @@ int remove_request_add(
|
||||
assert(netlink);
|
||||
assert(message);
|
||||
|
||||
/* Unlike request_new(), remove requests will be also processed when the manager is in
|
||||
* MANAGER_TERMINATING or MANAGER_RESTARTING. When the manager is in MANAGER_STOPPED, we cannot
|
||||
* queue new remove requests anymore with the same reason explained in request_new(). */
|
||||
if (manager->state == MANAGER_STOPPED)
|
||||
return 0;
|
||||
|
||||
req = new(RemoveRequest, 1);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -574,6 +574,9 @@ int route_remove(Route *route, Manager *manager) {
|
||||
assert(route);
|
||||
assert(manager);
|
||||
|
||||
if (manager->state == MANAGER_STOPPED)
|
||||
return 0; /* The remove request will not be queued anyway. Suppress logging below. */
|
||||
|
||||
/* If the route is remembered, then use the remembered object. */
|
||||
(void) route_get(manager, route, &route);
|
||||
|
||||
|
||||
@@ -948,6 +948,11 @@ void link_dirty(Link *link) {
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
/* When the manager is in MANAGER_STOPPED, it is not necessary to update state files anymore, as they
|
||||
* will be removed soon anyway. Moreover, we cannot call link_ref() in that case. */
|
||||
if (link->manager->state == MANAGER_STOPPED)
|
||||
return;
|
||||
|
||||
/* The serialized state in /run is no longer up-to-date. */
|
||||
|
||||
/* Also mark manager dirty as link is dirty */
|
||||
|
||||
Reference in New Issue
Block a user