Esempio n. 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;
}
Esempio n. 2
0
int
main(int argc, char *argv[])
{
    char *unixctl_path = NULL;
    struct unixctl_server *unixctl;
    char *remote;
    bool exiting;
    int retval;

    set_program_name(argv[0]);
    retval = dpdk_init(argc,argv);
    argc -= retval;
    argv += retval;

    ovs_cmdl_proctitle_init(argc, argv);
    service_start(&argc, &argv);
    remote = parse_options(argc, argv, &unixctl_path);
    fatal_ignore_sigpipe();
    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) {
        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();

        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;
}
int
main(int argc, char *argv[])
{
    struct unixctl_server *server;
    enum { MAX_RECV = 1500 };
    const char *target;
    struct ofpbuf buf;
    bool exiting = false;
    int error;
    int sock;
    int n;

    proctitle_init(argc, argv);
    set_program_name(argv[0]);
    parse_options(argc, argv);

    if (argc - optind != 1) {
        ovs_fatal(0, "exactly one non-option argument required "
                  "(use --help for help)");
    }
    target = argv[optind];

    sock = inet_open_passive(SOCK_DGRAM, target, 0, NULL, 0);
    if (sock < 0) {
        ovs_fatal(0, "%s: failed to open (%s)", argv[1], strerror(-sock));
    }

    daemon_save_fd(STDOUT_FILENO);
    daemonize_start();

    error = unixctl_server_create(NULL, &server);
    if (error) {
        ovs_fatal(error, "failed to create unixctl server");
    }
    unixctl_command_register("exit", "", 0, 0, test_netflow_exit, &exiting);

    daemonize_complete();

    ofpbuf_init(&buf, MAX_RECV);
    n = 0;
    for (;;) {
        int retval;

        unixctl_server_run(server);

        ofpbuf_clear(&buf);
        do {
            retval = read(sock, buf.data, buf.allocated);
        } while (retval < 0 && errno == EINTR);
        if (retval > 0) {
            ofpbuf_put_uninit(&buf, retval);
            if (n++ > 0) {
                putchar('\n');
            }
            print_netflow(&buf);
            fflush(stdout);
        }

        if (exiting) {
            break;
        }

        poll_fd_wait(sock, POLLIN);
        unixctl_server_wait(server);
        poll_block();
    }

    return 0;
}
Esempio n. 4
0
/* If configured with set_pidfile() or set_detach(), creates the pid file and
 * detaches from the foreground session.  */
void
daemonize(void)
{
    daemonize_start();
    daemonize_complete();
}
Esempio n. 5
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]);
    stress_init_command();
    remote = parse_options(argc, argv, &unixctl_path);
    signal(SIGPIPE, SIG_IGN);
    sighup = signal_register(SIGHUP);
    process_init();
    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
    }

    worker_start();

    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) {
        worker_run();
        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_fast();
        bridge_run();
        bridge_run_fast();
        unixctl_server_run(unixctl);
        netdev_run();

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

    return 0;
}
Esempio n. 6
0
int
main(int argc, char *argv[])
{
    struct unixctl_server *unixctl;
    bool exiting;
    int retval;

    ovs_cmdl_proctitle_init(argc, argv);
    set_program_name(argv[0]);
    parse_options(argc, argv);
    fatal_ignore_sigpipe();

    daemonize_start();

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

    daemonize_complete();

    ovsrec_init();
    sbrec_init();

    ofctrl_init();
    lflow_init();

    /* Connect to OVS OVSDB instance.  We do not monitor all tables by
     * default, so modules must register their interest explicitly.  */
    struct idl_loop ovs_idl_loop = IDL_LOOP_INITIALIZER(
        ovsdb_idl_create(ovs_remote, &ovsrec_idl_class, false, true));
    ovsdb_idl_add_table(ovs_idl_loop.idl, &ovsrec_table_open_vswitch);
    ovsdb_idl_add_column(ovs_idl_loop.idl,
                         &ovsrec_open_vswitch_col_external_ids);
    chassis_register_ovs_idl(ovs_idl_loop.idl);
    encaps_register_ovs_idl(ovs_idl_loop.idl);
    binding_register_ovs_idl(ovs_idl_loop.idl);
    physical_register_ovs_idl(ovs_idl_loop.idl);
    get_initial_snapshot(ovs_idl_loop.idl);

    /* Connect to OVN SB database. */
    char *ovnsb_remote = get_ovnsb_remote(ovs_idl_loop.idl);
    struct idl_loop ovnsb_idl_loop = IDL_LOOP_INITIALIZER(
        ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true));
    get_initial_snapshot(ovnsb_idl_loop.idl);

    /* Main loop. */
    exiting = false;
    while (!exiting) {
        struct controller_ctx ctx = {
            .ovs_idl = ovs_idl_loop.idl,
            .ovs_idl_txn = idl_loop_run(&ovs_idl_loop),
            .ovnsb_idl = ovnsb_idl_loop.idl,
            .ovnsb_idl_txn = idl_loop_run(&ovnsb_idl_loop),
        };

        const struct ovsrec_bridge *br_int = get_br_int(ctx.ovs_idl);
        const char *chassis_id = get_chassis_id(ctx.ovs_idl);

        if (chassis_id) {
            chassis_run(&ctx, chassis_id);
            encaps_run(&ctx, br_int, chassis_id);
            binding_run(&ctx, br_int, chassis_id);
        }

        if (br_int) {
            struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
            lflow_run(&ctx, &flow_table);
            if (chassis_id) {
                physical_run(&ctx, br_int, chassis_id, &flow_table);
            }
            ofctrl_run(br_int, &flow_table);
            hmap_destroy(&flow_table);
        }

        unixctl_server_run(unixctl);

        unixctl_server_wait(unixctl);
        if (exiting) {
            poll_immediate_wake();
        }

        idl_loop_commit_and_wait(&ovnsb_idl_loop);
        idl_loop_commit_and_wait(&ovs_idl_loop);

        if (br_int) {
            ofctrl_wait();
        }
        poll_block();
    }

    /* It's time to exit.  Clean up the databases. */
    bool done = false;
    while (!done) {
        struct controller_ctx ctx = {
            .ovs_idl = ovs_idl_loop.idl,
            .ovs_idl_txn = idl_loop_run(&ovs_idl_loop),
            .ovnsb_idl = ovnsb_idl_loop.idl,
            .ovnsb_idl_txn = idl_loop_run(&ovnsb_idl_loop),
        };

        const struct ovsrec_bridge *br_int = get_br_int(ctx.ovs_idl);
        const char *chassis_id = get_chassis_id(ctx.ovs_idl);

        /* Run all of the cleanup functions, even if one of them returns false.
         * We're done if all of them return true. */
        done = binding_cleanup(&ctx, chassis_id);
        done = chassis_cleanup(&ctx, chassis_id) && done;
        done = encaps_cleanup(&ctx, br_int) && done;
        if (done) {
            poll_immediate_wake();
        }

        idl_loop_commit_and_wait(&ovnsb_idl_loop);
        idl_loop_commit_and_wait(&ovs_idl_loop);
        poll_block();
    }

    unixctl_server_destroy(unixctl);
    lflow_destroy();
    ofctrl_destroy();

    idl_loop_destroy(&ovs_idl_loop);
    idl_loop_destroy(&ovnsb_idl_loop);

    free(ovnsb_remote);
    free(ovs_remote);

    exit(retval);
}

static void
parse_options(int argc, char *argv[])
{
    enum {
        OPT_PEER_CA_CERT = UCHAR_MAX + 1,
        VLOG_OPTION_ENUMS,
        DAEMON_OPTION_ENUMS
    };

    static struct option long_options[] = {
        {"help", no_argument, NULL, 'h'},
        {"version", no_argument, NULL, 'V'},
        VLOG_LONG_OPTIONS,
        DAEMON_LONG_OPTIONS,
        STREAM_SSL_LONG_OPTIONS,
        {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
        {NULL, 0, NULL, 0}
    };
    char *short_options = ovs_cmdl_long_options_to_short_options(long_options);

    for (;;) {
        int c;

        c = getopt_long(argc, argv, short_options, long_options, NULL);
        if (c == -1) {
            break;
        }

        switch (c) {
        case 'h':
            usage();

        case 'V':
            ovs_print_version(OFP13_VERSION, OFP13_VERSION);
            exit(EXIT_SUCCESS);

        VLOG_OPTION_HANDLERS
        DAEMON_OPTION_HANDLERS
        STREAM_SSL_OPTION_HANDLERS

        case OPT_PEER_CA_CERT:
            stream_ssl_set_peer_ca_cert_file(optarg);
            break;

        case '?':
            exit(EXIT_FAILURE);

        default:
            abort();
        }
    }
    free(short_options);

    argc -= optind;
    argv += optind;

    if (argc == 0) {
        ovs_remote = xasprintf("unix:%s/db.sock", ovs_rundir());
    } else if (argc == 1) {
        ovs_remote = xstrdup(argv[0]);
    } else {
        VLOG_FATAL("exactly zero or one non-option argument required; "
                   "use --help for usage");
    }
}

static void
usage(void)
{
    printf("%s: OVN controller\n"
           "usage %s [OPTIONS] [OVS-DATABASE]\n"
           "where OVS-DATABASE is a socket on which the OVS OVSDB server is listening.\n",
               program_name, program_name);
    stream_usage("OVS-DATABASE", true, false, false);
    daemon_usage();
    vlog_usage();
    printf("\nOther options:\n"
           "  -h, --help              display this help message\n"
           "  -V, --version           display version information\n");
    exit(EXIT_SUCCESS);
}

static void
ovn_controller_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
             const char *argv[] OVS_UNUSED, void *exiting_)
{
    bool *exiting = exiting_;
    *exiting = true;

    unixctl_command_reply(conn, NULL);
}
Esempio n. 7
0
int
main(int argc, char **argv)
{
	extern char *optarg;
	char *proxystr = NULL;
	char *proxyhost, *proxyport;
	int rc, err_code;
	int sval;
	int sockfd;
	int pipefd = -1;
	int sleeptime = 0;
	boolean_t quit = B_FALSE;
	struct addrinfo hints;
	struct addrinfo *ai = NULL;
	sigset_t main_ss;

	while ((rc = getopt(argc, argv, "s:")) != -1) {
		switch (rc) {
		case 's':
			proxystr = optarg;
			break;
		case ':':
			(void) fprintf(stderr, "Option -%c requires operand\n",
			    optopt);
			usage();
			break;
		case '?':
			(void) fprintf(stderr, "Unrecognized option -%c\n",
			    optopt);
			usage();
			break;
		default:
			break;
		}
	}

	if (proxystr == NULL) {
		usage();
	}

	proxyhost = strtok(proxystr, ":");
	if (proxyhost == NULL) {
		(void) fprintf(stderr,
		    "host must be of format hostname:port\n");
		usage();
	}
	proxyport = strtok(NULL, ":");
	if (proxyport == NULL) {
		(void) fprintf(stderr,
		    "host must be of format hostname:port\n");
		usage();
	}

	(void) signal(SIGPIPE, SIG_IGN);

	if (daemonize_start() < 0) {
		(void) fprintf(stderr, "Unable to start daemon\n");
		exit(EXIT_FAILURE);
	}

	/*
	 * Before doing anything else, check to see if it's possible to reach
	 * the proxyd.  If not, sit in a loop waiting for a period of time.
	 * If the proxyd doesn't come on-line after waiting, return an error
	 * code that tells smf to enter this service into maintenance mode.
	 */
	while ((rc = zp_ping_proxy()) < -1) {
		(void) sleep(SLEEP_INTERVAL);
		sleeptime += SLEEP_INTERVAL;
		if (sleeptime >= SLEEP_DURATION)
			break;
	}

	if (rc == -2) {
		/* never successfully reached proxy */
		(void) fprintf(stderr, "Timed out trying to reach proxy\n");
		exit(SMF_EXIT_ERR_FATAL);
	} else if (rc == -1) {
		/* got some other error */
		exit(EXIT_FAILURE);
	}

	(void) memset(&hints, 0, sizeof (struct addrinfo));
	hints.ai_flags = AI_ALL;
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if ((err_code = getaddrinfo(proxyhost, proxyport, &hints, &ai))
	    != 0) {
		(void) fprintf(stderr, "Unable to perform name lookup\n");
		(void) fprintf(stderr, "%s: %s\n", proxyhost,
		    gai_strerror(err_code));
		exit(EXIT_FAILURE);
	}

	if ((sockfd = socket(ai->ai_family, SOCK_STREAM, 0)) < 0) {
		perror("socket");
		exit(EXIT_FAILURE);
	}

	sval = 1;
	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&sval,
	    sizeof (sval)) < 0) {
		perror("setsocketopt");
		exit(EXIT_FAILURE);
	}

	if (bind(sockfd, (struct sockaddr *)ai->ai_addr, ai->ai_addrlen) < 0) {
		if (errno != EADDRINUSE) {
			perror("bind");
			exit(EXIT_FAILURE);
		}
		/*
		 * If the socket is in use, call zoneproxyd and
		 * ask it to un-register the current socket.  Then
		 * try again.
		 */

		if (zp_unregister_zone() < 0) {
			exit(EXIT_FAILURE);
		}

		if (bind(sockfd, (struct sockaddr *)ai->ai_addr,
		    ai->ai_addrlen) < 0) {
			perror("bind");
			exit(EXIT_FAILURE);
		}

	}

	if (listen(sockfd, 5) < 0) {
		perror("listen");
		exit(EXIT_FAILURE);
	}

	if (zp_register_socket(sockfd, &pipefd) < 0) {
		exit(EXIT_FAILURE);
	}

	/*
	 * At this point, the proxyd has a copy of the socket and will answer
	 * all incoming connection requests.  Close our refernce to the socket
	 * here.
	 */
	(void) close(sockfd);
	freeaddrinfo(ai);

	daemonize_ready(0);

	(void) sigfillset(&main_ss);

	if (thr_sigsetmask(SIG_BLOCK, &main_ss, NULL) < 0) {
		perror("thr_sigsetmask");
		exit(EXIT_FAILURE);
	}

	/* create signal handling thread */
	if (thr_create(NULL, 0, (void *(*)(void *))s_handler, NULL,
	    THR_BOUND, NULL) < 0) {
		perror("thr_create");
		exit(EXIT_FAILURE);
	}

	drop_privs();

	/* Wait for signal to quit */
	while (quit == B_FALSE) {
		struct pollfd pfd[1];
		boolean_t unexpected = B_FALSE;
		char value;

		/*
		 * Pipe to proxyd notfies client when to quit.  If the proxy
		 * writes a byte to the pipe, or the pipe is closed
		 * unexpectedly, POLLIN will be true, telling us to exit.
		 */
		pfd[0].fd = pipefd;
		pfd[0].events = POLLIN;

		if (poll(pfd, 1, INFTIM) < 0) {
			if (errno == EINTR) {
				continue;
			}
			perror("poll");
			exit(EXIT_FAILURE);
		}

		if (pfd[0].revents & POLLIN) {
			rc = read(pipefd, &value, 1);
			if (rc < 0) {
				perror("read");
				exit(EXIT_FAILURE);
			}
			quit = B_TRUE;
			if (rc == 0)
				unexpected = B_TRUE;
		} else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
			quit = B_TRUE;
			unexpected = B_TRUE;
		}

		if (quit && unexpected) {
			exit(EXIT_DAEMON_TERM);
		}

	}

	return (0);
}
Esempio n. 8
0
int
main(int argc, char *argv[])
{
    char *unixctl_path = NULL;
    char *run_command = NULL;
    struct unixctl_server *unixctl;
    struct ovsdb_jsonrpc_server *jsonrpc;
    struct shash remotes;
    struct ovsdb_error *error;
    struct ovsdb_file *file;
    struct ovsdb *db;
    struct process *run_process;
    char *file_name;
    bool exiting;
    int retval;

    proctitle_init(argc, argv);
    set_program_name(argv[0]);
    signal(SIGPIPE, SIG_IGN);
    process_init();

    parse_options(argc, argv, &file_name, &remotes, &unixctl_path,
                  &run_command);

    die_if_already_running();
    daemonize_start();

    error = ovsdb_file_open(file_name, false, &db, &file);
    if (error) {
        ovs_fatal(0, "%s", ovsdb_error_to_string(error));
    }

    jsonrpc = ovsdb_jsonrpc_server_create(db);
    reconfigure_from_db(jsonrpc, db, &remotes);

    retval = unixctl_server_create(unixctl_path, &unixctl);
    if (retval) {
        exit(EXIT_FAILURE);
    }

    if (run_command) {
        char *run_argv[4];

        run_argv[0] = "/bin/sh";
        run_argv[1] = "-c";
        run_argv[2] = run_command;
        run_argv[3] = NULL;

        retval = process_start(run_argv, NULL, 0, NULL, 0, &run_process);
        if (retval) {
            ovs_fatal(retval, "%s: process failed to start", run_command);
        }
    } else {
        run_process = NULL;
    }

    daemonize_complete();

    unixctl_command_register("exit", ovsdb_server_exit, &exiting);
    unixctl_command_register("ovsdb-server/compact", ovsdb_server_compact,
                             file);
    unixctl_command_register("ovsdb-server/reconnect", ovsdb_server_reconnect,
                             jsonrpc);

    exiting = false;
    while (!exiting) {
        reconfigure_from_db(jsonrpc, db, &remotes);
        ovsdb_jsonrpc_server_run(jsonrpc);
        unixctl_server_run(unixctl);
        ovsdb_trigger_run(db, time_msec());
        if (run_process && process_exited(run_process)) {
            exiting = true;
        }

        ovsdb_jsonrpc_server_wait(jsonrpc);
        unixctl_server_wait(unixctl);
        ovsdb_trigger_wait(db, time_msec());
        if (run_process) {
            process_wait(run_process);
        }
        poll_block();
    }
    ovsdb_jsonrpc_server_destroy(jsonrpc);
    ovsdb_destroy(db);
    shash_destroy(&remotes);
    unixctl_server_destroy(unixctl);

    if (run_process && process_exited(run_process)) {
        int status = process_status(run_process);
        if (status) {
            ovs_fatal(0, "%s: child exited, %s",
                      run_command, process_status_msg(status));
        }
    }

    return 0;
}