fix sysvinit compatibility
This allows openrc to direct sysvinit to shut down the system by setting the INIT_HALT environment variable appropriately. Also, we do not try to communicate with sysvinit if its fifo does not exist.
This commit is contained in:
parent
92de9a693b
commit
0dabda6f6f
@ -330,16 +330,29 @@ int main(int argc, char **argv)
|
|||||||
unlink(nologin_file);
|
unlink(nologin_file);
|
||||||
unlink(shutdown_pid);
|
unlink(shutdown_pid);
|
||||||
if (do_halt) {
|
if (do_halt) {
|
||||||
sysvinit_runlevel('0');
|
if (exists("/run/initctl")) {
|
||||||
send_cmd("halt");
|
sysvinit_setenv("INIT_HALT", "HALT");
|
||||||
|
sysvinit_runlevel('0');
|
||||||
|
} else
|
||||||
|
send_cmd("halt");
|
||||||
} else if (do_kexec)
|
} else if (do_kexec)
|
||||||
send_cmd("kexec");
|
send_cmd("kexec");
|
||||||
else if (do_poweroff)
|
else if (do_poweroff) {
|
||||||
send_cmd("poweroff");
|
if (exists("/run/initctl")) {
|
||||||
else if (do_reboot) {
|
sysvinit_setenv("INIT_HALT", "POWEROFF");
|
||||||
sysvinit_runlevel('6');
|
sysvinit_runlevel('0');
|
||||||
|
} else
|
||||||
|
send_cmd("poweroff");
|
||||||
|
} else if (do_reboot) {
|
||||||
|
if (exists("/run/initctl"))
|
||||||
|
sysvinit_runlevel('6');
|
||||||
|
else
|
||||||
send_cmd("reboot");
|
send_cmd("reboot");
|
||||||
} else if (do_single)
|
} else if (do_single) {
|
||||||
send_cmd("single");
|
if (exists("/run/initctl"))
|
||||||
|
sysvinit_runlevel('S');
|
||||||
|
else
|
||||||
|
send_cmd("single");
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -26,31 +26,21 @@
|
|||||||
#include "einfo.h"
|
#include "einfo.h"
|
||||||
#include "rc-sysvinit.h"
|
#include "rc-sysvinit.h"
|
||||||
|
|
||||||
void sysvinit_runlevel(char rl)
|
static void sysvinit_send_cmd(struct init_request *request)
|
||||||
{
|
{
|
||||||
struct init_request request;
|
|
||||||
int fd;
|
int fd;
|
||||||
char *p;
|
char *p;
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
|
|
||||||
if (!rl)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fd = open("/run/initctl", O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
|
fd = open("/run/initctl", O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
eerror("Failed to open initctl fifo: %s", strerror(errno));
|
eerror("Failed to open initctl fifo: %s", strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
request = (struct init_request) {
|
p = (char *) request;
|
||||||
.magic = INIT_MAGIC,
|
bytes = sizeof(*request);
|
||||||
.sleeptime = 0,
|
|
||||||
.cmd = INIT_CMD_RUNLVL,
|
|
||||||
.runlevel = rl,
|
|
||||||
};
|
|
||||||
p = (char *) &request;
|
|
||||||
bytes = sizeof(request);
|
|
||||||
do {
|
do {
|
||||||
r = write(fd, p, bytes);
|
r = write(fd, p, bytes);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -62,5 +52,51 @@ void sysvinit_runlevel(char rl)
|
|||||||
p += r;
|
p += r;
|
||||||
bytes -= r;
|
bytes -= r;
|
||||||
} while (bytes > 0);
|
} while (bytes > 0);
|
||||||
exit(0);
|
}
|
||||||
|
|
||||||
|
void sysvinit_runlevel(char rl)
|
||||||
|
{
|
||||||
|
struct init_request request;
|
||||||
|
|
||||||
|
if (!rl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
request = (struct init_request) {
|
||||||
|
.magic = INIT_MAGIC,
|
||||||
|
.sleeptime = 0,
|
||||||
|
.cmd = INIT_CMD_RUNLVL,
|
||||||
|
.runlevel = rl,
|
||||||
|
};
|
||||||
|
sysvinit_send_cmd(&request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set environment variables in the init process.
|
||||||
|
*/
|
||||||
|
void sysvinit_setenv(char *name, char *value)
|
||||||
|
{
|
||||||
|
struct init_request request;
|
||||||
|
size_t nl;
|
||||||
|
size_t vl;
|
||||||
|
|
||||||
|
memset(&request, 0, sizeof(request));
|
||||||
|
request.magic = INIT_MAGIC;
|
||||||
|
request.cmd = INIT_CMD_SETENV;
|
||||||
|
nl = strlen(name);
|
||||||
|
if (value)
|
||||||
|
vl = strlen(value);
|
||||||
|
else
|
||||||
|
vl = 0;
|
||||||
|
|
||||||
|
if (nl + vl + 3 >= (int)sizeof(request.i.data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy(request.i.data, name, nl);
|
||||||
|
if (value) {
|
||||||
|
request.i.data[nl] = '=';
|
||||||
|
memcpy(request.i.data + nl + 1, value, vl);
|
||||||
|
}
|
||||||
|
sysvinit_send_cmd(&request);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -67,5 +67,6 @@ struct init_request {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void sysvinit_runlevel(char rl);
|
void sysvinit_runlevel(char rl);
|
||||||
|
void sysvinit_setenv(char *name, char *value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user