chiark / gitweb /
550419d5ed608082bca14c7f7ae5e538a0f90f7b
[elogind.git] / src / basic / process-util.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2010 Lennart Poettering
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <ctype.h>
21 #include <errno.h>
22 #include <limits.h>
23 #include <linux/oom.h>
24 #include <sched.h>
25 #include <signal.h>
26 #include <stdbool.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/personality.h>
31 #include <sys/prctl.h>
32 #include <sys/types.h>
33 #include <sys/wait.h>
34 #include <syslog.h>
35 #include <unistd.h>
36 #ifdef HAVE_VALGRIND_VALGRIND_H
37 #include <valgrind/valgrind.h>
38 #endif
39
40 #include "alloc-util.h"
41 #include "escape.h"
42 #include "fd-util.h"
43 #include "fileio.h"
44 #include "fs-util.h"
45 //#include "ioprio.h"
46 #include "log.h"
47 #include "macro.h"
48 #include "missing.h"
49 #include "process-util.h"
50 #include "signal-util.h"
51 //#include "stat-util.h"
52 #include "string-table.h"
53 #include "string-util.h"
54 #include "user-util.h"
55 #include "util.h"
56
57 int get_process_state(pid_t pid) {
58         const char *p;
59         char state;
60         int r;
61         _cleanup_free_ char *line = NULL;
62
63         assert(pid >= 0);
64
65         p = procfs_file_alloca(pid, "stat");
66
67         r = read_one_line_file(p, &line);
68         if (r == -ENOENT)
69                 return -ESRCH;
70         if (r < 0)
71                 return r;
72
73         p = strrchr(line, ')');
74         if (!p)
75                 return -EIO;
76
77         p++;
78
79         if (sscanf(p, " %c", &state) != 1)
80                 return -EIO;
81
82         return (unsigned char) state;
83 }
84
85 int get_process_comm(pid_t pid, char **name) {
86         const char *p;
87         int r;
88
89         assert(name);
90         assert(pid >= 0);
91
92         p = procfs_file_alloca(pid, "comm");
93
94         r = read_one_line_file(p, name);
95         if (r == -ENOENT)
96                 return -ESRCH;
97
98         return r;
99 }
100
101 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
102         _cleanup_fclose_ FILE *f = NULL;
103         char *r = NULL, *k;
104         const char *p;
105         int c;
106
107         assert(line);
108         assert(pid >= 0);
109
110         p = procfs_file_alloca(pid, "cmdline");
111
112         f = fopen(p, "re");
113         if (!f) {
114                 if (errno == ENOENT)
115                         return -ESRCH;
116                 return -errno;
117         }
118
119         if (max_length == 0) {
120                 size_t len = 0, allocated = 0;
121
122                 while ((c = getc(f)) != EOF) {
123
124                         if (!GREEDY_REALLOC(r, allocated, len+2)) {
125                                 free(r);
126                                 return -ENOMEM;
127                         }
128
129                         r[len++] = isprint(c) ? c : ' ';
130                 }
131
132                 if (len > 0)
133                         r[len-1] = 0;
134
135         } else {
136                 bool space = false;
137                 size_t left;
138
139                 r = new(char, max_length);
140                 if (!r)
141                         return -ENOMEM;
142
143                 k = r;
144                 left = max_length;
145                 while ((c = getc(f)) != EOF) {
146
147                         if (isprint(c)) {
148                                 if (space) {
149                                         if (left <= 4)
150                                                 break;
151
152                                         *(k++) = ' ';
153                                         left--;
154                                         space = false;
155                                 }
156
157                                 if (left <= 4)
158                                         break;
159
160                                 *(k++) = (char) c;
161                                 left--;
162                         }  else
163                                 space = true;
164                 }
165
166                 if (left <= 4) {
167                         size_t n = MIN(left-1, 3U);
168                         memcpy(k, "...", n);
169                         k[n] = 0;
170                 } else
171                         *k = 0;
172         }
173
174         /* Kernel threads have no argv[] */
175         if (isempty(r)) {
176                 _cleanup_free_ char *t = NULL;
177                 int h;
178
179                 free(r);
180
181                 if (!comm_fallback)
182                         return -ENOENT;
183
184                 h = get_process_comm(pid, &t);
185                 if (h < 0)
186                         return h;
187
188                 r = strjoin("[", t, "]", NULL);
189                 if (!r)
190                         return -ENOMEM;
191         }
192
193         *line = r;
194         return 0;
195 }
196
197 #if 0 /// UNNEEDED by elogind
198 void rename_process(const char name[8]) {
199         assert(name);
200
201         /* This is a like a poor man's setproctitle(). It changes the
202          * comm field, argv[0], and also the glibc's internally used
203          * name of the process. For the first one a limit of 16 chars
204          * applies, to the second one usually one of 10 (i.e. length
205          * of "/sbin/init"), to the third one one of 7 (i.e. length of
206          * "systemd"). If you pass a longer string it will be
207          * truncated */
208
209         prctl(PR_SET_NAME, name);
210
211         if (program_invocation_name)
212                 strncpy(program_invocation_name, name, strlen(program_invocation_name));
213
214         if (saved_argc > 0) {
215                 int i;
216
217                 if (saved_argv[0])
218                         strncpy(saved_argv[0], name, strlen(saved_argv[0]));
219
220                 for (i = 1; i < saved_argc; i++) {
221                         if (!saved_argv[i])
222                                 break;
223
224                         memzero(saved_argv[i], strlen(saved_argv[i]));
225                 }
226         }
227 }
228 #endif // 0
229
230 int is_kernel_thread(pid_t pid) {
231         const char *p;
232         size_t count;
233         char c;
234         bool eof;
235         FILE *f;
236
237         if (pid == 0 || pid == 1) /* pid 1, and we ourselves certainly aren't a kernel thread */
238                 return 0;
239
240         assert(pid > 1);
241
242         p = procfs_file_alloca(pid, "cmdline");
243         f = fopen(p, "re");
244         if (!f) {
245                 if (errno == ENOENT)
246                         return -ESRCH;
247                 return -errno;
248         }
249
250         count = fread(&c, 1, 1, f);
251         eof = feof(f);
252         fclose(f);
253
254         /* Kernel threads have an empty cmdline */
255
256         if (count <= 0)
257                 return eof ? 1 : -errno;
258
259         return 0;
260 }
261
262 #if 0 /// UNNEEDED by elogind
263 int get_process_capeff(pid_t pid, char **capeff) {
264         const char *p;
265         int r;
266
267         assert(capeff);
268         assert(pid >= 0);
269
270         p = procfs_file_alloca(pid, "status");
271
272         r = get_proc_field(p, "CapEff", WHITESPACE, capeff);
273         if (r == -ENOENT)
274                 return -ESRCH;
275
276         return r;
277 }
278 #endif // 0
279
280 static int get_process_link_contents(const char *proc_file, char **name) {
281         int r;
282
283         assert(proc_file);
284         assert(name);
285
286         r = readlink_malloc(proc_file, name);
287         if (r == -ENOENT)
288                 return -ESRCH;
289         if (r < 0)
290                 return r;
291
292         return 0;
293 }
294
295 int get_process_exe(pid_t pid, char **name) {
296         const char *p;
297         char *d;
298         int r;
299
300         assert(pid >= 0);
301
302         p = procfs_file_alloca(pid, "exe");
303         r = get_process_link_contents(p, name);
304         if (r < 0)
305                 return r;
306
307         d = endswith(*name, " (deleted)");
308         if (d)
309                 *d = '\0';
310
311         return 0;
312 }
313
314 #if 0 /// UNNEEDED by elogind
315 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
316         _cleanup_fclose_ FILE *f = NULL;
317         char line[LINE_MAX];
318         const char *p;
319
320         assert(field);
321         assert(uid);
322
323         if (pid == 0)
324                 return getuid();
325
326         p = procfs_file_alloca(pid, "status");
327         f = fopen(p, "re");
328         if (!f) {
329                 if (errno == ENOENT)
330                         return -ESRCH;
331                 return -errno;
332         }
333
334         FOREACH_LINE(line, f, return -errno) {
335                 char *l;
336
337                 l = strstrip(line);
338
339                 if (startswith(l, field)) {
340                         l += strlen(field);
341                         l += strspn(l, WHITESPACE);
342
343                         l[strcspn(l, WHITESPACE)] = 0;
344
345                         return parse_uid(l, uid);
346                 }
347         }
348
349         return -EIO;
350 }
351
352 int get_process_uid(pid_t pid, uid_t *uid) {
353         return get_process_id(pid, "Uid:", uid);
354 }
355
356 int get_process_gid(pid_t pid, gid_t *gid) {
357         assert_cc(sizeof(uid_t) == sizeof(gid_t));
358         return get_process_id(pid, "Gid:", gid);
359 }
360
361 int get_process_cwd(pid_t pid, char **cwd) {
362         const char *p;
363
364         assert(pid >= 0);
365
366         p = procfs_file_alloca(pid, "cwd");
367
368         return get_process_link_contents(p, cwd);
369 }
370
371 int get_process_root(pid_t pid, char **root) {
372         const char *p;
373
374         assert(pid >= 0);
375
376         p = procfs_file_alloca(pid, "root");
377
378         return get_process_link_contents(p, root);
379 }
380
381 int get_process_environ(pid_t pid, char **env) {
382         _cleanup_fclose_ FILE *f = NULL;
383         _cleanup_free_ char *outcome = NULL;
384         int c;
385         const char *p;
386         size_t allocated = 0, sz = 0;
387
388         assert(pid >= 0);
389         assert(env);
390
391         p = procfs_file_alloca(pid, "environ");
392
393         f = fopen(p, "re");
394         if (!f) {
395                 if (errno == ENOENT)
396                         return -ESRCH;
397                 return -errno;
398         }
399
400         while ((c = fgetc(f)) != EOF) {
401                 if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
402                         return -ENOMEM;
403
404                 if (c == '\0')
405                         outcome[sz++] = '\n';
406                 else
407                         sz += cescape_char(c, outcome + sz);
408         }
409
410         if (!outcome) {
411                 outcome = strdup("");
412                 if (!outcome)
413                         return -ENOMEM;
414         } else
415         outcome[sz] = '\0';
416
417         *env = outcome;
418         outcome = NULL;
419
420         return 0;
421 }
422
423 int get_process_ppid(pid_t pid, pid_t *_ppid) {
424         int r;
425         _cleanup_free_ char *line = NULL;
426         long unsigned ppid;
427         const char *p;
428
429         assert(pid >= 0);
430         assert(_ppid);
431
432         if (pid == 0) {
433                 *_ppid = getppid();
434                 return 0;
435         }
436
437         p = procfs_file_alloca(pid, "stat");
438         r = read_one_line_file(p, &line);
439         if (r == -ENOENT)
440                 return -ESRCH;
441         if (r < 0)
442                 return r;
443
444         /* Let's skip the pid and comm fields. The latter is enclosed
445          * in () but does not escape any () in its value, so let's
446          * skip over it manually */
447
448         p = strrchr(line, ')');
449         if (!p)
450                 return -EIO;
451
452         p++;
453
454         if (sscanf(p, " "
455                    "%*c "  /* state */
456                    "%lu ", /* ppid */
457                    &ppid) != 1)
458                 return -EIO;
459
460         if ((long unsigned) (pid_t) ppid != ppid)
461                 return -ERANGE;
462
463         *_ppid = (pid_t) ppid;
464
465         return 0;
466 }
467 #endif // 0
468
469 int wait_for_terminate(pid_t pid, siginfo_t *status) {
470         siginfo_t dummy;
471
472         assert(pid >= 1);
473
474         if (!status)
475                 status = &dummy;
476
477         for (;;) {
478                 zero(*status);
479
480                 if (waitid(P_PID, pid, status, WEXITED) < 0) {
481
482                         if (errno == EINTR)
483                                 continue;
484
485                         return -errno;
486                 }
487
488                 return 0;
489         }
490 }
491
492 /*
493  * Return values:
494  * < 0 : wait_for_terminate() failed to get the state of the
495  *       process, the process was terminated by a signal, or
496  *       failed for an unknown reason.
497  * >=0 : The process terminated normally, and its exit code is
498  *       returned.
499  *
500  * That is, success is indicated by a return value of zero, and an
501  * error is indicated by a non-zero value.
502  *
503  * A warning is emitted if the process terminates abnormally,
504  * and also if it returns non-zero unless check_exit_code is true.
505  */
506 int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code) {
507         int r;
508         siginfo_t status;
509
510         assert(name);
511         assert(pid > 1);
512
513         r = wait_for_terminate(pid, &status);
514         if (r < 0)
515                 return log_warning_errno(r, "Failed to wait for %s: %m", name);
516
517         if (status.si_code == CLD_EXITED) {
518                 if (status.si_status != 0)
519                         log_full(check_exit_code ? LOG_WARNING : LOG_DEBUG,
520                                  "%s failed with error code %i.", name, status.si_status);
521                 else
522                         log_debug("%s succeeded.", name);
523
524                 return status.si_status;
525         } else if (status.si_code == CLD_KILLED ||
526                    status.si_code == CLD_DUMPED) {
527
528                 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
529                 return -EPROTO;
530         }
531
532         log_warning("%s failed due to unknown reason.", name);
533         return -EPROTO;
534 }
535
536 void sigkill_wait(pid_t *pid) {
537         if (!pid)
538                 return;
539         if (*pid <= 1)
540                 return;
541
542         if (kill(*pid, SIGKILL) > 0)
543                 (void) wait_for_terminate(*pid, NULL);
544 }
545
546 #if 0 /// UNNEEDED by elogind
547 int kill_and_sigcont(pid_t pid, int sig) {
548         int r;
549
550         r = kill(pid, sig) < 0 ? -errno : 0;
551
552         if (r >= 0)
553                 kill(pid, SIGCONT);
554
555         return r;
556 }
557 #endif // 0
558
559 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
560         _cleanup_fclose_ FILE *f = NULL;
561         char *value = NULL;
562         int r;
563         bool done = false;
564         size_t l;
565         const char *path;
566
567         assert(pid >= 0);
568         assert(field);
569         assert(_value);
570
571         path = procfs_file_alloca(pid, "environ");
572
573         f = fopen(path, "re");
574         if (!f) {
575                 if (errno == ENOENT)
576                         return -ESRCH;
577                 return -errno;
578         }
579
580         l = strlen(field);
581         r = 0;
582
583         do {
584                 char line[LINE_MAX];
585                 unsigned i;
586
587                 for (i = 0; i < sizeof(line)-1; i++) {
588                         int c;
589
590                         c = getc(f);
591                         if (_unlikely_(c == EOF)) {
592                                 done = true;
593                                 break;
594                         } else if (c == 0)
595                                 break;
596
597                         line[i] = c;
598                 }
599                 line[i] = 0;
600
601                 if (memcmp(line, field, l) == 0 && line[l] == '=') {
602                         value = strdup(line + l + 1);
603                         if (!value)
604                                 return -ENOMEM;
605
606                         r = 1;
607                         break;
608                 }
609
610         } while (!done);
611
612         *_value = value;
613         return r;
614 }
615
616 bool pid_is_unwaited(pid_t pid) {
617         /* Checks whether a PID is still valid at all, including a zombie */
618
619         if (pid < 0)
620                 return false;
621
622         if (pid <= 1) /* If we or PID 1 would be dead and have been waited for, this code would not be running */
623                 return true;
624
625         if (kill(pid, 0) >= 0)
626                 return true;
627
628         return errno != ESRCH;
629 }
630
631 bool pid_is_alive(pid_t pid) {
632         int r;
633
634         /* Checks whether a PID is still valid and not a zombie */
635
636         if (pid < 0)
637                 return false;
638
639         if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
640                 return true;
641
642         r = get_process_state(pid);
643         if (r == -ESRCH || r == 'Z')
644                 return false;
645
646         return true;
647 }
648
649 #if 0 /// UNNEEDED by elogind
650 int pid_from_same_root_fs(pid_t pid) {
651         const char *root;
652
653         if (pid < 0)
654                 return 0;
655
656         root = procfs_file_alloca(pid, "root");
657
658         return files_same(root, "/proc/1/root");
659 }
660 #endif // 0
661
662 bool is_main_thread(void) {
663         static thread_local int cached = 0;
664
665         if (_unlikely_(cached == 0))
666                 cached = getpid() == gettid() ? 1 : -1;
667
668         return cached > 0;
669 }
670
671 #if 0 /// UNNEEDED by elogind
672 noreturn void freeze(void) {
673
674         /* Make sure nobody waits for us on a socket anymore */
675         close_all_fds(NULL, 0);
676
677         sync();
678
679         for (;;)
680                 pause();
681 }
682
683 bool oom_score_adjust_is_valid(int oa) {
684         return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
685 }
686
687 unsigned long personality_from_string(const char *p) {
688
689         /* Parse a personality specifier. We introduce our own
690          * identifiers that indicate specific ABIs, rather than just
691          * hints regarding the register size, since we want to keep
692          * things open for multiple locally supported ABIs for the
693          * same register size. We try to reuse the ABI identifiers
694          * used by libseccomp. */
695
696 #if defined(__x86_64__)
697
698         if (streq(p, "x86"))
699                 return PER_LINUX32;
700
701         if (streq(p, "x86-64"))
702                 return PER_LINUX;
703
704 #elif defined(__i386__)
705
706         if (streq(p, "x86"))
707                 return PER_LINUX;
708
709 #elif defined(__s390x__)
710
711         if (streq(p, "s390"))
712                 return PER_LINUX32;
713
714         if (streq(p, "s390x"))
715                 return PER_LINUX;
716
717 #elif defined(__s390__)
718
719         if (streq(p, "s390"))
720                 return PER_LINUX;
721 #endif
722
723         return PERSONALITY_INVALID;
724 }
725
726 const char* personality_to_string(unsigned long p) {
727
728 #if defined(__x86_64__)
729
730         if (p == PER_LINUX32)
731                 return "x86";
732
733         if (p == PER_LINUX)
734                 return "x86-64";
735
736 #elif defined(__i386__)
737
738         if (p == PER_LINUX)
739                 return "x86";
740
741 #elif defined(__s390x__)
742
743         if (p == PER_LINUX)
744                 return "s390x";
745
746         if (p == PER_LINUX32)
747                 return "s390";
748
749 #elif defined(__s390__)
750
751         if (p == PER_LINUX)
752                 return "s390";
753
754 #endif
755
756         return NULL;
757 }
758
759 void valgrind_summary_hack(void) {
760 #ifdef HAVE_VALGRIND_VALGRIND_H
761         if (getpid() == 1 && RUNNING_ON_VALGRIND) {
762                 pid_t pid;
763                 pid = raw_clone(SIGCHLD, NULL);
764                 if (pid < 0)
765                         log_emergency_errno(errno, "Failed to fork off valgrind helper: %m");
766                 else if (pid == 0)
767                         exit(EXIT_SUCCESS);
768                 else {
769                         log_info("Spawned valgrind helper as PID "PID_FMT".", pid);
770                         (void) wait_for_terminate(pid, NULL);
771                 }
772         }
773 #endif
774 }
775
776 static const char *const ioprio_class_table[] = {
777         [IOPRIO_CLASS_NONE] = "none",
778         [IOPRIO_CLASS_RT] = "realtime",
779         [IOPRIO_CLASS_BE] = "best-effort",
780         [IOPRIO_CLASS_IDLE] = "idle"
781 };
782
783 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
784
785 static const char *const sigchld_code_table[] = {
786         [CLD_EXITED] = "exited",
787         [CLD_KILLED] = "killed",
788         [CLD_DUMPED] = "dumped",
789         [CLD_TRAPPED] = "trapped",
790         [CLD_STOPPED] = "stopped",
791         [CLD_CONTINUED] = "continued",
792 };
793
794 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
795
796 static const char* const sched_policy_table[] = {
797         [SCHED_OTHER] = "other",
798         [SCHED_BATCH] = "batch",
799         [SCHED_IDLE] = "idle",
800         [SCHED_FIFO] = "fifo",
801         [SCHED_RR] = "rr"
802 };
803
804 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
805 #endif // 0