diff options
| author | Roy Marples <roy@marples.name> | 2014-09-05 12:28:05 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2014-09-05 12:28:05 +0000 |
| commit | 923e118097c5296c5e94b5518d8b06c67c2f4b52 (patch) | |
| tree | 0bf095f0aa39591a067c5db653cd351e46e519ce /dhcpcd.c | |
| parent | a0011b993364c6ac24e4e5e534ac07fcef2d02c3 (diff) | |
| download | dhcpcd-923e118097c5296c5e94b5518d8b06c67c2f4b52.tar.xz | |
Implement a send queue for each control fd.
Only one call to write(2) should be performed for each POLLOUT check
via poll(2) so we should never see EAGAIN when writing to control
sockets ever again.
Each fd queue is limited to 100 entries so we don't OOM with badly
written control subscribers.
Diffstat (limited to 'dhcpcd.c')
| -rw-r--r-- | dhcpcd.c | 55 |
1 files changed, 8 insertions, 47 deletions
@@ -1047,42 +1047,6 @@ signal_init(void (*func)(int, siginfo_t *, void *), sigset_t *oldset) #endif static void -dhcpcd_version(void *arg) -{ - struct fd_list *fd = arg; - size_t len; - struct iovec iov[2]; - - len = strlen(VERSION) + 1; - iov[0].iov_base = &len; - iov[0].iov_len = sizeof(ssize_t); - iov[1].iov_base = UNCONST(VERSION); - iov[1].iov_len = len; - if (writev(fd->fd, iov, 2) == -1) - syslog(LOG_ERR, "%s: writev: %m", __func__); - else - eloop_event_delete(fd->ctx->eloop, fd->fd, 1); -} - -static void -dhcpcd_getconfigfile(void *arg) -{ - struct fd_list *fd = arg; - size_t len; - struct iovec iov[2]; - - len = strlen(fd->ctx->cffile) + 1; - iov[0].iov_base = &len; - iov[0].iov_len = sizeof(ssize_t); - iov[1].iov_base = UNCONST(fd->ctx->cffile); - iov[1].iov_len = len; - if (writev(fd->fd, iov, 2) == -1) - syslog(LOG_ERR, "%s: writev: %m", __func__); - else - eloop_event_delete(fd->ctx->eloop, fd->fd, 1); -} - -static void dhcpcd_getinterfaces(void *arg) { struct fd_list *fd = arg; @@ -1101,11 +1065,11 @@ dhcpcd_getinterfaces(void *arg) } if (write(fd->fd, &len, sizeof(len)) != sizeof(len)) return; + eloop_event_delete(fd->ctx->eloop, fd->fd, 1); TAILQ_FOREACH(ifp, fd->ctx->ifaces, next) { - if (send_interface(fd->fd, ifp) == -1) + if (send_interface(fd, ifp) == -1) syslog(LOG_ERR, "send_interface %d: %m", fd->fd); } - eloop_event_delete(fd->ctx->eloop, fd->fd, 1); } int @@ -1124,13 +1088,11 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd, * expected reply we should be safely able just to change the * write callback on the fd */ if (strcmp(*argv, "--version") == 0) { - eloop_event_add(fd->ctx->eloop, fd->fd, NULL, NULL, - dhcpcd_version, fd); - return 0; + return control_queue(fd, UNCONST(VERSION), + strlen(VERSION) + 1, 0); } else if (strcmp(*argv, "--getconfigfile") == 0) { - eloop_event_add(fd->ctx->eloop, fd->fd, NULL, NULL, - dhcpcd_getconfigfile, fd); - return 0; + return control_queue(fd, UNCONST(fd->ctx->cffile), + strlen(fd->ctx->cffile) + 1, 0); } else if (strcmp(*argv, "--getinterfaces") == 0) { eloop_event_add(fd->ctx->eloop, fd->fd, NULL, NULL, dhcpcd_getinterfaces, fd); @@ -1146,10 +1108,8 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd, for (opt = 0; opt < argc; opt++) len += strlen(argv[opt]) + 1; tmp = malloc(len); - if (tmp == NULL) { - syslog(LOG_ERR, "%s: %m", __func__); + if (tmp == NULL) return -1; - } p = tmp; for (opt = 0; opt < argc; opt++) { l = strlen(argv[opt]); @@ -1256,6 +1216,7 @@ main(int argc, char **argv) ifo = NULL; ctx.cffile = CONFIG; ctx.pid_fd = ctx.control_fd = ctx.link_fd = -1; + TAILQ_INIT(&ctx.control_fds); #ifdef PLUGIN_DEV ctx.dev_fd = -1; #endif |
