X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Finitctl%2Finitctl.c;h=8b632e88aeaf64870c92f9614f8c557c157431a2;hp=0eb008d9e6bd6969635d96b182f8a7729c47330e;hb=d5d8429a12c4b1ef0dcd226c0904f00f4fa4898a;hpb=dce818b390a857a11f7dd634684500675cf79833 diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c index 0eb008d9e..8b632e88a 100644 --- a/src/initctl/initctl.c +++ b/src/initctl/initctl.c @@ -27,21 +27,22 @@ #include #include #include -#include +#include #include #include #include #include -#include -#include +#include "sd-daemon.h" +#include "sd-bus.h" #include "util.h" #include "log.h" #include "list.h" #include "initreq.h" #include "special.h" -#include "dbus-common.h" +#include "bus-util.h" +#include "bus-error.h" #include "def.h" #define SERVER_FD_MAX 16 @@ -55,7 +56,7 @@ typedef struct Server { LIST_HEAD(Fifo, fifos); unsigned n_fifos; - DBusConnection *bus; + sd_bus *bus; bool quit; } Server; @@ -77,15 +78,15 @@ static const char *translate_runlevel(int runlevel, bool *isolate) { const char *special; bool isolate; } table[] = { - { '0', SPECIAL_POWEROFF_TARGET, false }, - { '1', SPECIAL_RESCUE_TARGET, true }, - { 's', SPECIAL_RESCUE_TARGET, true }, - { 'S', SPECIAL_RESCUE_TARGET, true }, - { '2', SPECIAL_RUNLEVEL2_TARGET, true }, - { '3', SPECIAL_RUNLEVEL3_TARGET, true }, - { '4', SPECIAL_RUNLEVEL4_TARGET, true }, - { '5', SPECIAL_RUNLEVEL5_TARGET, true }, - { '6', SPECIAL_REBOOT_TARGET, false }, + { '0', SPECIAL_POWEROFF_TARGET, false }, + { '1', SPECIAL_RESCUE_TARGET, true }, + { 's', SPECIAL_RESCUE_TARGET, true }, + { 'S', SPECIAL_RESCUE_TARGET, true }, + { '2', SPECIAL_MULTI_USER_TARGET, true }, + { '3', SPECIAL_MULTI_USER_TARGET, true }, + { '4', SPECIAL_MULTI_USER_TARGET, true }, + { '5', SPECIAL_GRAPHICAL_TARGET, true }, + { '6', SPECIAL_REBOOT_TARGET, false }, }; unsigned i; @@ -105,53 +106,39 @@ static const char *translate_runlevel(int runlevel, bool *isolate) { static void change_runlevel(Server *s, int runlevel) { const char *target; - DBusMessage *m = NULL, *reply = NULL; - DBusError error; + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; const char *mode; bool isolate = false; + int r; assert(s); - dbus_error_init(&error); - - if (!(target = translate_runlevel(runlevel, &isolate))) { + target = translate_runlevel(runlevel, &isolate); + if (!target) { log_warning("Got request for unknown runlevel %c, ignoring.", runlevel); - goto finish; + return; } if (isolate) mode = "isolate"; else - mode = "replace"; + mode = "replace-irreversibly"; log_debug("Running request %s/start/%s", target, mode); - if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) { - log_error("Could not allocate message."); - goto finish; - } - - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &target, - DBUS_TYPE_STRING, &mode, - DBUS_TYPE_INVALID)) { - log_error("Could not attach target and flag information to message."); - goto finish; - } - - if (!(reply = dbus_connection_send_with_reply_and_block(s->bus, m, -1, &error))) { - log_error("Failed to start unit: %s", bus_error_message(&error)); - goto finish; + r = sd_bus_call_method( + s->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartUnit", + &error, + NULL, + "ss", target, mode); + if (r < 0) { + log_error("Failed to change runlevel: %s", bus_error_message(&error, -r)); + return; } - -finish: - if (m) - dbus_message_unref(m); - - if (reply) - dbus_message_unref(reply); - - dbus_error_free(&error); } static void request_process(Server *s, const struct init_request *req) { @@ -175,7 +162,7 @@ static void request_process(Server *s, const struct init_request *req) { case 'u': case 'U': if (kill(1, SIGTERM) < 0) - log_error("kill() failed: %m"); + log_error_errno(errno, "kill() failed: %m"); /* The bus connection will be * terminated if PID 1 is reexecuted, @@ -188,7 +175,7 @@ static void request_process(Server *s, const struct init_request *req) { case 'q': case 'Q': if (kill(1, SIGHUP) < 0) - log_error("kill() failed: %m"); + log_error_errno(errno, "kill() failed: %m"); break; default: @@ -223,13 +210,15 @@ static int fifo_process(Fifo *f) { assert(f); errno = EIO; - if ((l = read(f->fd, ((uint8_t*) &f->buffer) + f->bytes_read, sizeof(f->buffer) - f->bytes_read)) <= 0) { - + l = read(f->fd, + ((uint8_t*) &f->buffer) + f->bytes_read, + sizeof(f->buffer) - f->bytes_read); + if (l <= 0) { if (errno == EAGAIN) return 0; - log_warning("Failed to read from fifo: %s", strerror(errno)); - return -1; + log_warning_errno(errno, "Failed to read from fifo: %m"); + return -errno; } f->bytes_read += l; @@ -249,14 +238,14 @@ static void fifo_free(Fifo *f) { if (f->server) { assert(f->server->n_fifos > 0); f->server->n_fifos--; - LIST_REMOVE(Fifo, fifo, f->server->fifos, f); + LIST_REMOVE(fifo, f->server->fifos, f); } if (f->fd >= 0) { if (f->server) epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL); - close_nointr_nofail(f->fd); + safe_close(f->fd); } free(f); @@ -268,31 +257,27 @@ static void server_done(Server *s) { while (s->fifos) fifo_free(s->fifos); - if (s->epoll_fd >= 0) - close_nointr_nofail(s->epoll_fd); + safe_close(s->epoll_fd); if (s->bus) { - dbus_connection_flush(s->bus); - dbus_connection_close(s->bus); - dbus_connection_unref(s->bus); + sd_bus_flush(s->bus); + sd_bus_unref(s->bus); } } static int server_init(Server *s, unsigned n_sockets) { int r; unsigned i; - DBusError error; assert(s); assert(n_sockets > 0); - dbus_error_init(&error); - zero(*s); - if ((s->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) { + s->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (s->epoll_fd < 0) { r = -errno; - log_error("Failed to create epoll object: %s", strerror(errno)); + log_error_errno(errno, "Failed to create epoll object: %m"); goto fail; } @@ -303,8 +288,9 @@ static int server_init(Server *s, unsigned n_sockets) { fd = SD_LISTEN_FDS_START+i; - if ((r = sd_is_fifo(fd, NULL)) < 0) { - log_error("Failed to determine file descriptor type: %s", strerror(-r)); + r = sd_is_fifo(fd, NULL); + if (r < 0) { + log_error_errno(r, "Failed to determine file descriptor type: %m"); goto fail; } @@ -314,9 +300,10 @@ static int server_init(Server *s, unsigned n_sockets) { goto fail; } - if (!(f = new0(Fifo, 1))) { + f = new0(Fifo, 1); + if (!f) { r = -ENOMEM; - log_error("Failed to create fifo object: %s", strerror(errno)); + log_error_errno(errno, "Failed to create fifo object: %m"); goto fail; } @@ -328,18 +315,20 @@ static int server_init(Server *s, unsigned n_sockets) { if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { r = -errno; fifo_free(f); - log_error("Failed to add fifo fd to epoll object: %s", strerror(errno)); + log_error_errno(errno, "Failed to add fifo fd to epoll object: %m"); goto fail; } f->fd = fd; - LIST_PREPEND(Fifo, fifo, s->fifos, f); + LIST_PREPEND(fifo, s->fifos, f); f->server = s; s->n_fifos ++; } - if (bus_connect(DBUS_BUS_SYSTEM, &s->bus, NULL, &error) < 0) { - log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + r = bus_open_system_systemd(&s->bus); + if (r < 0) { + log_error_errno(r, "Failed to get D-Bus connection: %m"); + r = -EIO; goto fail; } @@ -348,7 +337,6 @@ static int server_init(Server *s, unsigned n_sockets) { fail: server_done(s); - dbus_error_free(&error); return r; } @@ -364,9 +352,9 @@ static int process_event(Server *s, struct epoll_event *ev) { } f = (Fifo*) ev->data.ptr; - - if ((r = fifo_process(f)) < 0) { - log_info("Got error on fifo: %s", strerror(-r)); + r = fifo_process(f); + if (r < 0) { + log_info_errno(r, "Got error on fifo: %m"); fifo_free(f); return r; } @@ -394,8 +382,9 @@ int main(int argc, char *argv[]) { umask(0022); - if ((n = sd_listen_fds(true)) < 0) { - log_error("Failed to read listening file descriptors from environment: %s", strerror(-r)); + n = sd_listen_fds(true); + if (n < 0) { + log_error_errno(r, "Failed to read listening file descriptors from environment: %m"); return EXIT_FAILURE; } @@ -407,7 +396,7 @@ int main(int argc, char *argv[]) { if (server_init(&server, (unsigned) n) < 0) return EXIT_FAILURE; - log_debug("systemd-initctl running as pid %lu", (unsigned long) getpid()); + log_debug("systemd-initctl running as pid "PID_FMT, getpid()); sd_notify(false, "READY=1\n" @@ -424,7 +413,7 @@ int main(int argc, char *argv[]) { if (errno == EINTR) continue; - log_error("epoll_wait() failed: %s", strerror(errno)); + log_error_errno(errno, "epoll_wait() failed: %m"); goto fail; } @@ -437,15 +426,14 @@ int main(int argc, char *argv[]) { r = EXIT_SUCCESS; - log_debug("systemd-initctl stopped as pid %lu", (unsigned long) getpid()); + log_debug("systemd-initctl stopped as pid "PID_FMT, getpid()); fail: sd_notify(false, + "STOPPING=1\n" "STATUS=Shutting down..."); server_done(&server); - dbus_shutdown(); - return r; }