From 557e37183de13d82888291b041c93cdd8b6e91f3 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 27 Jan 2010 13:19:46 -0800 Subject: [PATCH] ovs-vsctl: Add new "create" command. --- utilities/ovs-vsctl.8.in | 6 ++ utilities/ovs-vsctl.c | 138 +++++++++++++++++++++++---------------- 2 files changed, 88 insertions(+), 56 deletions(-) diff --git a/utilities/ovs-vsctl.8.in b/utilities/ovs-vsctl.8.in index 4dc971ca..d50a752d 100644 --- a/utilities/ovs-vsctl.8.in +++ b/utilities/ovs-vsctl.8.in @@ -523,6 +523,12 @@ Sets each \fIcolumn\fR in \fIrecord\fR in \fItable\fR to the empty set or empty map, as appropriate. This command applies only to columns that are allowed to be empty. . +.IP "\fB\-\-force create \fItable column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..." +Creates a new record in \fItable\fR and sets the initial values of +each \fIcolumn\fR. Columns not explicitly set will receive their +default values. +.IP +This command requires the \fB\-\-force\fR option. .SH "EXAMPLES" Create a new bridge named br0 and add port eth0 to it: .IP diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index 18d7e083..a9a8950d 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -1855,7 +1855,7 @@ parse_column_key_value(const char *arg, const struct vsctl_table_class *table, if (columnp) { char *column_name; - error = ovsdb_token_parse(&arg, &column_name); + error = ovsdb_token_parse(&p, &column_name); if (error) { goto error; } @@ -2119,72 +2119,78 @@ check_constraint(const struct ovsdb_datum *datum, } static void -cmd_set(struct vsctl_context *ctx) +set_column(const struct vsctl_table_class *table, + const struct ovsdb_idl_row *row, + const char *arg, bool force) { - bool force = shash_find(&ctx->options, "--force"); - const char *table_name = ctx->argv[1]; - const char *record_id = ctx->argv[2]; - const struct vsctl_table_class *table; - const struct ovsdb_idl_row *row; - struct ds *out = &ctx->output; - int i; + const struct vsctl_column *column; + char *key_string, *value_string; + char *error; - table = get_table(table_name); - row = get_row(ctx, table, record_id); - for (i = 3; i < ctx->argc; i++) { - const struct vsctl_column *column; - char *key_string, *value_string; - char *error; + error = parse_column_key_value(arg, table, &column, &key_string, + &value_string); + die_if_error(error); + if (column->flags & VSCF_READONLY && !force) { + ovs_fatal(0, "%s: cannot modify read-only column %s in table %s", + arg, column->idl->name, table->class->name); + } + if (!value_string) { + ovs_fatal(0, "%s: missing value", arg); + } - error = parse_column_key_value(ctx->argv[i], table, - &column, &key_string, &value_string); - die_if_error(error); - if (column->flags & VSCF_READONLY && !force) { - ovs_fatal(0, "%s: cannot modify read-only column %s in table %s", - ctx->argv[i], column->idl->name, table_name); - } - if (!value_string) { - ovs_fatal(0, "%s: missing value", ctx->argv[i]); + if (key_string) { + union ovsdb_atom key, value; + struct ovsdb_datum old, new; + + if (column->idl->type.value_type == OVSDB_TYPE_VOID) { + ovs_fatal(0, "cannot specify key to set for non-map column %s", + column->idl->name); } - if (key_string) { - union ovsdb_atom key, value; - struct ovsdb_datum old, new; + die_if_error(ovsdb_atom_from_string(&key, + column->idl->type.key_type, + key_string)); + die_if_error(ovsdb_atom_from_string(&value, + column->idl->type.value_type, + value_string)); - if (column->idl->type.value_type == OVSDB_TYPE_VOID) { - ovs_fatal(0, "cannot specify key to set for non-map column %s", - column->idl->name); - } + ovsdb_datum_init_empty(&new); + ovsdb_datum_add_unsafe(&new, &key, &value, &column->idl->type); - die_if_error(ovsdb_atom_from_string(&key, - column->idl->type.key_type, - key_string)); - die_if_error(ovsdb_atom_from_string(&value, - column->idl->type.value_type, - value_string)); + ovsdb_idl_txn_read(row, column->idl, &old); + ovsdb_datum_union(&old, &new, &column->idl->type, true); + ovsdb_idl_txn_write(row, column->idl, &old); - ovsdb_datum_init_empty(&new); - ovsdb_datum_add_unsafe(&new, &key, &value, &column->idl->type); + ovsdb_datum_destroy(&new, &column->idl->type); + } else { + struct ovsdb_datum datum; - ovsdb_idl_txn_read(row, column->idl, &old); - ovsdb_datum_union(&old, &new, &column->idl->type, true); - ovsdb_idl_txn_write(row, column->idl, &old); + die_if_error(ovsdb_datum_from_string(&datum, &column->idl->type, + value_string)); + if (!force) { + check_constraint(&datum, &column->idl->type, + column->constraint); + } + ovsdb_idl_txn_write(row, column->idl, &datum); + } - ovsdb_datum_destroy(&new, &column->idl->type); - } else { - struct ovsdb_datum datum; + free(key_string); +} - die_if_error(ovsdb_datum_from_string(&datum, &column->idl->type, - value_string)); - if (!force) { - check_constraint(&datum, &column->idl->type, - column->constraint); - } - ovsdb_idl_txn_write(row, column->idl, &datum); - } - ds_put_char(out, '\n'); +static void +cmd_set(struct vsctl_context *ctx) +{ + bool force = shash_find(&ctx->options, "--force"); + const char *table_name = ctx->argv[1]; + const char *record_id = ctx->argv[2]; + const struct vsctl_table_class *table; + const struct ovsdb_idl_row *row; + int i; - free(key_string); + table = get_table(table_name); + row = get_row(ctx, table, record_id); + for (i = 3; i < ctx->argc; i++) { + set_column(table, row, ctx->argv[i], force); } } @@ -2317,6 +2323,26 @@ cmd_clear(struct vsctl_context *ctx) ovsdb_idl_txn_write(row, column->idl, &datum); } } + +static void +cmd_create(struct vsctl_context *ctx) +{ + bool force = shash_find(&ctx->options, "--force"); + const char *table_name = ctx->argv[1]; + const struct vsctl_table_class *table; + const struct ovsdb_idl_row *row; + int i; + + if (!force) { + ovs_fatal(0, "\"create\" requires --force"); + } + + table = get_table(table_name); + row = ovsdb_idl_txn_insert(txn_from_openvswitch(ctx->ovs), table->class); + for (i = 2; i < ctx->argc; i++) { + set_column(table, row, ctx->argv[i], force); + } +} typedef void vsctl_handler_func(struct vsctl_context *); @@ -2529,7 +2555,7 @@ get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx) {"add", 4, INT_MAX, cmd_add, "--force"}, {"remove", 4, INT_MAX, cmd_remove, "--force"}, {"clear", 3, INT_MAX, cmd_clear, "--force"}, - {"create", 1, INT_MAX, cmd_create, "--force"}, + {"create", 2, INT_MAX, cmd_create, "--force"}, }; const struct vsctl_command *p; -- 2.30.2