summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-01-04 15:53:27 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-01-04 17:37:42 +0100
commit4f6b801b0d69a01971cdb3745b7e9df0e2fe6c6f (patch)
tree4b1cbfb2c17e0ac2032ccd5302d070ec6a43dd2f /src
parentnetwork/queue: do not check if a request is ready multiple times in a single ... (diff)
downloadsystemd-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.h1
-rw-r--r--src/network/networkd-queue.c16
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;