예제 #1
0
int
main(int argc, char *argv[])
{
    struct unixctl_server *unixctl;
    struct signal *sighup;
    char *remote;
    bool exiting;
    int retval;

    proctitle_init(argc, argv);
    set_program_name(argv[0]);
    stress_init_command();
    remote = parse_options(argc, argv);
    signal(SIGPIPE, SIG_IGN);
    sighup = signal_register(SIGHUP);
    process_init();
    ovsrec_init();

    daemonize_start();

    retval = unixctl_server_create(NULL, &unixctl);
    if (retval) {
        exit(EXIT_FAILURE);
    }
    unixctl_command_register("exit", "", 0, 0, ovs_vswitchd_exit, &exiting);

    bridge_init(remote);
    free(remote);

    exiting = false;
    while (!exiting) {
        if (signal_poll(sighup)) {
            vlog_reopen_log_file();
        }
        bridge_run_fast();
        bridge_run();
        bridge_run_fast();
        unixctl_server_run(unixctl);
        netdev_run();

        signal_wait(sighup);
        bridge_wait();
        unixctl_server_wait(unixctl);
        netdev_wait();
        if (exiting) {
            poll_immediate_wake();
        }
        poll_block();
    }
    bridge_exit();
    unixctl_server_destroy(unixctl);
    signal_unregister(sighup);

    return 0;
}
/* Processes incoming requests for 'server'. */
static void
poll_server(int fd UNUSED, short int events UNUSED, void *server_)
{
    struct vlog_server *server = server_;
    for (;;) {
        char cmd_buf[512];
        struct sockaddr_un un;
        socklen_t un_len;
        char *reply;
        int error;

        error = recv_with_creds(server, cmd_buf, sizeof cmd_buf, &un, &un_len);
        if (error > 0) {
            if (error != EAGAIN && error != EWOULDBLOCK) {
                fprintf(stderr, "vlog: reading configuration socket: %s",
                        strerror(errno));
            }
            break;
        } else if (error < 0) {
            continue;
        }

        /* Process message and send reply. */
        if (!strncmp(cmd_buf, "set ", 4)) {
            char *msg = vlog_set_levels_from_string(cmd_buf + 4);
            reply = msg ? msg : xstrdup("ack");
        } else if (!strcmp(cmd_buf, "list")) {
            reply = vlog_get_levels();
        } else if (!strcmp(cmd_buf, "reopen")) {
            int error = vlog_reopen_log_file();
            reply = (error
                     ? xasprintf("could not reopen log file \"%s\": %s",
                                 vlog_get_log_file(), strerror(error))
                     : xstrdup("ack"));
        } else {
            reply = xstrdup("nak");
        }
        sendto(server->fd, reply, strlen(reply), 0,
               (struct sockaddr*) &un, un_len);
        free(reply);
    }
    server->waiter = poll_fd_callback(server->fd, POLLIN, poll_server, server);
}
예제 #3
0
int
main(int argc, char *argv[])
{
    char *unixctl_path = NULL;
    struct unixctl_server *unixctl;
    struct signal *sighup;
    char *remote;
    bool exiting;
    int retval;

    proctitle_init(argc, argv);
    set_program_name(argv[0]);
    service_start(&argc, &argv);
    remote = parse_options(argc, argv, &unixctl_path);
    signal(SIGPIPE, SIG_IGN);
    sighup = signal_register(SIGHUP);
    ovsrec_init();

    daemonize_start();

    if (want_mlockall) {
#ifdef HAVE_MLOCKALL
        if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
            VLOG_ERR("mlockall failed: %s", ovs_strerror(errno));
        }
#else
        VLOG_ERR("mlockall not supported on this system");
#endif
    }

    retval = unixctl_server_create(unixctl_path, &unixctl);
    if (retval) {
        exit(EXIT_FAILURE);
    }
    unixctl_command_register("exit", "", 0, 0, ovs_vswitchd_exit, &exiting);

    bridge_init(remote);
    free(remote);

    exiting = false;
    while (!exiting) {
        if (signal_poll(sighup)) {
            vlog_reopen_log_file();
        }
        memory_run();
        if (memory_should_report()) {
            struct simap usage;

            simap_init(&usage);
            bridge_get_memory_usage(&usage);
            memory_report(&usage);
            simap_destroy(&usage);
        }
        bridge_run();
        unixctl_server_run(unixctl);
        netdev_run();

        signal_wait(sighup);
        memory_wait();
        bridge_wait();
        unixctl_server_wait(unixctl);
        netdev_wait();
        if (exiting) {
            poll_immediate_wake();
        }
        poll_block();
        if (should_service_stop()) {
            exiting = true;
        }
    }
    bridge_exit();
    unixctl_server_destroy(unixctl);
    service_stop();

    return 0;
}
예제 #4
0
static void
monitor_daemon(pid_t daemon_pid)
{
    /* XXX Should log daemon's stderr output at startup time. */
    time_t last_restart;
    char *status_msg;
    int crashes;
    bool child_ready = true;

    set_subprogram_name("monitor");
    status_msg = xstrdup("healthy");
    last_restart = TIME_MIN;
    crashes = 0;
    for (;;) {
        int retval;
        int status;

        ovs_cmdl_proctitle_set("monitoring pid %lu (%s)",
                               (unsigned long int) daemon_pid, status_msg);

        if (child_ready) {
            int error;
            do {
                retval = waitpid(daemon_pid, &status, 0);
                error = retval == -1 ? errno : 0;
            } while (error == EINTR);
            vlog_reopen_log_file();
            if (error) {
                VLOG_FATAL("waitpid failed (%s)", ovs_strerror(error));
            }
        }

        if (!child_ready || retval == daemon_pid) {
            char *s = process_status_msg(status);
            if (should_restart(status)) {
                free(status_msg);
                status_msg = xasprintf("%d crashes: pid %lu died, %s",
                                       ++crashes,
                                       (unsigned long int) daemon_pid, s);
                free(s);

                if (WCOREDUMP(status)) {
                    /* Disable further core dumps to save disk space. */
                    struct rlimit r;

                    r.rlim_cur = 0;
                    r.rlim_max = 0;
                    if (setrlimit(RLIMIT_CORE, &r) == -1) {
                        VLOG_WARN("failed to disable core dumps: %s",
                                  ovs_strerror(errno));
                    }
                }

                /* Throttle restarts to no more than once every 10 seconds. */
                if (time(NULL) < last_restart + 10) {
                    VLOG_WARN("%s, waiting until 10 seconds since last "
                              "restart", status_msg);
                    for (;;) {
                        time_t now = time(NULL);
                        time_t wakeup = last_restart + 10;
                        if (now >= wakeup) {
                            break;
                        }
                        xsleep(wakeup - now);
                    }
                }
                last_restart = time(NULL);

                VLOG_ERR("%s, restarting", status_msg);
                child_ready = !fork_and_wait_for_startup(&daemonize_fd,
                                                         &daemon_pid);
                if (child_ready && !daemon_pid) {
                    /* Child process needs to break out of monitoring
                     * loop. */
                    break;
                }
            } else {
                VLOG_INFO("pid %lu died, %s, exiting",
                          (unsigned long int) daemon_pid, s);
                free(s);
                exit(0);
            }
        }
    }
    free(status_msg);

    /* Running in new daemon process. */
    ovs_cmdl_proctitle_restore();
    set_subprogram_name("");
}