Make the 'init <CMD | RUNLEVEL>' commands synchronous.

When a user changes runlevel, or wants to reload the config, we want the
command to return only when the operation has completed.  For instance,
rolling in a new system configuration in runlevel 1 requires that we are
sure we've actually entered that runlevel before rolling it in.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson
2015-04-25 10:17:46 +02:00
parent 56292f27c2
commit 71ecead5b7
3 changed files with 36 additions and 8 deletions
+22 -4
View File
@@ -45,7 +45,7 @@ static plugin_t plugin = {
static void fifo_open(void)
{
plugin.io.fd = open(FINIT_FIFO, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
plugin.io.fd = open(FINIT_FIFO, O_RDWR | O_NONBLOCK | O_CLOEXEC);
if (-1 == plugin.io.fd) {
_e("Failed opening %s FIFO, error %d: %s", FINIT_FIFO, errno, strerror(errno));
return;
@@ -85,7 +85,8 @@ static void parse(void *UNUSED(arg), int fd, int UNUSED(events))
}
_d("Magic OK ...");
if (rq.cmd == INIT_CMD_RUNLVL) {
switch (rq.cmd) {
case INIT_CMD_RUNLVL:
switch (rq.runlevel) {
case '0':
_d("Halting system (SIGUSR2)");
@@ -113,13 +114,30 @@ static void parse(void *UNUSED(arg), int fd, int UNUSED(events))
_d("Unsupported runlevel: %d", rq.runlevel);
break;
}
} else if (rq.cmd == INIT_CMD_DEBUG) {
break;
case INIT_CMD_DEBUG:
debug = !debug;
} else {
break;
case INIT_CMD_ACK:
_d("Client failed reading ACK.");
goto leave;
default:
_d("Unsupported cmd: %d", rq.cmd);
break;
}
rq.cmd = INIT_CMD_ACK;
len = write(fd, &rq, sizeof(rq));
if (len != sizeof(rq))
_d("Failed sending ACK back to client.");
else
sleep(1); /* Give client time to read FIFO */
}
leave:
close(fd);
fifo_open();
}