From: Roy Marples Date: Mon, 5 Sep 2022 12:20:50 +0000 (+0100) Subject: dhcpcd: Use eloop timeout to wait for pidfile removal X-Git-Tag: v10.0.0~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b294661fb106a6075654d6404e846df3438821e;p=thirdparty%2Fdhcpcd.git dhcpcd: Use eloop timeout to wait for pidfile removal As well as removing not enabled code to wait a bit before removing the IP address when sending a DHCP RELEASE message. This means that we no longer need to allow nanosleep in SECCOMP. Hopefully fixes #127. --- diff --git a/src/dhcp.c b/src/dhcp.c index c72135ec..e24f5594 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -84,11 +84,6 @@ /* We should define a maximum for the NAK exponential backoff */ #define NAKOFF_MAX 60 -/* Wait N nanoseconds between sending a RELEASE and dropping the address. - * This gives the kernel enough time to actually send it. */ -#define RELEASE_DELAY_S 0 -#define RELEASE_DELAY_NS 10000000 - #ifndef IPDEFTTL #define IPDEFTTL 64 /* RFC1340 */ #endif @@ -2755,12 +2750,8 @@ dhcp_reboot(struct interface *ifp) void dhcp_drop(struct interface *ifp, const char *reason) { - struct dhcp_state *state; -#ifdef RELEASE_SLOW - struct timespec ts; -#endif + struct dhcp_state *state = D_STATE(ifp); - state = D_STATE(ifp); /* dhcp_start may just have been called and we don't yet have a state * but we do have a timeout, so punt it. */ if (state == NULL || state->state == DHS_NONE) { @@ -2794,12 +2785,6 @@ dhcp_drop(struct interface *ifp, const char *reason) ifp->name, inet_ntoa(state->lease.addr)); dhcp_new_xid(ifp); send_message(ifp, DHCP_RELEASE, NULL); -#ifdef RELEASE_SLOW - /* Give the packet a chance to go */ - ts.tv_sec = RELEASE_DELAY_S; - ts.tv_nsec = RELEASE_DELAY_NS; - nanosleep(&ts, NULL); -#endif } } #ifdef AUTH @@ -2820,10 +2805,6 @@ dhcp_drop(struct interface *ifp, const char *reason) dhcp_auth_reset(&state->auth); #endif - /* Close DHCP ports so a changed interface family is picked - * up by a new BPF state. */ - dhcp_close(ifp); - state->state = DHS_NONE; free(state->offer); state->offer = NULL; @@ -2847,6 +2828,10 @@ dhcp_drop(struct interface *ifp, const char *reason) state->lease.addr.s_addr = 0; ifp->options->options &= ~(DHCPCD_CSR_WARNED | DHCPCD_ROUTER_HOST_ROUTE_WARNED); + + /* Close DHCP ports so a changed interface family is picked + * up by a new BPF state. */ + dhcp_close(ifp); } static int diff --git a/src/dhcpcd.c b/src/dhcpcd.c index dcaba1e9..dca38086 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -1828,6 +1828,24 @@ dhcpcd_stderr_cb(void *arg, unsigned short events) fprintf(stderr, "%s", log); } +static void +dhcpcd_pidfile_timeout(void *arg) +{ + struct dhcpcd_ctx *ctx = arg; + pid_t pid; + + pid = pidfile_read(ctx->pidfile); + + if(pid == -1) + eloop_exit(ctx->eloop, EXIT_SUCCESS); + else if (++ctx->duid_len >= 100) { /* overload duid_len */ + logerrx("pid %d failed to exit", pid); + eloop_exit(ctx->eloop, EXIT_FAILURE); + } else + eloop_timeout_add_msec(ctx->eloop, 100, + dhcpcd_pidfile_timeout, ctx); +} + int main(int argc, char **argv, char **envp) { @@ -2164,21 +2182,12 @@ printpidfile: /* We can still continue and send the command * via the control socket. */ } else { - struct timespec ts; - if (sig == SIGHUP || sig == SIGUSR1) goto exit_success; /* Spin until it exits */ loginfox("waiting for pid %d to exit", pid); - ts.tv_sec = 0; - ts.tv_nsec = 100000000; /* 10th of a second */ - for(i = 0; i < 100; i++) { - nanosleep(&ts, NULL); - if (pidfile_read(ctx.pidfile) == -1) - goto exit_success; - } - logerrx("pid %d failed to exit", pid); - goto exit_failure; + dhcpcd_pidfile_timeout(&ctx); + goto run_loop; } } #endif diff --git a/src/privsep-linux.c b/src/privsep-linux.c index d4439634..c9f4ea84 100644 --- a/src/privsep-linux.c +++ b/src/privsep-linux.c @@ -353,9 +353,6 @@ static struct sock_filter ps_seccomp_filter[] = { #ifdef __NR_munmap SECCOMP_ALLOW(__NR_munmap), #endif -#ifdef __NR_nanosleep - SECCOMP_ALLOW(__NR_nanosleep), /* XXX should use ppoll instead */ -#endif #ifdef __NR_newfstatat SECCOMP_ALLOW(__NR_newfstatat), #endif