+
+/* Some IDL users should only write to write-only columns. Furthermore,
+ * writing to a column which is not write-only can cause serious performance
+ * degradations for these users. This function causes 'idl' to reject writes
+ * to columns which are not marked write only using ovsdb_idl_omit_alert(). */
+void
+ovsdb_idl_verify_write_only(struct ovsdb_idl *idl)
+{
+ idl->verify_write_only = true;
+}
+
+bool
+ovsdb_idl_is_alive(const struct ovsdb_idl *idl)
+{
+ return jsonrpc_session_is_alive(idl->session);
+}
+
+int
+ovsdb_idl_get_last_error(const struct ovsdb_idl *idl)
+{
+ return jsonrpc_session_get_last_error(idl->session);
+}
+\f
+static unsigned char *
+ovsdb_idl_get_mode(struct ovsdb_idl *idl,
+ const struct ovsdb_idl_column *column)
+{
+ size_t i;
+
+ ovs_assert(!idl->change_seqno);
+
+ for (i = 0; i < idl->class->n_tables; i++) {
+ const struct ovsdb_idl_table *table = &idl->tables[i];
+ const struct ovsdb_idl_table_class *tc = table->class;
+
+ if (column >= tc->columns && column < &tc->columns[tc->n_columns]) {
+ return &table->modes[column - tc->columns];
+ }
+ }
+
+ OVS_NOT_REACHED();
+}
+
+static void
+add_ref_table(struct ovsdb_idl *idl, const struct ovsdb_base_type *base)
+{
+ if (base->type == OVSDB_TYPE_UUID && base->u.uuid.refTableName) {
+ struct ovsdb_idl_table *table;
+
+ table = shash_find_data(&idl->table_by_name,
+ base->u.uuid.refTableName);
+ if (table) {
+ table->need_table = true;
+ } else {
+ VLOG_WARN("%s IDL class missing referenced table %s",
+ idl->class->database, base->u.uuid.refTableName);
+ }
+ }
+}
+
+/* Turns on OVSDB_IDL_MONITOR and OVSDB_IDL_ALERT for 'column' in 'idl'. Also
+ * ensures that any tables referenced by 'column' will be replicated, even if
+ * no columns in that table are selected for replication (see
+ * ovsdb_idl_add_table() for more information).
+ *
+ * This function is only useful if 'monitor_everything_by_default' was false in
+ * the call to ovsdb_idl_create(). This function should be called between
+ * ovsdb_idl_create() and the first call to ovsdb_idl_run().
+ */
+void
+ovsdb_idl_add_column(struct ovsdb_idl *idl,
+ const struct ovsdb_idl_column *column)
+{
+ *ovsdb_idl_get_mode(idl, column) = OVSDB_IDL_MONITOR | OVSDB_IDL_ALERT;
+ add_ref_table(idl, &column->type.key);
+ add_ref_table(idl, &column->type.value);
+}
+
+/* Ensures that the table with class 'tc' will be replicated on 'idl' even if
+ * no columns are selected for replication. This can be useful because it
+ * allows 'idl' to keep track of what rows in the table actually exist, which
+ * in turn allows columns that reference the table to have accurate contents.
+ * (The IDL presents the database with references to rows that do not exist
+ * removed.)
+ *
+ * This function is only useful if 'monitor_everything_by_default' was false in
+ * the call to ovsdb_idl_create(). This function should be called between
+ * ovsdb_idl_create() and the first call to ovsdb_idl_run().
+ */
+void
+ovsdb_idl_add_table(struct ovsdb_idl *idl,
+ const struct ovsdb_idl_table_class *tc)
+{
+ size_t i;
+
+ for (i = 0; i < idl->class->n_tables; i++) {
+ struct ovsdb_idl_table *table = &idl->tables[i];
+
+ if (table->class == tc) {
+ table->need_table = true;
+ return;
+ }
+ }
+
+ OVS_NOT_REACHED();
+}
+
+/* Turns off OVSDB_IDL_ALERT for 'column' in 'idl'.
+ *
+ * This function should be called between ovsdb_idl_create() and the first call
+ * to ovsdb_idl_run().
+ */
+void
+ovsdb_idl_omit_alert(struct ovsdb_idl *idl,
+ const struct ovsdb_idl_column *column)
+{
+ *ovsdb_idl_get_mode(idl, column) &= ~OVSDB_IDL_ALERT;
+}
+
+/* Sets the mode for 'column' in 'idl' to 0. See the big comment above
+ * OVSDB_IDL_MONITOR for details.
+ *
+ * This function should be called between ovsdb_idl_create() and the first call
+ * to ovsdb_idl_run().
+ */
+void
+ovsdb_idl_omit(struct ovsdb_idl *idl, const struct ovsdb_idl_column *column)
+{
+ *ovsdb_idl_get_mode(idl, column) = 0;
+}