diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-01-04 15:53:27 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-01-04 17:37:42 +0100 |
commit | 4f6b801b0d69a01971cdb3745b7e9df0e2fe6c6f (patch) | |
tree | 4b1cbfb2c17e0ac2032ccd5302d070ec6a43dd2f /src | |
parent | network/queue: do not check if a request is ready multiple times in a single ... (diff) | |
download | systemd-4f6b801b0d69a01971cdb3745b7e9df0e2fe6c6f.tar.xz systemd-4f6b801b0d69a01971cdb3745b7e9df0e2fe6c6f.zip |
network/queue: stop processing requests when a new request is queued
Otherwise, the loop triggers assertion:
```
Assertion 'e->p.b.key == i->next_key' failed at src/basic/hashmap.c:614, function hashmap_iterate_in_insertion_order(). Aborting.
```
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkd-manager.h | 1 | ||||
-rw-r--r-- | src/network/networkd-queue.c | 16 |
2 files changed, 15 insertions, 2 deletions
diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index 3f3569f44d..a2edfd0e79 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -100,6 +100,7 @@ struct Manager { FirewallContext *fw_ctx; + bool request_queued; OrderedSet *request_queue; Hashmap *tuntap_fds_by_name; diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index 7c62630968..1678510d52 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -168,6 +168,10 @@ static int request_new( if (req->counter) (*req->counter)++; + /* If this is called in the ORDERED_SET_FOREACH() loop of manager_process_requests(), we need to + * exit from the loop, due to the limitation of the iteration on OrderedSet. */ + manager->request_queued = true; + if (ret) *ret = req; @@ -220,6 +224,8 @@ int manager_process_requests(Manager *manager) { assert(manager); + manager->request_queued = false; + ORDERED_SET_FOREACH(req, manager->request_queue) { _cleanup_(link_unrefp) Link *link = link_ref(req->link); @@ -236,8 +242,11 @@ int manager_process_requests(Manager *manager) { return 0; r = req->process(req, link, req->userdata); - if (r == 0) - continue; /* The request is not ready. */ + if (r == 0) { /* The request is not ready. */ + if (manager->request_queued) + break; /* a new request is queued during processing the request. */ + continue; + } /* If the request sends netlink message, e.g. for Address or so, the Request object is * referenced by the netlink slot, and will be detached later by its destroy callback. @@ -251,6 +260,9 @@ int manager_process_requests(Manager *manager) { * hence we need to exit from the loop. */ break; } + + if (manager->request_queued) + break; } return 0; |