From 9c2f0b2dc832bd23d5237ac6bf8b44500a492c7d Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Thu, 25 Mar 2021 17:18:50 +0100 Subject: [PATCH] initctl: finit may be busy, wait for it ... When calling initctl early in the boot process, e.g. just when Finit is switching to the final runlevel, it may take a few milliseconds for it to actually be ready to process our request. This patch adds poll() to both the write(REQ) and the read(RSP) steps to prevent from getting weird errors when Finit is busy. The timeout is currently 2 sec in both directions, which should be enough. Signed-off-by: Joachim Wiberg --- src/client.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/client.c b/src/client.c index 15d1b8f5..bc6ccc31 100644 --- a/src/client.c +++ b/src/client.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -64,27 +65,44 @@ int client_disconnect(void) int client_send(struct init_request *rq, ssize_t len) { + struct pollfd pfd = { 0 }; int sd, result = 255; sd = client_connect(); if (-1 == sd) return -1; - if (write(sd, rq, len) != len) - goto error; + pfd.fd = sd; + pfd.events = POLLOUT; + if (poll(&pfd, 1, 2000) <= 0) { + warn("Timed out waiting for Finit, errno %d", errno); + goto exit; + } - if (read(sd, rq, len) != len) - goto error; + if (write(sd, rq, len) != len) { + warn("Failed communicating with Finit, errno %d", errno); + goto exit; + } + + pfd.fd = sd; + pfd.events = POLLIN; + if (poll(&pfd, 1, 2000) <= 0) { + warn("Timed out waiting for reply from Finit, errno %d", errno); + goto exit; + } + + if (read(sd, rq, len) != len) { + warn("Failed reading reply from Finit, errno %d", errno); + goto exit; + } if (rq->cmd == INIT_CMD_NACK) result = 1; else result = 0; - goto exit; -error: - perror("Failed communicating with finit"); exit: client_disconnect(); + return result; }