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 committed 2015-04-25 10:17:46 +02:00
1 parent 56292f27c2
commit 71ecead5b7
3 files changed
+36 -8

No files matched your search

+13 -4
View File
@@ -84,6 +84,8 @@ static int client(int argc, char *argv[])
{ {
int fd; int fd;
int c; int c;
int result = -1;
ssize_t len;
struct option long_options[] = { struct option long_options[] = {
{"debug", 0, NULL, 'd'}, {"debug", 0, NULL, 'd'},
{"help", 0, NULL, 'h'}, {"help", 0, NULL, 'h'},
@@ -94,7 +96,7 @@ static int client(int argc, char *argv[])
.cmd = 0 .cmd = 0
}; };
while ((c = getopt_long (argc, argv, "h?d", long_options, NULL)) != EOF) { while ((c = getopt_long(argc, argv, "h?d", long_options, NULL)) != EOF) {
switch(c) { switch(c) {
case 'd': case 'd':
rq.cmd = INIT_CMD_DEBUG; rq.cmd = INIT_CMD_DEBUG;
@@ -123,15 +125,22 @@ static int client(int argc, char *argv[])
return 1; return 1;
} }
fd = open(FINIT_FIFO, O_WRONLY); fd = open(FINIT_FIFO, O_RDWR);
if (-1 == fd) { if (-1 == fd) {
perror("Failed opening " FINIT_FIFO); perror("Failed opening " FINIT_FIFO);
return 1; return 1;
} }
write(fd, &rq, sizeof(rq));
len = write(fd, &rq, sizeof(rq));
if (len == sizeof(rq)) {
len = read(fd, &rq, sizeof(rq));
if (len == sizeof(rq) && rq.cmd == INIT_CMD_ACK)
result = 0;
}
close(fd); close(fd);
return 0; return result;
} }
static void banner(void) static void banner(void)
+1
View File
@@ -76,6 +76,7 @@
#define INIT_MAGIC 0x03091969 #define INIT_MAGIC 0x03091969
#define INIT_CMD_RUNLVL 1 #define INIT_CMD_RUNLVL 1
#define INIT_CMD_DEBUG 2 #define INIT_CMD_DEBUG 2
#define INIT_CMD_ACK 255
struct init_request { struct init_request {
int magic; /* Magic number */ int magic; /* Magic number */
+22 -4
View File
@@ -45,7 +45,7 @@ static plugin_t plugin = {
static void fifo_open(void) 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) { if (-1 == plugin.io.fd) {
_e("Failed opening %s FIFO, error %d: %s", FINIT_FIFO, errno, strerror(errno)); _e("Failed opening %s FIFO, error %d: %s", FINIT_FIFO, errno, strerror(errno));
return; return;
@@ -85,7 +85,8 @@ static void parse(void *UNUSED(arg), int fd, int UNUSED(events))
} }
_d("Magic OK ..."); _d("Magic OK ...");
if (rq.cmd == INIT_CMD_RUNLVL) { switch (rq.cmd) {
case INIT_CMD_RUNLVL:
switch (rq.runlevel) { switch (rq.runlevel) {
case '0': case '0':
_d("Halting system (SIGUSR2)"); _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); _d("Unsupported runlevel: %d", rq.runlevel);
break; break;
} }
} else if (rq.cmd == INIT_CMD_DEBUG) { break;
case INIT_CMD_DEBUG:
debug = !debug; debug = !debug;
} else { break;
case INIT_CMD_ACK:
_d("Client failed reading ACK.");
goto leave;
default:
_d("Unsupported cmd: %d", rq.cmd); _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); close(fd);
fifo_open(); fifo_open();
} }