#include "stream-ssl.h"
#include "sset.h"
#include "svec.h"
-#include "vswitch-idl.h"
+#include "lib/vswitch-idl.h"
#include "table.h"
#include "timeval.h"
#include "util.h"
static const struct vsctl_command_syntax *find_command(const char *name);
static void run_prerequisites(struct vsctl_command[], size_t n_commands,
struct ovsdb_idl *);
-static enum ovsdb_idl_txn_status do_vsctl(const char *args,
- struct vsctl_command *, size_t n,
- struct ovsdb_idl *);
+static void do_vsctl(const char *args, struct vsctl_command *, size_t n,
+ struct ovsdb_idl *);
static const struct vsctl_table_class *get_table(const char *table_name);
static void set_column(const struct vsctl_table_class *,
main(int argc, char *argv[])
{
extern struct vlog_module VLM_reconnect;
- enum ovsdb_idl_txn_status status;
struct ovsdb_idl *idl;
struct vsctl_command *commands;
+ unsigned int seqno;
size_t n_commands;
char *args;
idl = the_idl = ovsdb_idl_create(db, &ovsrec_idl_class, false);
run_prerequisites(commands, n_commands, idl);
- /* Now execute the commands. */
- status = TXN_AGAIN_WAIT;
+ /* Execute the commands.
+ *
+ * 'seqno' is the database sequence number for which we last tried to
+ * execute our transaction. There's no point in trying to commit more than
+ * once for any given sequence number, because if the transaction fails
+ * it's because the database changed and we need to obtain an up-to-date
+ * view of the database before we try the transaction again. */
+ seqno = ovsdb_idl_get_seqno(idl);
for (;;) {
- if (ovsdb_idl_run(idl) || status == TXN_AGAIN_NOW) {
- status = do_vsctl(args, commands, n_commands, idl);
+ ovsdb_idl_run(idl);
+
+ if (seqno != ovsdb_idl_get_seqno(idl)) {
+ seqno = ovsdb_idl_get_seqno(idl);
+ do_vsctl(args, commands, n_commands, idl);
}
- if (status != TXN_AGAIN_NOW) {
+ if (seqno == ovsdb_idl_get_seqno(idl)) {
ovsdb_idl_wait(idl);
poll_block();
}
struct ovsrec_controller **ctrl;
char *fail_mode;
size_t n_ctrl;
- struct vsctl_bridge *parent;
- int vlan;
+
+ /* VLAN ("fake") bridge support.
+ *
+ * Use 'parent != NULL' to detect a fake bridge, because 'vlan' can be 0
+ * in either case. */
+ struct vsctl_bridge *parent; /* Real bridge, or NULL. */
+ int vlan; /* VLAN VID (0...4095), or 0. */
};
struct vsctl_port {
{
return (port_cfg->fake_bridge
&& port_cfg->tag
- && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095);
+ && *port_cfg->tag >= 0 && *port_cfg->tag <= 4095);
}
static struct vsctl_bridge *
port = xmalloc(sizeof *port);
port->port_cfg = port_cfg;
if (port_cfg->tag
- && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095) {
+ && *port_cfg->tag >= 0 && *port_cfg->tag <= 4095) {
port->bridge = find_vlan_bridge(info, br, *port_cfg->tag);
if (!port->bridge) {
port->bridge = br;
} else if (ctx->argc == 4) {
parent_name = ctx->argv[2];
vlan = atoi(ctx->argv[3]);
- if (vlan < 1 || vlan > 4095) {
- vsctl_fatal("%s: vlan must be between 1 and 4095", ctx->argv[0]);
+ if (vlan < 0 || vlan > 4095) {
+ vsctl_fatal("%s: vlan must be between 0 and 4095", ctx->argv[0]);
}
} else {
vsctl_fatal("'%s' command takes exactly 1 or 3 arguments",
br_name, parent_name, vlan, br_name, br->vlan);
}
}
+ free_info(&info);
return;
}
}
int64_t tag = vlan;
parent = find_bridge(&info, parent_name, false);
- if (parent && parent->vlan) {
+ if (parent && parent->parent) {
vsctl_fatal("cannot create bridge with fake bridge as parent");
}
if (!parent) {
svec_destroy(&want_names);
svec_destroy(&have_names);
+ free_info(&info);
return;
}
ovsrec_port_set_bond_fake_iface(port, fake_iface);
free(ifaces);
- if (bridge->vlan) {
+ if (bridge->parent) {
int64_t tag = bridge->vlan;
ovsrec_port_set_tag(port, &tag, 1);
}
}
ovsdb_atom_destroy(&want_key, column->type.key.type);
+ ovsdb_datum_destroy(&b, &type);
} else {
struct ovsdb_datum want_datum;
}
}
\f
-static struct json *
-where_uuid_equals(const struct uuid *uuid)
-{
- return
- json_array_create_1(
- json_array_create_3(
- json_string_create("_uuid"),
- json_string_create("=="),
- json_array_create_2(
- json_string_create("uuid"),
- json_string_create_nocopy(
- xasprintf(UUID_FMT, UUID_ARGS(uuid))))));
-}
-
static void
vsctl_context_init(struct vsctl_context *ctx, struct vsctl_command *command,
struct ovsdb_idl *idl, struct ovsdb_idl_txn *txn,
}
}
-static enum ovsdb_idl_txn_status
+static void
do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
struct ovsdb_idl *idl)
{
}
if (wait_for_reload) {
- struct json *where = where_uuid_equals(&ovs->header_.uuid);
- ovsdb_idl_txn_increment(txn, "Open_vSwitch", "next_cfg", where);
- json_destroy(where);
+ ovsdb_idl_txn_increment(txn, &ovs->header_,
+ &ovsrec_open_vswitch_col_next_cfg);
}
symtab = ovsdb_symbol_table_create();
vsctl_context_done(&ctx, c);
if (ctx.try_again) {
- status = TXN_AGAIN_WAIT;
+ status = TXN_TRY_AGAIN;
goto try_again;
}
}
case TXN_SUCCESS:
break;
- case TXN_AGAIN_WAIT:
- case TXN_AGAIN_NOW:
+ case TXN_TRY_AGAIN:
goto try_again;
case TXN_ERROR:
free(c->table);
}
free(error);
-
- return status;
}
static const struct vsctl_command_syntax all_commands[] = {