initctl.c revision 3143987f93120da696c2d363c34cacf9a82aea93
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen This file is part of systemd.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen Copyright 2010 Lennart Poettering
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen systemd is free software; you can redistribute it and/or modify it
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen under the terms of the GNU Lesser General Public License as published by
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen (at your option) any later version.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen systemd is distributed in the hope that it will be useful, but
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen Lesser General Public License for more details.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen You should have received a copy of the GNU Lesser General Public License
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#define TIMEOUT_MSEC ((int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC))
99634696183dfabae20104e58157c69029a11594Tom Gundersentypedef struct Server {
99634696183dfabae20104e58157c69029a11594Tom Gundersenstatic const char *translate_runlevel(int runlevel, bool *isolate) {
99634696183dfabae20104e58157c69029a11594Tom Gundersen static const struct {
3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8Lennart Poetteringstatic void change_runlevel(Server *s, int runlevel) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (!(target = translate_runlevel(runlevel, &isolate))) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen log_warning("Got request for unknown runlevel %c, ignoring.", runlevel);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen log_debug("Running request %s/start/%s", target, mode);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen log_error("Could not attach target and flag information to message.");
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt if (!(reply = dbus_connection_send_with_reply_and_block(s->bus, m, -1, &error))) {
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt log_error("Failed to start unit: %s", bus_error_message(&error));
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersenstatic void request_process(Server *s, const struct init_request *req) {
3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8Lennart Poettering log_error("Got initctl request with invalid magic. Ignoring.");
1a04db0fc9d08fffe80d6d7b5b60459295922b11Lennart Poettering /* we are async anyway, so just use kill for reexec/reload */
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering /* The bus connection will be
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering * terminated if PID 1 is reexecuted,
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering * hence let's just exit here, and
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen * rely on that we'll be restarted on
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen * the next request */
b3ec603ce8053ba3f95da1d36f15ea762c83d1e1Lennart Poettering log_warning("Received UPS/power initctl request. This is not implemented in systemd. Upgrade your UPS daemon!");
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen log_warning("Received console change initctl request. This is not implemented in systemd.");
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen log_warning("Received environment initctl request. This is not implemented in systemd.");
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen log_warning("Received unknown initctl request. Ignoring.");
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if ((l = read(f->fd, ((uint8_t*) &f->buffer) + f->bytes_read, sizeof(f->buffer) - f->bytes_read)) <= 0) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen log_warning("Failed to read from fifo: %s", strerror(errno));
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (f->fd >= 0) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenstatic int server_init(Server *s, unsigned n_sockets) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error("Failed to create epoll object: %s", strerror(errno));
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen for (i = 0; i < n_sockets; i++) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error("Failed to determine file descriptor type: %s",
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error("Failed to add fifo fd to epoll object: %s",
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (bus_connect(DBUS_BUS_SYSTEM, &s->bus, NULL, &error) < 0) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error("Failed to get D-Bus connection: %s",
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenstatic int process_event(Server *s, struct epoll_event *ev) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_info("Got invalid event from epoll. (3)");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if ((r = fifo_process(f)) < 0) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_info("Got error on fifo: %s", strerror(-r));
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error("This program should be invoked by init only.");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error("This program does not take arguments.");
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen if ((n = sd_listen_fds(true)) < 0) {
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen log_error("Failed to read listening file descriptors from environment: %s", strerror(-r));
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (n <= 0 || n > SERVER_FD_MAX) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error("No or too many file descriptors passed.");
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen log_debug("systemd-initctl running as pid %lu", (unsigned long) getpid());
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen "STATUS=Processing requests...");
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen log_error("epoll_wait() failed: %s", strerror(errno));
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen log_debug("systemd-initctl stopped as pid %lu", (unsigned long) getpid());
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen "STATUS=Shutting down...");