X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fdbus-manager.c;h=f8a54000552476fad60d3cbbec71854765069ea6;hp=3bf0c07b88def894eeaae96b9844b989d4180fc8;hb=b4efdf97203ddf781c17f77be84cc61516a077d2;hpb=b30e2f4c18ad81b04e4314fd191a5d458553773c
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 3bf0c07b8..f8a540005 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -6,16 +6,16 @@
Copyright 2010 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
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 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.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see .
***/
@@ -30,6 +30,9 @@
#include "build.h"
#include "dbus-common.h"
#include "install.h"
+#include "watchdog.h"
+#include "hwclock.h"
+#include "path-util.h"
#define BUS_MANAGER_INTERFACE_BEGIN \
" \n"
@@ -111,7 +114,9 @@
" \n" \
" \n" \
" \n" \
- " \n" \
+ " \n" \
+ " \n" \
+ " \n" \
" \n" \
" \n" \
" \n" \
@@ -124,6 +129,10 @@
" \n" \
" \n" \
" \n" \
+ " \n" \
+ " \n" \
+ " \n" \
+ " \n" \
" \n" \
" \n" \
" \n" \
@@ -197,10 +206,12 @@
" \n" \
" \n" \
" \n" \
+ " \n" \
" \n" \
" \n" \
" \n" \
" \n" \
+ " \n" \
" \n" \
" " \
" \n" \
@@ -216,7 +227,6 @@
" \n" \
" \n" \
" \n" \
- " \n" \
" \n" \
" \n" \
" \n" \
@@ -234,24 +244,12 @@
" \n" \
" \n" \
" \n" \
- " \n" \
" \n" \
- " \n" \
- " \n" \
" \n" \
" \n" \
" \n" \
- " \n" \
- " \n"
-
-#ifdef HAVE_SYSV_COMPAT
-#define BUS_MANAGER_INTERFACE_PROPERTIES_SYSV \
- " \n" \
- " \n" \
- " \n"
-#else
-#define BUS_MANAGER_INTERFACE_PROPERTIES_SYSV
-#endif
+ " \n" \
+ " \n"
#define BUS_MANAGER_INTERFACE_END \
" \n"
@@ -261,7 +259,6 @@
BUS_MANAGER_INTERFACE_METHODS \
BUS_MANAGER_INTERFACE_SIGNALS \
BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \
- BUS_MANAGER_INTERFACE_PROPERTIES_SYSV \
BUS_MANAGER_INTERFACE_END
#define INTROSPECTION_BEGIN \
@@ -281,7 +278,6 @@
const char bus_manager_interface[] _introspect_("Manager") = BUS_MANAGER_INTERFACE;
-static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_running_as, manager_running_as, ManagerRunningAs);
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_exec_output, exec_output, ExecOutput);
static int bus_manager_append_tainted(DBusMessageIter *i, const char *property, void *data) {
@@ -294,17 +290,24 @@ static int bus_manager_append_tainted(DBusMessageIter *i, const char *property,
assert(m);
if (m->taint_usr)
- e = stpcpy(e, "usr-separate-fs ");
+ e = stpcpy(e, "split-usr:");
if (readlink_malloc("/etc/mtab", &p) < 0)
- e = stpcpy(e, "etc-mtab-not-symlink ");
+ e = stpcpy(e, "mtab-not-symlink:");
else
free(p);
if (access("/proc/cgroups", F_OK) < 0)
- stpcpy(e, "cgroups-missing ");
+ e = stpcpy(e, "cgroups-missing:");
+
+ if (hwclock_is_localtime() > 0)
+ e = stpcpy(e, "local-hwclock:");
- t = strstrip(buf);
+ /* remove the last ':' */
+ if (e != buf)
+ e[-1] = 0;
+
+ t = buf;
if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t))
return -ENOMEM;
@@ -493,6 +496,17 @@ static int bus_manager_send_unit_files_changed(Manager *m) {
return r;
}
+static int bus_manager_set_runtime_watchdog_usec(DBusMessageIter *i, const char *property, void *data) {
+ uint64_t *t = data;
+
+ assert(i);
+ assert(property);
+
+ dbus_message_iter_get_basic(i, t);
+
+ return watchdog_set_timeout(t);
+}
+
static const char systemd_property_string[] =
PACKAGE_STRING "\0"
DISTRIBUTION "\0"
@@ -506,7 +520,6 @@ static const BusProperty bus_systemd_properties[] = {
};
static const BusProperty bus_manager_properties[] = {
- { "RunningAs", bus_manager_append_running_as, "s", offsetof(Manager, running_as) },
{ "Tainted", bus_manager_append_tainted, "s", 0 },
{ "InitRDTimestamp", bus_property_append_uint64, "t", offsetof(Manager, initrd_timestamp.realtime) },
{ "InitRDTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, initrd_timestamp.monotonic) },
@@ -514,8 +527,8 @@ static const BusProperty bus_manager_properties[] = {
{ "StartupTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, startup_timestamp.monotonic) },
{ "FinishTimestamp", bus_property_append_uint64, "t", offsetof(Manager, finish_timestamp.realtime) },
{ "FinishTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, finish_timestamp.monotonic) },
- { "LogLevel", bus_manager_append_log_level, "s", 0, 0, bus_manager_set_log_level },
- { "LogTarget", bus_manager_append_log_target, "s", 0, 0, bus_manager_set_log_target },
+ { "LogLevel", bus_manager_append_log_level, "s", 0, false, bus_manager_set_log_level },
+ { "LogTarget", bus_manager_append_log_target, "s", 0, false, bus_manager_set_log_target },
{ "NNames", bus_manager_append_n_names, "u", 0 },
{ "NJobs", bus_manager_append_n_jobs, "u", 0 },
{ "NInstalledJobs",bus_property_append_uint32, "u", offsetof(Manager, n_installed_jobs) },
@@ -525,20 +538,12 @@ static const BusProperty bus_manager_properties[] = {
{ "ConfirmSpawn", bus_property_append_bool, "b", offsetof(Manager, confirm_spawn) },
{ "ShowStatus", bus_property_append_bool, "b", offsetof(Manager, show_status) },
{ "UnitPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.unit_path), true },
- { "NotifySocket", bus_property_append_string, "s", offsetof(Manager, notify_socket), true },
{ "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_hierarchy), true },
- { "MountAuto", bus_property_append_bool, "b", offsetof(Manager, mount_auto) },
- { "SwapAuto", bus_property_append_bool, "b", offsetof(Manager, swap_auto) },
{ "DefaultControllers", bus_property_append_strv, "as", offsetof(Manager, default_controllers), true },
{ "DefaultStandardOutput", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_output) },
{ "DefaultStandardError", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_error) },
- { "RuntimeWatchdogUSec", bus_property_append_usec, "t", offsetof(Manager, runtime_watchdog), },
- { "ShutdownWatchdogUSec", bus_property_append_usec, "t", offsetof(Manager, shutdown_watchdog), },
-#ifdef HAVE_SYSV_COMPAT
- { "SysVConsole", bus_property_append_bool, "b", offsetof(Manager, sysv_console) },
- { "SysVInitPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.sysvinit_path), true },
- { "SysVRcndPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.sysvrcnd_path), true },
-#endif
+ { "RuntimeWatchdogUSec", bus_property_append_usec, "t", offsetof(Manager, runtime_watchdog), false, bus_manager_set_runtime_watchdog_usec },
+ { "ShutdownWatchdogUSec", bus_property_append_usec, "t", offsetof(Manager, shutdown_watchdog), false, bus_property_set_usec },
{ NULL, }
};
@@ -1144,6 +1149,70 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
m->exit_code = MANAGER_KEXEC;
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SwitchRoot")) {
+ const char *switch_root, *switch_root_init;
+ char *u, *v;
+ int k;
+
+ if (!dbus_message_get_args(
+ message,
+ &error,
+ DBUS_TYPE_STRING, &switch_root,
+ DBUS_TYPE_STRING, &switch_root_init,
+ DBUS_TYPE_INVALID))
+ return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+ if (path_equal(switch_root, "/") || !path_is_absolute(switch_root))
+ return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+ if (!isempty(switch_root_init) && !path_is_absolute(switch_root_init))
+ return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
+ if (m->running_as != MANAGER_SYSTEM) {
+ dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Switching root is only supported for system managers.");
+ return bus_send_error_reply(connection, message, &error, -ENOTSUP);
+ }
+
+ /* Safety check */
+ if (isempty(switch_root_init))
+ k = access(switch_root, F_OK);
+ else {
+ char *p;
+
+ p = join(switch_root, "/", switch_root_init, NULL);
+ if (!p)
+ goto oom;
+
+ k = access(p, X_OK);
+ free(p);
+ }
+ if (k < 0)
+ return bus_send_error_reply(connection, message, NULL, -errno);
+
+ u = strdup(switch_root);
+ if (!u)
+ goto oom;
+
+ if (!isempty(switch_root_init)) {
+ v = strdup(switch_root_init);
+ if (!v) {
+ free(u);
+ goto oom;
+ }
+ } else
+ v = NULL;
+
+ free(m->switch_root);
+ free(m->switch_root_init);
+ m->switch_root = u;
+ m->switch_root_init = v;
+
+ reply = dbus_message_new_method_return(message);
+ if (!reply)
+ goto oom;
+
+ m->exit_code = MANAGER_SWITCH_ROOT;
+
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetEnvironment")) {
char **l = NULL, **e = NULL;
@@ -1442,6 +1511,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
const char *name, *smode, *old_name = NULL;
JobMode mode;
Job *j;
+ JobBusClient *cl;
Unit *u;
bool b;
@@ -1488,6 +1558,11 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
job_type = JOB_RELOAD;
}
+ if (job_type == JOB_STOP && u->load_state == UNIT_ERROR && unit_active_state(u) == UNIT_INACTIVE) {
+ dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
+ return bus_send_error_reply(connection, message, &error, -EPERM);
+ }
+
if ((job_type == JOB_START && u->refuse_manual_start) ||
(job_type == JOB_STOP && u->refuse_manual_stop) ||
((job_type == JOB_RESTART || job_type == JOB_TRY_RESTART) &&
@@ -1499,10 +1574,11 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
if ((r = manager_add_job(m, job_type, u, mode, true, &error, &j)) < 0)
return bus_send_error_reply(connection, message, &error, r);
- if (!(j->bus_client = strdup(message_get_sender_with_fallback(message))))
+ cl = job_bus_client_new(connection, message_get_sender_with_fallback(message));
+ if (!cl)
goto oom;
- j->bus = connection;
+ LIST_PREPEND(JobBusClient, client, j->bus_client_list, cl);
if (!(reply = dbus_message_new_method_return(message)))
goto oom;