dbus-manager.c revision 128c3c5881e5708b3f15517ee24dd8c0a1c6307e
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering This file is part of systemd.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Copyright 2010 Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (at your option) any later version.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is distributed in the hope that it will be useful, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Lesser General Public License for more details.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_message_append(reply, "s", id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (readlink_malloc("/etc/mtab", &p) < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* remove the last ':' */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_message_append(reply, "s", buf);
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering const char *t;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack r = log_level_to_string_alloc(log_get_max_level(), &t);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack const char *path,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *t;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering if (dual_timestamp_is_set(&m->finish_timestamp))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_message_append(reply, "d", d);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert_cc(sizeof(usec_t) == sizeof(uint64_t));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(message, "s", &name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(u, bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, "o", path);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidtstatic int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert_cc(sizeof(pid_t) == sizeof(uint32_t));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "u", &pid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(u, bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, "o", path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = manager_load_unit(m, name, NULL, error, &u);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(u, bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, "o", path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_start_unit_generic(sd_bus *bus, sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = manager_load_unit(m, name, NULL, error, &u);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(message, "s", &old_name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!u || !u->job || u->job->type != JOB_START)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return method_start_unit_generic(bus, message, m, JOB_START, false, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return bus_unit_method_kill(bus, message, u, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return bus_unit_method_reset_failed(bus, message, u, error);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mackstatic int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return bus_unit_method_set_properties(bus, message, u, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "ss", &name, &smode);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "start", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = manager_load_unit(m, name, NULL, error, &u);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* OK, the unit failed to load and is unreferenced, now let's
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * fill in the transient data instead */
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack /* Set our properties */
05a08cb60f02970e8476306074c70ee4e6a57fb3Thomas Hindoe Paaboel Andersen r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering /* And load this stub fully */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Finally, start it */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
995c5e96cdf9e6054a4df04960253d897f4d7cc2Lennart Poettering r = sd_bus_message_read(message, "u", &id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(j->unit, bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, "o", path);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering job_finish_and_invalidate(j, JOB_CANCELED, true);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "reboot", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "reload", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *k;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "status", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_new_method_return(message, &reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unit_load_state_to_string(u->load_state),
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering unit_active_state_to_string(unit_active_state(u)),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering u->job ? job_type_to_string(u->job->type) : "",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_close_container(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
e24e415e5f3af2fe86d2be9a1f1a2e8d5f8c96bfDaniel Mack r = selinux_access_check(bus, message, "status", error);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_message_new_method_return(message, &reply);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_message_close_container(reply);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poetteringstatic int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = selinux_access_check(bus, message, "status", error);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = bus_client_track(&m->subscribed, bus, sd_bus_message_get_sender(message));
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering return sd_bus_reply_method_return(message, NULL);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poetteringstatic int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering r = selinux_access_check(bus, message, "status", error);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = bus_client_untrack(m->subscribed, bus, sd_bus_message_get_sender(message));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "status", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, "s", dump);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = selinux_access_check(bus, message, "start", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "sb", &name, &cleanup);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = snapshot_create(m, name, cleanup, error, &s);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, "o", path);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "stop", error);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = sd_bus_message_read(message, "s", &name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return bus_snapshot_method_remove(bus, message, u, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "reload", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Instead of sending the reply back right away, we just
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * remember that we need to and then send it after the reload
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * is finished. That way the caller knows when the reload
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * finished. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_new_method_return(message, &m->queued_message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering r = selinux_access_check(bus, message, "reload", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* We don't send a reply back here, the client should
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * just wait for us disconnecting. */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "halt", error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering return sd_bus_reply_method_return(message, NULL);
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poetteringstatic int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "reboot", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = selinux_access_check(bus, message, "halt", error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_return(message, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = selinux_access_check(bus, message, "halt", error);
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_return(message, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. /etc/os-release is missing.", root);
return -ENOMEM;
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
if (!rt)
return -ENOMEM;
if (!ri) {
return -ENOMEM;
static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Hashmap *h;
Iterator i;
assert(m);
return -ENOMEM;
r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
goto fail;
goto fail;
goto fail;
fail:
static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
if (state < 0)
return state;
static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged", &message);
static int reply_unit_file_changes_and_free(
Manager *m,
int carries_install_info,
unsigned n_changes) {
if (n_changes > 0)
goto fail;
if (carries_install_info >= 0) {
goto fail;
goto fail;
for (i = 0; i < n_changes; i++) {
goto fail;
goto fail;
fail:
static int method_enable_unit_files_generic(
Manager *m, const
char *verb,
int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
bool carries_install_info,
unsigned n_changes = 0;
assert(m);
return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
static int method_disable_unit_files_generic(
Manager *m, const
char *verb,
int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
unsigned n_changes = 0;
int r, runtime;
assert(m);
static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
unsigned n_changes = 0;
const char *name;
int force, r;
assert(m);
BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), 0),
BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), 0),
SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
int bus_manager_foreach_client(Manager *m, int (*send_message)(sd_bus *bus, const char *destination, void *userdata), void *userdata) {
Iterator i;
sd_bus *b;
BusTrackedClient *d;
if (m->api_bus)
r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished", &message);
r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
Manager *m,
assert(m);
r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading", &message);
assert(m);