X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=utilities%2Fovs-vsctl.c;h=19ab4728f6f196a3b6e75e36bb0951cfccdfa46d;hb=4816a18f33380a33d381b77d41df39113c94500d;hp=bccb2c921583e48025de36e8c0dabc2df6656517;hpb=401d5a6d16438ceb2e09c19677b97504593b4b51;p=sliver-openvswitch.git diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index bccb2c921..19ab4728f 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ #include -#include #include #include #include @@ -115,6 +114,16 @@ static bool wait_for_reload = true; /* --timeout: Time to wait for a connection to 'db'. */ static int timeout; +/* --retry: If true, ovs-vsctl will retry connecting to the database forever. + * If false and --db says to use an active connection method (e.g. "unix:", + * "tcp:", "ssl:"), then ovs-vsctl will try to connect once and exit with an + * error if the database server cannot be contacted (e.g. ovsdb-server is not + * running). + * + * Regardless of this setting, --timeout always limits how long ovs-vsctl will + * wait. */ +static bool retry; + /* Format for table output. */ static struct table_style table_style = TABLE_STYLE_DEFAULT; @@ -187,7 +196,7 @@ main(int argc, char *argv[]) } /* Initialize IDL. */ - idl = the_idl = ovsdb_idl_create(db, &ovsrec_idl_class, false); + idl = the_idl = ovsdb_idl_create(db, &ovsrec_idl_class, false, retry); run_prerequisites(commands, n_commands, idl); /* Execute the commands. @@ -200,6 +209,11 @@ main(int argc, char *argv[]) seqno = ovsdb_idl_get_seqno(idl); for (;;) { ovsdb_idl_run(idl); + if (!ovsdb_idl_is_alive(idl)) { + int retval = ovsdb_idl_get_last_error(idl); + vsctl_fatal("%s: database connection failed (%s)", + db, ovs_retval_to_string(retval)); + } if (seqno != ovsdb_idl_get_seqno(idl)) { seqno = ovsdb_idl_get_seqno(idl); @@ -248,6 +262,7 @@ parse_options(int argc, char *argv[], struct shash *local_options) OPT_DRY_RUN, OPT_PEER_CA_CERT, OPT_LOCAL, + OPT_RETRY, VLOG_OPTION_ENUMS, TABLE_OPTION_ENUMS }; @@ -258,6 +273,7 @@ parse_options(int argc, char *argv[], struct shash *local_options) {"dry-run", no_argument, NULL, OPT_DRY_RUN}, {"oneline", no_argument, NULL, OPT_ONELINE}, {"timeout", required_argument, NULL, 't'}, + {"retry", no_argument, NULL, OPT_RETRY}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, VLOG_LONG_OPTIONS, @@ -298,7 +314,7 @@ parse_options(int argc, char *argv[], struct shash *local_options) char *equals; int has_arg; - assert(name[0] == '-' && name[1] == '-' && name[2]); + ovs_assert(name[0] == '-' && name[1] == '-' && name[2]); name += 2; equals = strchr(name, '='); @@ -311,8 +327,8 @@ parse_options(int argc, char *argv[], struct shash *local_options) o = find_option(name, options, n_options); if (o) { - assert(o - options >= n_global_long_options); - assert(o->has_arg == has_arg); + ovs_assert(o - options >= n_global_long_options); + ovs_assert(o->has_arg == has_arg); } else { o = add_option(&options, &n_options, &allocated_options); o->name = xstrdup(name); @@ -385,6 +401,10 @@ parse_options(int argc, char *argv[], struct shash *local_options) } break; + case OPT_RETRY: + retry = true; + break; + VLOG_OPTION_HANDLERS TABLE_OPTION_HANDLERS(&table_style) @@ -663,6 +683,7 @@ Options:\n\ --db=DATABASE connect to DATABASE\n\ (default: %s)\n\ --no-wait do not wait for ovs-vswitchd to reconfigure\n\ + --retry keep trying to connect to server forever\n\ -t, --timeout=SECS wait at most SECS seconds for ovs-vswitchd\n\ --dry-run do not commit changes to database\n\ --oneline print exactly one line of output per command\n", @@ -845,8 +866,8 @@ ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs, static void del_cached_bridge(struct vsctl_context *ctx, struct vsctl_bridge *br) { - assert(list_is_empty(&br->ports)); - assert(hmap_is_empty(&br->children)); + ovs_assert(list_is_empty(&br->ports)); + ovs_assert(hmap_is_empty(&br->children)); if (br->parent) { hmap_remove(&br->parent->children, &br->children_node); } @@ -912,7 +933,7 @@ add_port_to_cache(struct vsctl_context *ctx, struct vsctl_bridge *parent, static void del_cached_port(struct vsctl_context *ctx, struct vsctl_port *port) { - assert(list_is_empty(&port->ifaces)); + ovs_assert(list_is_empty(&port->ifaces)); list_remove(&port->ports_node); shash_find_and_delete(&ctx->ports, port->port_cfg->name); ovsrec_port_delete(port->port_cfg); @@ -1133,7 +1154,7 @@ find_bridge(struct vsctl_context *ctx, const char *name, bool must_exist) { struct vsctl_bridge *br; - assert(ctx->cache_valid); + ovs_assert(ctx->cache_valid); br = shash_find_data(&ctx->bridges, name); if (must_exist && !br) { @@ -1158,7 +1179,7 @@ find_port(struct vsctl_context *ctx, const char *name, bool must_exist) { struct vsctl_port *port; - assert(ctx->cache_valid); + ovs_assert(ctx->cache_valid); port = shash_find_data(&ctx->ports, name); if (port && !strcmp(name, port->bridge->name)) { @@ -1176,7 +1197,7 @@ find_iface(struct vsctl_context *ctx, const char *name, bool must_exist) { struct vsctl_iface *iface; - assert(ctx->cache_valid); + ovs_assert(ctx->cache_valid); iface = shash_find_data(&ctx->ifaces, name); if (iface && !strcmp(name, iface->port->bridge->name)) { @@ -1432,6 +1453,7 @@ pre_cmd_emer_reset(struct vsctl_context *ctx) ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_mirrors); ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_netflow); ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_sflow); + ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_ipfix); ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_flood_vlans); ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_other_config); @@ -1456,6 +1478,8 @@ cmd_emer_reset(struct vsctl_context *ctx) const struct ovsrec_netflow *nf, *next_nf; const struct ovsrec_ssl *ssl, *next_ssl; const struct ovsrec_sflow *sflow, *next_sflow; + const struct ovsrec_ipfix *ipfix, *next_ipfix; + const struct ovsrec_flow_sample_collector_set *fscset, *next_fscset; /* Reset the Open_vSwitch table. */ ovsrec_open_vswitch_set_manager_options(ctx->ovs, NULL, 0); @@ -1469,6 +1493,7 @@ cmd_emer_reset(struct vsctl_context *ctx) ovsrec_bridge_set_mirrors(br, NULL, 0); ovsrec_bridge_set_netflow(br, NULL); ovsrec_bridge_set_sflow(br, NULL); + ovsrec_bridge_set_ipfix(br, NULL); ovsrec_bridge_set_flood_vlans(br, NULL, 0); /* We only want to save the "hwaddr" key from other_config. */ @@ -1518,6 +1543,14 @@ cmd_emer_reset(struct vsctl_context *ctx) ovsrec_sflow_delete(sflow); } + OVSREC_IPFIX_FOR_EACH_SAFE (ipfix, next_ipfix, idl) { + ovsrec_ipfix_delete(ipfix); + } + + OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH_SAFE (fscset, next_fscset, idl) { + ovsrec_flow_sample_collector_set_delete(fscset); + } + vsctl_context_invalidate_cache(ctx); } @@ -1647,6 +1680,7 @@ del_bridge(struct vsctl_context *ctx, struct vsctl_bridge *br) { struct vsctl_bridge *child, *next_child; struct vsctl_port *port, *next_port; + const struct ovsrec_flow_sample_collector_set *fscset, *next_fscset; HMAP_FOR_EACH_SAFE (child, next_child, children_node, &br->children) { del_bridge(ctx, child); @@ -1656,6 +1690,13 @@ del_bridge(struct vsctl_context *ctx, struct vsctl_bridge *br) del_port(ctx, port); } + OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH_SAFE (fscset, next_fscset, + ctx->idl) { + if (fscset->bridge == br->br_cfg) { + ovsrec_flow_sample_collector_set_delete(fscset); + } + } + del_cached_bridge(ctx, br); } @@ -2443,7 +2484,8 @@ struct vsctl_table_class { static const struct vsctl_table_class tables[] = { {&ovsrec_table_bridge, {{&ovsrec_table_bridge, &ovsrec_bridge_col_name, NULL}, - {NULL, NULL, NULL}}}, + {&ovsrec_table_flow_sample_collector_set, NULL, + &ovsrec_flow_sample_collector_set_col_bridge}}}, {&ovsrec_table_controller, {{&ovsrec_table_bridge, @@ -2497,6 +2539,17 @@ static const struct vsctl_table_class tables[] = { {{&ovsrec_table_flow_table, &ovsrec_flow_table_col_name, NULL}, {NULL, NULL, NULL}}}, + {&ovsrec_table_ipfix, + {{&ovsrec_table_bridge, + &ovsrec_bridge_col_name, + &ovsrec_bridge_col_ipfix}, + {&ovsrec_table_flow_sample_collector_set, NULL, + &ovsrec_flow_sample_collector_set_col_ipfix}}}, + + {&ovsrec_table_flow_sample_collector_set, + {{NULL, NULL, NULL}, + {NULL, NULL, NULL}}}, + {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}} }; @@ -2646,7 +2699,8 @@ get_row_by_id(struct vsctl_context *ctx, const struct vsctl_table_class *table, static const struct ovsdb_idl_row * get_row (struct vsctl_context *ctx, - const struct vsctl_table_class *table, const char *record_id) + const struct vsctl_table_class *table, const char *record_id, + bool must_exist) { const struct ovsdb_idl_row *row; struct uuid uuid; @@ -2663,15 +2717,7 @@ get_row (struct vsctl_context *ctx, } } } - return row; -} - -static const struct ovsdb_idl_row * -must_get_row(struct vsctl_context *ctx, - const struct vsctl_table_class *table, const char *record_id) -{ - const struct ovsdb_idl_row *row = get_row(ctx, table, record_id); - if (!row) { + if (must_exist && !row) { vsctl_fatal("no row \"%s\" in table %s", record_id, table->class->name); } @@ -2794,7 +2840,7 @@ parse_column_key_value(const char *arg, char *column_name; char *error; - assert(!(operatorp && !valuep)); + ovs_assert(!(operatorp && !valuep)); *keyp = NULL; if (valuep) { *valuep = NULL; @@ -2943,7 +2989,7 @@ static void cmd_get(struct vsctl_context *ctx) { const char *id = shash_find_data(&ctx->options, "--id"); - bool if_exists = shash_find(&ctx->options, "--if-exists"); + bool must_exist = !shash_find(&ctx->options, "--if-exists"); const char *table_name = ctx->argv[1]; const char *record_id = ctx->argv[2]; const struct vsctl_table_class *table; @@ -2951,8 +2997,16 @@ cmd_get(struct vsctl_context *ctx) struct ds *out = &ctx->output; int i; + if (id && !must_exist) { + vsctl_fatal("--if-exists and --id may not be specified together"); + } + table = get_table(table_name); - row = must_get_row(ctx, table, record_id); + row = get_row(ctx, table, record_id, must_exist); + if (!row) { + return; + } + if (id) { struct ovsdb_symbol *symbol; bool new; @@ -3004,7 +3058,7 @@ cmd_get(struct vsctl_context *ctx) idx = ovsdb_datum_find_key(datum, &key, column->type.key.type); if (idx == UINT_MAX) { - if (!if_exists) { + if (must_exist) { vsctl_fatal("no key \"%s\" in %s record \"%s\" column %s", key_string, table->class->name, record_id, column->name); @@ -3130,6 +3184,10 @@ list_record(const struct ovsdb_idl_row *row, { size_t i; + if (!row) { + return; + } + table_add_row(out); for (i = 0; i < n_columns; i++) { const struct ovsdb_idl_column *column = columns[i]; @@ -3160,6 +3218,7 @@ static void cmd_list(struct vsctl_context *ctx) { const char *column_names = shash_find_data(&ctx->options, "--columns"); + bool must_exist = !shash_find(&ctx->options, "--if-exists"); const struct ovsdb_idl_column **columns; const char *table_name = ctx->argv[1]; const struct vsctl_table_class *table; @@ -3172,7 +3231,7 @@ cmd_list(struct vsctl_context *ctx) out = ctx->table = list_make_table(columns, n_columns); if (ctx->argc > 2) { for (i = 2; i < ctx->argc; i++) { - list_record(must_get_row(ctx, table, ctx->argv[i]), + list_record(get_row(ctx, table, ctx->argv[i], must_exist), columns, n_columns, out); } } else { @@ -3302,6 +3361,7 @@ set_column(const struct vsctl_table_class *table, static void cmd_set(struct vsctl_context *ctx) { + bool must_exist = !shash_find(&ctx->options, "--if-exists"); const char *table_name = ctx->argv[1]; const char *record_id = ctx->argv[2]; const struct vsctl_table_class *table; @@ -3309,7 +3369,11 @@ cmd_set(struct vsctl_context *ctx) int i; table = get_table(table_name); - row = must_get_row(ctx, table, record_id); + row = get_row(ctx, table, record_id, must_exist); + if (!row) { + return; + } + for (i = 3; i < ctx->argc; i++) { set_column(table, row, ctx->argv[i], ctx->symtab); } @@ -3333,6 +3397,7 @@ pre_cmd_add(struct vsctl_context *ctx) static void cmd_add(struct vsctl_context *ctx) { + bool must_exist = !shash_find(&ctx->options, "--if-exists"); const char *table_name = ctx->argv[1]; const char *record_id = ctx->argv[2]; const char *column_name = ctx->argv[3]; @@ -3344,8 +3409,11 @@ cmd_add(struct vsctl_context *ctx) int i; table = get_table(table_name); - row = must_get_row(ctx, table, record_id); die_if_error(get_column(table, column_name, &column)); + row = get_row(ctx, table, record_id, must_exist); + if (!row) { + return; + } type = &column->type; ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type); @@ -3390,6 +3458,7 @@ pre_cmd_remove(struct vsctl_context *ctx) static void cmd_remove(struct vsctl_context *ctx) { + bool must_exist = !shash_find(&ctx->options, "--if-exists"); const char *table_name = ctx->argv[1]; const char *record_id = ctx->argv[2]; const char *column_name = ctx->argv[3]; @@ -3401,8 +3470,11 @@ cmd_remove(struct vsctl_context *ctx) int i; table = get_table(table_name); - row = must_get_row(ctx, table, record_id); die_if_error(get_column(table, column_name, &column)); + row = get_row(ctx, table, record_id, must_exist); + if (!row) { + return; + } type = &column->type; ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type); @@ -3457,6 +3529,7 @@ pre_cmd_clear(struct vsctl_context *ctx) static void cmd_clear(struct vsctl_context *ctx) { + bool must_exist = !shash_find(&ctx->options, "--if-exists"); const char *table_name = ctx->argv[1]; const char *record_id = ctx->argv[2]; const struct vsctl_table_class *table; @@ -3464,7 +3537,11 @@ cmd_clear(struct vsctl_context *ctx) int i; table = get_table(table_name); - row = must_get_row(ctx, table, record_id); + row = get_row(ctx, table, record_id, must_exist); + if (!row) { + return; + } + for (i = 3; i < ctx->argc; i++) { const struct ovsdb_idl_column *column; const struct ovsdb_type *type; @@ -3597,7 +3674,7 @@ cmd_destroy(struct vsctl_context *ctx) for (i = 2; i < ctx->argc; i++) { const struct ovsdb_idl_row *row; - row = (must_exist ? must_get_row : get_row)(ctx, table, ctx->argv[i]); + row = get_row(ctx, table, ctx->argv[i], must_exist); if (row) { ovsdb_idl_txn_delete(row); } @@ -3778,7 +3855,7 @@ cmd_wait_until(struct vsctl_context *ctx) table = get_table(table_name); - row = get_row(ctx, table, record_id); + row = get_row(ctx, table, record_id, false); if (!row) { ctx->try_again = true; return; @@ -3874,8 +3951,8 @@ run_prerequisites(struct vsctl_command *commands, size_t n_commands, (c->syntax->prerequisites)(&ctx); vsctl_context_done(&ctx, c); - assert(!c->output.string); - assert(!c->table); + ovs_assert(!c->output.string); + ovs_assert(!c->table); } } } @@ -4060,6 +4137,7 @@ try_again: if (txn) { ovsdb_idl_txn_abort(txn); ovsdb_idl_txn_destroy(txn); + the_idl_txn = NULL; } ovsdb_symbol_table_destroy(symtab); for (c = commands; c < &commands[n_commands]; c++) { @@ -4126,12 +4204,14 @@ static const struct vsctl_command_syntax all_commands[] = { /* Database commands. */ {"comment", 0, INT_MAX, NULL, NULL, NULL, "", RO}, {"get", 2, INT_MAX, pre_cmd_get, cmd_get, NULL, "--if-exists,--id=", RO}, - {"list", 1, INT_MAX, pre_cmd_list, cmd_list, NULL, "--columns=", RO}, + {"list", 1, INT_MAX, pre_cmd_list, cmd_list, NULL, + "--if-exists,--columns=", RO}, {"find", 1, INT_MAX, pre_cmd_find, cmd_find, NULL, "--columns=", RO}, - {"set", 3, INT_MAX, pre_cmd_set, cmd_set, NULL, "", RW}, - {"add", 4, INT_MAX, pre_cmd_add, cmd_add, NULL, "", RW}, - {"remove", 4, INT_MAX, pre_cmd_remove, cmd_remove, NULL, "", RW}, - {"clear", 3, INT_MAX, pre_cmd_clear, cmd_clear, NULL, "", RW}, + {"set", 3, INT_MAX, pre_cmd_set, cmd_set, NULL, "--if-exists", RW}, + {"add", 4, INT_MAX, pre_cmd_add, cmd_add, NULL, "--if-exists", RW}, + {"remove", 4, INT_MAX, pre_cmd_remove, cmd_remove, NULL, "--if-exists", + RW}, + {"clear", 3, INT_MAX, pre_cmd_clear, cmd_clear, NULL, "--if-exists", RW}, {"create", 2, INT_MAX, pre_create, cmd_create, post_create, "--id=", RW}, {"destroy", 1, INT_MAX, pre_cmd_destroy, cmd_destroy, NULL, "--if-exists,--all", RW},