This file is part of systemd.
Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <errno.h>
s->guess_main_pid = true;
s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
+
+ s->exec_context.keyring_mode = MANAGER_IS_SYSTEM(u->manager) ?
+ EXEC_KEYRING_PRIVATE : EXEC_KEYRING_INHERIT;
}
static void service_unwatch_control_pid(Service *s) {
s->bus_name_owner = mfree(s->bus_name_owner);
+ s->usb_function_descriptors = mfree(s->usb_function_descriptors);
+ s->usb_function_strings = mfree(s->usb_function_strings);
+
service_close_socket_fd(s);
s->peer = socket_peer_unref(s->peer);
if (r < 0)
return r;
- if (s->type == SERVICE_NOTIFY && s->notify_access == NOTIFY_NONE)
- s->notify_access = NOTIFY_MAIN;
-
- if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE)
+ /* If the service needs the notify socket, let's enable it automatically. */
+ if (s->notify_access == NOTIFY_NONE &&
+ (s->type == SERVICE_NOTIFY || s->watchdog_usec > 0 || s->n_fd_store_max > 0))
s->notify_access = NOTIFY_MAIN;
r = service_add_default_dependencies(s);
if (s->n_fd_store_max > 0)
fprintf(f,
"%sFile Descriptor Store Max: %u\n"
- "%sFile Descriptor Store Current: %u\n",
+ "%sFile Descriptor Store Current: %zu\n",
prefix, s->n_fd_store_max,
prefix, s->n_fd_store);
continue;
if (!rfds) {
- rfds = cfds;
+ rfds = TAKE_PTR(cfds);
rn_socket_fds = cn_fds;
-
- cfds = NULL;
} else {
int *t;
- t = realloc(rfds, (rn_socket_fds + cn_fds) * sizeof(int));
+ t = reallocarray(rfds, rn_socket_fds + cn_fds, sizeof(int));
if (!t)
return -ENOMEM;
char **nl;
int *t;
- t = realloc(rfds, (rn_socket_fds + s->n_fd_store) * sizeof(int));
+ t = reallocarray(rfds, rn_socket_fds + s->n_fd_store, sizeof(int));
if (!t)
return -ENOMEM;
rfds = t;
- nl = realloc(rfd_names, (rn_socket_fds + s->n_fd_store + 1) * sizeof(char*));
+ nl = reallocarray(rfd_names, rn_socket_fds + s->n_fd_store + 1, sizeof(char *));
if (!nl)
return -ENOMEM;
rfd_names[n_fds] = NULL;
}
- *fds = rfds;
- *fd_names = rfd_names;
+ *fds = TAKE_PTR(rfds);
+ *fd_names = TAKE_PTR(rfd_names);
*n_socket_fds = rn_socket_fds;
*n_storage_fds = rn_storage_fds;
- rfds = NULL;
- rfd_names = NULL;
-
return 0;
}
}
}
- manager_set_exec_params(UNIT(s)->manager, &exec_params);
unit_set_exec_params(UNIT(s), &exec_params);
final_env = strv_env_merge(2, exec_params.environment, our_env, NULL);
service_unwatch_control_pid(s);
- if (service_good(s)) {
+ if (s->result != SERVICE_SUCCESS)
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
+ else if (service_good(s)) {
- /* If there are any queued up sd_notify()
- * notifications, process them now */
+ /* If there are any queued up sd_notify() notifications, process them now */
if (s->notify_state == NOTIFY_RELOADING)
service_enter_reload_by_notify(s);
else if (s->notify_state == NOTIFY_STOPPING)
service_arm_timer(s, usec_add(UNIT(s)->active_enter_timestamp.monotonic, s->runtime_max_usec));
}
- } else if (f != SERVICE_SUCCESS)
- service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
- else if (s->remain_after_exit)
+ } else if (s->remain_after_exit)
service_set_state(s, SERVICE_EXITED);
else
service_enter_stop(s, SERVICE_SUCCESS);
LOG_UNIT_ID(UNIT(s)),
LOG_UNIT_INVOCATION_ID(UNIT(s)),
LOG_UNIT_MESSAGE(UNIT(s), "Scheduled restart job, restart counter is at %u.", s->n_restarts),
- "N_RESTARTS=%u", s->n_restarts,
- NULL);
+ "N_RESTARTS=%u", s->n_restarts);
/* Notify clients about changed restart counter */
unit_add_to_dbus_queue(UNIT(s));
state = STATE_EXEC_COMMAND_PATH;
break;
case STATE_EXEC_COMMAND_PATH:
- path = arg;
- arg = NULL;
+ path = TAKE_PTR(arg);
state = STATE_EXEC_COMMAND_ARGS;
if (!path_is_absolute(path))
if (r < 0)
log_unit_debug_errno(u, r, "Failed to load accept-socket unit: %s", value);
else {
- unit_ref_set(&s->accept_socket, socket);
+ unit_ref_set(&s->accept_socket, u, socket);
SOCKET(socket)->n_connections++;
}
return -ENOMEM;
}
- path_kill_slashes(ps->path);
+ path_simplify(ps->path, false);
/* PATH_CHANGED would not be enough. There are daemons (sendmail) that
* keep their PID file open all the time. */
"EXIT_CODE=%s", sigchld_code_to_string(code),
"EXIT_STATUS=%i", status,
LOG_UNIT_ID(u),
- LOG_UNIT_INVOCATION_ID(u),
- NULL);
+ LOG_UNIT_INVOCATION_ID(u));
if (s->result == SERVICE_SUCCESS)
s->result = f;
break;
case SERVICE_AUTO_RESTART:
- log_unit_info(UNIT(s),
- s->restart_usec > 0 ?
- "Service hold-off time over, scheduling restart." :
- "Service has no hold-off time, scheduling restart.");
+ if (s->restart_usec > 0) {
+ char buf_restart[FORMAT_TIMESPAN_MAX];
+ log_unit_info(UNIT(s),
+ "Service RestartSec=%s expired, scheduling restart.",
+ format_timespan(buf_restart, sizeof buf_restart, s->restart_usec, USEC_PER_SEC));
+ } else
+ log_unit_info(UNIT(s),
+ "Service has no hold-off time (RestartSec=0), scheduling restart.");
+
service_enter_restart(s);
break;
s->socket_fd = fd;
s->socket_fd_selinux_context_net = selinux_context_net;
- unit_ref_set(&s->accept_socket, UNIT(sock));
+ unit_ref_set(&s->accept_socket, UNIT(s), UNIT(sock));
return 0;
}
"Install\0",
.private_section = "Service",
+ .can_transient = true,
+ .can_delegate = true,
+
.init = service_init,
.done = service_done,
.load = service_load,
.get_timeout = service_get_timeout,
.needs_console = service_needs_console,
- .can_transient = true,
.status_message_formats = {
.starting_stopping = {