~ubuntu-branches/ubuntu/wily/openvswitch/wily

« back to all changes in this revision

Viewing changes to lib/daemon-unix.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-08-10 11:35:15 UTC
  • mfrom: (1.1.30)
  • Revision ID: package-import@ubuntu.com-20150810113515-575vj06oq29emxsn
Tags: 2.4.0~git20150810.97bab95-0ubuntu1
* New upstream snapshot from 2.4 branch:
  - d/*: Align any relevant packaging changes with upstream.
* d/*: wrap-and-sort.
* d/openvswitch-{common,vswitch}.install: Correct install location for
  bash completion files.
* d/tests/openflow.py: Explicitly use ovs-testcontroller as provided
  by 2.4.0 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include "socket-util.h"
36
36
#include "timeval.h"
37
37
#include "util.h"
38
 
#include "vlog.h"
 
38
#include "openvswitch/vlog.h"
39
39
 
40
40
VLOG_DEFINE_THIS_MODULE(daemon_unix);
41
41
 
214
214
/* Forks, then:
215
215
 *
216
216
 *   - In the parent, waits for the child to signal that it has completed its
217
 
 *     startup sequence.  Then stores -1 in '*fdp' and returns the child's pid.
218
 
 *
219
 
 *   - In the child, stores a fd in '*fdp' and returns 0.  The caller should
220
 
 *     pass the fd to fork_notify_startup() after it finishes its startup
221
 
 *     sequence.
222
 
 *
223
 
 * If something goes wrong with the fork, logs a critical error and aborts the
224
 
 * process. */
225
 
static pid_t
226
 
fork_and_wait_for_startup(int *fdp)
 
217
 *     startup sequence.  Then stores -1 in '*fdp' and returns the child's
 
218
 *     pid in '*child_pid' argument.
 
219
 *
 
220
 *   - In the child, stores a fd in '*fdp' and returns 0 through '*child_pid'
 
221
 *     argument.  The caller should pass the fd to fork_notify_startup() after
 
222
 *     it finishes its startup sequence.
 
223
 *
 
224
 * Returns 0 on success.  If something goes wrong and child process was not
 
225
 * able to signal its readiness by calling fork_notify_startup(), then this
 
226
 * function returns -1. However, even in case of failure it still sets child
 
227
 * process id in '*child_pid'. */
 
228
static int
 
229
fork_and_wait_for_startup(int *fdp, pid_t *child_pid)
227
230
{
228
231
    int fds[2];
229
232
    pid_t pid;
 
233
    int ret = 0;
230
234
 
231
235
    xpipe(fds);
232
236
 
252
256
                    exit(WEXITSTATUS(status));
253
257
                } else {
254
258
                    char *status_msg = process_status_msg(status);
255
 
                    VLOG_FATAL("fork child died before signaling startup (%s)",
256
 
                               status_msg);
 
259
                    VLOG_ERR("fork child died before signaling startup (%s)",
 
260
                             status_msg);
 
261
                    ret = -1;
257
262
                }
258
263
            } else if (retval < 0) {
259
264
                VLOG_FATAL("waitpid failed (%s)", ovs_strerror(errno));
268
273
        close(fds[0]);
269
274
        *fdp = fds[1];
270
275
    }
271
 
 
272
 
    return pid;
 
276
    *child_pid = pid;
 
277
    return ret;
273
278
}
274
279
 
275
280
static void
317
322
    time_t last_restart;
318
323
    char *status_msg;
319
324
    int crashes;
 
325
    bool child_ready = true;
320
326
 
321
327
    set_subprogram_name("monitor");
322
328
    status_msg = xstrdup("healthy");
326
332
        int retval;
327
333
        int status;
328
334
 
329
 
        proctitle_set("monitoring pid %lu (%s)",
330
 
                      (unsigned long int) daemon_pid, status_msg);
331
 
 
332
 
        do {
333
 
            retval = waitpid(daemon_pid, &status, 0);
334
 
        } while (retval == -1 && errno == EINTR);
335
 
 
336
 
        if (retval == -1) {
337
 
            VLOG_FATAL("waitpid failed (%s)", ovs_strerror(errno));
338
 
        } else if (retval == daemon_pid) {
 
335
        ovs_cmdl_proctitle_set("monitoring pid %lu (%s)",
 
336
                               (unsigned long int) daemon_pid, status_msg);
 
337
 
 
338
        if (child_ready) {
 
339
            do {
 
340
                retval = waitpid(daemon_pid, &status, 0);
 
341
            } while (retval == -1 && errno == EINTR);
 
342
            if (retval == -1) {
 
343
                VLOG_FATAL("waitpid failed (%s)", ovs_strerror(errno));
 
344
            }
 
345
        }
 
346
 
 
347
        if (!child_ready || retval == daemon_pid) {
339
348
            char *s = process_status_msg(status);
340
349
            if (should_restart(status)) {
341
350
                free(status_msg);
372
381
                last_restart = time(NULL);
373
382
 
374
383
                VLOG_ERR("%s, restarting", status_msg);
375
 
                daemon_pid = fork_and_wait_for_startup(&daemonize_fd);
376
 
                if (!daemon_pid) {
 
384
                child_ready = !fork_and_wait_for_startup(&daemonize_fd,
 
385
                                                         &daemon_pid);
 
386
                if (child_ready && !daemon_pid) {
 
387
                    /* Child process needs to break out of monitoring
 
388
                     * loop. */
377
389
                    break;
378
390
                }
379
391
            } else {
387
399
    free(status_msg);
388
400
 
389
401
    /* Running in new daemon process. */
390
 
    proctitle_restore();
 
402
    ovs_cmdl_proctitle_restore();
391
403
    set_subprogram_name("");
392
404
}
393
405
 
403
415
    daemonize_fd = -1;
404
416
 
405
417
    if (detach) {
406
 
        if (fork_and_wait_for_startup(&daemonize_fd) > 0) {
 
418
        pid_t pid;
 
419
 
 
420
        if (fork_and_wait_for_startup(&daemonize_fd, &pid)) {
 
421
            VLOG_FATAL("could not detach from foreground session");
 
422
        }
 
423
        if (pid > 0) {
407
424
            /* Running in parent process. */
408
425
            exit(0);
409
426
        }
416
433
        int saved_daemonize_fd = daemonize_fd;
417
434
        pid_t daemon_pid;
418
435
 
419
 
        daemon_pid = fork_and_wait_for_startup(&daemonize_fd);
 
436
        if (fork_and_wait_for_startup(&daemonize_fd, &daemon_pid)) {
 
437
            VLOG_FATAL("could not initiate process monitoring");
 
438
        }
420
439
        if (daemon_pid > 0) {
421
440
            /* Running in monitor process. */
422
441
            fork_notify_startup(saved_daemonize_fd);