summaryrefslogtreecommitdiff
path: root/src/core/dbus-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/dbus-manager.c')
-rw-r--r--src/core/dbus-manager.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index d8b39bdf5f..561b6f8bfa 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -81,14 +81,10 @@ static int property_get_virtualization(
void *userdata,
sd_bus_error *error) {
- const char *id = NULL;
-
assert(bus);
assert(reply);
- detect_virtualization(&id);
-
- return sd_bus_message_append(reply, "s", id);
+ return sd_bus_message_append(reply, "s", virtualization_to_string(detect_virtualization()));
}
static int property_get_architecture(
@@ -1069,10 +1065,9 @@ static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *er
manager_dump_units(m, f, NULL);
manager_dump_jobs(m, f, NULL);
- fflush(f);
-
- if (ferror(f))
- return -ENOMEM;
+ r = fflush_and_check(f);
+ if (r < 0)
+ return r;
return sd_bus_reply_method_return(message, "s", dump);
}
@@ -1206,8 +1201,10 @@ static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *er
if (r < 0)
return r;
- if (m->running_as == MANAGER_SYSTEM)
- return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
+ /* Exit() (in contrast to SetExitCode()) is actually allowed even if
+ * we are running on the host. It will fall back on reboot() in
+ * systemd-shutdown if it cannot do the exit() because it isn't a
+ * container. */
m->exit_code = MANAGER_EXIT;
@@ -1455,6 +1452,30 @@ static int method_unset_and_set_environment(sd_bus_message *message, void *userd
return sd_bus_reply_method_return(message, NULL);
}
+static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ uint8_t code;
+ Manager *m = userdata;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = mac_selinux_access_check(message, "exit", error);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_basic(message, 'y', &code);
+ if (r < 0)
+ return r;
+
+ if (m->running_as == MANAGER_SYSTEM && detect_container() <= 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "ExitCode can only be set for user service managers or in containers.");
+
+ m->return_value = code;
+
+ return sd_bus_reply_method_return(message, NULL);
+}
+
static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
Manager *m = userdata;
@@ -1651,10 +1672,6 @@ static int method_enable_unit_files_generic(
if (r < 0)
return r;
- r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
- if (r < 0)
- return r;
-
r = bus_verify_manage_unit_files_async(m, message, error);
if (r < 0)
return r;
@@ -1724,10 +1741,6 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
return -EINVAL;
}
- r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
- if (r < 0)
- return r;
-
r = bus_verify_manage_unit_files_async(m, message, error);
if (r < 0)
return r;
@@ -1767,10 +1780,6 @@ static int method_disable_unit_files_generic(
if (r < 0)
return r;
- r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
- if (r < 0)
- return r;
-
scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
r = bus_verify_manage_unit_files_async(m, message, error);
@@ -1903,10 +1912,6 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd
if (dep < 0)
return -EINVAL;
- r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
- if (r < 0)
- return r;
-
scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
@@ -1954,6 +1959,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
+ SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned, offsetof(Manager, return_value), 0),
SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -2007,6 +2013,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetExitCode", "y", NULL, method_set_exit_code, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("UnitNew", "so", 0),
SD_BUS_SIGNAL("UnitRemoved", "so", 0),