systemctl: hook up new install logic

This adds a number of new options to systemctl, for presets, reenabling,
masking/unmask, and runtime operations.
This commit is contained in:
Lennart Poettering
2011-07-25 04:58:02 +02:00
parent 4b7a6af440
commit 729e3769c3
11 changed files with 1099 additions and 1006 deletions
+31 -11
View File
@@ -145,6 +145,7 @@
" <arg name=\"files\" type=\"as\" direction=\"in\"/>\n" \
" <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n" \
" <arg name=\"force\" type=\"b\" direction=\"in\"/>\n" \
" <arg name=\"carries_install_info\" type=\"b\" directrion=\"out\"/>\n" \
" <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
" </method>\n" \
" <method name=\"DisableUnitFiles\">\n" \
@@ -156,6 +157,7 @@
" <arg name=\"files\" type=\"as\" direction=\"in\"/>\n" \
" <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n" \
" <arg name=\"force\" type=\"b\" direction=\"in\"/>\n" \
" <arg name=\"carries_install_info\" type=\"b\" directrion=\"out\"/>\n" \
" <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
" </method>\n" \
" <method name=\"LinkUnitFiles\">\n" \
@@ -168,6 +170,7 @@
" <arg name=\"files\" type=\"as\" direction=\"in\"/>\n" \
" <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n" \
" <arg name=\"force\" type=\"b\" direction=\"in\"/>\n" \
" <arg name=\"carries_install_info\" type=\"b\" directrion=\"out\"/>\n" \
" <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
" </method>\n" \
" <method name=\"MaskUnitFiles\">\n" \
@@ -422,7 +425,12 @@ static const char *message_get_sender_with_fallback(DBusMessage *m) {
return ":no-sender";
}
static DBusMessage *message_from_file_changes(DBusMessage *m, UnitFileChange *changes, unsigned n_changes) {
static DBusMessage *message_from_file_changes(
DBusMessage *m,
UnitFileChange *changes,
unsigned n_changes,
int carries_install_info) {
DBusMessageIter iter, sub, sub2;
DBusMessage *reply;
unsigned i;
@@ -435,6 +443,14 @@ static DBusMessage *message_from_file_changes(DBusMessage *m, UnitFileChange *ch
dbus_message_iter_init_append(reply, &iter);
if (carries_install_info >= 0) {
dbus_bool_t b;
b = carries_install_info;
if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b))
goto oom;
}
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sss)", &sub))
goto oom;
@@ -446,9 +462,9 @@ static DBusMessage *message_from_file_changes(DBusMessage *m, UnitFileChange *ch
source = strempty(changes[i].source);
if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &type) ||
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &path) ||
!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &source) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &type) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &path) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &source) ||
!dbus_message_iter_close_container(&sub, &sub2))
goto oom;
}
@@ -1304,6 +1320,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
dbus_bool_t runtime, force;
bool carries_install_info = -1;
if (!dbus_message_iter_init(message, &iter))
goto oom;
@@ -1323,15 +1340,18 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
return bus_send_error_reply(connection, message, NULL, -EIO);
}
if (streq(member, "EnableUnitFiles"))
if (streq(member, "EnableUnitFiles")) {
r = unit_file_enable(scope, runtime, NULL, l, force, &changes, &n_changes);
else if (streq(member, "ReenableUnitFiles"))
carries_install_info = r;
} else if (streq(member, "ReenableUnitFiles")) {
r = unit_file_reenable(scope, runtime, NULL, l, force, &changes, &n_changes);
else if (streq(member, "LinkUnitFiles"))
carries_install_info = r;
} else if (streq(member, "LinkUnitFiles"))
r = unit_file_link(scope, runtime, NULL, l, force, &changes, &n_changes);
else if (streq(member, "PresetUnitFiles"))
else if (streq(member, "PresetUnitFiles")) {
r = unit_file_preset(scope, runtime, NULL, l, force, &changes, &n_changes);
else if (streq(member, "MaskUnitFiles"))
carries_install_info = r;
} else if (streq(member, "MaskUnitFiles"))
r = unit_file_mask(scope, runtime, NULL, l, force, &changes, &n_changes);
else
assert_not_reached("Uh? Wrong method");
@@ -1344,7 +1364,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
return bus_send_error_reply(connection, message, NULL, r);
}
reply = message_from_file_changes(message, changes, n_changes);
reply = message_from_file_changes(message, changes, n_changes, carries_install_info);
unit_file_changes_free(changes, n_changes);
if (!reply)
@@ -1392,7 +1412,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
return bus_send_error_reply(connection, message, NULL, r);
}
reply = message_from_file_changes(message, changes, n_changes);
reply = message_from_file_changes(message, changes, n_changes, -1);
unit_file_changes_free(changes, n_changes);
if (!reply)
+5 -5
View File
@@ -596,16 +596,16 @@ Hashmap *hashmap_copy(Hashmap *h) {
char **hashmap_get_strv(Hashmap *h) {
char **sv;
Iterator it;
char *path;
char *item;
int n;
sv = malloc((h->n_entries+1) * sizeof(char *));
if (sv == NULL)
sv = new(char*, h->n_entries+1);
if (!sv)
return NULL;
n = 0;
HASHMAP_FOREACH(path, h, it)
sv[n++] = path;
HASHMAP_FOREACH(item, h, it)
sv[n++] = item;
sv[n] = NULL;
return sv;
+6 -2
View File
@@ -126,8 +126,6 @@ static int add_file_change(
UnitFileChange *c;
unsigned i;
assert(type >= 0);
assert(type < _UNIT_FILE_CHANGE_TYPE_MAX);
assert(path);
assert(!changes == !n_changes);
@@ -1414,6 +1412,10 @@ int unit_file_enable(
goto finish;
}
/* This will return the number of symlink rules that were
supposed to be created, not the ones actually created. This is
useful to determine whether the passed files hat any
installation data at all. */
r = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
finish:
@@ -1514,6 +1516,7 @@ int unit_file_reenable(
r = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes);
/* Returns number of symlinks that where supposed to be installed. */
q = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
if (r == 0)
r = q;
@@ -1763,6 +1766,7 @@ int unit_file_preset(
if (r == 0)
r = q;
/* Returns number of symlinks that where supposed to be installed. */
q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
if (r == 0)
r = q;
+8
View File
@@ -62,6 +62,14 @@
send_interface="org.freedesktop.systemd1.Manager"
send_member="ListUnits"/>
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
send_member="ListUnitFiles"/>
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
send_member="GetUnitFileState"/>
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
send_member="ListJobs"/>
+3 -3
View File
@@ -39,13 +39,13 @@ void pager_open(void) {
if (pager_pid > 0)
return;
if (isatty(STDOUT_FILENO) <= 0)
return;
if ((pager = getenv("SYSTEMD_PAGER")) || (pager = getenv("PAGER")))
if (!*pager || streq(pager, "cat"))
return;
if (isatty(STDOUT_FILENO) <= 0)
return;
/* Determine and cache number of columns before we spawn the
* pager so that we get the value from the actual tty */
columns();
+120
View File
@@ -0,0 +1,120 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2011 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/prctl.h>
#include <signal.h>
#include <fcntl.h>
#include "log.h"
#include "util.h"
#include "spawn-agent.h"
static pid_t agent_pid = 0;
void agent_open(void) {
pid_t parent_pid;
if (agent_pid > 0)
return;
/* We check STDIN here, not STDOUT, since this is about input,
* not output */
if (!isatty(STDIN_FILENO))
return;
parent_pid = getpid();
/* Spawns a temporary TTY agent, making sure it goes away when
* we go away */
agent_pid = fork();
if (agent_pid < 0) {
log_error("Failed to fork agent: %m");
return;
}
if (agent_pid == 0) {
/* In the child */
int fd;
bool stdout_is_tty, stderr_is_tty;
/* Make sure the agent goes away when the parent dies */
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
_exit(EXIT_FAILURE);
/* Check whether our parent died before we were able
* to set the death signal */
if (getppid() != parent_pid)
_exit(EXIT_SUCCESS);
/* Don't leak fds to the agent */
close_all_fds(NULL, 0);
stdout_is_tty = isatty(STDOUT_FILENO);
stderr_is_tty = isatty(STDERR_FILENO);
if (!stdout_is_tty || !stderr_is_tty) {
/* Detach from stdout/stderr. and reopen
* /dev/tty for them. This is important to
* ensure that when systemctl is started via
* popen() or a similar call that expects to
* read EOF we actually do generate EOF and
* not delay this indefinitely by because we
* keep an unused copy of stdin around. */
fd = open("/dev/tty", O_WRONLY);
if (fd < 0) {
log_error("Failed to open /dev/tty: %m");
_exit(EXIT_FAILURE);
}
if (!stdout_is_tty)
dup2(fd, STDOUT_FILENO);
if (!stderr_is_tty)
dup2(fd, STDERR_FILENO);
if (fd > 2)
close(fd);
}
execl(SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, "--watch", NULL);
log_error("Unable to execute agent: %m");
_exit(EXIT_FAILURE);
}
}
void agent_close(void) {
if (agent_pid <= 0)
return;
/* Inform agent that we are done */
kill(agent_pid, SIGTERM);
kill(agent_pid, SIGCONT);
wait_for_terminate(agent_pid, NULL);
agent_pid = 0;
}
+28
View File
@@ -0,0 +1,28 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foospawnagenthfoo
#define foospawnagenthfoo
/***
This file is part of systemd.
Copyright 2011 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
void agent_open(void);
void agent_close(void);
#endif
+793 -947
View File
File diff suppressed because it is too large Load Diff