From patchwork Mon Jan 1 05:16:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 854287 X-Patchwork-Delegate: jpettit@nicira.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3z957s4hxPz9t84 for ; Mon, 1 Jan 2018 16:18:33 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id B4CD2C7F; Mon, 1 Jan 2018 05:16:55 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id F1278C48 for ; Mon, 1 Jan 2018 05:16:53 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 3D35314D for ; Mon, 1 Jan 2018 05:16:53 +0000 (UTC) X-Originating-IP: 173.228.112.64 Received: from sigabrt.gateway.sonic.net (173-228-112-64.dsl.dynamic.fusionbroadband.com [173.228.112.64]) (Authenticated sender: blp@ovn.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 223BBC5A53; Mon, 1 Jan 2018 06:16:50 +0100 (CET) From: Ben Pfaff To: dev@openvswitch.org Date: Sun, 31 Dec 2017 21:16:29 -0800 Message-Id: <20180101051640.13043-4-blp@ovn.org> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20180101051640.13043-1-blp@ovn.org> References: <20180101051640.13043-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH 04/15] ovsdb-server: Distinguish logs from other replicas. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org 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 Acked-by: Justin Pettit --- 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(-) diff --git a/ovsdb/file.c b/ovsdb/file.c index fdd5f8e35a44..4aafb3be8ab4 100644 --- a/ovsdb/file.c +++ b/ovsdb/file.c @@ -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) diff --git a/ovsdb/file.h b/ovsdb/file.h index c6ca92621044..a9ef0585b261 100644 --- a/ovsdb/file.h +++ b/ovsdb/file.h @@ -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 */ diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c index c0f9c557ab67..b2ecd109ed60 100644 --- a/ovsdb/monitor.c +++ b/ovsdb/monitor.c @@ -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 diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c index d8f441ad0728..213d0d4823e1 100644 --- a/ovsdb/ovsdb.c +++ b/ovsdb/ovsdb.c @@ -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 diff --git a/ovsdb/ovsdb.h b/ovsdb/ovsdb.h index 89bbfa2512fa..06cd3a72e49e 100644 --- a/ovsdb/ovsdb.h +++ b/ovsdb/ovsdb.h @@ -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 *); }; diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index f47d45fca397..ba17834aa633 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -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;