return NULL;
}
-static ExecFlags service_exec_flags(ServiceExecCommand command_id, ExecFlags cred_flag) {
+static ExecFlags service_exec_flags(
+ const Service *s,
+ ServiceExecCommand command_id,
+ ExecFlags cred_flag) {
+
/* All service main/control processes honor sandboxing and namespacing options (except those
explicitly excluded in service_spawn()) */
ExecFlags flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT;
+ assert(s);
assert(command_id >= 0);
assert(command_id < _SERVICE_EXEC_COMMAND_MAX);
assert((cred_flag & ~(EXEC_SETUP_CREDENTIALS_FRESH|EXEC_SETUP_CREDENTIALS)) == 0);
if (!IN_SET(command_id, SERVICE_EXEC_CONDITION, SERVICE_EXEC_START_PRE))
flags |= EXEC_CONTROL_CGROUP;
+ /* Pass credentials to ExecReload*= too, but only if the credentials are actually refreshed,
+ * to make sure they have the same understanding of the world as the main process. */
+ if (IN_SET(command_id, SERVICE_EXEC_RELOAD, SERVICE_EXEC_RELOAD_POST) &&
+ FLAGS_SET(s->refreshed_mask, SERVICE_RELOAD_CREDENTIALS))
+ flags |= EXEC_SETUP_CREDENTIALS;
+
if (IN_SET(command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST))
flags |= EXEC_SETENV_RESULT;
r = service_spawn(s,
s->control_command,
- service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
+ service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
s->timeout_stop_usec,
&s->control_pid);
if (r < 0) {
r = service_spawn(s,
s->control_command,
- service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
+ service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
s->timeout_stop_usec,
&s->control_pid);
if (r < 0) {
r = service_spawn(s,
s->control_command,
- service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
+ service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
s->timeout_start_usec,
&s->control_pid);
if (r < 0) {
r = service_spawn(s,
c,
- service_exec_flags(SERVICE_EXEC_START, EXEC_SETUP_CREDENTIALS_FRESH),
+ service_exec_flags(s, SERVICE_EXEC_START, EXEC_SETUP_CREDENTIALS_FRESH),
timeout,
&pidref);
if (r < 0) {
r = service_spawn(s,
s->control_command,
- service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
+ service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
s->timeout_start_usec,
&s->control_pid);
if (r < 0) {
r = service_spawn(s,
s->control_command,
- service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
+ service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
s->timeout_start_usec,
&s->control_pid);
if (r < 0) {
r = service_spawn(s,
s->control_command,
- service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
+ service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
s->timeout_start_usec,
&s->control_pid);
if (r < 0) {
r = service_spawn(s,
s->control_command,
- service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
+ service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
s->timeout_start_usec,
&s->control_pid);
if (r < 0) {
r = service_spawn(s,
s->control_command,
- service_exec_flags(s->control_command_id, /* cred_flag= */ 0),
+ service_exec_flags(s, s->control_command_id, /* cred_flag = */ 0),
timeout,
&s->control_pid);
if (r < 0) {
r = service_spawn(s,
s->main_command,
- service_exec_flags(SERVICE_EXEC_START, EXEC_SETUP_CREDENTIALS),
+ service_exec_flags(s, SERVICE_EXEC_START, EXEC_SETUP_CREDENTIALS),
s->timeout_start_usec,
&pidref);
if (r < 0) {
assert(IN_SET(s->state, SERVICE_RUNNING, SERVICE_EXITED));
s->reload_result = SERVICE_SUCCESS;
+ s->refreshed_mask = 0;
service_enter_refresh_extensions(s);
(void) serialize_usec(f, "reload-begin-usec", s->reload_begin_usec);
+ if (s->refreshed_mask > 0) {
+ _cleanup_strv_free_ char **l = NULL;
+ _cleanup_free_ char *t = NULL;
+
+ r = service_refresh_on_reload_to_strv(s->refreshed_mask, &l);
+ if (r < 0)
+ return log_oom();
+
+ t = strv_join(l, " ");
+ if (!t)
+ return log_oom();
+
+ (void) serialize_item(f, "refreshed-mask", t);
+ }
+
return 0;
}
} else if (streq(key, "reload-begin-usec"))
(void) deserialize_usec(value, &s->reload_begin_usec);
- else
+ else if (streq(key, "refreshed-mask")) {
+ r = service_refresh_on_reload_from_string_many(value, &s->refreshed_mask);
+ if (r < 0)
+ log_unit_debug_errno(u, r, "Failed to parse refresh-mask value: %s", value);
+ } else
log_unit_debug(u, "Unknown serialization key: %s", key);
return 0;
break;
case SERVICE_REFRESH_EXTENSIONS:
- if (f == SERVICE_SUCCESS)
+ if (f == SERVICE_SUCCESS) {
+ s->refreshed_mask |= SERVICE_RELOAD_EXTENSIONS;
service_enter_refresh_credentials(s);
- else
+ } else
service_reload_finish(s, f);
break;
case SERVICE_REFRESH_CREDENTIALS:
if (f == SERVICE_SUCCESS ||
- (f == SERVICE_FAILURE_EXIT_CODE && IN_SET(status, EXIT_NOTINSTALLED, EXIT_NOPERMISSION)))
+ (f == SERVICE_FAILURE_EXIT_CODE && IN_SET(status, EXIT_NOTINSTALLED, EXIT_NOPERMISSION))) {
+
/* Refreshing asynchronously done, proceed to reload */
+ s->refreshed_mask |= f == SERVICE_SUCCESS ? SERVICE_RELOAD_CREDENTIALS : 0;
service_enter_reload(s);
- else
+ } else
service_reload_finish(s, f);
break;