summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ovsdb/_server.xml17
-rw-r--r--ovsdb/ovsdb-server.c3
-rw-r--r--ovsdb/relay.c34
-rw-r--r--ovsdb/relay.h4
4 files changed, 49 insertions, 9 deletions
diff --git a/ovsdb/_server.xml b/ovsdb/_server.xml
index 37297da73..7866f134f 100644
--- a/ovsdb/_server.xml
+++ b/ovsdb/_server.xml
@@ -71,6 +71,15 @@
source.
</column>
+ <column name="connected">
+ True if the database is connected to its storage. A standalone database
+ is always connected. A clustered database is connected if the server is
+ in contact with a majority of its cluster. A relay database is connected
+ if the server is in contact with the relay source, i.e. is connected to
+ the server it syncs from. An unconnected database cannot be modified and
+ its data might be unavailable or stale.
+ </column>
+
<group title="Clustered Databases">
<p>
These columns are most interesting and in some cases only relevant for
@@ -78,14 +87,6 @@
column is <code>clustered</code>.
</p>
- <column name="connected">
- True if the database is connected to its storage. A standalone or
- active-backup database is always connected. A clustered database is
- connected if the server is in contact with a majority of its cluster.
- An unconnected database cannot be modified and its data might be
- unavailable or stale.
- </column>
-
<column name="leader">
True if the database is the leader in its cluster. For a standalone or
active-backup database, this is always true. For a relay database,
diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
index 3197be5f8..0b3d2bb71 100644
--- a/ovsdb/ovsdb-server.c
+++ b/ovsdb/ovsdb-server.c
@@ -1194,7 +1194,8 @@ update_database_status(struct ovsdb_row *row, struct db *db)
ovsdb_util_write_string_column(row, "model",
db->db->is_relay ? "relay" : ovsdb_storage_get_model(db->db->storage));
ovsdb_util_write_bool_column(row, "connected",
- ovsdb_storage_is_connected(db->db->storage));
+ db->db->is_relay ? ovsdb_relay_is_connected(db->db)
+ : ovsdb_storage_is_connected(db->db->storage));
ovsdb_util_write_bool_column(row, "leader",
db->db->is_relay ? false : ovsdb_storage_is_leader(db->db->storage));
ovsdb_util_write_uuid_column(row, "cid",
diff --git a/ovsdb/relay.c b/ovsdb/relay.c
index f55cdbc6f..ef0e44d34 100644
--- a/ovsdb/relay.c
+++ b/ovsdb/relay.c
@@ -31,6 +31,7 @@
#include "ovsdb-error.h"
#include "row.h"
#include "table.h"
+#include "timeval.h"
#include "transaction.h"
#include "transaction-forward.h"
#include "util.h"
@@ -47,8 +48,36 @@ struct relay_ctx {
struct ovsdb_schema *new_schema;
schema_change_callback schema_change_cb;
void *schema_change_aux;
+
+ long long int last_connected;
};
+#define RELAY_MAX_RECONNECTION_MS 30000
+
+/* Reports if the database is connected to the relay source and functional,
+ * i.e. it actively monitors the source and is able to forward transactions. */
+bool
+ovsdb_relay_is_connected(struct ovsdb *db)
+{
+ struct relay_ctx *ctx = shash_find_data(&relay_dbs, db->name);
+
+ if (!ctx || !ovsdb_cs_is_alive(ctx->cs)) {
+ return false;
+ }
+
+ if (ovsdb_cs_may_send_transaction(ctx->cs)) {
+ return true;
+ }
+
+ /* Trying to avoid connection state flapping by delaying report for
+ * upper layer and giving ovsdb-cs some time to reconnect. */
+ if (time_msec() - ctx->last_connected < RELAY_MAX_RECONNECTION_MS) {
+ return true;
+ }
+
+ return false;
+}
+
static struct json *
ovsdb_relay_compose_monitor_request(const struct json *schema_json, void *ctx_)
{
@@ -119,6 +148,7 @@ ovsdb_relay_add_db(struct ovsdb *db, const char *remote,
ctx->schema_change_aux = schema_change_aux;
ctx->db = db;
ctx->cs = ovsdb_cs_create(db->name, 3, &relay_cs_ops, ctx);
+ ctx->last_connected = 0;
shash_add(&relay_dbs, db->name, ctx);
ovsdb_cs_set_leader_only(ctx->cs, false);
ovsdb_cs_set_remote(ctx->cs, remote, true);
@@ -306,6 +336,10 @@ ovsdb_relay_run(void)
ovsdb_txn_forward_run(ctx->db, ctx->cs);
ovsdb_cs_run(ctx->cs, &events);
+ if (ovsdb_cs_may_send_transaction(ctx->cs)) {
+ ctx->last_connected = time_msec();
+ }
+
struct ovsdb_cs_event *event;
LIST_FOR_EACH_POP (event, list_node, &events) {
if (!ctx->db) {
diff --git a/ovsdb/relay.h b/ovsdb/relay.h
index 68586e9db..390ea70c8 100644
--- a/ovsdb/relay.h
+++ b/ovsdb/relay.h
@@ -17,6 +17,8 @@
#ifndef OVSDB_RELAY_H
#define OVSDB_RELAY_H 1
+#include <stdbool.h>
+
struct json;
struct ovsdb;
struct ovsdb_schema;
@@ -31,4 +33,6 @@ void ovsdb_relay_del_db(struct ovsdb *);
void ovsdb_relay_run(void);
void ovsdb_relay_wait(void);
+bool ovsdb_relay_is_connected(struct ovsdb *);
+
#endif /* OVSDB_RELAY_H */