]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/process-util.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / basic / process-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <ctype.h>
22 #include <errno.h>
23 #include <limits.h>
24 #include <linux/oom.h>
25 #include <sched.h>
26 #include <signal.h>
27 #include <stdbool.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/mman.h>
32 #include <sys/personality.h>
33 #include <sys/prctl.h>
34 #include <sys/types.h>
35 #include <sys/wait.h>
36 #include <syslog.h>
37 #include <unistd.h>
38 #if HAVE_VALGRIND_VALGRIND_H
39 #include <valgrind/valgrind.h>
40 #endif
41
42 #include "alloc-util.h"
43 #include "architecture.h"
44 #include "escape.h"
45 #include "fd-util.h"
46 #include "fileio.h"
47 #include "fs-util.h"
48 #include "ioprio.h"
49 #include "log.h"
50 #include "macro.h"
51 #include "missing.h"
52 #include "process-util.h"
53 #include "raw-clone.h"
54 #include "signal-util.h"
55 #include "stat-util.h"
56 #include "string-table.h"
57 #include "string-util.h"
58 #include "user-util.h"
59 #include "util.h"
60
61 int get_process_state(pid_t pid) {
62 const char *p;
63 char state;
64 int r;
65 _cleanup_free_ char *line = NULL;
66
67 assert(pid >= 0);
68
69 p = procfs_file_alloca(pid, "stat");
70
71 r = read_one_line_file(p, &line);
72 if (r == -ENOENT)
73 return -ESRCH;
74 if (r < 0)
75 return r;
76
77 p = strrchr(line, ')');
78 if (!p)
79 return -EIO;
80
81 p++;
82
83 if (sscanf(p, " %c", &state) != 1)
84 return -EIO;
85
86 return (unsigned char) state;
87 }
88
89 int get_process_comm(pid_t pid, char **name) {
90 const char *p;
91 int r;
92
93 assert(name);
94 assert(pid >= 0);
95
96 p = procfs_file_alloca(pid, "comm");
97
98 r = read_one_line_file(p, name);
99 if (r == -ENOENT)
100 return -ESRCH;
101
102 return r;
103 }
104
105 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
106 _cleanup_fclose_ FILE *f = NULL;
107 bool space = false;
108 char *k, *ans = NULL;
109 const char *p;
110 int c;
111
112 assert(line);
113 assert(pid >= 0);
114
115 /* Retrieves a process' command line. Replaces unprintable characters while doing so by whitespace (coalescing
116 * multiple sequential ones into one). If max_length is != 0 will return a string of the specified size at most
117 * (the trailing NUL byte does count towards the length here!), abbreviated with a "..." ellipsis. If
118 * comm_fallback is true and the process has no command line set (the case for kernel threads), or has a
119 * command line that resolves to the empty string will return the "comm" name of the process instead.
120 *
121 * Returns -ESRCH if the process doesn't exist, and -ENOENT if the process has no command line (and
122 * comm_fallback is false). Returns 0 and sets *line otherwise. */
123
124 p = procfs_file_alloca(pid, "cmdline");
125
126 f = fopen(p, "re");
127 if (!f) {
128 if (errno == ENOENT)
129 return -ESRCH;
130 return -errno;
131 }
132
133 if (max_length == 1) {
134
135 /* If there's only room for one byte, return the empty string */
136 ans = new0(char, 1);
137 if (!ans)
138 return -ENOMEM;
139
140 *line = ans;
141 return 0;
142
143 } else if (max_length == 0) {
144 size_t len = 0, allocated = 0;
145
146 while ((c = getc(f)) != EOF) {
147
148 if (!GREEDY_REALLOC(ans, allocated, len+3)) {
149 free(ans);
150 return -ENOMEM;
151 }
152
153 if (isprint(c)) {
154 if (space) {
155 ans[len++] = ' ';
156 space = false;
157 }
158
159 ans[len++] = c;
160 } else if (len > 0)
161 space = true;
162 }
163
164 if (len > 0)
165 ans[len] = '\0';
166 else
167 ans = mfree(ans);
168
169 } else {
170 bool dotdotdot = false;
171 size_t left;
172
173 ans = new(char, max_length);
174 if (!ans)
175 return -ENOMEM;
176
177 k = ans;
178 left = max_length;
179 while ((c = getc(f)) != EOF) {
180
181 if (isprint(c)) {
182
183 if (space) {
184 if (left <= 2) {
185 dotdotdot = true;
186 break;
187 }
188
189 *(k++) = ' ';
190 left--;
191 space = false;
192 }
193
194 if (left <= 1) {
195 dotdotdot = true;
196 break;
197 }
198
199 *(k++) = (char) c;
200 left--;
201 } else if (k > ans)
202 space = true;
203 }
204
205 if (dotdotdot) {
206 if (max_length <= 4) {
207 k = ans;
208 left = max_length;
209 } else {
210 k = ans + max_length - 4;
211 left = 4;
212
213 /* Eat up final spaces */
214 while (k > ans && isspace(k[-1])) {
215 k--;
216 left++;
217 }
218 }
219
220 strncpy(k, "...", left-1);
221 k[left-1] = 0;
222 } else
223 *k = 0;
224 }
225
226 /* Kernel threads have no argv[] */
227 if (isempty(ans)) {
228 _cleanup_free_ char *t = NULL;
229 int h;
230
231 free(ans);
232
233 if (!comm_fallback)
234 return -ENOENT;
235
236 h = get_process_comm(pid, &t);
237 if (h < 0)
238 return h;
239
240 if (max_length == 0)
241 ans = strjoin("[", t, "]");
242 else {
243 size_t l;
244
245 l = strlen(t);
246
247 if (l + 3 <= max_length)
248 ans = strjoin("[", t, "]");
249 else if (max_length <= 6) {
250
251 ans = new(char, max_length);
252 if (!ans)
253 return -ENOMEM;
254
255 memcpy(ans, "[...]", max_length-1);
256 ans[max_length-1] = 0;
257 } else {
258 char *e;
259
260 t[max_length - 6] = 0;
261
262 /* Chop off final spaces */
263 e = strchr(t, 0);
264 while (e > t && isspace(e[-1]))
265 e--;
266 *e = 0;
267
268 ans = strjoin("[", t, "...]");
269 }
270 }
271 if (!ans)
272 return -ENOMEM;
273 }
274
275 *line = ans;
276 return 0;
277 }
278
279 int rename_process(const char name[]) {
280 static size_t mm_size = 0;
281 static char *mm = NULL;
282 bool truncated = false;
283 size_t l;
284
285 /* This is a like a poor man's setproctitle(). It changes the comm field, argv[0], and also the glibc's
286 * internally used name of the process. For the first one a limit of 16 chars applies; to the second one in
287 * many cases one of 10 (i.e. length of "/sbin/init") — however if we have CAP_SYS_RESOURCES it is unbounded;
288 * to the third one 7 (i.e. the length of "systemd". If you pass a longer string it will likely be
289 * truncated.
290 *
291 * Returns 0 if a name was set but truncated, > 0 if it was set but not truncated. */
292
293 if (isempty(name))
294 return -EINVAL; /* let's not confuse users unnecessarily with an empty name */
295
296 l = strlen(name);
297
298 /* First step, change the comm field. */
299 (void) prctl(PR_SET_NAME, name);
300 if (l > 15) /* Linux process names can be 15 chars at max */
301 truncated = true;
302
303 /* Second step, change glibc's ID of the process name. */
304 if (program_invocation_name) {
305 size_t k;
306
307 k = strlen(program_invocation_name);
308 strncpy(program_invocation_name, name, k);
309 if (l > k)
310 truncated = true;
311 }
312
313 /* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but
314 * has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at
315 * the end. This is the best option for changing /proc/self/cmdline. */
316
317 /* Let's not bother with this if we don't have euid == 0. Strictly speaking we should check for the
318 * CAP_SYS_RESOURCE capability which is independent of the euid. In our own code the capability generally is
319 * present only for euid == 0, hence let's use this as quick bypass check, to avoid calling mmap() if
320 * PR_SET_MM_ARG_{START,END} fails with EPERM later on anyway. After all geteuid() is dead cheap to call, but
321 * mmap() is not. */
322 if (geteuid() != 0)
323 log_debug("Skipping PR_SET_MM, as we don't have privileges.");
324 else if (mm_size < l+1) {
325 size_t nn_size;
326 char *nn;
327
328 nn_size = PAGE_ALIGN(l+1);
329 nn = mmap(NULL, nn_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
330 if (nn == MAP_FAILED) {
331 log_debug_errno(errno, "mmap() failed: %m");
332 goto use_saved_argv;
333 }
334
335 strncpy(nn, name, nn_size);
336
337 /* Now, let's tell the kernel about this new memory */
338 if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) {
339 log_debug_errno(errno, "PR_SET_MM_ARG_START failed, proceeding without: %m");
340 (void) munmap(nn, nn_size);
341 goto use_saved_argv;
342 }
343
344 /* And update the end pointer to the new end, too. If this fails, we don't really know what to do, it's
345 * pretty unlikely that we can rollback, hence we'll just accept the failure, and continue. */
346 if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0)
347 log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
348
349 if (mm)
350 (void) munmap(mm, mm_size);
351
352 mm = nn;
353 mm_size = nn_size;
354 } else {
355 strncpy(mm, name, mm_size);
356
357 /* Update the end pointer, continuing regardless of any failure. */
358 if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) mm + l + 1, 0, 0) < 0)
359 log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
360 }
361
362 use_saved_argv:
363 /* Fourth step: in all cases we'll also update the original argv[], so that our own code gets it right too if
364 * it still looks here */
365
366 if (saved_argc > 0) {
367 int i;
368
369 if (saved_argv[0]) {
370 size_t k;
371
372 k = strlen(saved_argv[0]);
373 strncpy(saved_argv[0], name, k);
374 if (l > k)
375 truncated = true;
376 }
377
378 for (i = 1; i < saved_argc; i++) {
379 if (!saved_argv[i])
380 break;
381
382 memzero(saved_argv[i], strlen(saved_argv[i]));
383 }
384 }
385
386 return !truncated;
387 }
388
389 int is_kernel_thread(pid_t pid) {
390 const char *p;
391 size_t count;
392 char c;
393 bool eof;
394 FILE *f;
395
396 if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */
397 return 0;
398
399 assert(pid > 1);
400
401 p = procfs_file_alloca(pid, "cmdline");
402 f = fopen(p, "re");
403 if (!f) {
404 if (errno == ENOENT)
405 return -ESRCH;
406 return -errno;
407 }
408
409 count = fread(&c, 1, 1, f);
410 eof = feof(f);
411 fclose(f);
412
413 /* Kernel threads have an empty cmdline */
414
415 if (count <= 0)
416 return eof ? 1 : -errno;
417
418 return 0;
419 }
420
421 int get_process_capeff(pid_t pid, char **capeff) {
422 const char *p;
423 int r;
424
425 assert(capeff);
426 assert(pid >= 0);
427
428 p = procfs_file_alloca(pid, "status");
429
430 r = get_proc_field(p, "CapEff", WHITESPACE, capeff);
431 if (r == -ENOENT)
432 return -ESRCH;
433
434 return r;
435 }
436
437 static int get_process_link_contents(const char *proc_file, char **name) {
438 int r;
439
440 assert(proc_file);
441 assert(name);
442
443 r = readlink_malloc(proc_file, name);
444 if (r == -ENOENT)
445 return -ESRCH;
446 if (r < 0)
447 return r;
448
449 return 0;
450 }
451
452 int get_process_exe(pid_t pid, char **name) {
453 const char *p;
454 char *d;
455 int r;
456
457 assert(pid >= 0);
458
459 p = procfs_file_alloca(pid, "exe");
460 r = get_process_link_contents(p, name);
461 if (r < 0)
462 return r;
463
464 d = endswith(*name, " (deleted)");
465 if (d)
466 *d = '\0';
467
468 return 0;
469 }
470
471 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
472 _cleanup_fclose_ FILE *f = NULL;
473 char line[LINE_MAX];
474 const char *p;
475
476 assert(field);
477 assert(uid);
478
479 if (pid < 0)
480 return -EINVAL;
481
482 p = procfs_file_alloca(pid, "status");
483 f = fopen(p, "re");
484 if (!f) {
485 if (errno == ENOENT)
486 return -ESRCH;
487 return -errno;
488 }
489
490 FOREACH_LINE(line, f, return -errno) {
491 char *l;
492
493 l = strstrip(line);
494
495 if (startswith(l, field)) {
496 l += strlen(field);
497 l += strspn(l, WHITESPACE);
498
499 l[strcspn(l, WHITESPACE)] = 0;
500
501 return parse_uid(l, uid);
502 }
503 }
504
505 return -EIO;
506 }
507
508 int get_process_uid(pid_t pid, uid_t *uid) {
509
510 if (pid == 0 || pid == getpid_cached()) {
511 *uid = getuid();
512 return 0;
513 }
514
515 return get_process_id(pid, "Uid:", uid);
516 }
517
518 int get_process_gid(pid_t pid, gid_t *gid) {
519
520 if (pid == 0 || pid == getpid_cached()) {
521 *gid = getgid();
522 return 0;
523 }
524
525 assert_cc(sizeof(uid_t) == sizeof(gid_t));
526 return get_process_id(pid, "Gid:", gid);
527 }
528
529 int get_process_cwd(pid_t pid, char **cwd) {
530 const char *p;
531
532 assert(pid >= 0);
533
534 p = procfs_file_alloca(pid, "cwd");
535
536 return get_process_link_contents(p, cwd);
537 }
538
539 int get_process_root(pid_t pid, char **root) {
540 const char *p;
541
542 assert(pid >= 0);
543
544 p = procfs_file_alloca(pid, "root");
545
546 return get_process_link_contents(p, root);
547 }
548
549 int get_process_environ(pid_t pid, char **env) {
550 _cleanup_fclose_ FILE *f = NULL;
551 _cleanup_free_ char *outcome = NULL;
552 int c;
553 const char *p;
554 size_t allocated = 0, sz = 0;
555
556 assert(pid >= 0);
557 assert(env);
558
559 p = procfs_file_alloca(pid, "environ");
560
561 f = fopen(p, "re");
562 if (!f) {
563 if (errno == ENOENT)
564 return -ESRCH;
565 return -errno;
566 }
567
568 while ((c = fgetc(f)) != EOF) {
569 if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
570 return -ENOMEM;
571
572 if (c == '\0')
573 outcome[sz++] = '\n';
574 else
575 sz += cescape_char(c, outcome + sz);
576 }
577
578 if (!outcome) {
579 outcome = strdup("");
580 if (!outcome)
581 return -ENOMEM;
582 } else
583 outcome[sz] = '\0';
584
585 *env = outcome;
586 outcome = NULL;
587
588 return 0;
589 }
590
591 int get_process_ppid(pid_t pid, pid_t *_ppid) {
592 int r;
593 _cleanup_free_ char *line = NULL;
594 long unsigned ppid;
595 const char *p;
596
597 assert(pid >= 0);
598 assert(_ppid);
599
600 if (pid == 0 || pid == getpid_cached()) {
601 *_ppid = getppid();
602 return 0;
603 }
604
605 p = procfs_file_alloca(pid, "stat");
606 r = read_one_line_file(p, &line);
607 if (r == -ENOENT)
608 return -ESRCH;
609 if (r < 0)
610 return r;
611
612 /* Let's skip the pid and comm fields. The latter is enclosed
613 * in () but does not escape any () in its value, so let's
614 * skip over it manually */
615
616 p = strrchr(line, ')');
617 if (!p)
618 return -EIO;
619
620 p++;
621
622 if (sscanf(p, " "
623 "%*c " /* state */
624 "%lu ", /* ppid */
625 &ppid) != 1)
626 return -EIO;
627
628 if ((long unsigned) (pid_t) ppid != ppid)
629 return -ERANGE;
630
631 *_ppid = (pid_t) ppid;
632
633 return 0;
634 }
635
636 int wait_for_terminate(pid_t pid, siginfo_t *status) {
637 siginfo_t dummy;
638
639 assert(pid >= 1);
640
641 if (!status)
642 status = &dummy;
643
644 for (;;) {
645 zero(*status);
646
647 if (waitid(P_PID, pid, status, WEXITED) < 0) {
648
649 if (errno == EINTR)
650 continue;
651
652 return negative_errno();
653 }
654
655 return 0;
656 }
657 }
658
659 /*
660 * Return values:
661 * < 0 : wait_for_terminate() failed to get the state of the
662 * process, the process was terminated by a signal, or
663 * failed for an unknown reason.
664 * >=0 : The process terminated normally, and its exit code is
665 * returned.
666 *
667 * That is, success is indicated by a return value of zero, and an
668 * error is indicated by a non-zero value.
669 *
670 * A warning is emitted if the process terminates abnormally,
671 * and also if it returns non-zero unless check_exit_code is true.
672 */
673 int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code) {
674 int r;
675 siginfo_t status;
676
677 assert(name);
678 assert(pid > 1);
679
680 r = wait_for_terminate(pid, &status);
681 if (r < 0)
682 return log_warning_errno(r, "Failed to wait for %s: %m", name);
683
684 if (status.si_code == CLD_EXITED) {
685 if (status.si_status != 0)
686 log_full(check_exit_code ? LOG_WARNING : LOG_DEBUG,
687 "%s failed with error code %i.", name, status.si_status);
688 else
689 log_debug("%s succeeded.", name);
690
691 return status.si_status;
692 } else if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED)) {
693
694 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
695 return -EPROTO;
696 }
697
698 log_warning("%s failed due to unknown reason.", name);
699 return -EPROTO;
700 }
701
702 void sigkill_wait(pid_t pid) {
703 assert(pid > 1);
704
705 if (kill(pid, SIGKILL) > 0)
706 (void) wait_for_terminate(pid, NULL);
707 }
708
709 void sigkill_waitp(pid_t *pid) {
710 if (!pid)
711 return;
712 if (*pid <= 1)
713 return;
714
715 sigkill_wait(*pid);
716 }
717
718 int kill_and_sigcont(pid_t pid, int sig) {
719 int r;
720
721 r = kill(pid, sig) < 0 ? -errno : 0;
722
723 /* If this worked, also send SIGCONT, unless we already just sent a SIGCONT, or SIGKILL was sent which isn't
724 * affected by a process being suspended anyway. */
725 if (r >= 0 && !IN_SET(sig, SIGCONT, SIGKILL))
726 (void) kill(pid, SIGCONT);
727
728 return r;
729 }
730
731 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
732 _cleanup_fclose_ FILE *f = NULL;
733 char *value = NULL;
734 int r;
735 bool done = false;
736 size_t l;
737 const char *path;
738
739 assert(pid >= 0);
740 assert(field);
741 assert(_value);
742
743 path = procfs_file_alloca(pid, "environ");
744
745 f = fopen(path, "re");
746 if (!f) {
747 if (errno == ENOENT)
748 return -ESRCH;
749 return -errno;
750 }
751
752 l = strlen(field);
753 r = 0;
754
755 do {
756 char line[LINE_MAX];
757 unsigned i;
758
759 for (i = 0; i < sizeof(line)-1; i++) {
760 int c;
761
762 c = getc(f);
763 if (_unlikely_(c == EOF)) {
764 done = true;
765 break;
766 } else if (c == 0)
767 break;
768
769 line[i] = c;
770 }
771 line[i] = 0;
772
773 if (strneq(line, field, l) && line[l] == '=') {
774 value = strdup(line + l + 1);
775 if (!value)
776 return -ENOMEM;
777
778 r = 1;
779 break;
780 }
781
782 } while (!done);
783
784 *_value = value;
785 return r;
786 }
787
788 bool pid_is_unwaited(pid_t pid) {
789 /* Checks whether a PID is still valid at all, including a zombie */
790
791 if (pid < 0)
792 return false;
793
794 if (pid <= 1) /* If we or PID 1 would be dead and have been waited for, this code would not be running */
795 return true;
796
797 if (pid == getpid_cached())
798 return true;
799
800 if (kill(pid, 0) >= 0)
801 return true;
802
803 return errno != ESRCH;
804 }
805
806 bool pid_is_alive(pid_t pid) {
807 int r;
808
809 /* Checks whether a PID is still valid and not a zombie */
810
811 if (pid < 0)
812 return false;
813
814 if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
815 return true;
816
817 if (pid == getpid_cached())
818 return true;
819
820 r = get_process_state(pid);
821 if (IN_SET(r, -ESRCH, 'Z'))
822 return false;
823
824 return true;
825 }
826
827 int pid_from_same_root_fs(pid_t pid) {
828 const char *root;
829
830 if (pid < 0)
831 return false;
832
833 if (pid == 0 || pid == getpid_cached())
834 return true;
835
836 root = procfs_file_alloca(pid, "root");
837
838 return files_same(root, "/proc/1/root", 0);
839 }
840
841 bool is_main_thread(void) {
842 static thread_local int cached = 0;
843
844 if (_unlikely_(cached == 0))
845 cached = getpid_cached() == gettid() ? 1 : -1;
846
847 return cached > 0;
848 }
849
850 noreturn void freeze(void) {
851
852 log_close();
853
854 /* Make sure nobody waits for us on a socket anymore */
855 close_all_fds(NULL, 0);
856
857 sync();
858
859 for (;;)
860 pause();
861 }
862
863 bool oom_score_adjust_is_valid(int oa) {
864 return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
865 }
866
867 unsigned long personality_from_string(const char *p) {
868 int architecture;
869
870 if (!p)
871 return PERSONALITY_INVALID;
872
873 /* Parse a personality specifier. We use our own identifiers that indicate specific ABIs, rather than just
874 * hints regarding the register size, since we want to keep things open for multiple locally supported ABIs for
875 * the same register size. */
876
877 architecture = architecture_from_string(p);
878 if (architecture < 0)
879 return PERSONALITY_INVALID;
880
881 if (architecture == native_architecture())
882 return PER_LINUX;
883 #ifdef SECONDARY_ARCHITECTURE
884 if (architecture == SECONDARY_ARCHITECTURE)
885 return PER_LINUX32;
886 #endif
887
888 return PERSONALITY_INVALID;
889 }
890
891 const char* personality_to_string(unsigned long p) {
892 int architecture = _ARCHITECTURE_INVALID;
893
894 if (p == PER_LINUX)
895 architecture = native_architecture();
896 #ifdef SECONDARY_ARCHITECTURE
897 else if (p == PER_LINUX32)
898 architecture = SECONDARY_ARCHITECTURE;
899 #endif
900
901 if (architecture < 0)
902 return NULL;
903
904 return architecture_to_string(architecture);
905 }
906
907 int safe_personality(unsigned long p) {
908 int ret;
909
910 /* So here's the deal, personality() is weirdly defined by glibc. In some cases it returns a failure via errno,
911 * and in others as negative return value containing an errno-like value. Let's work around this: this is a
912 * wrapper that uses errno if it is set, and uses the return value otherwise. And then it sets both errno and
913 * the return value indicating the same issue, so that we are definitely on the safe side.
914 *
915 * See https://github.com/systemd/systemd/issues/6737 */
916
917 errno = 0;
918 ret = personality(p);
919 if (ret < 0) {
920 if (errno != 0)
921 return -errno;
922
923 errno = -ret;
924 }
925
926 return ret;
927 }
928
929 int opinionated_personality(unsigned long *ret) {
930 int current;
931
932 /* Returns the current personality, or PERSONALITY_INVALID if we can't determine it. This function is a bit
933 * opinionated though, and ignores all the finer-grained bits and exotic personalities, only distinguishing the
934 * two most relevant personalities: PER_LINUX and PER_LINUX32. */
935
936 current = safe_personality(PERSONALITY_INVALID);
937 if (current < 0)
938 return current;
939
940 if (((unsigned long) current & 0xffff) == PER_LINUX32)
941 *ret = PER_LINUX32;
942 else
943 *ret = PER_LINUX;
944
945 return 0;
946 }
947
948 void valgrind_summary_hack(void) {
949 #if HAVE_VALGRIND_VALGRIND_H
950 if (getpid_cached() == 1 && RUNNING_ON_VALGRIND) {
951 pid_t pid;
952 pid = raw_clone(SIGCHLD);
953 if (pid < 0)
954 log_emergency_errno(errno, "Failed to fork off valgrind helper: %m");
955 else if (pid == 0)
956 exit(EXIT_SUCCESS);
957 else {
958 log_info("Spawned valgrind helper as PID "PID_FMT".", pid);
959 (void) wait_for_terminate(pid, NULL);
960 }
961 }
962 #endif
963 }
964
965 int pid_compare_func(const void *a, const void *b) {
966 const pid_t *p = a, *q = b;
967
968 /* Suitable for usage in qsort() */
969
970 if (*p < *q)
971 return -1;
972 if (*p > *q)
973 return 1;
974 return 0;
975 }
976
977 int ioprio_parse_priority(const char *s, int *ret) {
978 int i, r;
979
980 assert(s);
981 assert(ret);
982
983 r = safe_atoi(s, &i);
984 if (r < 0)
985 return r;
986
987 if (!ioprio_priority_is_valid(i))
988 return -EINVAL;
989
990 *ret = i;
991 return 0;
992 }
993
994 /* The cached PID, possible values:
995 *
996 * == UNSET [0] → cache not initialized yet
997 * == BUSY [-1] → some thread is initializing it at the moment
998 * any other → the cached PID
999 */
1000
1001 #define CACHED_PID_UNSET ((pid_t) 0)
1002 #define CACHED_PID_BUSY ((pid_t) -1)
1003
1004 static pid_t cached_pid = CACHED_PID_UNSET;
1005
1006 static void reset_cached_pid(void) {
1007 /* Invoked in the child after a fork(), i.e. at the first moment the PID changed */
1008 cached_pid = CACHED_PID_UNSET;
1009 }
1010
1011 /* We use glibc __register_atfork() + __dso_handle directly here, as they are not included in the glibc
1012 * headers. __register_atfork() is mostly equivalent to pthread_atfork(), but doesn't require us to link against
1013 * libpthread, as it is part of glibc anyway. */
1014 extern int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void * __dso_handle);
1015 extern void* __dso_handle __attribute__ ((__weak__));
1016
1017 pid_t getpid_cached(void) {
1018 pid_t current_value;
1019
1020 /* getpid_cached() is much like getpid(), but caches the value in local memory, to avoid having to invoke a
1021 * system call each time. This restores glibc behaviour from before 2.24, when getpid() was unconditionally
1022 * cached. Starting with 2.24 getpid() started to become prohibitively expensive when used for detecting when
1023 * objects were used across fork()s. With this caching the old behaviour is somewhat restored.
1024 *
1025 * https://bugzilla.redhat.com/show_bug.cgi?id=1443976
1026 * https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c579f48edba88380635ab98cb612030e3ed8691e
1027 */
1028
1029 current_value = __sync_val_compare_and_swap(&cached_pid, CACHED_PID_UNSET, CACHED_PID_BUSY);
1030
1031 switch (current_value) {
1032
1033 case CACHED_PID_UNSET: { /* Not initialized yet, then do so now */
1034 pid_t new_pid;
1035
1036 new_pid = getpid();
1037
1038 if (__register_atfork(NULL, NULL, reset_cached_pid, __dso_handle) != 0) {
1039 /* OOM? Let's try again later */
1040 cached_pid = CACHED_PID_UNSET;
1041 return new_pid;
1042 }
1043
1044 cached_pid = new_pid;
1045 return new_pid;
1046 }
1047
1048 case CACHED_PID_BUSY: /* Somebody else is currently initializing */
1049 return getpid();
1050
1051 default: /* Properly initialized */
1052 return current_value;
1053 }
1054 }
1055
1056 static const char *const ioprio_class_table[] = {
1057 [IOPRIO_CLASS_NONE] = "none",
1058 [IOPRIO_CLASS_RT] = "realtime",
1059 [IOPRIO_CLASS_BE] = "best-effort",
1060 [IOPRIO_CLASS_IDLE] = "idle"
1061 };
1062
1063 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
1064
1065 static const char *const sigchld_code_table[] = {
1066 [CLD_EXITED] = "exited",
1067 [CLD_KILLED] = "killed",
1068 [CLD_DUMPED] = "dumped",
1069 [CLD_TRAPPED] = "trapped",
1070 [CLD_STOPPED] = "stopped",
1071 [CLD_CONTINUED] = "continued",
1072 };
1073
1074 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
1075
1076 static const char* const sched_policy_table[] = {
1077 [SCHED_OTHER] = "other",
1078 [SCHED_BATCH] = "batch",
1079 [SCHED_IDLE] = "idle",
1080 [SCHED_FIFO] = "fifo",
1081 [SCHED_RR] = "rr"
1082 };
1083
1084 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);