const char *inc_table;
const char *inc_column;
struct uuid inc_row;
+ bool inc_force;
unsigned int inc_index;
int64_t inc_new_value;
* successfully, the client may retrieve the final (incremented) value of
* 'column' with ovsdb_idl_txn_get_increment_new_value().
*
+ * If at time of commit the transaction is otherwise empty, that is, it doesn't
+ * change the database, then 'force' is important. If 'force' is false in this
+ * case, the IDL suppresses the increment and skips a round trip to the
+ * database server. If 'force' is true, the IDL will still increment the
+ * column.
+ *
* The client could accomplish something similar with ovsdb_idl_read(),
* ovsdb_idl_txn_verify() and ovsdb_idl_txn_write(), or with ovsdb-idlc
* generated wrappers for these functions. However, ovsdb_idl_txn_increment()
void
ovsdb_idl_txn_increment(struct ovsdb_idl_txn *txn,
const struct ovsdb_idl_row *row,
- const struct ovsdb_idl_column *column)
+ const struct ovsdb_idl_column *column,
+ bool force)
{
ovs_assert(!txn->inc_table);
ovs_assert(column->type.key.type == OVSDB_TYPE_INTEGER);
txn->inc_table = row->table->class->name;
txn->inc_column = column->name;
txn->inc_row = row->uuid;
+ txn->inc_force = force;
}
/* Destroys 'txn' and frees all associated memory. If ovsdb_idl_txn_commit()
}
/* Add increment. */
- if (txn->inc_table && any_updates) {
- struct json *op;
-
+ if (txn->inc_table && (any_updates || txn->inc_force)) {
+ any_updates = true;
txn->inc_index = operations->u.array.n - 1;
- op = json_object_create();
+ struct json *op = json_object_create();
json_object_put_string(op, "op", "mutate");
json_object_put_string(op, "table", txn->inc_table);
json_object_put(op, "where",
void ovsdb_idl_txn_set_dry_run(struct ovsdb_idl_txn *);
void ovsdb_idl_txn_increment(struct ovsdb_idl_txn *,
const struct ovsdb_idl_row *,
- const struct ovsdb_idl_column *);
+ const struct ovsdb_idl_column *,
+ bool force);
void ovsdb_idl_txn_destroy(struct ovsdb_idl_txn *);
void ovsdb_idl_txn_wait(const struct ovsdb_idl_txn *);
enum ovsdb_idl_txn_status ovsdb_idl_txn_commit(struct ovsdb_idl_txn *);
<xi:include href="lib/db-ctl-base.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
+ <h1>Synchronization Commands</h1>
+
+ <dl>
+ <dt>sync</dt>
+ <dd>
+ Ordinarily, <code>--wait=sb</code> or <code>--wait=hv</code> only waits
+ for changes by the current <code>ovn-nbctl</code> invocation to take
+ effect. This means that, if none of the commands supplied to
+ <code>ovn-nbctl</code> change the database, then the command does not
+ wait at all. With the <code>sync</code> command, however,
+ <code>ovn-nbctl</code> waits even for earlier changes to the database
+ to propagate down to the southbound database or all of the OVN chassis,
+ according to the argument to <code>--wait</code>.
+ </dd>
+ </dl>
+
<h1>Options</h1>
<dl>
become up-to-date with the northbound database updates. (This can
become an indefinite wait if any chassis is malfunctioning.)
</p>
+
+ <p>
+ Ordinarily, <code>--wait=sb</code> or <code>--wait=hv</code> only
+ waits for changes by the current <code>ovn-nbctl</code> invocation to
+ take effect. This means that, if none of the commands supplied to
+ <code>ovn-nbctl</code> change the database, then the command does not
+ wait at all. Use the <code>sync</code> command to override this
+ behavior.
+ </p>
</dd>
<dt><code>--db</code> <var>database</var></dt>
};
static enum nbctl_wait_type wait_type = NBCTL_WAIT_NONE;
+/* Should we wait (if specified by 'wait_type') even if the commands don't
+ * change the database at all? */
+static bool force_wait = false;
+
/* --timeout: Time to wait for a connection to 'db'. */
static int timeout;
\n\
%s\
\n\
+Synchronization command (use with --wait=sb|hv):\n\
+ sync wait even for earlier changes to take effect\n\
+\n\
Options:\n\
--db=DATABASE connect to DATABASE\n\
(default: %s)\n\
{
}
+static void
+nbctl_pre_sync(struct ctl_context *ctx OVS_UNUSED)
+{
+ if (wait_type != NBCTL_WAIT_NONE) {
+ force_wait = true;
+ } else {
+ VLOG_INFO("\"sync\" command has no effect without --wait");
+ }
+}
+
+static void
+nbctl_sync(struct ctl_context *ctx OVS_UNUSED)
+{
+}
+
static void
nbctl_show(struct ctl_context *ctx)
{
}
if (wait_type != NBCTL_WAIT_NONE) {
- ovsdb_idl_txn_increment(txn, &nb->header_,
- &nbrec_nb_global_col_nb_cfg);
+ ovsdb_idl_txn_increment(txn, &nb->header_, &nbrec_nb_global_col_nb_cfg,
+ force_wait);
}
symtab = ovsdb_symbol_table_create();
static const struct ctl_command_syntax nbctl_commands[] = {
{ "init", 0, 0, "", NULL, nbctl_init, NULL, "", RW },
+ { "sync", 0, 0, "", nbctl_pre_sync, nbctl_sync, NULL, "", RO },
{ "show", 0, 1, "[SWITCH]", NULL, nbctl_show, NULL, "", RO },
/* logical switch commands. */
/*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
"i=%d", atoi(arg1));
}
- ovsdb_idl_txn_increment(txn, &s->header_, &idltest_simple_col_i);
+ ovsdb_idl_txn_increment(txn, &s->header_, &idltest_simple_col_i,
+ false);
increment = true;
} else if (!strcmp(name, "abort")) {
ovsdb_idl_txn_abort(txn);
if (wait_for_reload) {
ovsdb_idl_txn_increment(txn, &ovs->header_,
- &ovsrec_open_vswitch_col_next_cfg);
+ &ovsrec_open_vswitch_col_next_cfg, false);
}
post_db_reload_check_init();