mirror of
https://github.com/troglobit/finit.git
synced 2026-11-09 16:21:24 +00:00
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:
1 parent
56292f27c2
commit
71ecead5b7
3 files changed
+36
-8
No files matched your search
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user