8263437c136ce2c86d94937ae96cd6a006f24791
[sliver-openvswitch.git] / lib / process.c
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include "process.h"
19 #include <assert.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <signal.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/stat.h>
26 #include <sys/wait.h>
27 #include <unistd.h>
28 #include "coverage.h"
29 #include "dynamic-string.h"
30 #include "fatal-signal.h"
31 #include "list.h"
32 #include "poll-loop.h"
33 #include "socket-util.h"
34 #include "util.h"
35 #include "vlog.h"
36
37 VLOG_DEFINE_THIS_MODULE(process);
38
39 COVERAGE_DEFINE(process_run);
40 COVERAGE_DEFINE(process_run_capture);
41 COVERAGE_DEFINE(process_sigchld);
42 COVERAGE_DEFINE(process_start);
43
44 struct process {
45     struct list node;
46     char *name;
47     pid_t pid;
48
49     /* Modified by signal handler. */
50     volatile bool exited;
51     volatile int status;
52 };
53
54 /* Pipe used to signal child termination. */
55 static int fds[2];
56
57 /* All processes. */
58 static struct list all_processes = LIST_INITIALIZER(&all_processes);
59
60 static bool sigchld_is_blocked(void);
61 static void block_sigchld(sigset_t *);
62 static void unblock_sigchld(const sigset_t *);
63 static void sigchld_handler(int signr OVS_UNUSED);
64 static bool is_member(int x, const int *array, size_t);
65
66 /* Initializes the process subsystem (if it is not already initialized).  Calls
67  * exit() if initialization fails.
68  *
69  * Calling this function is optional; it will be called automatically by
70  * process_start() if necessary.  Calling it explicitly allows the client to
71  * prevent the process from exiting at an unexpected time. */
72 void
73 process_init(void)
74 {
75     static bool inited;
76     struct sigaction sa;
77
78     if (inited) {
79         return;
80     }
81     inited = true;
82
83     /* Create notification pipe. */
84     if (pipe(fds)) {
85         ovs_fatal(errno, "could not create pipe");
86     }
87     set_nonblocking(fds[0]);
88     set_nonblocking(fds[1]);
89
90     /* Set up child termination signal handler. */
91     memset(&sa, 0, sizeof sa);
92     sa.sa_handler = sigchld_handler;
93     sigemptyset(&sa.sa_mask);
94     sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
95     if (sigaction(SIGCHLD, &sa, NULL)) {
96         ovs_fatal(errno, "sigaction(SIGCHLD) failed");
97     }
98 }
99
100 char *
101 process_escape_args(char **argv)
102 {
103     struct ds ds = DS_EMPTY_INITIALIZER;
104     char **argp;
105     for (argp = argv; *argp; argp++) {
106         const char *arg = *argp;
107         const char *p;
108         if (argp != argv) {
109             ds_put_char(&ds, ' ');
110         }
111         if (arg[strcspn(arg, " \t\r\n\v\\\'\"")]) {
112             ds_put_char(&ds, '"');
113             for (p = arg; *p; p++) {
114                 if (*p == '\\' || *p == '\"') {
115                     ds_put_char(&ds, '\\');
116                 }
117                 ds_put_char(&ds, *p);
118             }
119             ds_put_char(&ds, '"');
120         } else {
121             ds_put_cstr(&ds, arg);
122         }
123     }
124     return ds_cstr(&ds);
125 }
126
127 /* Prepare to start a process whose command-line arguments are given by the
128  * null-terminated 'argv' array.  Returns 0 if successful, otherwise a
129  * positive errno value. */
130 static int
131 process_prestart(char **argv)
132 {
133     char *binary;
134
135     process_init();
136
137     /* Log the process to be started. */
138     if (VLOG_IS_DBG_ENABLED()) {
139         char *args = process_escape_args(argv);
140         VLOG_DBG("starting subprocess: %s", args);
141         free(args);
142     }
143
144     /* execvp() will search PATH too, but the error in that case is more
145      * obscure, since it is only reported post-fork. */
146     binary = process_search_path(argv[0]);
147     if (!binary) {
148         VLOG_ERR("%s not found in PATH", argv[0]);
149         return ENOENT;
150     }
151     free(binary);
152
153     return 0;
154 }
155
156 /* Creates and returns a new struct process with the specified 'name' and
157  * 'pid'.
158  *
159  * This is racy unless SIGCHLD is blocked (and has been blocked since before
160  * the fork()) that created the subprocess.  */
161 static struct process *
162 process_register(const char *name, pid_t pid)
163 {
164     struct process *p;
165     const char *slash;
166
167     assert(sigchld_is_blocked());
168
169     p = xzalloc(sizeof *p);
170     p->pid = pid;
171     slash = strrchr(name, '/');
172     p->name = xstrdup(slash ? slash + 1 : name);
173     p->exited = false;
174
175     list_push_back(&all_processes, &p->node);
176
177     return p;
178 }
179
180 /* Starts a subprocess with the arguments in the null-terminated argv[] array.
181  * argv[0] is used as the name of the process.  Searches the PATH environment
182  * variable to find the program to execute.
183  *
184  * All file descriptors are closed before executing the subprocess, except for
185  * fds 0, 1, and 2 and the 'n_keep_fds' fds listed in 'keep_fds'.  Also, any of
186  * the 'n_null_fds' fds listed in 'null_fds' are replaced by /dev/null.
187  *
188  * Returns 0 if successful, otherwise a positive errno value indicating the
189  * error.  If successful, '*pp' is assigned a new struct process that may be
190  * used to query the process's status.  On failure, '*pp' is set to NULL. */
191 int
192 process_start(char **argv,
193               const int keep_fds[], size_t n_keep_fds,
194               const int null_fds[], size_t n_null_fds,
195               struct process **pp)
196 {
197     sigset_t oldsigs;
198     int nullfd;
199     pid_t pid;
200     int error;
201
202     *pp = NULL;
203     COVERAGE_INC(process_start);
204     error = process_prestart(argv);
205     if (error) {
206         return error;
207     }
208
209     if (n_null_fds) {
210         nullfd = get_null_fd();
211         if (nullfd < 0) {
212             return -nullfd;
213         }
214     } else {
215         nullfd = -1;
216     }
217
218     block_sigchld(&oldsigs);
219     pid = fork();
220     if (pid < 0) {
221         unblock_sigchld(&oldsigs);
222         VLOG_WARN("fork failed: %s", strerror(errno));
223         return errno;
224     } else if (pid) {
225         /* Running in parent process. */
226         *pp = process_register(argv[0], pid);
227         unblock_sigchld(&oldsigs);
228         return 0;
229     } else {
230         /* Running in child process. */
231         int fd_max = get_max_fds();
232         int fd;
233
234         fatal_signal_fork();
235         unblock_sigchld(&oldsigs);
236         for (fd = 0; fd < fd_max; fd++) {
237             if (is_member(fd, null_fds, n_null_fds)) {
238                 dup2(nullfd, fd);
239             } else if (fd >= 3 && fd != nullfd
240                        && !is_member(fd, keep_fds, n_keep_fds)) {
241                 close(fd);
242             }
243         }
244         if (nullfd >= 0
245             && !is_member(nullfd, keep_fds, n_keep_fds)
246             && !is_member(nullfd, null_fds, n_null_fds)) {
247             close(nullfd);
248         }
249         execvp(argv[0], argv);
250         fprintf(stderr, "execvp(\"%s\") failed: %s\n",
251                 argv[0], strerror(errno));
252         _exit(1);
253     }
254 }
255
256 /* Destroys process 'p'. */
257 void
258 process_destroy(struct process *p)
259 {
260     if (p) {
261         sigset_t oldsigs;
262
263         block_sigchld(&oldsigs);
264         list_remove(&p->node);
265         unblock_sigchld(&oldsigs);
266
267         free(p->name);
268         free(p);
269     }
270 }
271
272 /* Sends signal 'signr' to process 'p'.  Returns 0 if successful, otherwise a
273  * positive errno value. */
274 int
275 process_kill(const struct process *p, int signr)
276 {
277     return (p->exited ? ESRCH
278             : !kill(p->pid, signr) ? 0
279             : errno);
280 }
281
282 /* Returns the pid of process 'p'. */
283 pid_t
284 process_pid(const struct process *p)
285 {
286     return p->pid;
287 }
288
289 /* Returns the name of process 'p' (the name passed to process_start() with any
290  * leading directories stripped). */
291 const char *
292 process_name(const struct process *p)
293 {
294     return p->name;
295 }
296
297 /* Returns true if process 'p' has exited, false otherwise. */
298 bool
299 process_exited(struct process *p)
300 {
301     if (p->exited) {
302         return true;
303     } else {
304         char buf[_POSIX_PIPE_BUF];
305         ignore(read(fds[0], buf, sizeof buf));
306         return false;
307     }
308 }
309
310 /* Returns process 'p''s exit status, as reported by waitpid(2).
311  * process_status(p) may be called only after process_exited(p) has returned
312  * true. */
313 int
314 process_status(const struct process *p)
315 {
316     assert(p->exited);
317     return p->status;
318 }
319
320 int
321 process_run(char **argv,
322             const int keep_fds[], size_t n_keep_fds,
323             const int null_fds[], size_t n_null_fds,
324             int *status)
325 {
326     struct process *p;
327     int retval;
328
329     COVERAGE_INC(process_run);
330     retval = process_start(argv, keep_fds, n_keep_fds, null_fds, n_null_fds,
331                            &p);
332     if (retval) {
333         *status = 0;
334         return retval;
335     }
336
337     while (!process_exited(p)) {
338         process_wait(p);
339         poll_block();
340     }
341     *status = process_status(p);
342     process_destroy(p);
343     return 0;
344 }
345
346 /* Given 'status', which is a process status in the form reported by waitpid(2)
347  * and returned by process_status(), returns a string describing how the
348  * process terminated.  The caller is responsible for freeing the string when
349  * it is no longer needed. */
350 char *
351 process_status_msg(int status)
352 {
353     struct ds ds = DS_EMPTY_INITIALIZER;
354     if (WIFEXITED(status)) {
355         ds_put_format(&ds, "exit status %d", WEXITSTATUS(status));
356     } else if (WIFSIGNALED(status) || WIFSTOPPED(status)) {
357         int signr = WIFSIGNALED(status) ? WTERMSIG(status) : WSTOPSIG(status);
358         const char *name = NULL;
359 #ifdef HAVE_STRSIGNAL
360         name = strsignal(signr);
361 #endif
362         ds_put_format(&ds, "%s by signal %d",
363                       WIFSIGNALED(status) ? "killed" : "stopped", signr);
364         if (name) {
365             ds_put_format(&ds, " (%s)", name);
366         }
367     } else {
368         ds_put_format(&ds, "terminated abnormally (%x)", status);
369     }
370     if (WCOREDUMP(status)) {
371         ds_put_cstr(&ds, ", core dumped");
372     }
373     return ds_cstr(&ds);
374 }
375
376 /* Causes the next call to poll_block() to wake up when process 'p' has
377  * exited. */
378 void
379 process_wait(struct process *p)
380 {
381     if (p->exited) {
382         poll_immediate_wake();
383     } else {
384         poll_fd_wait(fds[0], POLLIN);
385     }
386 }
387
388 char *
389 process_search_path(const char *name)
390 {
391     char *save_ptr = NULL;
392     char *path, *dir;
393     struct stat s;
394
395     if (strchr(name, '/') || !getenv("PATH")) {
396         return stat(name, &s) == 0 ? xstrdup(name) : NULL;
397     }
398
399     path = xstrdup(getenv("PATH"));
400     for (dir = strtok_r(path, ":", &save_ptr); dir;
401          dir = strtok_r(NULL, ":", &save_ptr)) {
402         char *file = xasprintf("%s/%s", dir, name);
403         if (stat(file, &s) == 0) {
404             free(path);
405             return file;
406         }
407         free(file);
408     }
409     free(path);
410     return NULL;
411 }
412 \f
413 /* process_run_capture() and supporting functions. */
414
415 struct stream {
416     struct ds log;
417     int fds[2];
418 };
419
420 static int
421 stream_open(struct stream *s)
422 {
423     ds_init(&s->log);
424     if (pipe(s->fds)) {
425         VLOG_WARN("failed to create pipe: %s", strerror(errno));
426         return errno;
427     }
428     set_nonblocking(s->fds[0]);
429     return 0;
430 }
431
432 static void
433 stream_read(struct stream *s)
434 {
435     if (s->fds[0] < 0) {
436         return;
437     }
438
439     for (;;) {
440         char buffer[512];
441         int error;
442         size_t n;
443
444         error = read_fully(s->fds[0], buffer, sizeof buffer, &n);
445         ds_put_buffer(&s->log, buffer, n);
446         if (error) {
447             if (error == EAGAIN || error == EWOULDBLOCK) {
448                 return;
449             } else {
450                 if (error != EOF) {
451                     VLOG_WARN("error reading subprocess pipe: %s",
452                               strerror(error));
453                 }
454                 break;
455             }
456         } else if (s->log.length > PROCESS_MAX_CAPTURE) {
457             VLOG_WARN("subprocess output overflowed %d-byte buffer",
458                       PROCESS_MAX_CAPTURE);
459             break;
460         }
461     }
462     close(s->fds[0]);
463     s->fds[0] = -1;
464 }
465
466 static void
467 stream_wait(struct stream *s)
468 {
469     if (s->fds[0] >= 0) {
470         poll_fd_wait(s->fds[0], POLLIN);
471     }
472 }
473
474 static void
475 stream_close(struct stream *s)
476 {
477     ds_destroy(&s->log);
478     if (s->fds[0] >= 0) {
479         close(s->fds[0]);
480     }
481     if (s->fds[1] >= 0) {
482         close(s->fds[1]);
483     }
484 }
485
486 /* Starts the process whose arguments are given in the null-terminated array
487  * 'argv' and waits for it to exit.  On success returns 0 and stores the
488  * process exit value (suitable for passing to process_status_msg()) in
489  * '*status'.  On failure, returns a positive errno value and stores 0 in
490  * '*status'.
491  *
492  * If 'stdout_log' is nonnull, then the subprocess's output to stdout (up to a
493  * limit of PROCESS_MAX_CAPTURE bytes) is captured in a memory buffer, which
494  * when this function returns 0 is stored as a null-terminated string in
495  * '*stdout_log'.  The caller is responsible for freeing '*stdout_log' (by
496  * passing it to free()).  When this function returns an error, '*stdout_log'
497  * is set to NULL.
498  *
499  * If 'stderr_log' is nonnull, then it is treated like 'stdout_log' except
500  * that it captures the subprocess's output to stderr. */
501 int
502 process_run_capture(char **argv, char **stdout_log, char **stderr_log,
503                     int *status)
504 {
505     struct stream s_stdout, s_stderr;
506     sigset_t oldsigs;
507     pid_t pid;
508     int error;
509
510     COVERAGE_INC(process_run_capture);
511     if (stdout_log) {
512         *stdout_log = NULL;
513     }
514     if (stderr_log) {
515         *stderr_log = NULL;
516     }
517     *status = 0;
518     error = process_prestart(argv);
519     if (error) {
520         return error;
521     }
522
523     error = stream_open(&s_stdout);
524     if (error) {
525         return error;
526     }
527
528     error = stream_open(&s_stderr);
529     if (error) {
530         stream_close(&s_stdout);
531         return error;
532     }
533
534     block_sigchld(&oldsigs);
535     pid = fork();
536     if (pid < 0) {
537         error = errno;
538
539         unblock_sigchld(&oldsigs);
540         VLOG_WARN("fork failed: %s", strerror(error));
541
542         stream_close(&s_stdout);
543         stream_close(&s_stderr);
544         *status = 0;
545         return error;
546     } else if (pid) {
547         /* Running in parent process. */
548         struct process *p;
549
550         p = process_register(argv[0], pid);
551         unblock_sigchld(&oldsigs);
552
553         close(s_stdout.fds[1]);
554         close(s_stderr.fds[1]);
555         while (!process_exited(p)) {
556             stream_read(&s_stdout);
557             stream_read(&s_stderr);
558
559             stream_wait(&s_stdout);
560             stream_wait(&s_stderr);
561             process_wait(p);
562             poll_block();
563         }
564         stream_read(&s_stdout);
565         stream_read(&s_stderr);
566
567         if (stdout_log) {
568             *stdout_log = ds_steal_cstr(&s_stdout.log);
569         }
570         if (stderr_log) {
571             *stderr_log = ds_steal_cstr(&s_stderr.log);
572         }
573
574         stream_close(&s_stdout);
575         stream_close(&s_stderr);
576
577         *status = process_status(p);
578         process_destroy(p);
579         return 0;
580     } else {
581         /* Running in child process. */
582         int max_fds;
583         int i;
584
585         fatal_signal_fork();
586         unblock_sigchld(&oldsigs);
587
588         dup2(get_null_fd(), 0);
589         dup2(s_stdout.fds[1], 1);
590         dup2(s_stderr.fds[1], 2);
591
592         max_fds = get_max_fds();
593         for (i = 3; i < max_fds; i++) {
594             close(i);
595         }
596
597         execvp(argv[0], argv);
598         fprintf(stderr, "execvp(\"%s\") failed: %s\n",
599                 argv[0], strerror(errno));
600         exit(EXIT_FAILURE);
601     }
602 }
603 \f
604 static void
605 sigchld_handler(int signr OVS_UNUSED)
606 {
607     struct process *p;
608
609     COVERAGE_INC(process_sigchld);
610     LIST_FOR_EACH (p, node, &all_processes) {
611         if (!p->exited) {
612             int retval, status;
613             do {
614                 retval = waitpid(p->pid, &status, WNOHANG);
615             } while (retval == -1 && errno == EINTR);
616             if (retval == p->pid) {
617                 p->exited = true;
618                 p->status = status;
619             } else if (retval < 0) {
620                 /* XXX We want to log something but we're in a signal
621                  * handler. */
622                 p->exited = true;
623                 p->status = -1;
624             }
625         }
626     }
627     ignore(write(fds[1], "", 1));
628 }
629
630 static bool
631 is_member(int x, const int *array, size_t n)
632 {
633     size_t i;
634
635     for (i = 0; i < n; i++) {
636         if (array[i] == x) {
637             return true;
638         }
639     }
640     return false;
641 }
642
643 static bool
644 sigchld_is_blocked(void)
645 {
646     sigset_t sigs;
647     if (sigprocmask(SIG_SETMASK, NULL, &sigs)) {
648         ovs_fatal(errno, "sigprocmask");
649     }
650     return sigismember(&sigs, SIGCHLD);
651 }
652
653 static void
654 block_sigchld(sigset_t *oldsigs)
655 {
656     sigset_t sigchld;
657     sigemptyset(&sigchld);
658     sigaddset(&sigchld, SIGCHLD);
659     if (sigprocmask(SIG_BLOCK, &sigchld, oldsigs)) {
660         ovs_fatal(errno, "sigprocmask");
661     }
662 }
663
664 static void
665 unblock_sigchld(const sigset_t *oldsigs)
666 {
667     if (sigprocmask(SIG_SETMASK, oldsigs, NULL)) {
668         ovs_fatal(errno, "sigprocmask");
669     }
670 }