void dpdk_init(const struct smap *ovs_other_config) { static bool enabled = false; if (enabled || !ovs_other_config) { return; } if (smap_get_bool(ovs_other_config, "dpdk-init", false)) { static struct ovsthread_once once_enable = OVSTHREAD_ONCE_INITIALIZER; if (ovsthread_once_start(&once_enable)) { VLOG_INFO("DPDK Enabled - initializing..."); dpdk_init__(ovs_other_config); enabled = true; VLOG_INFO("DPDK Enabled - initialized"); ovsthread_once_done(&once_enable); } } else { static struct ovsthread_once once_disable = OVSTHREAD_ONCE_INITIALIZER; if (ovsthread_once_start(&once_disable)) { VLOG_INFO("DPDK Disabled - Use other_config:dpdk-init to enable"); ovsthread_once_done(&once_disable); } } }
void dpdk_init(const struct smap *ovs_other_config) { if (smap_get_bool(ovs_other_config, "dpdk-init", false)) { static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; if (ovsthread_once_start(&once)) { VLOG_ERR("DPDK not supported in this copy of Open vSwitch."); ovsthread_once_done(&once); } } }
static int ecmp_config_set_status (bool status, const char * field) { const struct ovsrec_system *ovs_row = NULL; enum ovsdb_idl_txn_status txn_status; struct ovsdb_idl_txn *status_txn = cli_do_config_start (); bool rc = false; struct smap smap_ecmp_config; if (status_txn == NULL) { VLOG_ERR (OVSDB_TXN_CREATE_ERROR); cli_do_config_abort (status_txn); return CMD_OVSDB_FAILURE; } /* Need to set ecmp_config status */ ovs_row = ovsrec_system_first (idl); if (!ovs_row) { VLOG_ERR (OVSDB_ROW_FETCH_ERROR); cli_do_config_abort (status_txn); return CMD_OVSDB_FAILURE; } rc = smap_get_bool (&ovs_row->ecmp_config, field, SYSTEM_ECMP_CONFIG_ENABLE_DEFAULT); if (rc != status) { smap_clone (&smap_ecmp_config, &ovs_row->ecmp_config); smap_replace (&smap_ecmp_config, field, status ? "true" : "false"); VLOG_DBG ("%s Set the ecmp config to status = %s old state = %s", __func__, status ? "enabled" : "disabled", rc ? "enabled" : "disabled"); ovsrec_system_set_ecmp_config (ovs_row, &smap_ecmp_config); smap_destroy (&smap_ecmp_config); } txn_status = cli_do_config_finish (status_txn); if (txn_status == TXN_SUCCESS || txn_status == TXN_UNCHANGED) return CMD_SUCCESS; else { VLOG_ERR (OVSDB_TXN_COMMIT_ERROR); return CMD_OVSDB_FAILURE; } }
static void dpdk_init__(const struct smap *ovs_other_config) { char **argv = NULL, **argv_to_release = NULL; int result; int argc, argc_tmp; bool auto_determine = true; int err = 0; cpu_set_t cpuset; char *sock_dir_subcomponent; if (!smap_get_bool(ovs_other_config, "dpdk-init", false)) { VLOG_INFO("DPDK Disabled - to change this requires a restart.\n"); return; } VLOG_INFO("DPDK Enabled, initializing"); if (process_vhost_flags("vhost-sock-dir", xstrdup(ovs_rundir()), NAME_MAX, ovs_other_config, &sock_dir_subcomponent)) { struct stat s; if (!strstr(sock_dir_subcomponent, "..")) { vhost_sock_dir = xasprintf("%s/%s", ovs_rundir(), sock_dir_subcomponent); err = stat(vhost_sock_dir, &s); if (err) { VLOG_ERR("vhost-user sock directory '%s' does not exist.", vhost_sock_dir); } } else { vhost_sock_dir = xstrdup(ovs_rundir()); VLOG_ERR("vhost-user sock directory request '%s/%s' has invalid" "characters '..' - using %s instead.", ovs_rundir(), sock_dir_subcomponent, ovs_rundir()); } free(sock_dir_subcomponent); } else { vhost_sock_dir = sock_dir_subcomponent; } argv = grow_argv(&argv, 0, 1); argc = 1; argv[0] = xstrdup(ovs_get_program_name()); argc_tmp = get_dpdk_args(ovs_other_config, &argv, argc); while (argc_tmp != argc) { if (!strcmp("-c", argv[argc]) || !strcmp("-l", argv[argc])) { auto_determine = false; break; } argc++; } argc = argc_tmp; /** * NOTE: This is an unsophisticated mechanism for determining the DPDK * lcore for the DPDK Master. */ if (auto_determine) { int i; /* Get the main thread affinity */ CPU_ZERO(&cpuset); err = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); if (!err) { for (i = 0; i < CPU_SETSIZE; i++) { if (CPU_ISSET(i, &cpuset)) { argv = grow_argv(&argv, argc, 2); argv[argc++] = xstrdup("-c"); argv[argc++] = xasprintf("0x%08llX", (1ULL<<i)); i = CPU_SETSIZE; } } } else { VLOG_ERR("Thread getaffinity error %d. Using core 0x1", err); /* User did not set dpdk-lcore-mask and unable to get current * thread affintity - default to core 0x1 */ argv = grow_argv(&argv, argc, 2); argv[argc++] = xstrdup("-c"); argv[argc++] = xasprintf("0x%X", 1); } } argv = grow_argv(&argv, argc, 1); argv[argc] = NULL; optind = 1; if (VLOG_IS_INFO_ENABLED()) { struct ds eal_args; int opt; ds_init(&eal_args); ds_put_cstr(&eal_args, "EAL ARGS:"); for (opt = 0; opt < argc; ++opt) { ds_put_cstr(&eal_args, " "); ds_put_cstr(&eal_args, argv[opt]); } VLOG_INFO("%s", ds_cstr_ro(&eal_args)); ds_destroy(&eal_args); } argv_to_release = grow_argv(&argv_to_release, 0, argc); for (argc_tmp = 0; argc_tmp < argc; ++argc_tmp) { argv_to_release[argc_tmp] = argv[argc_tmp]; } /* Make sure things are initialized ... */ result = rte_eal_init(argc, argv); if (result < 0) { ovs_abort(result, "Cannot init EAL"); } argv_release(argv, argv_to_release, argc); /* Set the main thread affinity back to pre rte_eal_init() value */ if (auto_determine && !err) { err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); if (err) { VLOG_ERR("Thread setaffinity error %d", err); } } rte_memzone_dump(stdout); /* We are called from the main thread here */ RTE_PER_LCORE(_lcore_id) = NON_PMD_CORE_ID; #ifdef DPDK_PDUMP VLOG_INFO("DPDK pdump packet capture enabled"); err = rte_pdump_init(ovs_rundir()); if (err) { VLOG_INFO("Error initialising DPDK pdump"); rte_pdump_uninit(); } else { char *server_socket_path; server_socket_path = xasprintf("%s/%s", ovs_rundir(), "pdump_server_socket"); fatal_signal_add_file_to_unlink(server_socket_path); free(server_socket_path); } #endif /* Finally, register the dpdk classes */ netdev_dpdk_register(); }
/* Returns this chassis's Chassis record, if it is available and is currently * amenable to a transaction. */ const struct sbrec_chassis * chassis_run(struct controller_ctx *ctx, const char *chassis_id, const struct ovsrec_bridge *br_int) { if (!ctx->ovnsb_idl_txn) { return NULL; } const struct ovsrec_open_vswitch *cfg; const char *encap_type, *encap_ip; static bool inited = false; cfg = ovsrec_open_vswitch_first(ctx->ovs_idl); if (!cfg) { VLOG_INFO("No Open_vSwitch row defined."); return NULL; } encap_type = smap_get(&cfg->external_ids, "ovn-encap-type"); encap_ip = smap_get(&cfg->external_ids, "ovn-encap-ip"); if (!encap_type || !encap_ip) { VLOG_INFO("Need to specify an encap type and ip"); return NULL; } char *tokstr = xstrdup(encap_type); char *save_ptr = NULL; char *token; uint32_t req_tunnels = 0; for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL; token = strtok_r(NULL, ",", &save_ptr)) { uint32_t type = get_tunnel_type(token); if (!type) { VLOG_INFO("Unknown tunnel type: %s", token); } req_tunnels |= type; } free(tokstr); const char *hostname = smap_get_def(&cfg->external_ids, "hostname", ""); char hostname_[HOST_NAME_MAX + 1]; if (!hostname[0]) { if (gethostname(hostname_, sizeof hostname_)) { hostname_[0] = '\0'; } hostname = hostname_; } const char *bridge_mappings = get_bridge_mappings(&cfg->external_ids); const char *datapath_type = br_int && br_int->datapath_type ? br_int->datapath_type : ""; struct ds iface_types = DS_EMPTY_INITIALIZER; ds_put_cstr(&iface_types, ""); for (int j = 0; j < cfg->n_iface_types; j++) { ds_put_format(&iface_types, "%s,", cfg->iface_types[j]); } ds_chomp(&iface_types, ','); const char *iface_types_str = ds_cstr(&iface_types); const struct sbrec_chassis *chassis_rec = get_chassis(ctx->ovnsb_idl, chassis_id); if (chassis_rec) { if (strcmp(hostname, chassis_rec->hostname)) { sbrec_chassis_set_hostname(chassis_rec, hostname); } /* Determine new values for Chassis external-ids. */ const char *chassis_bridge_mappings = get_bridge_mappings(&chassis_rec->external_ids); const char *chassis_datapath_type = smap_get_def(&chassis_rec->external_ids, "datapath-type", ""); const char *chassis_iface_types = smap_get_def(&chassis_rec->external_ids, "iface-types", ""); /* If any of the external-ids should change, update them. */ if (strcmp(bridge_mappings, chassis_bridge_mappings) || strcmp(datapath_type, chassis_datapath_type) || strcmp(iface_types_str, chassis_iface_types)) { struct smap new_ids; smap_clone(&new_ids, &chassis_rec->external_ids); smap_replace(&new_ids, "ovn-bridge-mappings", bridge_mappings); smap_replace(&new_ids, "datapath-type", datapath_type); smap_replace(&new_ids, "iface-types", iface_types_str); sbrec_chassis_verify_external_ids(chassis_rec); sbrec_chassis_set_external_ids(chassis_rec, &new_ids); smap_destroy(&new_ids); } /* Compare desired tunnels against those currently in the database. */ uint32_t cur_tunnels = 0; bool same = true; for (int i = 0; i < chassis_rec->n_encaps; i++) { cur_tunnels |= get_tunnel_type(chassis_rec->encaps[i]->type); same = same && !strcmp(chassis_rec->encaps[i]->ip, encap_ip); same = same && smap_get_bool(&chassis_rec->encaps[i]->options, "csum", false); } same = same && req_tunnels == cur_tunnels; if (same) { /* Nothing changed. */ inited = true; ds_destroy(&iface_types); return chassis_rec; } else if (!inited) { struct ds cur_encaps = DS_EMPTY_INITIALIZER; for (int i = 0; i < chassis_rec->n_encaps; i++) { ds_put_format(&cur_encaps, "%s,", chassis_rec->encaps[i]->type); } ds_chomp(&cur_encaps, ','); VLOG_WARN("Chassis config changing on startup, make sure " "multiple chassis are not configured : %s/%s->%s/%s", ds_cstr(&cur_encaps), chassis_rec->encaps[0]->ip, encap_type, encap_ip); ds_destroy(&cur_encaps); } } ovsdb_idl_txn_add_comment(ctx->ovnsb_idl_txn, "ovn-controller: registering chassis '%s'", chassis_id); if (!chassis_rec) { struct smap ext_ids = SMAP_INITIALIZER(&ext_ids); smap_add(&ext_ids, "ovn-bridge-mappings", bridge_mappings); smap_add(&ext_ids, "datapath-type", datapath_type); smap_add(&ext_ids, "iface-types", iface_types_str); chassis_rec = sbrec_chassis_insert(ctx->ovnsb_idl_txn); sbrec_chassis_set_name(chassis_rec, chassis_id); sbrec_chassis_set_hostname(chassis_rec, hostname); sbrec_chassis_set_external_ids(chassis_rec, &ext_ids); smap_destroy(&ext_ids); } ds_destroy(&iface_types); int n_encaps = count_1bits(req_tunnels); struct sbrec_encap **encaps = xmalloc(n_encaps * sizeof *encaps); const struct smap options = SMAP_CONST1(&options, "csum", "true"); for (int i = 0; i < n_encaps; i++) { const char *type = pop_tunnel_name(&req_tunnels); encaps[i] = sbrec_encap_insert(ctx->ovnsb_idl_txn); sbrec_encap_set_type(encaps[i], type); sbrec_encap_set_ip(encaps[i], encap_ip); sbrec_encap_set_options(encaps[i], &options); } sbrec_chassis_set_encaps(chassis_rec, encaps, n_encaps); free(encaps); inited = true; return chassis_rec; }