diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-04-13 23:24:47 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-04-13 23:29:59 +0200 |
commit | ecedd90fcdf647f9a7b56b4934b65e30b2979b04 (patch) | |
tree | 6e8bc8e509801a7c3801c1e77244df6dec72ac1c | |
parent | 3b6d9a7c50bd7217a0ca80d39fd30decbb0c935a (diff) |
service: place control command in subcgroup control/
Previously, we were brutally and onconditionally killing all processes
in a service's cgroup before starting the service anew, in order to
ensure that StartPre lines cannot be misused to spawn long-running
processes.
On logind-less systems this has the effect that restarting sshd
necessarily calls all active ssh sessions, which is usually not
desirable.
With this patch control processes for a service are placed in a
sub-cgroup called "control/". When starting a service anew we simply
kill this cgroup, but not the main cgroup, in order to avoid killing any
long-running non-control processes from previous runs.
https://bugzilla.redhat.com/show_bug.cgi?id=805942
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | src/core/cgroup.c | 52 | ||||
-rw-r--r-- | src/core/cgroup.h | 8 | ||||
-rw-r--r-- | src/core/execute.c | 5 | ||||
-rw-r--r-- | src/core/execute.h | 1 | ||||
-rw-r--r-- | src/core/mount.c | 7 | ||||
-rw-r--r-- | src/core/service.c | 175 | ||||
-rw-r--r-- | src/core/socket.c | 7 | ||||
-rw-r--r-- | src/core/swap.c | 7 |
9 files changed, 163 insertions, 101 deletions
@@ -19,8 +19,6 @@ Features: | |||
19 | 19 | ||
20 | * cg_create_and_attach() should fail for non-available controllers | 20 | * cg_create_and_attach() should fail for non-available controllers |
21 | 21 | ||
22 | * place start-pre/start-post/... scripts in sub cgrouprs | ||
23 | |||
24 | * make gtk-doc optional (like kmod?) | 22 | * make gtk-doc optional (like kmod?) |
25 | 23 | ||
26 | * udev: find a way to tell udev to not cancel firmware requests in initramfs | 24 | * udev: find a way to tell udev to not cancel firmware requests in initramfs |
diff --git a/src/core/cgroup.c b/src/core/cgroup.c index ef9b02f46..7a5f673a7 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c | |||
@@ -108,26 +108,43 @@ void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root) { | |||
108 | cgroup_bonding_trim(b, delete_root); | 108 | cgroup_bonding_trim(b, delete_root); |
109 | } | 109 | } |
110 | 110 | ||
111 | int cgroup_bonding_install(CGroupBonding *b, pid_t pid) { | 111 | |
112 | int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *cgroup_suffix) { | ||
113 | char *p = NULL; | ||
114 | const char *path; | ||
112 | int r; | 115 | int r; |
113 | 116 | ||
114 | assert(b); | 117 | assert(b); |
115 | assert(pid >= 0); | 118 | assert(pid >= 0); |
116 | 119 | ||
117 | if ((r = cg_create_and_attach(b->controller, b->path, pid)) < 0) | 120 | if (cgroup_suffix) { |
121 | p = join(b->path, "/", cgroup_suffix, NULL); | ||
122 | if (!p) | ||
123 | return -ENOMEM; | ||
124 | |||
125 | path = p; | ||
126 | } else | ||
127 | path = b->path; | ||
128 | |||
129 | r = cg_create_and_attach(b->controller, path, pid); | ||
130 | free(p); | ||
131 | |||
132 | if (r < 0) | ||
118 | return r; | 133 | return r; |
119 | 134 | ||
120 | b->realized = true; | 135 | b->realized = true; |
121 | return 0; | 136 | return 0; |
122 | } | 137 | } |
123 | 138 | ||
124 | int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid) { | 139 | int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *cgroup_suffix) { |
125 | CGroupBonding *b; | 140 | CGroupBonding *b; |
126 | int r; | 141 | int r; |
127 | 142 | ||
128 | LIST_FOREACH(by_unit, b, first) | 143 | LIST_FOREACH(by_unit, b, first) { |
129 | if ((r = cgroup_bonding_install(b, pid)) < 0 && b->essential) | 144 | r = cgroup_bonding_install(b, pid, cgroup_suffix); |
145 | if (r < 0 && b->essential) | ||
130 | return r; | 146 | return r; |
147 | } | ||
131 | 148 | ||
132 | return 0; | 149 | return 0; |
133 | } | 150 | } |
@@ -176,7 +193,11 @@ int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t | |||
176 | return 0; | 193 | return 0; |
177 | } | 194 | } |
178 | 195 | ||
179 | int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) { | 196 | int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s, const char *cgroup_suffix) { |
197 | char *p = NULL; | ||
198 | const char *path; | ||
199 | int r; | ||
200 | |||
180 | assert(b); | 201 | assert(b); |
181 | assert(sig >= 0); | 202 | assert(sig >= 0); |
182 | 203 | ||
@@ -184,10 +205,22 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) { | |||
184 | if (!b->ours) | 205 | if (!b->ours) |
185 | return 0; | 206 | return 0; |
186 | 207 | ||
187 | return cg_kill_recursive(b->controller, b->path, sig, sigcont, true, false, s); | 208 | if (cgroup_suffix) { |
209 | p = join(b->path, "/", cgroup_suffix, NULL); | ||
210 | if (!p) | ||
211 | return -ENOMEM; | ||
212 | |||
213 | path = p; | ||
214 | } else | ||
215 | path = b->path; | ||
216 | |||
217 | r = cg_kill_recursive(b->controller, path, sig, sigcont, true, false, s); | ||
218 | free(p); | ||
219 | |||
220 | return r; | ||
188 | } | 221 | } |
189 | 222 | ||
190 | int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s) { | 223 | int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s, const char *cgroup_suffix) { |
191 | CGroupBonding *b; | 224 | CGroupBonding *b; |
192 | Set *allocated_set = NULL; | 225 | Set *allocated_set = NULL; |
193 | int ret = -EAGAIN, r; | 226 | int ret = -EAGAIN, r; |
@@ -200,7 +233,8 @@ int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s | |||
200 | return -ENOMEM; | 233 | return -ENOMEM; |
201 | 234 | ||
202 | LIST_FOREACH(by_unit, b, first) { | 235 | LIST_FOREACH(by_unit, b, first) { |
203 | if ((r = cgroup_bonding_kill(b, sig, sigcont, s)) < 0) { | 236 | r = cgroup_bonding_kill(b, sig, sigcont, s, cgroup_suffix); |
237 | if (r < 0) { | ||
204 | if (r == -EAGAIN || r == -ESRCH) | 238 | if (r == -EAGAIN || r == -ESRCH) |
205 | continue; | 239 | continue; |
206 | 240 | ||
diff --git a/src/core/cgroup.h b/src/core/cgroup.h index de248fbca..95f09e001 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h | |||
@@ -56,8 +56,8 @@ int cgroup_bonding_realize_list(CGroupBonding *first); | |||
56 | void cgroup_bonding_free(CGroupBonding *b, bool trim); | 56 | void cgroup_bonding_free(CGroupBonding *b, bool trim); |
57 | void cgroup_bonding_free_list(CGroupBonding *first, bool trim); | 57 | void cgroup_bonding_free_list(CGroupBonding *first, bool trim); |
58 | 58 | ||
59 | int cgroup_bonding_install(CGroupBonding *b, pid_t pid); | 59 | int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *suffix); |
60 | int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid); | 60 | int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *suffix); |
61 | 61 | ||
62 | int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); | 62 | int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); |
63 | int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); | 63 | int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); |
@@ -65,8 +65,8 @@ int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t ui | |||
65 | int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); | 65 | int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); |
66 | int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); | 66 | int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); |
67 | 67 | ||
68 | int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s); | 68 | int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s, const char *suffix); |
69 | int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s); | 69 | int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s, const char *suffix); |
70 | 70 | ||
71 | void cgroup_bonding_trim(CGroupBonding *first, bool delete_root); | 71 | void cgroup_bonding_trim(CGroupBonding *first, bool delete_root); |
72 | void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root); | 72 | void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root); |
diff --git a/src/core/execute.c b/src/core/execute.c index 271c57f56..c59f7e2da 100644 --- a/src/core/execute.c +++ b/src/core/execute.c | |||
@@ -962,6 +962,7 @@ int exec_spawn(ExecCommand *command, | |||
962 | bool confirm_spawn, | 962 | bool confirm_spawn, |
963 | CGroupBonding *cgroup_bondings, | 963 | CGroupBonding *cgroup_bondings, |
964 | CGroupAttribute *cgroup_attributes, | 964 | CGroupAttribute *cgroup_attributes, |
965 | const char *cgroup_suffix, | ||
965 | pid_t *ret) { | 966 | pid_t *ret) { |
966 | 967 | ||
967 | pid_t pid; | 968 | pid_t pid; |
@@ -1154,7 +1155,7 @@ int exec_spawn(ExecCommand *command, | |||
1154 | } | 1155 | } |
1155 | 1156 | ||
1156 | if (cgroup_bondings) { | 1157 | if (cgroup_bondings) { |
1157 | err = cgroup_bonding_install_list(cgroup_bondings, 0); | 1158 | err = cgroup_bonding_install_list(cgroup_bondings, 0, cgroup_suffix); |
1158 | if (err < 0) { | 1159 | if (err < 0) { |
1159 | r = EXIT_CGROUP; | 1160 | r = EXIT_CGROUP; |
1160 | goto fail_child; | 1161 | goto fail_child; |
@@ -1505,7 +1506,7 @@ int exec_spawn(ExecCommand *command, | |||
1505 | * sure that when we kill the cgroup the process will be | 1506 | * sure that when we kill the cgroup the process will be |
1506 | * killed too). */ | 1507 | * killed too). */ |
1507 | if (cgroup_bondings) | 1508 | if (cgroup_bondings) |
1508 | cgroup_bonding_install_list(cgroup_bondings, pid); | 1509 | cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix); |
1509 | 1510 | ||
1510 | log_debug("Forked %s as %lu", command->path, (unsigned long) pid); | 1511 | log_debug("Forked %s as %lu", command->path, (unsigned long) pid); |
1511 | 1512 | ||
diff --git a/src/core/execute.h b/src/core/execute.h index fc4c71e53..428bb7c9b 100644 --- a/src/core/execute.h +++ b/src/core/execute.h | |||
@@ -192,6 +192,7 @@ int exec_spawn(ExecCommand *command, | |||
192 | bool confirm_spawn, | 192 | bool confirm_spawn, |
193 | struct CGroupBonding *cgroup_bondings, | 193 | struct CGroupBonding *cgroup_bondings, |
194 | struct CGroupAttribute *cgroup_attributes, | 194 | struct CGroupAttribute *cgroup_attributes, |
195 | const char *cgroup_suffix, | ||
195 | pid_t *ret); | 196 | pid_t *ret); |
196 | 197 | ||
197 | void exec_command_done(ExecCommand *c); | 198 | void exec_command_done(ExecCommand *c); |
diff --git a/src/core/mount.c b/src/core/mount.c index 6c768a3d0..760ffcdbf 100644 --- a/src/core/mount.c +++ b/src/core/mount.c | |||
@@ -805,6 +805,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { | |||
805 | UNIT(m)->manager->confirm_spawn, | 805 | UNIT(m)->manager->confirm_spawn, |
806 | UNIT(m)->cgroup_bondings, | 806 | UNIT(m)->cgroup_bondings, |
807 | UNIT(m)->cgroup_attributes, | 807 | UNIT(m)->cgroup_attributes, |
808 | NULL, | ||
808 | &pid)) < 0) | 809 | &pid)) < 0) |
809 | goto fail; | 810 | goto fail; |
810 | 811 | ||
@@ -875,7 +876,8 @@ static void mount_enter_signal(Mount *m, MountState state, MountResult f) { | |||
875 | if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0) | 876 | if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0) |
876 | goto fail; | 877 | goto fail; |
877 | 878 | ||
878 | if ((r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, pid_set)) < 0) { | 879 | r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, pid_set, NULL); |
880 | if (r < 0) { | ||
879 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) | 881 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) |
880 | log_warning("Failed to kill control group: %s", strerror(-r)); | 882 | log_warning("Failed to kill control group: %s", strerror(-r)); |
881 | } else if (r > 0) | 883 | } else if (r > 0) |
@@ -1833,7 +1835,8 @@ static int mount_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError | |||
1833 | goto finish; | 1835 | goto finish; |
1834 | } | 1836 | } |
1835 | 1837 | ||
1836 | if ((q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, pid_set)) < 0) | 1838 | q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, pid_set, NULL); |
1839 | if (q < 0) | ||
1837 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) | 1840 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) |
1838 | r = q; | 1841 | r = q; |
1839 | } | 1842 | } |
diff --git a/src/core/service.c b/src/core/service.c index 1c04ed338..59dd71294 100644 --- a/src/core/service.c +++ b/src/core/service.c | |||
@@ -1686,6 +1686,7 @@ static int service_spawn( | |||
1686 | bool apply_chroot, | 1686 | bool apply_chroot, |
1687 | bool apply_tty_stdin, | 1687 | bool apply_tty_stdin, |
1688 | bool set_notify_socket, | 1688 | bool set_notify_socket, |
1689 | bool is_control, | ||
1689 | pid_t *_pid) { | 1690 | pid_t *_pid) { |
1690 | 1691 | ||
1691 | pid_t pid; | 1692 | pid_t pid; |
@@ -1767,6 +1768,7 @@ static int service_spawn( | |||
1767 | UNIT(s)->manager->confirm_spawn, | 1768 | UNIT(s)->manager->confirm_spawn, |
1768 | UNIT(s)->cgroup_bondings, | 1769 | UNIT(s)->cgroup_bondings, |
1769 | UNIT(s)->cgroup_attributes, | 1770 | UNIT(s)->cgroup_attributes, |
1771 | is_control ? "control" : NULL, | ||
1770 | &pid); | 1772 | &pid); |
1771 | 1773 | ||
1772 | if (r < 0) | 1774 | if (r < 0) |
@@ -1886,15 +1888,17 @@ static void service_enter_stop_post(Service *s, ServiceResult f) { | |||
1886 | if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP_POST])) { | 1888 | if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP_POST])) { |
1887 | s->control_command_id = SERVICE_EXEC_STOP_POST; | 1889 | s->control_command_id = SERVICE_EXEC_STOP_POST; |
1888 | 1890 | ||
1889 | if ((r = service_spawn(s, | 1891 | r = service_spawn(s, |
1890 | s->control_command, | 1892 | s->control_command, |
1891 | true, | 1893 | true, |
1892 | false, | 1894 | false, |
1893 | !s->permissions_start_only, | 1895 | !s->permissions_start_only, |
1894 | !s->root_directory_start_only, | 1896 | !s->root_directory_start_only, |
1895 | true, | 1897 | true, |
1896 | false, | 1898 | false, |
1897 | &s->control_pid)) < 0) | 1899 | true, |
1900 | &s->control_pid); | ||
1901 | if (r < 0) | ||
1898 | goto fail; | 1902 | goto fail; |
1899 | 1903 | ||
1900 | 1904 | ||
@@ -1952,7 +1956,8 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f | |||
1952 | if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) | 1956 | if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) |
1953 | goto fail; | 1957 | goto fail; |
1954 | 1958 | ||
1955 | if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) { | 1959 | r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set, NULL); |
1960 | if (r < 0) { | ||
1956 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) | 1961 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) |
1957 | log_warning("Failed to kill control group: %s", strerror(-r)); | 1962 | log_warning("Failed to kill control group: %s", strerror(-r)); |
1958 | } else if (r > 0) | 1963 | } else if (r > 0) |
@@ -2001,15 +2006,17 @@ static void service_enter_stop(Service *s, ServiceResult f) { | |||
2001 | if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP])) { | 2006 | if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP])) { |
2002 | s->control_command_id = SERVICE_EXEC_STOP; | 2007 | s->control_command_id = SERVICE_EXEC_STOP; |
2003 | 2008 | ||
2004 | if ((r = service_spawn(s, | 2009 | r = service_spawn(s, |
2005 | s->control_command, | 2010 | s->control_command, |
2006 | true, | 2011 | true, |
2007 | false, | 2012 | false, |
2008 | !s->permissions_start_only, | 2013 | !s->permissions_start_only, |
2009 | !s->root_directory_start_only, | 2014 | !s->root_directory_start_only, |
2010 | false, | 2015 | false, |
2011 | false, | 2016 | false, |
2012 | &s->control_pid)) < 0) | 2017 | true, |
2018 | &s->control_pid); | ||
2019 | if (r < 0) | ||
2013 | goto fail; | 2020 | goto fail; |
2014 | 2021 | ||
2015 | service_set_state(s, SERVICE_STOP); | 2022 | service_set_state(s, SERVICE_STOP); |
@@ -2054,15 +2061,17 @@ static void service_enter_start_post(Service *s) { | |||
2054 | if ((s->control_command = s->exec_command[SERVICE_EXEC_START_POST])) { | 2061 | if ((s->control_command = s->exec_command[SERVICE_EXEC_START_POST])) { |
2055 | s->control_command_id = SERVICE_EXEC_START_POST; | 2062 | s->control_command_id = SERVICE_EXEC_START_POST; |
2056 | 2063 | ||
2057 | if ((r = service_spawn(s, | 2064 | r = service_spawn(s, |
2058 | s->control_command, | 2065 | s->control_command, |
2059 | true, | 2066 | true, |
2060 | false, | 2067 | false, |
2061 | !s->permissions_start_only, | 2068 | !s->permissions_start_only, |
2062 | !s->root_directory_start_only, | 2069 | !s->root_directory_start_only, |
2063 | false, | 2070 | false, |
2064 | false, | 2071 | false, |
2065 | &s->control_pid)) < 0) | 2072 | true, |
2073 | &s->control_pid); | ||
2074 | if (r < 0) | ||
2066 | goto fail; | 2075 | goto fail; |
2067 | 2076 | ||
2068 | service_set_state(s, SERVICE_START_POST); | 2077 | service_set_state(s, SERVICE_START_POST); |
@@ -2094,7 +2103,7 @@ static void service_enter_start(Service *s) { | |||
2094 | /* We want to ensure that nobody leaks processes from | 2103 | /* We want to ensure that nobody leaks processes from |
2095 | * START_PRE here, so let's go on a killing spree, People | 2104 | * START_PRE here, so let's go on a killing spree, People |
2096 | * should not spawn long running processes from START_PRE. */ | 2105 | * should not spawn long running processes from START_PRE. */ |
2097 | cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL); | 2106 | cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL, "control"); |
2098 | 2107 | ||
2099 | if (s->type == SERVICE_FORKING) { | 2108 | if (s->type == SERVICE_FORKING) { |
2100 | s->control_command_id = SERVICE_EXEC_START; | 2109 | s->control_command_id = SERVICE_EXEC_START; |
@@ -2108,15 +2117,17 @@ static void service_enter_start(Service *s) { | |||
2108 | c = s->main_command = s->exec_command[SERVICE_EXEC_START]; | 2117 | c = s->main_command = s->exec_command[SERVICE_EXEC_START]; |
2109 | } | 2118 | } |
2110 | 2119 | ||
2111 | if ((r = service_spawn(s, | 2120 | r = service_spawn(s, |
2112 | c, | 2121 | c, |
2113 | s->type == SERVICE_FORKING || s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY, | 2122 | s->type == SERVICE_FORKING || s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY, |
2114 | true, | 2123 | true, |
2115 | true, | 2124 | true, |
2116 | true, | 2125 | true, |
2117 | true, | 2126 | true, |
2118 | s->notify_access != NOTIFY_NONE, | 2127 | s->notify_access != NOTIFY_NONE, |
2119 | &pid)) < 0) | 2128 | false, |
2129 | &pid); | ||
2130 | if (r < 0) | ||
2120 | goto fail; | 2131 | goto fail; |
2121 | 2132 | ||
2122 | if (s->type == SERVICE_SIMPLE) { | 2133 | if (s->type == SERVICE_SIMPLE) { |
@@ -2168,19 +2179,21 @@ static void service_enter_start_pre(Service *s) { | |||
2168 | 2179 | ||
2169 | /* Before we start anything, let's clear up what might | 2180 | /* Before we start anything, let's clear up what might |
2170 | * be left from previous runs. */ | 2181 | * be left from previous runs. */ |
2171 | cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL); | 2182 | cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL, "control"); |
2172 | 2183 | ||
2173 | s->control_command_id = SERVICE_EXEC_START_PRE; | 2184 | s->control_command_id = SERVICE_EXEC_START_PRE; |
2174 | 2185 | ||
2175 | if ((r = service_spawn(s, | 2186 | r = service_spawn(s, |
2176 | s->control_command, | 2187 | s->control_command, |
2177 | true, | 2188 | true, |
2178 | false, | 2189 | false, |
2179 | !s->permissions_start_only, | 2190 | !s->permissions_start_only, |
2180 | !s->root_directory_start_only, | 2191 | !s->root_directory_start_only, |
2181 | true, | 2192 | true, |
2182 | false, | 2193 | false, |
2183 | &s->control_pid)) < 0) | 2194 | true, |
2195 | &s->control_pid); | ||
2196 | if (r < 0) | ||
2184 | goto fail; | 2197 | goto fail; |
2185 | 2198 | ||
2186 | service_set_state(s, SERVICE_START_PRE); | 2199 | service_set_state(s, SERVICE_START_PRE); |
@@ -2236,15 +2249,17 @@ static void service_enter_reload(Service *s) { | |||
2236 | if ((s->control_command = s->exec_command[SERVICE_EXEC_RELOAD])) { | 2249 | if ((s->control_command = s->exec_command[SERVICE_EXEC_RELOAD])) { |
2237 | s->control_command_id = SERVICE_EXEC_RELOAD; | 2250 | s->control_command_id = SERVICE_EXEC_RELOAD; |
2238 | 2251 | ||
2239 | if ((r = service_spawn(s, | 2252 | r = service_spawn(s, |
2240 | s->control_command, | 2253 | s->control_command, |
2241 | true, | 2254 | true, |
2242 | false, | 2255 | false, |
2243 | !s->permissions_start_only, | 2256 | !s->permissions_start_only, |
2244 | !s->root_directory_start_only, | 2257 | !s->root_directory_start_only, |
2245 | false, | 2258 | false, |
2246 | false, | 2259 | false, |
2247 | &s->control_pid)) < 0) | 2260 | true, |
2261 | &s->control_pid); | ||
2262 | if (r < 0) | ||
2248 | goto fail; | 2263 | goto fail; |
2249 | 2264 | ||
2250 | service_set_state(s, SERVICE_RELOAD); | 2265 | service_set_state(s, SERVICE_RELOAD); |
@@ -2271,16 +2286,18 @@ static void service_run_next_control(Service *s) { | |||
2271 | s->control_command = s->control_command->command_next; | 2286 | s->control_command = s->control_command->command_next; |
2272 | service_unwatch_control_pid(s); | 2287 | service_unwatch_control_pid(s); |
2273 | 2288 | ||
2274 | if ((r = service_spawn(s, | 2289 | r = service_spawn(s, |
2275 | s->control_command, | 2290 | s->control_command, |
2276 | true, | 2291 | true, |
2277 | false, | 2292 | false, |
2278 | !s->permissions_start_only, | 2293 | !s->permissions_start_only, |
2279 | !s->root_directory_start_only, | 2294 | !s->root_directory_start_only, |
2280 | s->control_command_id == SERVICE_EXEC_START_PRE || | 2295 | s->control_command_id == SERVICE_EXEC_START_PRE || |
2281 | s->control_command_id == SERVICE_EXEC_STOP_POST, | 2296 | s->control_command_id == SERVICE_EXEC_STOP_POST, |
2282 | false, | 2297 | false, |
2283 | &s->control_pid)) < 0) | 2298 | true, |
2299 | &s->control_pid); | ||
2300 | if (r < 0) | ||
2284 | goto fail; | 2301 | goto fail; |
2285 | 2302 | ||
2286 | return; | 2303 | return; |
@@ -2313,15 +2330,17 @@ static void service_run_next_main(Service *s) { | |||
2313 | s->main_command = s->main_command->command_next; | 2330 | s->main_command = s->main_command->command_next; |
2314 | service_unwatch_main_pid(s); | 2331 | service_unwatch_main_pid(s); |
2315 | 2332 | ||
2316 | if ((r = service_spawn(s, | 2333 | r = service_spawn(s, |
2317 | s->main_command, | 2334 | s->main_command, |
2318 | false, | 2335 | false, |
2319 | true, | 2336 | true, |
2320 | true, | 2337 | true, |
2321 | true, | 2338 | true, |
2322 | true, | 2339 | true, |
2323 | s->notify_access != NOTIFY_NONE, | 2340 | s->notify_access != NOTIFY_NONE, |
2324 | &pid)) < 0) | 2341 | false, |
2342 | &pid); | ||
2343 | if (r < 0) | ||
2325 | goto fail; | 2344 | goto fail; |
2326 | 2345 | ||
2327 | service_set_main_pid(s, pid); | 2346 | service_set_main_pid(s, pid); |
@@ -3647,8 +3666,8 @@ static int service_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusErro | |||
3647 | r = q; | 3666 | r = q; |
3648 | goto finish; | 3667 | goto finish; |
3649 | } | 3668 | } |
3650 | 3669 | q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set, NULL); | |
3651 | if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0) | 3670 | if (q < 0) |
3652 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) | 3671 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) |
3653 | r = q; | 3672 | r = q; |
3654 | } | 3673 | } |
diff --git a/src/core/socket.c b/src/core/socket.c index 37a023615..a43971765 100644 --- a/src/core/socket.c +++ b/src/core/socket.c | |||
@@ -1150,6 +1150,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { | |||
1150 | UNIT(s)->manager->confirm_spawn, | 1150 | UNIT(s)->manager->confirm_spawn, |
1151 | UNIT(s)->cgroup_bondings, | 1151 | UNIT(s)->cgroup_bondings, |
1152 | UNIT(s)->cgroup_attributes, | 1152 | UNIT(s)->cgroup_attributes, |
1153 | NULL, | ||
1153 | &pid); | 1154 | &pid); |
1154 | 1155 | ||
1155 | strv_free(argv); | 1156 | strv_free(argv); |
@@ -1240,7 +1241,8 @@ static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) { | |||
1240 | if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) | 1241 | if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) |
1241 | goto fail; | 1242 | goto fail; |
1242 | 1243 | ||
1243 | if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) { | 1244 | r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set, NULL); |
1245 | if (r < 0) { | ||
1244 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) | 1246 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) |
1245 | log_warning("Failed to kill control group: %s", strerror(-r)); | 1247 | log_warning("Failed to kill control group: %s", strerror(-r)); |
1246 | } else if (r > 0) | 1248 | } else if (r > 0) |
@@ -2127,7 +2129,8 @@ static int socket_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError | |||
2127 | goto finish; | 2129 | goto finish; |
2128 | } | 2130 | } |
2129 | 2131 | ||
2130 | if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0) | 2132 | q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set, NULL); |
2133 | if (q < 0) | ||
2131 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) | 2134 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) |
2132 | r = q; | 2135 | r = q; |
2133 | } | 2136 | } |
diff --git a/src/core/swap.c b/src/core/swap.c index 6331864d8..363852d33 100644 --- a/src/core/swap.c +++ b/src/core/swap.c | |||
@@ -621,6 +621,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { | |||
621 | UNIT(s)->manager->confirm_spawn, | 621 | UNIT(s)->manager->confirm_spawn, |
622 | UNIT(s)->cgroup_bondings, | 622 | UNIT(s)->cgroup_bondings, |
623 | UNIT(s)->cgroup_attributes, | 623 | UNIT(s)->cgroup_attributes, |
624 | NULL, | ||
624 | &pid)) < 0) | 625 | &pid)) < 0) |
625 | goto fail; | 626 | goto fail; |
626 | 627 | ||
@@ -690,7 +691,8 @@ static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { | |||
690 | if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) | 691 | if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) |
691 | goto fail; | 692 | goto fail; |
692 | 693 | ||
693 | if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) { | 694 | r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set, NULL); |
695 | if (r < 0) { | ||
694 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) | 696 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) |
695 | log_warning("Failed to kill control group: %s", strerror(-r)); | 697 | log_warning("Failed to kill control group: %s", strerror(-r)); |
696 | } else if (r > 0) | 698 | } else if (r > 0) |
@@ -1321,7 +1323,8 @@ static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError * | |||
1321 | goto finish; | 1323 | goto finish; |
1322 | } | 1324 | } |
1323 | 1325 | ||
1324 | if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0) | 1326 | q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set, NULL); |
1327 | if (q < 0) | ||
1325 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) | 1328 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) |
1326 | r = q; | 1329 | r = q; |
1327 | } | 1330 | } |