]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Adapt to new eloop.
authorRoy Marples <roy@marples.name>
Fri, 14 Nov 2025 13:08:58 +0000 (13:08 +0000)
committerRoy Marples <roy@marples.name>
Fri, 14 Nov 2025 13:08:58 +0000 (13:08 +0000)
src/dhcpcd.c
src/dhcpcd.h
src/privsep-root.c
src/privsep.c

index 4881f7dd90dc1d65fc9d3eefbd55c7130267c391..149c2a3d03f9dba2091fda231e5f0edb58e64a54 100644 (file)
@@ -1489,7 +1489,7 @@ dhcpcd_renew(struct dhcpcd_ctx *ctx)
 
 #ifdef USE_SIGNALS
 #define sigmsg "received %s, %s"
-void
+static void
 dhcpcd_signal_cb(int sig, void *arg)
 {
        struct dhcpcd_ctx *ctx = arg;
@@ -1576,11 +1576,10 @@ dhcpcd_signal_cb(int sig, void *arg)
            stop_all_interfaces(ctx, opts))
        {
                /* We stopped something, we will exit once that is done. */
-               eloop_exitallinners(exit_code);
                return;
        }
 
-       eloop_exitall(exit_code);
+       eloop_exit(ctx->eloop, exit_code);
 }
 #endif
 
@@ -2797,7 +2796,6 @@ exit1:
 #ifdef PRIVSEP
        if (ps_root_stop(&ctx) == -1)
                i = EXIT_FAILURE;
-       eloop_free(ctx.ps_eloop);
 #endif
 
 #ifdef USE_SIGNALS
index c4dbe9993014152bb18cf7461f8053a92851ce58..5f7fed00c71a2295699cd59ac2586b712245ab49 100644 (file)
@@ -196,7 +196,6 @@ struct dhcpcd_ctx {
        int ps_data_fd;         /* data returned from processes */
        int ps_log_fd;          /* chroot logging */
        int ps_log_root_fd;     /* outside chroot log reader */
-       struct eloop *ps_eloop; /* eloop for polling root data */
        struct fd_list *ps_control;             /* Queue for the above */
        struct fd_list *ps_control_client;      /* Queue for the above */
 #endif
@@ -259,8 +258,6 @@ int dhcpcd_afwaiting(const struct dhcpcd_ctx *);
 void dhcpcd_daemonised(struct dhcpcd_ctx *);
 void dhcpcd_daemonise(struct dhcpcd_ctx *);
 
-void dhcpcd_signal_cb(int, void *);
-
 void dhcpcd_linkoverflow(struct dhcpcd_ctx *);
 int dhcpcd_handleargs(struct dhcpcd_ctx *, struct fd_list *, int, char **);
 void dhcpcd_handlecarrier(struct interface *, int, unsigned int);
index 3f4930cdb588ad66ca5f28db07150036430f78db..28dfcc4d45af821ea6bf4ad6c914bab37162bd15 100644 (file)
@@ -76,33 +76,29 @@ struct psr_ctx {
        bool psr_usemdata;
 };
 
-static void
-ps_root_readerrorcb(void *arg, unsigned short events)
+static ssize_t
+ps_root_readerrorcb(struct psr_ctx *psr_ctx)
 {
-       struct psr_ctx *psr_ctx = arg;
        struct dhcpcd_ctx *ctx = psr_ctx->psr_ctx;
+       int fd = PS_ROOT_FD(ctx);
        struct psr_error *psr_error = &psr_ctx->psr_error;
        struct iovec iov[] = {
                { .iov_base = psr_error, .iov_len = sizeof(*psr_error) },
                { .iov_base = NULL, .iov_len = 0 },
        };
        ssize_t len;
-       int exit_code = EXIT_FAILURE;
-
-       if (events & ELE_HANGUP)
-               goto out;
-
-       if (events != ELE_READ)
-               logerrx("%s: unexpected event 0x%04x", __func__, events);
 
 #define PSR_ERROR(e)                           \
        do {                                    \
                psr_error->psr_result = -1;     \
                psr_error->psr_errno = (e);     \
-               goto out;                       \
+               return -1;                      \
        } while (0 /* CONSTCOND */)
 
-       len = recv(PS_ROOT_FD(ctx), psr_error, sizeof(*psr_error), MSG_PEEK);
+       if (eloop_waitfd(fd) == -1)
+               PSR_ERROR(errno);
+
+       len = recv(fd, psr_error, sizeof(*psr_error), MSG_PEEK);
        if (len == -1)
                PSR_ERROR(errno);
        else if ((size_t)len < sizeof(*psr_error))
@@ -130,29 +126,23 @@ ps_root_readerrorcb(void *arg, unsigned short events)
                iov[1].iov_len = psr_error->psr_datalen;
        }
 
-       len = readv(PS_ROOT_FD(ctx), iov, __arraycount(iov));
+       len = readv(fd, iov, __arraycount(iov));
        if (len == -1)
                PSR_ERROR(errno);
        else if ((size_t)len != sizeof(*psr_error) + psr_error->psr_datalen)
                PSR_ERROR(EINVAL);
-       exit_code = EXIT_SUCCESS;
-
-out:
-       eloop_exit(ctx->ps_eloop, exit_code);
+       return len;
 }
 
 ssize_t
 ps_root_readerror(struct dhcpcd_ctx *ctx, void *data, size_t len)
 {
        struct psr_ctx *pc = ctx->ps_root->psp_data;
-       int err;
 
        pc->psr_data = data;
        pc->psr_datalen = len;
        pc->psr_usemdata = false;
-       err = eloop_start(ctx->ps_eloop);
-       if (err < 0)
-               return err;
+       ps_root_readerrorcb(pc);
 
        errno = pc->psr_error.psr_errno;
        return pc->psr_error.psr_result;
@@ -162,13 +152,10 @@ ssize_t
 ps_root_mreaderror(struct dhcpcd_ctx *ctx, void **data, size_t *len)
 {
        struct psr_ctx *pc = ctx->ps_root->psp_data;
-       int err;
        void *d;
 
        pc->psr_usemdata = true;
-       err = eloop_start(ctx->ps_eloop);
-       if (err < 0)
-               return err;
+       ps_root_readerrorcb(pc);
 
        if (pc->psr_error.psr_datalen != 0) {
                if (pc->psr_error.psr_datalen > pc->psr_mdatalen) {
@@ -212,7 +199,7 @@ ps_root_writeerror(struct dhcpcd_ctx *ctx, ssize_t result,
        err = sendmsg(fd, &msg, MSG_EOR);
 
        /* Error sending the message? Try sending the error of sending. */
-       if (err == -1) {
+       if (err == -1 && errno != EPIPE) {
                logerr("%s: result=%zd, data=%p, len=%zu",
                    __func__, result, data, len);
                psr.psr_result = err;
@@ -776,7 +763,7 @@ ps_root_signalcb(int sig, void *arg)
        if (!(ctx->options & DHCPCD_EXITING))
                return;
        if (!(ps_waitforprocs(ctx)))
-               eloop_exit(ctx->ps_eloop, EXIT_SUCCESS);
+               eloop_exit(ctx->eloop, EXIT_SUCCESS);
 }
 
 int (*handle_interface)(void *, int, const char *);
@@ -888,6 +875,7 @@ ps_root_start(struct dhcpcd_ctx *ctx)
 
        if (xsocketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CXNB, 0, datafd) == -1)
                return -1;
+
        if (ps_setbuf_fdpair(datafd) == -1)
                return -1;
 #ifdef PRIVSEP_RIGHTS
@@ -916,9 +904,6 @@ ps_root_start(struct dhcpcd_ctx *ctx)
        }
 
        psp->psp_data = pc;
-       if (eloop_event_add(ctx->ps_eloop, psp->psp_fd, ELE_READ,
-           ps_root_readerrorcb, pc) == -1)
-               return -1;
 
        if (pid == 0) {
                ctx->ps_log_fd = logfd[0]; /* Keep open to pass to processes */
@@ -976,11 +961,9 @@ ps_root_stop(struct dhcpcd_ctx *ctx)
        struct ps_process *psp = ctx->ps_root;
        int err;
 
-       if (!(ctx->options & DHCPCD_PRIVSEP) ||
-           ctx->eloop == NULL)
+       if (!(ctx->options & DHCPCD_PRIVSEP))
                return 0;
 
-
        /* If we are the root process then remove the pidfile */
        if (ctx->options & DHCPCD_PRIVSEPROOT) {
                if (!(ctx->options & DHCPCD_TEST) && unlink(ctx->pidfile) == -1)
@@ -990,12 +973,25 @@ ps_root_stop(struct dhcpcd_ctx *ctx)
                if (ctx->ps_log_root_fd != -1) {
                        ssize_t loglen;
 
+#ifdef __linux__
+                       /* Seems to help to get the last parts,
+                        * sched_yield(2) does not. */
+                       sleep(0);
+#endif
                        do {
                                loglen = logreadfd(ctx->ps_log_root_fd);
                        } while (loglen != 0 && loglen != -1);
+                       close(ctx->ps_log_root_fd);
+                       ctx->ps_log_root_fd = -1;
                }
        }
 
+       if (ctx->ps_data_fd != -1) {
+               eloop_event_delete(ctx->eloop, ctx->ps_data_fd);
+               close(ctx->ps_data_fd);
+               ctx->ps_data_fd = -1;
+       }
+
        /* Only the manager process gets past this point. */
        if (ctx->options & DHCPCD_FORKED)
                return 0;
@@ -1015,7 +1011,8 @@ ps_root_stop(struct dhcpcd_ctx *ctx)
        } /* else the root process has already exited :( */
 
        err = ps_stopwait(ctx);
-       ps_freeprocess(ctx->ps_root);
+       if (ctx->ps_root != NULL)
+               ps_freeprocess(ctx->ps_root);
        return err;
 }
 
index e7f488ed468e569f30fea2c9484cf58406cfb204..7a81c196671359fd9996b53b6eb197349320be53 100644 (file)
@@ -342,7 +342,7 @@ ps_processhangup(void *arg, unsigned short events)
        if (!(ctx->options & DHCPCD_EXITING))
                return;
        if (!(ps_waitforprocs(ctx)))
-               eloop_exit(ctx->ps_eloop, EXIT_SUCCESS);
+               eloop_exit(ctx->eloop, EXIT_SUCCESS);
 }
 #endif
 
@@ -442,16 +442,6 @@ ps_startprocess(struct ps_process *psp,
                logerr("%s: eloop_forked", __func__);
                goto errexit;
        }
-       if (ctx->ps_eloop != NULL) {
-               if (eloop_forked(ctx->ps_eloop, ELF_KEEP_SIGNALS) == -1) {
-                       logerr("%s: eloop_forked", __func__);
-                       goto errexit;
-               }
-               if (!(flags & PSF_ELOOP)) {
-                       eloop_free(ctx->ps_eloop);
-                       ctx->ps_eloop = NULL;
-               }
-       }
 
        pidfile_clean();
        ps_freeprocesses(ctx, psp);
@@ -552,10 +542,6 @@ ps_start(struct dhcpcd_ctx *ctx)
 
        TAILQ_INIT(&ctx->ps_processes);
 
-       /* We need an inner eloop to block with. */
-       if ((ctx->ps_eloop = eloop_new_with_signals(ctx->eloop)) == NULL)
-               return -1;
-
        switch (pid = ps_root_start(ctx)) {
        case -1:
                logerr("ps_root_start");
@@ -738,11 +724,11 @@ ps_stopwait(struct dhcpcd_ctx *ctx)
 {
        int error = EXIT_SUCCESS;
 
-       if (ctx->ps_eloop == NULL || !ps_waitforprocs(ctx))
+       if (!ps_waitforprocs(ctx))
                return 0;
 
        ctx->options |= DHCPCD_EXITING;
-       if (eloop_timeout_add_sec(ctx->ps_eloop, PS_PROCESS_TIMEOUT,
+       if (eloop_timeout_add_sec(ctx->eloop, PS_PROCESS_TIMEOUT,
            ps_process_timeout, ctx) == -1)
                logerr("%s: eloop_timeout_add_sec", __func__);
 
@@ -752,18 +738,18 @@ ps_stopwait(struct dhcpcd_ctx *ctx)
        TAILQ_FOREACH(psp, &ctx->ps_processes, next) {
                if (psp->psp_pfd == -1)
                        continue;
-               if (eloop_event_add(ctx->ps_eloop, psp->psp_pfd,
+               if (eloop_event_add(ctx->eloop, psp->psp_pfd,
                    ELE_HANGUP, ps_processhangup, psp) == -1)
                        logerr("%s: eloop_event_add pfd %d",
                            __func__, psp->psp_pfd);
        }
 #endif
 
-       error = eloop_start(ctx->ps_eloop);
+       error = eloop_start(ctx->eloop);
        if (error < 0)
                logerr("%s: eloop_start", __func__);
 
-       eloop_timeout_delete(ctx->ps_eloop, ps_process_timeout, ctx);
+       eloop_timeout_delete(ctx->eloop, ps_process_timeout, ctx);
 
        return error;
 }
@@ -791,8 +777,6 @@ ps_freeprocess(struct ps_process *psp)
 #ifdef HAVE_CAPSICUM
        if (psp->psp_pfd != -1) {
                eloop_event_delete(ctx->eloop, psp->psp_pfd);
-               if (ctx->ps_eloop != NULL)
-                       eloop_event_delete(ctx->ps_eloop, psp->psp_pfd);
                close(psp->psp_pfd);
        }
 #endif
@@ -1173,7 +1157,7 @@ stop:
                logdebugx("process %d stopping", getpid());
 #endif
                ps_free(ctx);
-               eloop_exitall(len != -1 ? EXIT_SUCCESS : EXIT_FAILURE);
+               eloop_exit(ctx->eloop, len != -1 ? EXIT_SUCCESS : EXIT_FAILURE);
                return len;
        }
        dlen -= sizeof(psm.psm_hdr);