diff --git a/src/dhcpcd.8.in b/src/dhcpcd.8.in index 26d37772..348b7250 100644 --- a/src/dhcpcd.8.in +++ b/src/dhcpcd.8.in @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 5, 2026 +.Dd September 7, 2026 .Dt DHCPCD 8 .Os .Sh NAME @@ -818,6 +818,24 @@ sends to match. If using a DUID in place of the ClientID, edit .Pa @DBDIR@/duid accordingly. +.Pp +When sending a command such as +.Fl k , Fl Fl release +or +.Fl n , Fl Fl rebind +to the running manager, +.Nm +waits a short while for the manager to report the result. +Managers older than dhcpcd-10.5 action the command but never report a +result, so +.Nm +logs +.Dq timed out waiting for a reply from dhcpcd +and assumes the command was actioned. +This is expected if the +.Nm +binaries have been upgraded without restarting the running manager; +restarting the manager stops the message. .Sh FILES .Bl -ohang .It Pa @SYSCONFDIR@/dhcpcd.conf diff --git a/src/dhcpcd.c b/src/dhcpcd.c index bf277bbc..b2b0c2cb 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -42,6 +42,7 @@ static const char dhcpcd_copyright[] = "Copyright (c) 2006-2025 Roy Marples"; #include #include #include +#include #include #include #include @@ -1891,15 +1892,40 @@ dhcpcd_readdump1(void *arg, unsigned short events) eloop_exit(ctx->eloop, EXIT_FAILURE); } +/* How long to wait for the manager to report the result of a command. + * dhcpcd-10.5 introduced this reply; older managers action the command + * but never send one, so we must not wait for it forever. */ +#define READERROR_TIMEOUT_MS 5000 + static int dhcpcd_readerror(struct dhcpcd_ctx *ctx) { int error = 0; ssize_t len; + struct pollfd pfd = { .fd = ctx->control_fd, .events = POLLIN }; + int n; + + /* The socket is blocking, so poll for the reply rather than + * risk blocking in read(3) forever. */ + do { + n = poll(&pfd, 1, READERROR_TIMEOUT_MS); + } while (n == -1 && errno == EINTR); + if (n == -1) + return -1; + if (n == 0) { + logwarnx("timed out waiting for a reply from dhcpcd; " + "assuming the command was actioned " + "(is the running dhcpcd older than %s?)", VERSION); + return 0; + } len = read(ctx->control_fd, &error, sizeof(error)); if (len == -1) return -1; + if (len == 0) { + /* An older dhcpcd closed the socket without replying. */ + return 0; + } if (len != sizeof(error)) { errno = EINVAL; return -1;