mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-27 01:55:32 +03:00
execute: add ability to configure the kill signal
This commit is contained in:
parent
73c33e7f22
commit
2e22afe909
2
fixme
2
fixme
@ -35,8 +35,6 @@
|
||||
|
||||
* selinux
|
||||
|
||||
* pull in umount.target and shutdown.target from emergency.service (?)
|
||||
|
||||
* Show exit status auf auxiliary programs in systemctl status
|
||||
|
||||
External:
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "ioprio.h"
|
||||
#include "strv.h"
|
||||
|
||||
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_kill_mode, kill_mode, KillMode);
|
||||
|
||||
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput);
|
||||
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput);
|
||||
|
||||
|
@ -83,7 +83,9 @@
|
||||
" <property name=\"InaccessibleDirectories\" type=\"as\" access=\"read\"/>\n" \
|
||||
" <property name=\"MountFlags\" type=\"t\" access=\"read\"/>\n" \
|
||||
" <property name=\"PrivateTmp\" type=\"b\" access=\"read\"/>\n" \
|
||||
" <property name=\"SameProcessGroup\" type=\"b\" access=\"read\"/>\n"
|
||||
" <property name=\"SameProcessGroup\" type=\"b\" access=\"read\"/>\n" \
|
||||
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
|
||||
" <property name=\"KillSignal\" type=\"i\" access=\"read\"/>\n"
|
||||
|
||||
#define BUS_EXEC_COMMAND_INTERFACE(name) \
|
||||
" <property name=\"" name "\" type=\"a(sasttuii)\" access=\"read\"/>\n"
|
||||
@ -138,7 +140,9 @@
|
||||
{ interface, "InaccessibleDirectories", bus_property_append_strv, "as", (context).inaccessible_dirs }, \
|
||||
{ interface, "MountFlags", bus_property_append_ul, "t", &(context).mount_flags }, \
|
||||
{ interface, "PrivateTmp", bus_property_append_bool, "b", &(context).private_tmp }, \
|
||||
{ interface, "SameProcessGroup", bus_property_append_bool, "b", &(context).same_pgrp }
|
||||
{ interface, "SameProcessGroup", bus_property_append_bool, "b", &(context).same_pgrp }, \
|
||||
{ interface, "KillMode", bus_execute_append_kill_mode, "s", &(context).kill_mode }, \
|
||||
{ interface, "KillSignal", bus_property_append_int, "i", &(context).kill_signal }
|
||||
|
||||
#define BUS_EXEC_STATUS_PROPERTIES(interface, estatus, prefix) \
|
||||
{ interface, prefix "StartTimestamp", bus_property_append_usec, "t", &(estatus).start_timestamp.realtime }, \
|
||||
@ -162,5 +166,6 @@ int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const ch
|
||||
int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data);
|
||||
int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data);
|
||||
int bus_execute_append_command(Manager *m, DBusMessageIter *u, const char *property, void *data);
|
||||
int bus_execute_append_kill_mode(Manager *m, DBusMessageIter *i, const char *property, void *data);
|
||||
|
||||
#endif
|
||||
|
@ -36,7 +36,6 @@
|
||||
BUS_EXEC_COMMAND_INTERFACE("ExecUnmount") \
|
||||
BUS_EXEC_COMMAND_INTERFACE("ExecRemount") \
|
||||
BUS_EXEC_CONTEXT_INTERFACE \
|
||||
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
|
||||
" <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
|
||||
" <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
|
||||
" </interface>\n"
|
||||
@ -136,7 +135,6 @@ DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMess
|
||||
BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Mount", u->mount.exec_command+MOUNT_EXEC_UNMOUNT, "ExecUnmount"),
|
||||
BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Mount", u->mount.exec_command+MOUNT_EXEC_REMOUNT, "ExecRemount"),
|
||||
BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Mount", u->mount.exec_context),
|
||||
{ "org.freedesktop.systemd1.Mount", "KillMode", bus_unit_append_kill_mode, "s", &u->mount.kill_mode },
|
||||
{ "org.freedesktop.systemd1.Mount", "ControlPID", bus_property_append_pid, "u", &u->mount.control_pid },
|
||||
{ "org.freedesktop.systemd1.Mount", "DirectoryMode", bus_property_append_mode, "u", &u->mount.directory_mode },
|
||||
{ NULL, NULL, NULL, NULL, NULL }
|
||||
|
@ -43,7 +43,6 @@
|
||||
" <property name=\"PermissionsStartOnly\" type=\"b\" access=\"read\"/>\n" \
|
||||
" <property name=\"RootDirectoryStartOnly\" type=\"b\" access=\"read\"/>\n" \
|
||||
" <property name=\"ValidNoProcess\" type=\"b\" access=\"read\"/>\n" \
|
||||
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
|
||||
BUS_EXEC_STATUS_INTERFACE("ExecMain") \
|
||||
" <property name=\"MainPID\" type=\"u\" access=\"read\"/>\n" \
|
||||
" <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
|
||||
@ -88,7 +87,6 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio
|
||||
{ "org.freedesktop.systemd1.Service", "PermissionsStartOnly", bus_property_append_bool, "b", &u->service.permissions_start_only },
|
||||
{ "org.freedesktop.systemd1.Service", "RootDirectoryStartOnly", bus_property_append_bool, "b", &u->service.root_directory_start_only },
|
||||
{ "org.freedesktop.systemd1.Service", "ValidNoProcess", bus_property_append_bool, "b", &u->service.valid_no_process },
|
||||
{ "org.freedesktop.systemd1.Service", "KillMode", bus_unit_append_kill_mode, "s", &u->service.kill_mode },
|
||||
BUS_EXEC_STATUS_PROPERTIES("org.freedesktop.systemd1.Service", u->service.main_exec_status, "ExecMain"),
|
||||
{ "org.freedesktop.systemd1.Service", "MainPID", bus_property_append_pid, "u", &u->service.main_pid },
|
||||
{ "org.freedesktop.systemd1.Service", "ControlPID", bus_property_append_pid, "u", &u->service.control_pid },
|
||||
|
@ -35,7 +35,6 @@
|
||||
BUS_EXEC_COMMAND_INTERFACE("ExecStopPre") \
|
||||
BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \
|
||||
BUS_EXEC_CONTEXT_INTERFACE \
|
||||
" <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n" \
|
||||
" <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
|
||||
" <property name=\"BindToDevice\" type=\"s\" access=\"read\"/>\n" \
|
||||
" <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
|
||||
@ -79,7 +78,6 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMes
|
||||
BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", u->service.exec_command[SOCKET_EXEC_STOP_PRE], "ExecStopPre"),
|
||||
BUS_EXEC_COMMAND_PROPERTY("org.freedesktop.systemd1.Socket", u->service.exec_command[SOCKET_EXEC_STOP_POST], "ExecStopPost"),
|
||||
BUS_EXEC_CONTEXT_PROPERTIES("org.freedesktop.systemd1.Socket", u->socket.exec_context),
|
||||
{ "org.freedesktop.systemd1.Socket", "KillMode", bus_unit_append_kill_mode, "s", &u->socket.kill_mode },
|
||||
{ "org.freedesktop.systemd1.Socket", "ControlPID", bus_property_append_pid, "u", &u->socket.control_pid },
|
||||
{ "org.freedesktop.systemd1.Socket", "BindToDevice", bus_property_append_string, "s", u->socket.bind_to_device },
|
||||
{ "org.freedesktop.systemd1.Socket", "DirectoryMode", bus_property_append_mode, "u", &u->socket.directory_mode },
|
||||
|
@ -254,8 +254,6 @@ int bus_unit_append_cgroups(Manager *m, DBusMessageIter *i, const char *property
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_unit_append_kill_mode, kill_mode, KillMode);
|
||||
|
||||
static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *connection, DBusMessage *message) {
|
||||
DBusMessage *reply = NULL;
|
||||
Manager *m = u->meta.manager;
|
||||
|
@ -126,7 +126,6 @@ int bus_unit_append_can_reload(Manager *m, DBusMessageIter *i, const char *prope
|
||||
int bus_unit_append_job(Manager *m, DBusMessageIter *i, const char *property, void *data);
|
||||
int bus_unit_append_default_cgroup(Manager *m, DBusMessageIter *i, const char *property, void *data);
|
||||
int bus_unit_append_cgroups(Manager *m, DBusMessageIter *i, const char *property, void *data);
|
||||
int bus_unit_append_kill_mode(Manager *m, DBusMessageIter *i, const char *property, void *data);
|
||||
|
||||
void bus_unit_send_change_signal(Unit *u);
|
||||
void bus_unit_send_removed_signal(Unit *u);
|
||||
|
@ -1308,6 +1308,7 @@ void exec_context_init(ExecContext *c) {
|
||||
c->syslog_priority = LOG_DAEMON|LOG_INFO;
|
||||
c->syslog_level_prefix = true;
|
||||
c->mount_flags = MS_SHARED;
|
||||
c->kill_signal = SIGTERM;
|
||||
}
|
||||
|
||||
void exec_context_done(ExecContext *c) {
|
||||
@ -1571,6 +1572,12 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
|
||||
strv_fprintf(f, c->inaccessible_dirs);
|
||||
fputs("\n", f);
|
||||
}
|
||||
|
||||
fprintf(f,
|
||||
"%sKillMode: %s\n"
|
||||
"%sKillSignal: SIG%s\n",
|
||||
prefix, kill_mode_to_string(c->kill_mode),
|
||||
prefix, signal_to_string(c->kill_signal));
|
||||
}
|
||||
|
||||
void exec_status_start(ExecStatus *s, pid_t pid) {
|
||||
|
@ -45,6 +45,15 @@ struct CGroupBonding;
|
||||
#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT
|
||||
#define SIGNALS_IGNORE SIGKILL,SIGPIPE
|
||||
|
||||
typedef enum KillMode {
|
||||
KILL_CONTROL_GROUP = 0,
|
||||
KILL_PROCESS_GROUP,
|
||||
KILL_PROCESS,
|
||||
KILL_NONE,
|
||||
_KILL_MODE_MAX,
|
||||
_KILL_MODE_INVALID = -1
|
||||
} KillMode;
|
||||
|
||||
typedef enum ExecInput {
|
||||
EXEC_INPUT_NULL,
|
||||
EXEC_INPUT_TTY,
|
||||
@ -143,6 +152,10 @@ struct ExecContext {
|
||||
* that the autofs logic detects that it belongs to us and we
|
||||
* don't enter a trigger loop. */
|
||||
bool same_pgrp;
|
||||
|
||||
/* Not relevant for spawning processes, just for killing */
|
||||
KillMode kill_mode;
|
||||
int kill_signal;
|
||||
};
|
||||
|
||||
typedef enum ExitStatus {
|
||||
|
@ -969,6 +969,36 @@ static int config_parse_sysv_priority(
|
||||
|
||||
static DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
|
||||
|
||||
static int config_parse_kill_signal(
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
const char *lvalue,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
int *sig = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(sig);
|
||||
|
||||
if ((r = signal_from_string(rvalue)) <= 0)
|
||||
if (startswith(rvalue, "SIG"))
|
||||
r = signal_from_string(rvalue+3);
|
||||
|
||||
if (r <= 0) {
|
||||
log_error("[%s:%u] Failed to parse kill signal: %s", filename, line, rvalue);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*sig = r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int config_parse_mount_flags(
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
@ -1395,6 +1425,7 @@ static void dump_items(FILE *f, const ConfigItem *items) {
|
||||
{ config_parse_service_restart, "SERVICERESTART" },
|
||||
{ config_parse_sysv_priority, "SYSVPRIORITY" },
|
||||
{ config_parse_kill_mode, "KILLMODE" },
|
||||
{ config_parse_kill_signal, "SIGNAL" },
|
||||
{ config_parse_listen, "SOCKET [...]" },
|
||||
{ config_parse_socket_bind, "SOCKETBIND" },
|
||||
{ config_parse_bindtodevice, "NETWORKINTERFACE" },
|
||||
@ -1504,7 +1535,9 @@ static int load_from_path(Unit *u, const char *path) {
|
||||
{ "PrivateTmp", config_parse_bool, &(context).private_tmp, section }, \
|
||||
{ "MountFlags", config_parse_mount_flags, &(context), section }, \
|
||||
{ "TCPWrapName", config_parse_string_printf, &(context).tcpwrap_name, section }, \
|
||||
{ "PAMName", config_parse_string_printf, &(context).pam_name, section }
|
||||
{ "PAMName", config_parse_string_printf, &(context).pam_name, section }, \
|
||||
{ "KillMode", config_parse_kill_mode, &(context).kill_mode, section }, \
|
||||
{ "KillSignal", config_parse_kill_signal, &(context).kill_signal, section }
|
||||
|
||||
const ConfigItem items[] = {
|
||||
{ "Names", config_parse_names, u, "Unit" },
|
||||
@ -1537,7 +1570,6 @@ static int load_from_path(Unit *u, const char *path) {
|
||||
{ "RootDirectoryStartOnly", config_parse_bool, &u->service.root_directory_start_only, "Service" },
|
||||
{ "ValidNoProcess", config_parse_bool, &u->service.valid_no_process, "Service" },
|
||||
{ "SysVStartPriority", config_parse_sysv_priority, &u->service.sysv_start_priority, "Service" },
|
||||
{ "KillMode", config_parse_kill_mode, &u->service.kill_mode, "Service" },
|
||||
{ "NonBlocking", config_parse_bool, &u->service.exec_context.non_blocking, "Service" },
|
||||
{ "BusName", config_parse_string_printf, &u->service.bus_name, "Service" },
|
||||
{ "NotifyAccess", config_parse_notify_access, &u->service.notify_access, "Service" },
|
||||
@ -1557,7 +1589,6 @@ static int load_from_path(Unit *u, const char *path) {
|
||||
{ "TimeoutSec", config_parse_usec, &u->socket.timeout_usec, "Socket" },
|
||||
{ "DirectoryMode", config_parse_mode, &u->socket.directory_mode, "Socket" },
|
||||
{ "SocketMode", config_parse_mode, &u->socket.socket_mode, "Socket" },
|
||||
{ "KillMode", config_parse_kill_mode, &u->socket.kill_mode, "Socket" },
|
||||
{ "Accept", config_parse_bool, &u->socket.accept, "Socket" },
|
||||
{ "MaxConnections", config_parse_unsigned, &u->socket.max_connections, "Socket" },
|
||||
{ "KeepAlive", config_parse_bool, &u->socket.keep_alive, "Socket" },
|
||||
@ -1576,7 +1607,6 @@ static int load_from_path(Unit *u, const char *path) {
|
||||
{ "Options", config_parse_string, &u->mount.parameters_fragment.options, "Mount" },
|
||||
{ "Type", config_parse_string, &u->mount.parameters_fragment.fstype, "Mount" },
|
||||
{ "TimeoutSec", config_parse_usec, &u->mount.timeout_usec, "Mount" },
|
||||
{ "KillMode", config_parse_kill_mode, &u->mount.kill_mode, "Mount" },
|
||||
{ "DirectoryMode", config_parse_mode, &u->mount.directory_mode, "Mount" },
|
||||
EXEC_CONTEXT_CONFIG_ITEMS(u->mount.exec_context, "Mount"),
|
||||
|
||||
|
15
src/mount.c
15
src/mount.c
@ -301,7 +301,7 @@ static int mount_verify(Mount *m) {
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
if (m->exec_context.pam_name && m->kill_mode != KILL_CONTROL_GROUP) {
|
||||
if (m->exec_context.pam_name && m->exec_context.kill_mode != KILL_CONTROL_GROUP) {
|
||||
log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", m->meta.id);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -501,7 +501,6 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
"%sFrom /etc/fstab: %s\n"
|
||||
"%sFrom /proc/self/mountinfo: %s\n"
|
||||
"%sFrom fragment: %s\n"
|
||||
"%sKillMode: %s\n"
|
||||
"%sDirectoryMode: %04o\n",
|
||||
prefix, mount_state_to_string(m->state),
|
||||
prefix, m->where,
|
||||
@ -511,7 +510,6 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
prefix, yes_no(m->from_etc_fstab),
|
||||
prefix, yes_no(m->from_proc_self_mountinfo),
|
||||
prefix, yes_no(m->from_fragment),
|
||||
prefix, kill_mode_to_string(m->kill_mode),
|
||||
prefix, m->directory_mode);
|
||||
|
||||
if (m->control_pid > 0)
|
||||
@ -587,12 +585,12 @@ static void mount_enter_signal(Mount *m, MountState state, bool success) {
|
||||
if (!success)
|
||||
m->failure = true;
|
||||
|
||||
if (m->kill_mode != KILL_NONE) {
|
||||
if (m->exec_context.kill_mode != KILL_NONE) {
|
||||
int sig = (state == MOUNT_MOUNTING_SIGTERM ||
|
||||
state == MOUNT_UNMOUNTING_SIGTERM ||
|
||||
state == MOUNT_REMOUNTING_SIGTERM) ? SIGTERM : SIGKILL;
|
||||
state == MOUNT_REMOUNTING_SIGTERM) ? m->exec_context.kill_signal : SIGKILL;
|
||||
|
||||
if (m->kill_mode == KILL_CONTROL_GROUP) {
|
||||
if (m->exec_context.kill_mode == KILL_CONTROL_GROUP) {
|
||||
|
||||
if ((r = cgroup_bonding_kill_list(m->meta.cgroup_bondings, sig)) < 0) {
|
||||
if (r != -EAGAIN && r != -ESRCH)
|
||||
@ -602,7 +600,10 @@ static void mount_enter_signal(Mount *m, MountState state, bool success) {
|
||||
}
|
||||
|
||||
if (!sent && m->control_pid > 0)
|
||||
if (kill(m->kill_mode == KILL_PROCESS ? m->control_pid : -m->control_pid, sig) < 0 && errno != ESRCH) {
|
||||
if (kill(m->exec_context.kill_mode == KILL_PROCESS ?
|
||||
m->control_pid :
|
||||
-m->control_pid, sig) < 0 && errno != ESRCH) {
|
||||
|
||||
r = -errno;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -88,8 +88,6 @@ struct Mount {
|
||||
|
||||
MountState state, deserialized_state;
|
||||
|
||||
KillMode kill_mode;
|
||||
|
||||
ExecCommand* control_command;
|
||||
MountExecCommand control_command_id;
|
||||
pid_t control_pid;
|
||||
|
@ -684,9 +684,9 @@ static int service_load_sysv_path(Service *s, const char *path) {
|
||||
/* Special setting for all SysV services */
|
||||
s->type = SERVICE_FORKING;
|
||||
s->valid_no_process = true;
|
||||
s->kill_mode = KILL_PROCESS_GROUP;
|
||||
s->restart = SERVICE_ONCE;
|
||||
s->exec_context.std_output = EXEC_OUTPUT_TTY;
|
||||
s->exec_context.kill_mode = KILL_PROCESS_GROUP;
|
||||
|
||||
u->meta.load_state = UNIT_LOADED;
|
||||
r = 0;
|
||||
@ -821,7 +821,7 @@ static int service_verify(Service *s) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (s->exec_context.pam_name && s->kill_mode != KILL_CONTROL_GROUP) {
|
||||
if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) {
|
||||
log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", s->meta.id);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -928,14 +928,12 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
"%sPermissionsStartOnly: %s\n"
|
||||
"%sRootDirectoryStartOnly: %s\n"
|
||||
"%sValidNoProcess: %s\n"
|
||||
"%sKillMode: %s\n"
|
||||
"%sType: %s\n"
|
||||
"%sNotifyAccess: %s\n",
|
||||
prefix, service_state_to_string(s->state),
|
||||
prefix, yes_no(s->permissions_start_only),
|
||||
prefix, yes_no(s->root_directory_start_only),
|
||||
prefix, yes_no(s->valid_no_process),
|
||||
prefix, kill_mode_to_string(s->kill_mode),
|
||||
prefix, service_type_to_string(s->type),
|
||||
prefix, notify_access_to_string(s->notify_access));
|
||||
|
||||
@ -1533,10 +1531,10 @@ static void service_enter_signal(Service *s, ServiceState state, bool success) {
|
||||
if (!success)
|
||||
s->failure = true;
|
||||
|
||||
if (s->kill_mode != KILL_NONE) {
|
||||
int sig = (state == SERVICE_STOP_SIGTERM || state == SERVICE_FINAL_SIGTERM) ? SIGTERM : SIGKILL;
|
||||
if (s->exec_context.kill_mode != KILL_NONE) {
|
||||
int sig = (state == SERVICE_STOP_SIGTERM || state == SERVICE_FINAL_SIGTERM) ? s->exec_context.kill_signal : SIGKILL;
|
||||
|
||||
if (s->kill_mode == KILL_CONTROL_GROUP) {
|
||||
if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) {
|
||||
|
||||
if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig)) < 0) {
|
||||
if (r != -EAGAIN && r != -ESRCH)
|
||||
@ -1549,14 +1547,14 @@ static void service_enter_signal(Service *s, ServiceState state, bool success) {
|
||||
r = 0;
|
||||
|
||||
if (s->main_pid > 0) {
|
||||
if (kill(s->kill_mode == KILL_PROCESS ? s->main_pid : -s->main_pid, sig) < 0 && errno != ESRCH)
|
||||
if (kill(s->exec_context.kill_mode == KILL_PROCESS ? s->main_pid : -s->main_pid, sig) < 0 && errno != ESRCH)
|
||||
r = -errno;
|
||||
else
|
||||
sent = true;
|
||||
}
|
||||
|
||||
if (s->control_pid > 0) {
|
||||
if (kill(s->kill_mode == KILL_PROCESS ? s->control_pid : -s->control_pid, sig) < 0 && errno != ESRCH)
|
||||
if (kill(s->exec_context.kill_mode == KILL_PROCESS ? s->control_pid : -s->control_pid, sig) < 0 && errno != ESRCH)
|
||||
r = -errno;
|
||||
else
|
||||
sent = true;
|
||||
|
@ -107,8 +107,6 @@ struct Service {
|
||||
|
||||
ServiceState state, deserialized_state;
|
||||
|
||||
KillMode kill_mode;
|
||||
|
||||
ExecStatus main_exec_status;
|
||||
|
||||
ExecCommand *control_command;
|
||||
|
12
src/socket.c
12
src/socket.c
@ -165,7 +165,7 @@ static int socket_verify(Socket *s) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (s->exec_context.pam_name && s->kill_mode != KILL_CONTROL_GROUP) {
|
||||
if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) {
|
||||
log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", s->meta.id);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -326,7 +326,6 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
"%sSocket State: %s\n"
|
||||
"%sBindIPv6Only: %s\n"
|
||||
"%sBacklog: %u\n"
|
||||
"%sKillMode: %s\n"
|
||||
"%sSocketMode: %04o\n"
|
||||
"%sDirectoryMode: %04o\n"
|
||||
"%sKeepAlive: %s\n"
|
||||
@ -334,7 +333,6 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
prefix, socket_state_to_string(s->state),
|
||||
prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
|
||||
prefix, s->backlog,
|
||||
prefix, kill_mode_to_string(s->kill_mode),
|
||||
prefix, s->socket_mode,
|
||||
prefix, s->directory_mode,
|
||||
prefix, yes_no(s->keep_alive),
|
||||
@ -891,10 +889,10 @@ static void socket_enter_signal(Socket *s, SocketState state, bool success) {
|
||||
if (!success)
|
||||
s->failure = true;
|
||||
|
||||
if (s->kill_mode != KILL_NONE) {
|
||||
int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? SIGTERM : SIGKILL;
|
||||
if (s->exec_context.kill_mode != KILL_NONE) {
|
||||
int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? s->exec_context.kill_signal : SIGKILL;
|
||||
|
||||
if (s->kill_mode == KILL_CONTROL_GROUP) {
|
||||
if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) {
|
||||
|
||||
if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig)) < 0) {
|
||||
if (r != -EAGAIN && r != -ESRCH)
|
||||
@ -904,7 +902,7 @@ static void socket_enter_signal(Socket *s, SocketState state, bool success) {
|
||||
}
|
||||
|
||||
if (!sent && s->control_pid > 0)
|
||||
if (kill(s->kill_mode == KILL_PROCESS ? s->control_pid : -s->control_pid, sig) < 0 && errno != ESRCH) {
|
||||
if (kill(s->exec_context.kill_mode == KILL_PROCESS ? s->control_pid : -s->control_pid, sig) < 0 && errno != ESRCH) {
|
||||
r = -errno;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -88,8 +88,6 @@ struct Socket {
|
||||
|
||||
SocketState state, deserialized_state;
|
||||
|
||||
KillMode kill_mode;
|
||||
|
||||
ExecCommand* control_command;
|
||||
SocketExecCommand control_command_id;
|
||||
pid_t control_pid;
|
||||
|
@ -43,15 +43,6 @@ typedef enum UnitDependency UnitDependency;
|
||||
#define DEFAULT_TIMEOUT_USEC (60*USEC_PER_SEC)
|
||||
#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC)
|
||||
|
||||
typedef enum KillMode {
|
||||
KILL_CONTROL_GROUP = 0,
|
||||
KILL_PROCESS_GROUP,
|
||||
KILL_PROCESS,
|
||||
KILL_NONE,
|
||||
_KILL_MODE_MAX,
|
||||
_KILL_MODE_INVALID = -1
|
||||
} KillMode;
|
||||
|
||||
enum UnitType {
|
||||
UNIT_SERVICE = 0,
|
||||
UNIT_SOCKET,
|
||||
|
36
src/util.c
36
src/util.c
@ -2941,3 +2941,39 @@ static const char* const ip_tos_table[] = {
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(ip_tos, int);
|
||||
|
||||
static const char *const signal_table[] = {
|
||||
[SIGHUP] = "HUP",
|
||||
[SIGINT] = "INT",
|
||||
[SIGQUIT] = "QUIT",
|
||||
[SIGILL] = "ILL",
|
||||
[SIGTRAP] = "TRAP",
|
||||
[SIGABRT] = "ABRT",
|
||||
[SIGBUS] = "BUS",
|
||||
[SIGFPE] = "FPE",
|
||||
[SIGKILL] = "KILL",
|
||||
[SIGUSR1] = "USR1",
|
||||
[SIGSEGV] = "SEGV",
|
||||
[SIGUSR2] = "USR2",
|
||||
[SIGPIPE] = "PIPE",
|
||||
[SIGALRM] = "ALRM",
|
||||
[SIGTERM] = "TERM",
|
||||
[SIGSTKFLT] = "STKFLT",
|
||||
[SIGCHLD] = "CHLD",
|
||||
[SIGCONT] = "CONT",
|
||||
[SIGSTOP] = "STOP",
|
||||
[SIGTSTP] = "TSTP",
|
||||
[SIGTTIN] = "TTIN",
|
||||
[SIGTTOU] = "TTOU",
|
||||
[SIGURG] = "URG",
|
||||
[SIGXCPU] = "XCPU",
|
||||
[SIGXFSZ] = "XFSZ",
|
||||
[SIGVTALRM] = "VTALRM",
|
||||
[SIGPROF] = "PROF",
|
||||
[SIGWINCH] = "WINCH",
|
||||
[SIGIO] = "IO",
|
||||
[SIGPWR] = "PWR",
|
||||
[SIGSYS] = "SYS"
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(signal, int);
|
||||
|
@ -353,4 +353,7 @@ int rlimit_from_string(const char *s);
|
||||
const char *ip_tos_to_string(int i);
|
||||
int ip_tos_from_string(const char *s);
|
||||
|
||||
const char *signal_to_string(int i);
|
||||
int signal_from_string(const char *s);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user