Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : : /***
3 : : Copyright © 2010 ProFUSION embedded systems
4 : : ***/
5 : :
6 : : #include <errno.h>
7 : : #include <signal.h>
8 : : #include <sys/wait.h>
9 : : #include <unistd.h>
10 : :
11 : : #include "alloc-util.h"
12 : : #include "def.h"
13 : : #include "dirent-util.h"
14 : : #include "fd-util.h"
15 : : #include "format-util.h"
16 : : #include "killall.h"
17 : : #include "parse-util.h"
18 : : #include "process-util.h"
19 : : #include "set.h"
20 : : #include "string-util.h"
21 : : #include "terminal-util.h"
22 : : #include "util.h"
23 : :
24 : 0 : static bool ignore_proc(pid_t pid, bool warn_rootfs) {
25 : 0 : _cleanup_fclose_ FILE *f = NULL;
26 : : const char *p;
27 : 0 : char c = 0;
28 : : uid_t uid;
29 : : int r;
30 : :
31 : : /* We are PID 1, let's not commit suicide */
32 [ # # ]: 0 : if (pid <= 1)
33 : 0 : return true;
34 : :
35 : : /* Ignore kernel threads */
36 : 0 : r = is_kernel_thread(pid);
37 [ # # ]: 0 : if (r != 0)
38 : 0 : return true; /* also ignore processes where we can't determine this */
39 : :
40 : 0 : r = get_process_uid(pid, &uid);
41 [ # # ]: 0 : if (r < 0)
42 : 0 : return true; /* not really, but better safe than sorry */
43 : :
44 : : /* Non-root processes otherwise are always subject to be killed */
45 [ # # ]: 0 : if (uid != 0)
46 : 0 : return false;
47 : :
48 [ # # # # : 0 : p = procfs_file_alloca(pid, "cmdline");
# # ]
49 : 0 : f = fopen(p, "re");
50 [ # # ]: 0 : if (!f)
51 : 0 : return true; /* not really, but has the desired effect */
52 : :
53 : : /* Try to read the first character of the command line. If the cmdline is empty (which might be the case for
54 : : * kernel threads but potentially also other stuff), this line won't do anything, but we don't care much, as
55 : : * actual kernel threads are already filtered out above. */
56 : 0 : (void) fread(&c, 1, 1, f);
57 : :
58 : : /* Processes with argv[0][0] = '@' we ignore from the killing spree.
59 : : *
60 : : * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */
61 [ # # ]: 0 : if (c != '@')
62 : 0 : return false;
63 : :
64 [ # # # # ]: 0 : if (warn_rootfs &&
65 : 0 : pid_from_same_root_fs(pid) == 0) {
66 : :
67 : 0 : _cleanup_free_ char *comm = NULL;
68 : :
69 : 0 : (void) get_process_comm(pid, &comm);
70 : :
71 [ # # ]: 0 : log_notice("Process " PID_FMT " (%s) has been marked to be excluded from killing. It is "
72 : : "running from the root file system, and thus likely to block re-mounting of the "
73 : : "root file system to read-only. Please consider moving it into an initrd file "
74 : : "system instead.", pid, strna(comm));
75 : : }
76 : :
77 : 0 : return true;
78 : : }
79 : :
80 : 0 : static void log_children_no_yet_killed(Set *pids) {
81 [ # # ]: 0 : _cleanup_free_ char *lst_child = NULL;
82 : : Iterator i;
83 : : void *p;
84 : :
85 [ # # ]: 0 : SET_FOREACH(p, pids, i) {
86 [ # # ]: 0 : _cleanup_free_ char *s = NULL;
87 : :
88 [ # # ]: 0 : if (get_process_comm(PTR_TO_PID(p), &s) < 0)
89 : 0 : (void) asprintf(&s, PID_FMT, PTR_TO_PID(p));
90 : :
91 [ # # ]: 0 : if (!strextend(&lst_child, ", ", s, NULL)) {
92 : 0 : log_oom();
93 : 0 : return;
94 : : }
95 : : }
96 : :
97 [ # # ]: 0 : if (isempty(lst_child))
98 : 0 : return;
99 : :
100 [ # # ]: 0 : log_warning("Waiting for process: %s", lst_child + 2);
101 : : }
102 : :
103 : 0 : static int wait_for_children(Set *pids, sigset_t *mask, usec_t timeout) {
104 : : usec_t until, date_log_child, n;
105 : :
106 [ # # ]: 0 : assert(mask);
107 : :
108 : : /* Return the number of children remaining in the pids set: That correspond to the number
109 : : * of processes still "alive" after the timeout */
110 : :
111 [ # # ]: 0 : if (set_isempty(pids))
112 : 0 : return 0;
113 : :
114 : 0 : n = now(CLOCK_MONOTONIC);
115 : 0 : until = usec_add(n, timeout);
116 : 0 : date_log_child = usec_add(n, 10u * USEC_PER_SEC);
117 [ # # ]: 0 : if (date_log_child > until)
118 : 0 : date_log_child = usec_add(n, timeout / 2u);
119 : :
120 : 0 : for (;;) {
121 : : struct timespec ts;
122 : : int k;
123 : : void *p;
124 : : Iterator i;
125 : :
126 : : /* First, let the kernel inform us about killed
127 : : * children. Most processes will probably be our
128 : : * children, but some are not (might be our
129 : : * grandchildren instead...). */
130 : 0 : for (;;) {
131 : : pid_t pid;
132 : :
133 : 0 : pid = waitpid(-1, NULL, WNOHANG);
134 [ # # ]: 0 : if (pid == 0)
135 : 0 : break;
136 [ # # ]: 0 : if (pid < 0) {
137 [ # # ]: 0 : if (errno == ECHILD)
138 : 0 : break;
139 : :
140 [ # # ]: 0 : return log_error_errno(errno, "waitpid() failed: %m");
141 : : }
142 : :
143 : 0 : (void) set_remove(pids, PID_TO_PTR(pid));
144 : : }
145 : :
146 : : /* Now explicitly check who might be remaining, who
147 : : * might not be our child. */
148 [ # # ]: 0 : SET_FOREACH(p, pids, i) {
149 : :
150 : : /* kill(pid, 0) sends no signal, but it tells
151 : : * us whether the process still exists. */
152 [ # # ]: 0 : if (kill(PTR_TO_PID(p), 0) == 0)
153 : 0 : continue;
154 : :
155 [ # # ]: 0 : if (errno != ESRCH)
156 : 0 : continue;
157 : :
158 : 0 : set_remove(pids, p);
159 : : }
160 : :
161 [ # # ]: 0 : if (set_isempty(pids))
162 : 0 : return 0;
163 : :
164 : 0 : n = now(CLOCK_MONOTONIC);
165 [ # # # # ]: 0 : if (date_log_child > 0 && n >= date_log_child) {
166 : 0 : log_children_no_yet_killed(pids);
167 : : /* Log the children not yet killed only once */
168 : 0 : date_log_child = 0;
169 : : }
170 : :
171 [ # # ]: 0 : if (n >= until)
172 : 0 : return set_size(pids);
173 : :
174 [ # # ]: 0 : if (date_log_child > 0)
175 : 0 : timespec_store(&ts, MIN(until - n, date_log_child - n));
176 : : else
177 : 0 : timespec_store(&ts, until - n);
178 : :
179 : 0 : k = sigtimedwait(mask, NULL, &ts);
180 [ # # ]: 0 : if (k != SIGCHLD) {
181 : :
182 [ # # # # ]: 0 : if (k < 0 && errno != EAGAIN)
183 [ # # ]: 0 : return log_error_errno(errno, "sigtimedwait() failed: %m");
184 : :
185 [ # # ]: 0 : if (k >= 0)
186 [ # # ]: 0 : log_warning("sigtimedwait() returned unexpected signal.");
187 : : }
188 : : }
189 : : }
190 : :
191 : 0 : static int killall(int sig, Set *pids, bool send_sighup) {
192 : 0 : _cleanup_closedir_ DIR *dir = NULL;
193 : : struct dirent *d;
194 : 0 : int n_killed = 0;
195 : :
196 : : /* Send the specified signal to all remaining processes, if not excluded by ignore_proc().
197 : : * Returns the number of processes to which the specified signal was sent */
198 : :
199 : 0 : dir = opendir("/proc");
200 [ # # ]: 0 : if (!dir)
201 [ # # ]: 0 : return log_warning_errno(errno, "opendir(/proc) failed: %m");
202 : :
203 [ # # # # ]: 0 : FOREACH_DIRENT_ALL(d, dir, break) {
204 : : pid_t pid;
205 : : int r;
206 : :
207 [ # # # # ]: 0 : if (!IN_SET(d->d_type, DT_DIR, DT_UNKNOWN))
208 : 0 : continue;
209 : :
210 [ # # ]: 0 : if (parse_pid(d->d_name, &pid) < 0)
211 : 0 : continue;
212 : :
213 [ # # # # : 0 : if (ignore_proc(pid, sig == SIGKILL && !in_initrd()))
# # ]
214 : 0 : continue;
215 : :
216 [ # # ]: 0 : if (sig == SIGKILL) {
217 : 0 : _cleanup_free_ char *s = NULL;
218 : :
219 : 0 : get_process_comm(pid, &s);
220 [ # # ]: 0 : log_notice("Sending SIGKILL to PID "PID_FMT" (%s).", pid, strna(s));
221 : : }
222 : :
223 [ # # ]: 0 : if (kill(pid, sig) >= 0) {
224 : 0 : n_killed++;
225 [ # # ]: 0 : if (pids) {
226 : 0 : r = set_put(pids, PID_TO_PTR(pid));
227 [ # # ]: 0 : if (r < 0)
228 : 0 : log_oom();
229 : : }
230 [ # # ]: 0 : } else if (errno != ENOENT)
231 [ # # ]: 0 : log_warning_errno(errno, "Could not kill %d: %m", pid);
232 : :
233 [ # # ]: 0 : if (send_sighup) {
234 : : /* Optionally, also send a SIGHUP signal, but
235 : : only if the process has a controlling
236 : : tty. This is useful to allow handling of
237 : : shells which ignore SIGTERM but react to
238 : : SIGHUP. We do not send this to processes that
239 : : have no controlling TTY since we don't want to
240 : : trigger reloads of daemon processes. Also we
241 : : make sure to only send this after SIGTERM so
242 : : that SIGTERM is always first in the queue. */
243 : :
244 [ # # ]: 0 : if (get_ctty_devnr(pid, NULL) >= 0)
245 : : /* it's OK if the process is gone, just ignore the result */
246 : 0 : (void) kill(pid, SIGHUP);
247 : : }
248 : : }
249 : :
250 : 0 : return n_killed;
251 : : }
252 : :
253 : 0 : int broadcast_signal(int sig, bool wait_for_exit, bool send_sighup, usec_t timeout) {
254 : : int n_children_left;
255 : : sigset_t mask, oldmask;
256 : 0 : _cleanup_set_free_ Set *pids = NULL;
257 : :
258 : : /* Send the specified signal to all remaining processes, if not excluded by ignore_proc().
259 : : * Return:
260 : : * - The number of processes still "alive" after the timeout (that should have been killed)
261 : : * if the function needs to wait for the end of the processes (wait_for_exit).
262 : : * - Otherwise, the number of processes to which the specified signal was sent */
263 : :
264 [ # # ]: 0 : if (wait_for_exit)
265 : 0 : pids = set_new(NULL);
266 : :
267 [ # # ]: 0 : assert_se(sigemptyset(&mask) == 0);
268 [ # # ]: 0 : assert_se(sigaddset(&mask, SIGCHLD) == 0);
269 [ # # ]: 0 : assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
270 : :
271 [ # # # # ]: 0 : if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
272 [ # # ]: 0 : log_warning_errno(errno, "kill(-1, SIGSTOP) failed: %m");
273 : :
274 : 0 : n_children_left = killall(sig, pids, send_sighup);
275 : :
276 [ # # # # ]: 0 : if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
277 [ # # ]: 0 : log_warning_errno(errno, "kill(-1, SIGCONT) failed: %m");
278 : :
279 [ # # # # ]: 0 : if (wait_for_exit && n_children_left > 0)
280 : 0 : n_children_left = wait_for_children(pids, &mask, timeout);
281 : :
282 [ # # ]: 0 : assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0);
283 : :
284 : 0 : return n_children_left;
285 : : }
|