" <property name=\"PIDFile\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"NotifyAccess\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"RestartUSec\" type=\"t\" access=\"read\"/>\n" \
- " <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"TimeoutStartUSec\" type=\"t\" access=\"read\"/>\n" \
+ " <property name=\"TimeoutStopUSec\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"WatchdogUSec\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"WatchdogTimestamp\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"WatchdogTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"StartLimitInterval\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"StartLimitBurst\" type=\"u\" access=\"read\"/>\n" \
" <property name=\"StartLimitAction\" type=\"s\" access=\"readwrite\"/>\n" \
+ BUS_UNIT_CGROUP_INTERFACE \
BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \
BUS_EXEC_COMMAND_INTERFACE("ExecStart") \
BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \
BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \
BUS_EXEC_CONTEXT_INTERFACE \
BUS_KILL_CONTEXT_INTERFACE \
+ BUS_CGROUP_CONTEXT_INTERFACE \
" <property name=\"PermissionsStartOnly\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"RootDirectoryStartOnly\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"RemainAfterExit\" type=\"b\" access=\"read\"/>\n" \
{ "ExecMainPID", bus_property_append_pid, "u", offsetof(ExecStatus, pid) },
{ "ExecMainCode", bus_property_append_int, "i", offsetof(ExecStatus, code) },
{ "ExecMainStatus", bus_property_append_int, "i", offsetof(ExecStatus, status) },
- { NULL, }
+ {}
};
static const BusProperty bus_service_properties[] = {
{ "PIDFile", bus_property_append_string, "s", offsetof(Service, pid_file), true },
{ "NotifyAccess", bus_service_append_notify_access, "s", offsetof(Service, notify_access) },
{ "RestartUSec", bus_property_append_usec, "t", offsetof(Service, restart_usec) },
- { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Service, timeout_start_usec) },
{ "TimeoutStartUSec", bus_property_append_usec, "t", offsetof(Service, timeout_start_usec) },
{ "TimeoutStopUSec", bus_property_append_usec, "t", offsetof(Service, timeout_stop_usec) },
{ "WatchdogUSec", bus_property_append_usec, "t", offsetof(Service, watchdog_usec) },
{ "BusName", bus_property_append_string, "s", offsetof(Service, bus_name), true },
{ "StatusText", bus_property_append_string, "s", offsetof(Service, status_text), true },
{ "Result", bus_service_append_service_result,"s", offsetof(Service, result) },
- { NULL, }
+ {}
};
DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connection, DBusMessage *message) {
const BusBoundProperties bps[] = {
{ "org.freedesktop.systemd1.Unit", bus_unit_properties, u },
+ { "org.freedesktop.systemd1.Service", bus_unit_cgroup_properties, u },
{ "org.freedesktop.systemd1.Service", bus_service_properties, s },
{ "org.freedesktop.systemd1.Service", bus_exec_context_properties, &s->exec_context },
{ "org.freedesktop.systemd1.Service", bus_kill_context_properties, &s->kill_context },
{ "org.freedesktop.systemd1.Service", bus_cgroup_context_properties, &s->cgroup_context },
{ "org.freedesktop.systemd1.Service", bus_exec_main_status_properties, &s->main_exec_status },
- { NULL, }
+ {}
};
SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "status");
return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
}
-static int bus_service_set_transient_properties(
+static int bus_service_set_transient_property(
Service *s,
const char *name,
DBusMessageIter *i,
assert(s);
assert(i);
- if (streq(name, "ExecStart")) {
+ if (streq(name, "RemainAfterExit")) {
+ if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN)
+ return -EINVAL;
+
+ if (mode != UNIT_CHECK) {
+ dbus_bool_t b;
+
+ dbus_message_iter_get_basic(i, &b);
+
+ s->remain_after_exit = b;
+ unit_write_drop_in_private_format(UNIT(s), mode, name, "RemainAfterExit=%s\n", yes_no(b));
+ }
+
+ return 1;
+
+ } else if (streq(name, "ExecStart")) {
DBusMessageIter sub;
unsigned n = 0;
fputs("ExecStart=\n", f);
LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) {
- char **a;
- fputs("ExecStart=", f);
-
- if (c->ignore)
- fputc('-', f);
+ _cleanup_free_ char *a;
- fputc('@', f);
- fputs(c->path, f);
-
- STRV_FOREACH(a, c->argv) {
- fputc(' ', f);
- fputs(*a, f);
- }
+ a = strv_join_quoted(c->argv);
+ if (!a)
+ return -ENOMEM;
- fputc('\n', f);
+ fprintf(f, "ExecStart=%s@%s %s\n",
+ c->ignore ? "-" : "",
+ c->path,
+ a);
}
fflush(f);
- unit_write_drop_in_private_section(UNIT(s), mode, "exec-start", buf);
+ unit_write_drop_in_private(UNIT(s), mode, name, buf);
}
return 1;
if (u->transient && u->load_state == UNIT_STUB) {
/* This is a transient unit, let's load a little more */
- r = bus_service_set_transient_properties(s, name, i, mode, error);
+ r = bus_service_set_transient_property(s, name, i, mode, error);
+ if (r != 0)
+ return r;
+
+ r = bus_kill_context_set_transient_property(u, &s->kill_context, name, i, mode, error);
if (r != 0)
return r;
}