@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2016 Nicira, Inc.
+/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2016, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -250,6 +250,7 @@ ovsdb_file_open__(const char *file_name,
if (filep) {
*filep = file;
}
+ db->file = file;
} else {
ovsdb_log_close(log);
}
@@ -500,10 +501,7 @@ ovsdb_file_read_schema(const char *file_name, struct ovsdb_schema **schemap)
return ovsdb_file_open_log(file_name, OVSDB_LOG_READ_ONLY, NULL, schemap);
}
-/* Replica implementation. */
-
struct ovsdb_file {
- struct ovsdb_replica replica;
struct ovsdb *db;
struct ovsdb_log *log;
char *file_name;
@@ -512,8 +510,6 @@ struct ovsdb_file {
unsigned int n_transactions;
};
-static const struct ovsdb_replica_class ovsdb_file_class;
-
static struct ovsdb_error *
ovsdb_file_create(struct ovsdb *db, struct ovsdb_log *log,
const char *file_name,
@@ -535,26 +531,17 @@ ovsdb_file_create(struct ovsdb *db, struct ovsdb_log *log,
}
file = xmalloc(sizeof *file);
- ovsdb_replica_init(&file->replica, &ovsdb_file_class);
file->db = db;
file->log = log;
file->file_name = abs_name;
file->last_compact = time_msec();
file->next_compact = file->last_compact + COMPACT_MIN_MSEC;
file->n_transactions = n_transactions;
- ovsdb_add_replica(db, &file->replica);
*filep = file;
return NULL;
}
-static struct ovsdb_file *
-ovsdb_file_cast(struct ovsdb_replica *replica)
-{
- ovs_assert(replica->class == &ovsdb_file_class);
- return CONTAINER_OF(replica, struct ovsdb_file, replica);
-}
-
static bool
ovsdb_file_change_cb(const struct ovsdb_row *old,
const struct ovsdb_row *new,
@@ -579,11 +566,10 @@ ovsdb_file_txn_annotate(struct json *json, const char *comment)
return json;
}
-static struct ovsdb_error *
-ovsdb_file_commit(struct ovsdb_replica *replica,
+struct ovsdb_error *
+ovsdb_file_commit(struct ovsdb_file *file,
const struct ovsdb_txn *txn, bool durable)
{
- struct ovsdb_file *file = ovsdb_file_cast(replica);
struct ovsdb_file_txn ftxn;
struct ovsdb_error *error;
@@ -764,20 +750,13 @@ exit:
return error;
}
-static void
-ovsdb_file_destroy(struct ovsdb_replica *replica)
+void
+ovsdb_file_destroy(struct ovsdb_file *file)
{
- struct ovsdb_file *file = ovsdb_file_cast(replica);
-
ovsdb_log_close(file->log);
free(file->file_name);
free(file);
}
-
-static const struct ovsdb_replica_class ovsdb_file_class = {
- ovsdb_file_commit,
- ovsdb_file_destroy
-};
static void
ovsdb_file_txn_init(struct ovsdb_file_txn *ftxn)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, 2011 Nicira, Inc.
+/* Copyright (c) 2009, 2010, 2011, 2016, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
struct ovsdb;
struct ovsdb_file;
struct ovsdb_schema;
+struct ovsdb_txn;
struct ovsdb_error *ovsdb_file_open(const char *file_name, bool read_only,
struct ovsdb **, struct ovsdb_file **)
@@ -44,6 +45,10 @@ struct ovsdb_error *ovsdb_file_read_schema(const char *file_name,
struct ovsdb_schema **)
OVS_WARN_UNUSED_RESULT;
+struct ovsdb_error *ovsdb_file_commit(struct ovsdb_file *,
+ const struct ovsdb_txn *, bool durable);
+void ovsdb_file_destroy(struct ovsdb_file *);
+
struct json *ovsdb_file_txn_annotate(struct json *, const char *comment);
#endif /* ovsdb/file.h */
@@ -1573,7 +1573,7 @@ ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon)
free(dbmon);
}
-static struct ovsdb_error *
+static void
ovsdb_monitor_commit(struct ovsdb_replica *replica,
const struct ovsdb_txn *txn,
bool durable OVS_UNUSED)
@@ -1601,8 +1601,6 @@ ovsdb_monitor_commit(struct ovsdb_replica *replica,
ovsdb_monitor_json_cache_flush(m);
break;
}
-
- return NULL;
}
static void
@@ -18,6 +18,7 @@
#include "ovsdb.h"
#include "column.h"
+#include "file.h"
#include "openvswitch/json.h"
#include "ovsdb-error.h"
#include "ovsdb-parser.h"
@@ -328,6 +329,7 @@ ovsdb_create(struct ovsdb_schema *schema)
db = xmalloc(sizeof *db);
db->schema = schema;
+ db->file = NULL;
ovs_list_init(&db->replicas);
ovs_list_init(&db->triggers);
db->run_triggers = false;
@@ -363,6 +365,11 @@ ovsdb_destroy(struct ovsdb *db)
if (db) {
struct shash_node *node;
+ /* Close the log. */
+ if (db->file) {
+ ovsdb_file_destroy(db->file);
+ }
+
/* Remove all the replicas. */
while (!ovs_list_is_empty(&db->replicas)) {
struct ovsdb_replica *r
@@ -56,6 +56,7 @@ bool ovsdb_schema_equal(const struct ovsdb_schema *,
/* Database. */
struct ovsdb {
struct ovsdb_schema *schema;
+ struct ovsdb_file *file; /* If nonnull, log for transactions. */
struct ovs_list replicas; /* Contains "struct ovsdb_replica"s. */
struct shash tables; /* Contains "struct ovsdb_table *"s. */
@@ -87,8 +88,8 @@ struct ovsdb_replica {
};
struct ovsdb_replica_class {
- struct ovsdb_error *(*commit)(struct ovsdb_replica *,
- const struct ovsdb_txn *, bool durable);
+ void (*commit)(struct ovsdb_replica *,
+ const struct ovsdb_txn *, bool durable);
void (*destroy)(struct ovsdb_replica *);
};
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
+/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
#include "bitmap.h"
#include "openvswitch/dynamic-string.h"
+#include "file.h"
#include "hash.h"
#include "openvswitch/hmap.h"
#include "openvswitch/json.h"
@@ -865,17 +866,16 @@ ovsdb_txn_commit_(struct ovsdb_txn *txn, bool durable)
}
/* Send the commit to each replica. */
- LIST_FOR_EACH (replica, node, &txn->db->replicas) {
- error = (replica->class->commit)(replica, txn, durable);
+ if (txn->db->file) {
+ error = ovsdb_file_commit(txn->db->file, txn, durable);
if (error) {
- /* We don't support two-phase commit so only the first replica is
- * allowed to report an error. */
- ovs_assert(&replica->node == txn->db->replicas.next);
-
ovsdb_txn_abort(txn);
return error;
}
}
+ LIST_FOR_EACH (replica, node, &txn->db->replicas) {
+ replica->class->commit(replica, txn, durable);
+ }
/* Finalize commit. */
txn->db->run_triggers = true;
Until now, ovsdb-server has internally chained a list of replicas from each database. Whenever ovsdb_txn_commit() commits a transaction, it passes the transaction to each replica. The first replica, which is always the disk file that stores the database, is special because it is the only replica that can report an error and thereby abort the transaction. This is a very special property that genuinely distinguishes this first replica from the others on the chain. This commit breaks that first replica out as a separate kind of entity that is not on the list of replicas. When later commits add support for clustering, there will only be more and more special cases for the "first replica", so it makes sense to distinguish it this way. Signed-off-by: Ben Pfaff <blp@ovn.org> --- ovsdb/file.c | 33 ++++++--------------------------- ovsdb/file.h | 7 ++++++- ovsdb/monitor.c | 4 +--- ovsdb/ovsdb.c | 7 +++++++ ovsdb/ovsdb.h | 5 +++-- ovsdb/transaction.c | 14 +++++++------- 6 files changed, 30 insertions(+), 40 deletions(-)