X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-rtnl%2Fsd-rtnl.c;h=543bad9f4f4447d82abbf62cd01b8440428755a2;hb=6190b9f9d2574428d560458a99f2838041cfdaac;hp=367f165a1c46aa2d7148beae26d89e44b42c8b6b;hpb=bc078e7163a826126e9ba03934978f510e9ef9e5;p=elogind.git diff --git a/src/libsystemd/sd-rtnl/sd-rtnl.c b/src/libsystemd/sd-rtnl/sd-rtnl.c index 367f165a1..543bad9f4 100644 --- a/src/libsystemd/sd-rtnl/sd-rtnl.c +++ b/src/libsystemd/sd-rtnl/sd-rtnl.c @@ -54,6 +54,12 @@ static int sd_rtnl_new(sd_rtnl **ret) { if (!GREEDY_REALLOC(rtnl->wqueue, rtnl->wqueue_allocated, 1)) return -ENOMEM; + /* We guarantee that the read buffer has at least space for + * a message header */ + if (!greedy_realloc((void**)&rtnl->rbuffer, &rtnl->rbuffer_allocated, + sizeof(struct nlmsghdr), sizeof(uint8_t))) + return -ENOMEM; + *ret = rtnl; rtnl = NULL; @@ -129,10 +135,16 @@ sd_rtnl *sd_rtnl_unref(sd_rtnl *rtnl) { sd_rtnl_message_unref(rtnl->rqueue[i]); free(rtnl->rqueue); + for (i = 0; i < rtnl->rqueue_partial_size; i++) + sd_rtnl_message_unref(rtnl->rqueue_partial[i]); + free(rtnl->rqueue_partial); + for (i = 0; i < rtnl->wqueue_size; i++) sd_rtnl_message_unref(rtnl->wqueue[i]); free(rtnl->wqueue); + free(rtnl->rbuffer); + hashmap_free_free(rtnl->reply_callbacks); prioq_free(rtnl->reply_callbacks_prioq); @@ -191,8 +203,10 @@ int sd_rtnl_send(sd_rtnl *nl, } } else { /* append to queue */ - if (nl->wqueue_size >= RTNL_WQUEUE_MAX) + if (nl->wqueue_size >= RTNL_WQUEUE_MAX) { + log_debug("rtnl: exhausted the write queue size (%d)", RTNL_WQUEUE_MAX); return -ENOBUFS; + } if (!GREEDY_REALLOC(nl->wqueue, nl->wqueue_allocated, nl->wqueue_size + 1)) return -ENOMEM; @@ -209,8 +223,10 @@ int sd_rtnl_send(sd_rtnl *nl, int rtnl_rqueue_make_room(sd_rtnl *rtnl) { assert(rtnl); - if (rtnl->rqueue_size >= RTNL_RQUEUE_MAX) + if (rtnl->rqueue_size >= RTNL_RQUEUE_MAX) { + log_debug("rtnl: exhausted the read queue size (%d)", RTNL_RQUEUE_MAX); return -ENOBUFS; + } if (!GREEDY_REALLOC(rtnl->rqueue, rtnl->rqueue_allocated, rtnl->rqueue_size + 1)) return -ENOMEM; @@ -218,6 +234,21 @@ int rtnl_rqueue_make_room(sd_rtnl *rtnl) { return 0; } +int rtnl_rqueue_partial_make_room(sd_rtnl *rtnl) { + assert(rtnl); + + if (rtnl->rqueue_partial_size >= RTNL_RQUEUE_MAX) { + log_debug("rtnl: exhausted the partial read queue size (%d)", RTNL_RQUEUE_MAX); + return -ENOBUFS; + } + + if (!GREEDY_REALLOC(rtnl->rqueue_partial, rtnl->rqueue_partial_allocated, + rtnl->rqueue_partial_size + 1)) + return -ENOMEM; + + return 0; +} + static int dispatch_rqueue(sd_rtnl *rtnl, sd_rtnl_message **message) { int r;