2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

ovsdb-server: Add support for a built-in _Server database.

The _Server database is valuable primarily because it provides database
clients a way to find out the details of changes to databases, schemas,
etc. in a granular, natural way.  Until now, the only way that the server
could notify clients about these kinds of changes was to close the session;
when the client reconnects, it is expected to reassess the server's state.
One way to provide this kind of granular information would be to add
specific JSON-RPC requests to obtain notifications for different kinds of
changes, but since ovsdb-server already provides granular and flexible
notification support for databases, using a database for the purpose is
convenient and avoids duplicating functionality.

Initially this database only reports databases' names and schemas, but
when clustering support is added in a later commit it will also report
important aspects of clustering and cluster status.  Thus, this database
also reduces the need to add JSON-RPC calls to retrieve information about
new features.

Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Ben Pfaff 2017-12-15 11:14:55 -08:00
parent 00d5d6310d
commit 6bb9b060d5
18 changed files with 367 additions and 57 deletions

View File

@ -109,6 +109,10 @@ The remainder are still in roff format can be found below:
- `(pdf) <http://openvswitch.org/support/dist-docs/ovsdb-server.1.pdf>`__
- `(html) <http://openvswitch.org/support/dist-docs/ovsdb-server.1.html>`__
- `(plain text) <http://openvswitch.org/support/dist-docs/ovsdb-server.1.txt>`__
* - ovsdb-server(5)
- `(pdf) <http://openvswitch.org/support/dist-docs/ovsdb-server.5.pdf>`__
- `(html) <http://openvswitch.org/support/dist-docs/ovsdb-server.5.html>`__
- `(plain text) <http://openvswitch.org/support/dist-docs/ovsdb-server.5.txt>`__
* - ovsdb-tool(1)
- `(pdf) <http://openvswitch.org/support/dist-docs/ovsdb-tool.1.pdf>`__
- `(html) <http://openvswitch.org/support/dist-docs/ovsdb-tool.1.html>`__

View File

@ -82,14 +82,6 @@ EXTRA_DIST = \
.travis/osx-prepare.sh \
appveyor.yml \
boot.sh \
build-aux/cccl \
build-aux/cksum-schema-check \
build-aux/calculate-schema-cksum \
build-aux/dist-docs \
build-aux/dpdkstrip.py \
build-aux/sodepends.py \
build-aux/soexpand.py \
build-aux/xml2nroff \
poc/builders/Vagrantfile \
poc/playbook-centos-builder.yml \
poc/playbook-ubuntu-builder.yml \

2
NEWS
View File

@ -26,6 +26,8 @@ v2.9.0 - 19 Feb 2018
* New high-level documentation in ovsdb(7).
* New file format documentation for developers in ovsdb(5).
* Protocol documentation moved from ovsdb-server(1) to ovsdb-server(7).
* ovsdb-server now always hosts a built-in database named _Server. See
ovsdb-server(5) for more details.
* ovsdb-client: New "get-schema-cksum" and "query" commands.
* ovsdb-client: New "backup" and "restore" commands.
* ovsdb-client: New --timeout option.

View File

@ -1,4 +1,14 @@
# This file is purely used for checking the style of the python build tools.
EXTRA_DIST += \
build-aux/calculate-schema-cksum \
build-aux/cccl \
build-aux/cksum-schema-check \
build-aux/dist-docs \
build-aux/dpdkstrip.py \
build-aux/sodepends.py \
build-aux/soexpand.py \
build-aux/text2c \
build-aux/xml2nroff
FLAKE8_PYFILES += \
$(srcdir)/build-aux/xml2nroff \
build-aux/dpdkstrip.py \

16
build-aux/text2c Executable file
View File

@ -0,0 +1,16 @@
#! /usr/bin/python
import re
import sys
"""This utility reads its input, which should be plain text, and
prints it back transformed into quoted strings that may be #included
into C source code."""
while True:
line = sys.stdin.readline()
if not line:
break
s = line.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n")
print('"' + s + '"')

View File

@ -1,4 +1,5 @@
ovsdb/ovsdb-server.1
ovsdb/ovsdb-server.5
utilities/ovs-ctl.8
utilities/ovs-dpctl-top.8
utilities/ovs-dpctl.8

3
ovsdb/.gitignore vendored
View File

@ -1,3 +1,5 @@
/_server.ovsschema.inc
/_server.ovsschema.stamp
/ovsdb-client
/ovsdb-client.1
/ovsdb-doc
@ -5,6 +7,7 @@
/ovsdb-idlc
/ovsdb-server
/ovsdb-server.1
/ovsdb-server.5
/ovsdb-tool
/ovsdb-tool.1
/libovsdb.pc

9
ovsdb/_server.ovsschema Normal file
View File

@ -0,0 +1,9 @@
{"name": "_Server",
"version": "1.0.0",
"cksum": "3931859656 185",
"tables": {
"Database": {
"columns": {
"name": {"type": "string"},
"schema": {"type": "string"}},
"isRoot": true}}}

31
ovsdb/_server.xml Normal file
View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<database name="ovsdb-server" title="ovsdb-server _Server schema">
<p>
Every <code>ovsdb-server</code> (version 2.9 or later) always hosts an
instance of this schema, which holds information on the status and
configuration of the server itself. This database is read-only. This
manpage describes the schema for this database.
</p>
<table name="Database" title="Databases.">
<p>
This table describes the databases hosted by the database server, with
one row per database. As its database configuration and status changes,
the server automatically and immediately updates the table to match.
</p>
<p>
Clients can use the <code>_uuid</code> column in this table as a
generation number. The server generates a fresh <code>_uuid</code> every
time it adds a database, so that removing and then re-adding a database
to the server causes its row <code>_uuid</code> to change.
</p>
<column name="name">
The database's name, as specified in its schema.
</column>
<column name="schema">
The database schema, as a JSON string.
</column>
</table>
</database>

View File

@ -109,3 +109,28 @@ EXTRA_DIST += ovsdb/ovsdb-dot.in ovsdb/dot2pic
noinst_SCRIPTS += ovsdb/ovsdb-dot
CLEANFILES += ovsdb/ovsdb-dot
OVSDB_DOT = $(run_python) $(srcdir)/ovsdb/ovsdb-dot.in
EXTRA_DIST += ovsdb/_server.ovsschema
CLEANFILES += ovsdb/_server.ovsschema.inc
ovsdb/ovsdb-server.o: ovsdb/_server.ovsschema.inc
ovsdb/_server.ovsschema.inc: ovsdb/_server.ovsschema $(srcdir)/build-aux/text2c
$(AM_V_GEN)$(run_python) $(srcdir)/build-aux/text2c < $< > $@.tmp
$(AM_V_at)mv $@.tmp $@
# Version checking for _server.ovsschema.
ALL_LOCAL += ovsdb/_server.ovsschema.stamp
ovsdb/_server.ovsschema.stamp: ovsdb/_server.ovsschema
$(srcdir)/build-aux/cksum-schema-check $? $@
CLEANFILES += ovsdb/_server.ovsschema.stamp
# _Server schema documentation
EXTRA_DIST += ovsdb/_server.xml
CLEANFILES += ovsdb/ovsdb-server.5
man_MANS += ovsdb/ovsdb-server.5
ovsdb/ovsdb-server.5: \
ovsdb/ovsdb-doc ovsdb/_server.xml ovsdb/_server.ovsschema
$(AM_V_GEN)$(OVSDB_DOC) \
--version=$(VERSION) \
$(srcdir)/ovsdb/_server.ovsschema \
$(srcdir)/ovsdb/_server.xml > $@.tmp && \
mv $@.tmp $@

View File

@ -45,6 +45,12 @@ example, \fBovsdb\-tool create\fR.
This OVSDB implementation supports standalone and active-backup
databases, as well as database replication.
See the Service Models section of \fBovsdb\fR(7) for more information.
.PP
In addition to user-specified databases, \fBovsdb\-server\fR version
2.9 and later also always hosts a built-in database named
\fB_Server\fR. Please see \fBovsdb\-server\fR(5) for documentation on
this database's schema.
.
.SH OPTIONS
.
.IP "\fB\-\-remote=\fIremote\fR"

View File

@ -65,6 +65,7 @@ struct db {
char *filename;
struct ovsdb_file *file;
struct ovsdb *db;
struct uuid row_uuid;
};
/* SSL configuration. */
@ -107,6 +108,7 @@ static unixctl_cb_func ovsdb_server_remove_database;
static unixctl_cb_func ovsdb_server_list_databases;
static char *open_db(struct server_config *config, const char *filename);
static void add_server_db(struct server_config *);
static void close_db(struct db *db);
static void parse_options(int *argc, char **argvp[],
@ -124,6 +126,7 @@ static void report_error_if_changed(char *error, char **last_errorp);
static void update_remote_status(const struct ovsdb_jsonrpc_server *jsonrpc,
const struct sset *remotes,
struct shash *all_dbs);
static void update_server_status(struct shash *all_dbs);
static void save_config__(FILE *config_file, const struct sset *remotes,
const struct sset *db_filenames,
@ -214,6 +217,8 @@ main_loop(struct ovsdb_jsonrpc_server *jsonrpc, struct shash *all_dbs,
update_remote_status(jsonrpc, remotes, all_dbs);
}
update_server_status(all_dbs);
memory_wait();
if (*is_backup) {
replication_wait();
@ -328,6 +333,7 @@ main(int argc, char *argv[])
ovs_fatal(0, "%s", error);
}
}
add_server_db(&server_config);
error = reconfigure_remotes(jsonrpc, &all_dbs, &remotes);
if (!error) {
@ -490,6 +496,16 @@ close_db(struct db *db)
free(db);
}
static void
add_db(struct server_config *config, const char *name, struct db *db)
{
db->row_uuid = UUID_ZERO;
shash_add_assert(config->all_dbs, name, db);
bool ok OVS_UNUSED = ovsdb_jsonrpc_server_add_db(config->jsonrpc,
db->db);
ovs_assert(ok);
}
static char *
open_db(struct server_config *config, const char *filename)
{
@ -524,6 +540,27 @@ open_db(struct server_config *config, const char *filename)
return error;
}
/* Add the internal _Server database to the server configuration. */
static void
add_server_db(struct server_config *config)
{
struct json *schema_json = json_from_string(
#include "ovsdb/_server.ovsschema.inc"
);
ovs_assert(schema_json->type == JSON_OBJECT);
struct ovsdb_schema *schema;
struct ovsdb_error *error OVS_UNUSED = ovsdb_schema_from_json(schema_json,
&schema);
ovs_assert(!error);
json_destroy(schema_json);
struct db *db = xzalloc(sizeof *db);
db->filename = xstrdup("<internal>");
db->db = ovsdb_create(schema);
add_db(config, db->db->schema->name, db);
}
static char * OVS_WARN_UNUSED_RESULT
parse_db_column__(const struct shash *all_dbs,
const char *name_, char *name,
@ -887,6 +924,18 @@ update_remote_rows(const struct shash *all_dbs, const struct db *db_,
}
}
static void
commit_txn(struct ovsdb_txn *txn, const char *name)
{
struct ovsdb_error *error = ovsdb_txn_commit(txn, false);
if (error) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
char *msg = ovsdb_error_to_string_free(error);
VLOG_ERR_RL(&rl, "Failed to update %s: %s", name, msg);
free(msg);
}
}
static void
update_remote_status(const struct ovsdb_jsonrpc_server *jsonrpc,
const struct sset *remotes,
@ -903,14 +952,84 @@ update_remote_status(const struct ovsdb_jsonrpc_server *jsonrpc,
update_remote_rows(all_dbs, db, remote, jsonrpc, txn);
}
struct ovsdb_error *error = ovsdb_txn_commit(txn, false);
if (error) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
char *msg = ovsdb_error_to_string_free(error);
VLOG_ERR_RL(&rl, "Failed to update remote status: %s", msg);
free(msg);
commit_txn(txn, node->name);
}
}
/* Updates 'row', a row in the _Server database's Database table, to match
* 'db'. */
static void
update_database_status(struct ovsdb_row *row, struct db *db)
{
ovsdb_util_write_string_column(row, "name", db->db->schema->name);
const struct uuid *row_uuid = ovsdb_row_get_uuid(row);
if (!uuid_equals(row_uuid, &db->row_uuid)) {
db->row_uuid = *row_uuid;
/* The schema can only change if the row UUID changes, so only update
* it in that case. Presumably, this is worth optimizing because
* schemas are often kilobytes in size and nontrivial to serialize. */
struct json *json_schema = ovsdb_schema_to_json(db->db->schema);
char *schema = json_to_string(json_schema, JSSF_SORT);
ovsdb_util_write_string_column(row, "schema", schema);
free(schema);
json_destroy(json_schema);
}
}
/* Updates the Database table in the _Server database. */
static void
update_server_status(struct shash *all_dbs)
{
struct db *server_db = shash_find_data(all_dbs, "_Server");
struct ovsdb_table *database_table = shash_find_data(
&server_db->db->tables, "Database");
struct ovsdb_txn *txn = ovsdb_txn_create(server_db->db);
/* Update rows for databases that still exist.
* Delete rows for databases that no longer exist. */
const struct ovsdb_row *row, *next_row;
HMAP_FOR_EACH_SAFE (row, next_row, hmap_node, &database_table->rows) {
const char *name;
ovsdb_util_read_string_column(row, "name", &name);
struct db *db = shash_find_data(all_dbs, name);
if (!db || !db->db) {
ovsdb_txn_row_delete(txn, row);
} else {
update_database_status(ovsdb_txn_row_modify(txn, row), db);
}
}
/* Add rows for new databases.
*
* This is O(n**2) but usually there are only 2 or 3 databases. */
struct shash_node *node;
SHASH_FOR_EACH (node, all_dbs) {
struct db *db = node->data;
if (!db->db) {
continue;
}
HMAP_FOR_EACH (row, hmap_node, &database_table->rows) {
const char *name;
ovsdb_util_read_string_column(row, "name", &name);
if (!strcmp(name, node->name)) {
goto next;
}
}
/* Add row. */
struct ovsdb_row *row = ovsdb_row_create(database_table);
uuid_generate(ovsdb_row_get_uuid_rw(row));
update_database_status(row, db);
ovsdb_txn_row_insert(txn, row);
next:;
}
commit_txn(txn, "_Server");
}
/* Reconfigures ovsdb-server's remotes based on information in the database. */

View File

@ -22,6 +22,38 @@
VLOG_DEFINE_THIS_MODULE(ovsdb_util);
static void
ovsdb_util_clear_column(struct ovsdb_row *row, const char *column_name)
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
const struct ovsdb_table_schema *schema = row->table->schema;
const struct ovsdb_column *column;
column = ovsdb_table_schema_get_column(schema, column_name);
if (!column) {
VLOG_DBG_RL(&rl, "Table `%s' has no `%s' column",
schema->name, column_name);
return;
}
if (column->type.n_min) {
if (!VLOG_DROP_DBG(&rl)) {
char *type_name = ovsdb_type_to_english(&column->type);
VLOG_DBG("Table `%s' column `%s' has type %s, which requires "
"a value, but an attempt was made to clear it",
schema->name, column_name, type_name);
free(type_name);
}
return;
}
struct ovsdb_datum *datum = &row->fields[column->index];
if (datum->n) {
ovsdb_datum_destroy(datum, &column->type);
ovsdb_datum_init_empty(datum);
}
}
struct ovsdb_datum *
ovsdb_util_get_datum(struct ovsdb_row *row, const char *column_name,
const enum ovsdb_atomic_type key_type,
@ -164,29 +196,75 @@ ovsdb_util_read_bool_column(const struct ovsdb_row *row,
return atom != NULL;
}
void
ovsdb_util_write_bool_column(struct ovsdb_row *row, const char *column_name,
bool value)
bool
ovsdb_util_read_uuid_column(const struct ovsdb_row *row,
const char *column_name, struct uuid *uuid)
{
const union ovsdb_atom *atom;
atom = ovsdb_util_read_column(row, column_name, OVSDB_TYPE_UUID);
*uuid = atom ? atom->uuid : UUID_ZERO;
return atom != NULL;
}
static void
ovsdb_util_write_singleton(struct ovsdb_row *row, const char *column_name,
const union ovsdb_atom *atom,
enum ovsdb_atomic_type type)
{
const struct ovsdb_column *column;
struct ovsdb_datum *datum;
column = ovsdb_table_schema_get_column(row->table->schema, column_name);
datum = ovsdb_util_get_datum(row, column_name, OVSDB_TYPE_BOOLEAN,
OVSDB_TYPE_VOID, 1);
datum = ovsdb_util_get_datum(row, column_name, type, OVSDB_TYPE_VOID, 1);
if (!datum) {
return;
}
if (datum->n != 1) {
if (datum->n == 1) {
if (ovsdb_atom_equals(&datum->keys[0], atom, type)) {
return;
}
ovsdb_atom_destroy(&datum->keys[0], type);
} else {
ovsdb_datum_destroy(datum, &column->type);
datum->n = 1;
datum->keys = xmalloc(sizeof *datum->keys);
datum->values = NULL;
}
ovsdb_atom_clone(&datum->keys[0], atom, type);
}
datum->keys[0].boolean = value;
void
ovsdb_util_write_bool_column(struct ovsdb_row *row, const char *column_name,
bool value)
{
const union ovsdb_atom atom = { .boolean = value };
ovsdb_util_write_singleton(row, column_name, &atom, OVSDB_TYPE_BOOLEAN);
}
void
ovsdb_util_write_uuid_column(struct ovsdb_row *row, const char *column_name,
const struct uuid *uuid)
{
if (uuid) {
const union ovsdb_atom atom = { .uuid = *uuid };
ovsdb_util_write_singleton(row, column_name, &atom, OVSDB_TYPE_UUID);
} else {
ovsdb_util_clear_column(row, column_name);
}
}
void
ovsdb_util_write_string_column(struct ovsdb_row *row, const char *column_name,
const char *string)
{
if (string) {
const union ovsdb_atom atom = { .string = CONST_CAST(char *, string) };
ovsdb_util_write_singleton(row, column_name, &atom, OVSDB_TYPE_STRING);
} else {
ovsdb_util_clear_column(row, column_name);
}
}
void

View File

@ -38,6 +38,9 @@ bool ovsdb_util_read_integer_column(const struct ovsdb_row *row,
bool ovsdb_util_read_string_column(const struct ovsdb_row *row,
const char *column_name,
const char **stringp);
void ovsdb_util_write_string_column(struct ovsdb_row *row,
const char *column_name,
const char *string);
void ovsdb_util_write_string_string_column(struct ovsdb_row *row,
const char *column_name,
char **keys, char **values,
@ -48,5 +51,11 @@ bool ovsdb_util_read_bool_column(const struct ovsdb_row *row,
void ovsdb_util_write_bool_column(struct ovsdb_row *row,
const char *column_name,
bool value);
bool ovsdb_util_read_uuid_column(const struct ovsdb_row *row,
const char *column_name,
struct uuid *);
void ovsdb_util_write_uuid_column(struct ovsdb_row *row,
const char *column_name,
const struct uuid *);
#endif /* ovsdb/util.h */

View File

@ -562,6 +562,7 @@ fi
%{_mandir}/man1/ovsdb-client.1*
%{_mandir}/man1/ovsdb-server.1*
%{_mandir}/man1/ovsdb-tool.1*
%{_mandir}/man5/ovsdb-server.5*
%{_mandir}/man5/ovs-vswitchd.conf.db.5*
%{_mandir}/man5/ovsdb.5*
%{_mandir}/man5/vtep.5*

View File

@ -225,6 +225,7 @@ exit 0
/usr/share/man/man1/ovsdb-client.1.gz
/usr/share/man/man1/ovsdb-server.1.gz
/usr/share/man/man1/ovsdb-tool.1.gz
/usr/share/man/man5/ovsdb-server.5.gz
/usr/share/man/man5/ovs-vswitchd.conf.db.5.gz
%{_mandir}/man5/ovsdb.5*
/usr/share/man/man5/vtep.5.gz

View File

@ -137,20 +137,31 @@ AT_CHECK([uuidfilt output], [0],
[test ! -e pid || kill `cat pid`])
AT_CLEANUP
dnl CHECK_DBS([databases])
dnl
dnl Checks that ovsdb-server hosts the given 'databases', each of which
dnl needs to be followed by a newline.
m4_define([CHECK_DBS],
[AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [_Server
$1])
AT_CHECK([ovsdb-client --no-headings dump _Server Database name | sort], [0], [dnl
Database table
_Server
$1])])
AT_SETUP([database multiplexing implementation])
AT_KEYWORDS([ovsdb server positive])
ordinal_schema > schema1
constraint_schema > schema2
AT_CHECK([ovsdb-tool create db1 schema1], [0], [ignore], [ignore])
AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db1 db2], [0], [ignore], [ignore])
AT_CHECK(
[[ovsdb-client list-dbs unix:socket]],
[0], [constraints
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:db.sock db1 db2], [0], [ignore], [ignore])
CHECK_DBS([constraints
ordinals
], [ignore], [test ! -e pid || kill `cat pid`])
])
AT_CHECK(
[[ovstest test-jsonrpc request unix:socket get_schema [\"nonexistent\"]]], [0],
[[ovstest test-jsonrpc request unix:db.sock get_schema [\"nonexistent\"]]], [0],
[[{"error":{"details":"get_schema request specifies unknown database nonexistent","error":"unknown database","syntax":"[\"nonexistent\"]"},"id":0,"result":null}
]], [], [test ! -e pid || kill `cat pid`])
OVSDB_SERVER_SHUTDOWN
@ -165,21 +176,19 @@ AT_CHECK([ovsdb-tool create db1 schema1], [0], [ignore], [ignore])
AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
# Start ovsdb-server with just a single database - db1.
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db1], [0])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [ordinals
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:db.sock db1], [0])
CHECK_DBS([ordinals
])
# Add the second database.
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], [0])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [constraints
CHECK_DBS([constraints
ordinals
])
# The databases are responsive.
AT_CHECK([ovsdb-client list-tables unix:socket constraints], [0], [ignore], [ignore])
AT_CHECK([ovsdb-client list-tables unix:socket ordinals], [0], [ignore], [ignore])
AT_CHECK([ovsdb-client list-tables unix:db.sock constraints], [0], [ignore], [ignore])
AT_CHECK([ovsdb-client list-tables unix:db.sock ordinals], [0], [ignore], [ignore])
# Add an already added database.
if test $IS_WIN32 = "yes"; then
@ -205,25 +214,23 @@ ovs-appctl: ovsdb-server: server returned an error
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote db:ordinals,ordinals,name], [0])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
[0], [db:ordinals,ordinals,name
punix:socket
punix:db.sock
])
# Removing db1 has no effect on its remote.
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db ordinals], [0])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [constraints
CHECK_DBS([constraints
])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
[0], [db:ordinals,ordinals,name
punix:socket
punix:db.sock
])
AT_CHECK([ovsdb-client list-tables unix:socket ordinals], [1], [ignore], [ignore])
AT_CHECK([ovsdb-client list-tables unix:db.sock ordinals], [1], [ignore], [ignore])
# Remove db2.
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db constraints], [0])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [])
AT_CHECK([ovsdb-client list-tables unix:socket constraints], [1], [ignore], [ignore])
CHECK_DBS()
AT_CHECK([ovsdb-client list-tables unix:db.sock constraints], [1], [ignore], [ignore])
# Remove a non-existent database.
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db ordinals], [2],
@ -233,10 +240,9 @@ ovs-appctl: ovsdb-server: server returned an error
# Add a removed database.
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], [0])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [constraints
CHECK_DBS([constraints
])
AT_CHECK([ovsdb-client list-tables unix:socket constraints], [0], [ignore], [ignore])
AT_CHECK([ovsdb-client list-tables unix:db.sock constraints], [0], [ignore], [ignore])
OVS_APP_EXIT_AND_WAIT([ovsdb-server])
AT_CLEANUP
@ -247,14 +253,13 @@ AT_SKIP_IF([test "$IS_WIN32" = "yes"])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create db1 schema], [0], [ignore], [ignore])
on_exit 'kill `cat *.pid`'
AT_CHECK([ovsdb-server -v -vvlog:off --monitor --detach --no-chdir --pidfile --log-file db1])
AT_CHECK([ovsdb-server -v -vvlog:off --monitor --detach --no-chdir --pidfile --log-file --remote=punix:db.sock db1])
# Add the second database.
constraint_schema > schema2
AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], [0])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [constraints
CHECK_DBS([constraints
ordinals
])
@ -266,8 +271,7 @@ OVS_WAIT_WHILE([kill -0 `cat old.pid`])
OVS_WAIT_UNTIL(
[test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [constraints
CHECK_DBS([constraints
ordinals
])
OVS_APP_EXIT_AND_WAIT([ovsdb-server])
@ -282,12 +286,11 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [ignore], [ignore])
constraint_schema > schema2
AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
on_exit 'kill `cat *.pid`'
AT_CHECK([ovsdb-server -v -vvlog:off --monitor --detach --no-chdir --pidfile --log-file db1 db2])
AT_CHECK([ovsdb-server -v -vvlog:off --monitor --detach --no-chdir --pidfile --log-file --remote=punix:db.sock db1 db2])
# Remove the second database.
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db constraints])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [ordinals
CHECK_DBS([ordinals
])
# Kill the daemon process, making it look like a segfault,
@ -298,8 +301,7 @@ OVS_WAIT_WHILE([kill -0 `cat old.pid`])
OVS_WAIT_UNTIL(
[test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
[0], [ordinals
CHECK_DBS([ordinals
])
OVS_APP_EXIT_AND_WAIT([ovsdb-server])
AT_CLEANUP

View File

@ -481,6 +481,7 @@ exit 0
/usr/share/man/man1/ovsdb-client.1.gz
/usr/share/man/man1/ovsdb-server.1.gz
/usr/share/man/man1/ovsdb-tool.1.gz
/usr/share/man/man5/ovsdb-server.5.gz
/usr/share/man/man5/ovs-vswitchd.conf.db.5.gz
/usr/share/man/man5/vtep.5.gz
/usr/share/man/man7/ovs-fields.7.gz