mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-12 09:17:44 +03:00
systemctl: add /dev/initctl fallback
This commit is contained in:
parent
55293c152a
commit
eb22ac37f3
4
fixme
4
fixme
@ -69,9 +69,7 @@
|
||||
|
||||
* install must understand templates
|
||||
|
||||
* shutdown must be able to do wall
|
||||
|
||||
* upstart/initctl fallback in systemctl
|
||||
* upstart fallback in systemctl
|
||||
|
||||
Regularly:
|
||||
|
||||
|
@ -708,7 +708,7 @@ static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet))) != sizeof(packet)) {
|
||||
if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet), true)) != sizeof(packet)) {
|
||||
log_error("Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
@ -37,6 +38,7 @@
|
||||
#include "set.h"
|
||||
#include "utmp-wtmp.h"
|
||||
#include "special.h"
|
||||
#include "initreq.h"
|
||||
|
||||
static const char *arg_type = NULL;
|
||||
static bool arg_all = false;
|
||||
@ -1897,8 +1899,40 @@ static int talk_upstart(DBusConnection *bus) {
|
||||
}
|
||||
|
||||
static int talk_initctl(void) {
|
||||
log_error("Talking initctl");
|
||||
return 0;
|
||||
|
||||
static const char table[_ACTION_MAX] = {
|
||||
[ACTION_HALT] = '0',
|
||||
[ACTION_POWEROFF] = '0',
|
||||
[ACTION_REBOOT] = '6',
|
||||
[ACTION_RUNLEVEL2] = '2',
|
||||
[ACTION_RUNLEVEL3] = '3',
|
||||
[ACTION_RUNLEVEL4] = '4',
|
||||
[ACTION_RUNLEVEL5] = '5',
|
||||
[ACTION_RESCUE] = '1'
|
||||
};
|
||||
|
||||
struct init_request request;
|
||||
int r, fd;
|
||||
|
||||
if (!table[arg_action])
|
||||
return 0;
|
||||
|
||||
zero(request);
|
||||
request.magic = INIT_MAGIC;
|
||||
request.sleeptime = 0;
|
||||
request.cmd = INIT_CMD_RUNLVL;
|
||||
request.runlevel = table[arg_action];
|
||||
|
||||
if ((fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY)) < 0)
|
||||
return -errno;
|
||||
|
||||
r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
|
||||
close_nointr_nofail(fd);
|
||||
|
||||
if (r < 0)
|
||||
return errno ? -errno : -EIO;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int systemctl_main(DBusConnection *bus, int argc, char *argv[]) {
|
||||
@ -2148,6 +2182,7 @@ int main(int argc, char*argv[]) {
|
||||
case ACTION_RUNLEVEL5:
|
||||
case ACTION_RESCUE:
|
||||
case ACTION_EMERGENCY:
|
||||
case ACTION_DEFAULT:
|
||||
retval = start_with_fallback(bus) < 0;
|
||||
break;
|
||||
|
||||
@ -2156,6 +2191,8 @@ int main(int argc, char*argv[]) {
|
||||
retval = reload_with_fallback(bus) < 0;
|
||||
break;
|
||||
|
||||
case ACTION_INVALID:
|
||||
case ACTION_RUNLEVEL:
|
||||
default:
|
||||
assert_not_reached("Unknown action");
|
||||
}
|
||||
|
56
src/util.c
56
src/util.c
@ -1964,7 +1964,7 @@ int close_pipe(int p[]) {
|
||||
return a < 0 ? a : b;
|
||||
}
|
||||
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes) {
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
uint8_t *p;
|
||||
ssize_t n = 0;
|
||||
|
||||
@ -1978,10 +1978,10 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes) {
|
||||
|
||||
if ((k = read(fd, p, nbytes)) <= 0) {
|
||||
|
||||
if (errno == EINTR)
|
||||
if (k < 0 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN) {
|
||||
if (k < 0 && errno == EAGAIN && do_poll) {
|
||||
struct pollfd pollfd;
|
||||
|
||||
zero(pollfd);
|
||||
@ -2012,6 +2012,54 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes) {
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
||||
const uint8_t *p;
|
||||
ssize_t n = 0;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(buf);
|
||||
|
||||
p = buf;
|
||||
|
||||
while (nbytes > 0) {
|
||||
ssize_t k;
|
||||
|
||||
if ((k = write(fd, p, nbytes)) <= 0) {
|
||||
|
||||
if (k < 0 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (k < 0 && errno == EAGAIN && do_poll) {
|
||||
struct pollfd pollfd;
|
||||
|
||||
zero(pollfd);
|
||||
pollfd.fd = fd;
|
||||
pollfd.events = POLLOUT;
|
||||
|
||||
if (poll(&pollfd, 1, -1) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
return n > 0 ? n : -errno;
|
||||
}
|
||||
|
||||
if (pollfd.revents != POLLOUT)
|
||||
return n > 0 ? n : -EIO;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return n > 0 ? n : (k < 0 ? -errno : 0);
|
||||
}
|
||||
|
||||
p += k;
|
||||
nbytes -= k;
|
||||
n += k;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int path_is_mount_point(const char *t) {
|
||||
struct stat a, b;
|
||||
char *copy;
|
||||
@ -2182,7 +2230,7 @@ unsigned long long random_ull(void) {
|
||||
if ((fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0)
|
||||
goto fallback;
|
||||
|
||||
r = loop_read(fd, &ull, sizeof(ull));
|
||||
r = loop_read(fd, &ull, sizeof(ull), true);
|
||||
close_nointr_nofail(fd);
|
||||
|
||||
if (r != sizeof(ull))
|
||||
|
@ -246,7 +246,8 @@ int sigaction_many(const struct sigaction *sa, ...);
|
||||
|
||||
int close_pipe(int p[]);
|
||||
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes);
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
|
||||
|
||||
int path_is_mount_point(const char *path);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user