mirror of
https://github.com/openvswitch/ovs
synced 2025-08-30 13:58:14 +00:00
ovsdb: Add table exclusion functionality to OVSDB replication
A blacklist of tables that will be excluded from replication can be specified by the following option: --sync-exclude-tables=db:table[,db:table]… Where 'table' corresponds to a table name, and 'db' corresponds to the database name where the table resides. Signed-off-by: Mario Cabrera <mario.cabrera@hpe.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
@@ -1266,6 +1266,7 @@ parse_options(int *argcp, char **argvp[],
|
|||||||
OPT_BOOTSTRAP_CA_CERT,
|
OPT_BOOTSTRAP_CA_CERT,
|
||||||
OPT_PEER_CA_CERT,
|
OPT_PEER_CA_CERT,
|
||||||
OPT_SYNC_FROM,
|
OPT_SYNC_FROM,
|
||||||
|
OPT_SYNC_EXCLUDE,
|
||||||
VLOG_OPTION_ENUMS,
|
VLOG_OPTION_ENUMS,
|
||||||
DAEMON_OPTION_ENUMS
|
DAEMON_OPTION_ENUMS
|
||||||
};
|
};
|
||||||
@@ -1285,6 +1286,7 @@ parse_options(int *argcp, char **argvp[],
|
|||||||
{"certificate", required_argument, NULL, 'c'},
|
{"certificate", required_argument, NULL, 'c'},
|
||||||
{"ca-cert", required_argument, NULL, 'C'},
|
{"ca-cert", required_argument, NULL, 'C'},
|
||||||
{"sync-from", required_argument, NULL, OPT_SYNC_FROM},
|
{"sync-from", required_argument, NULL, OPT_SYNC_FROM},
|
||||||
|
{"sync-exclude-tables", required_argument, NULL, OPT_SYNC_EXCLUDE},
|
||||||
{NULL, 0, NULL, 0},
|
{NULL, 0, NULL, 0},
|
||||||
};
|
};
|
||||||
char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
|
char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
|
||||||
@@ -1350,6 +1352,10 @@ parse_options(int *argcp, char **argvp[],
|
|||||||
connect_to_remote_server = true;
|
connect_to_remote_server = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_SYNC_EXCLUDE:
|
||||||
|
set_tables_blacklist(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
@@ -35,8 +35,10 @@
|
|||||||
static char *remote_ovsdb_server;
|
static char *remote_ovsdb_server;
|
||||||
static struct jsonrpc *rpc;
|
static struct jsonrpc *rpc;
|
||||||
static struct sset monitored_tables = SSET_INITIALIZER(&monitored_tables);
|
static struct sset monitored_tables = SSET_INITIALIZER(&monitored_tables);
|
||||||
|
static struct sset tables_blacklist = SSET_INITIALIZER(&tables_blacklist);
|
||||||
static bool reset_dbs = true;
|
static bool reset_dbs = true;
|
||||||
|
|
||||||
|
void replication_init(void);
|
||||||
static struct jsonrpc *open_jsonrpc(const char *server);
|
static struct jsonrpc *open_jsonrpc(const char *server);
|
||||||
static struct ovsdb_error *check_jsonrpc_error(int error,
|
static struct ovsdb_error *check_jsonrpc_error(int error,
|
||||||
struct jsonrpc_msg **reply_);
|
struct jsonrpc_msg **reply_);
|
||||||
@@ -72,6 +74,14 @@ static struct ovsdb_error *execute_update(struct ovsdb_txn *txn,
|
|||||||
struct ovsdb_table *table,
|
struct ovsdb_table *table,
|
||||||
struct json *new);
|
struct json *new);
|
||||||
|
|
||||||
|
void
|
||||||
|
replication_init(void)
|
||||||
|
{
|
||||||
|
sset_init(&monitored_tables);
|
||||||
|
sset_init(&tables_blacklist);
|
||||||
|
reset_dbs = true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
replication_run(struct shash *all_dbs)
|
replication_run(struct shash *all_dbs)
|
||||||
{
|
{
|
||||||
@@ -108,11 +118,31 @@ set_remote_ovsdb_server(const char *remote_server)
|
|||||||
remote_ovsdb_server = remote_server ? xstrdup(remote_server) : NULL;
|
remote_ovsdb_server = remote_server ? xstrdup(remote_server) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_tables_blacklist(const char *blacklist)
|
||||||
|
{
|
||||||
|
char *save_ptr = NULL;
|
||||||
|
char *blacklist_item;
|
||||||
|
|
||||||
|
replication_init();
|
||||||
|
|
||||||
|
if (blacklist) {
|
||||||
|
char *t_blacklist = xstrdup(blacklist);
|
||||||
|
for (blacklist_item = strtok_r(t_blacklist, ",", &save_ptr);
|
||||||
|
blacklist_item != NULL;
|
||||||
|
blacklist_item = strtok_r(NULL, ",", &save_ptr)) {
|
||||||
|
sset_add(&tables_blacklist, blacklist_item);
|
||||||
|
}
|
||||||
|
free(t_blacklist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
disconnect_remote_server(void)
|
disconnect_remote_server(void)
|
||||||
{
|
{
|
||||||
jsonrpc_close(rpc);
|
jsonrpc_close(rpc);
|
||||||
sset_destroy(&monitored_tables);
|
sset_destroy(&monitored_tables);
|
||||||
|
sset_destroy(&tables_blacklist);
|
||||||
|
|
||||||
if (remote_ovsdb_server) {
|
if (remote_ovsdb_server) {
|
||||||
free(remote_ovsdb_server);
|
free(remote_ovsdb_server);
|
||||||
@@ -160,9 +190,15 @@ reset_database(struct ovsdb *db, struct ovsdb_txn *txn)
|
|||||||
struct ovsdb_table *table = table_node->data;
|
struct ovsdb_table *table = table_node->data;
|
||||||
struct ovsdb_row *row;
|
struct ovsdb_row *row;
|
||||||
|
|
||||||
HMAP_FOR_EACH (row, hmap_node, &table->rows) {
|
/* Do not reset if table is blacklisted. */
|
||||||
ovsdb_txn_row_delete(txn, row);
|
char *blacklist_item = xasprintf(
|
||||||
|
"%s%s%s", db->schema->name, ":", table_node->name);
|
||||||
|
if (!sset_contains(&tables_blacklist, blacklist_item)) {
|
||||||
|
HMAP_FOR_EACH (row, hmap_node, &table->rows) {
|
||||||
|
ovsdb_txn_row_delete(txn, row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
free(blacklist_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +329,14 @@ send_monitor_requests(struct shash *all_dbs)
|
|||||||
|
|
||||||
for (int j = 0; j < n; j++) {
|
for (int j = 0; j < n; j++) {
|
||||||
struct ovsdb_table_schema *table = nodes[j]->data;
|
struct ovsdb_table_schema *table = nodes[j]->data;
|
||||||
add_monitored_table(table, monitor_request);
|
|
||||||
|
/* Check if table is not blacklisted. */
|
||||||
|
char *blacklist_item = xasprintf(
|
||||||
|
"%s%s%s", db_name, ":", table->name);
|
||||||
|
if (!sset_contains(&tables_blacklist, blacklist_item)) {
|
||||||
|
add_monitored_table(table, monitor_request);
|
||||||
|
}
|
||||||
|
free(blacklist_item);
|
||||||
}
|
}
|
||||||
free(nodes);
|
free(nodes);
|
||||||
|
|
||||||
|
@@ -32,6 +32,7 @@ struct db {
|
|||||||
|
|
||||||
void replication_run(struct shash *dbs);
|
void replication_run(struct shash *dbs);
|
||||||
void set_remote_ovsdb_server(const char *remote_server);
|
void set_remote_ovsdb_server(const char *remote_server);
|
||||||
|
void set_tables_blacklist(const char *blacklist);
|
||||||
void disconnect_remote_server(void);
|
void disconnect_remote_server(void);
|
||||||
const struct db *find_db(const struct shash *all_dbs, const char *db_name);
|
const struct db *find_db(const struct shash *all_dbs, const char *db_name);
|
||||||
void replication_usage(void);
|
void replication_usage(void);
|
||||||
|
@@ -75,6 +75,7 @@ TESTSUITE_AT = \
|
|||||||
tests/ovsdb-execution.at \
|
tests/ovsdb-execution.at \
|
||||||
tests/ovsdb-trigger.at \
|
tests/ovsdb-trigger.at \
|
||||||
tests/ovsdb-tool.at \
|
tests/ovsdb-tool.at \
|
||||||
|
tests/ovsdb-replication.at \
|
||||||
tests/ovsdb-server.at \
|
tests/ovsdb-server.at \
|
||||||
tests/ovsdb-monitor.at \
|
tests/ovsdb-monitor.at \
|
||||||
tests/ovsdb-idl.at \
|
tests/ovsdb-idl.at \
|
||||||
|
174
tests/ovsdb-replication.at
Normal file
174
tests/ovsdb-replication.at
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
AT_BANNER([OVSDB -- replication])
|
||||||
|
|
||||||
|
m4_divert_push([PREPARE_TESTS])
|
||||||
|
[
|
||||||
|
replication_schema () {
|
||||||
|
cat <<'EOF'
|
||||||
|
{"name": "mydb",
|
||||||
|
"tables": {
|
||||||
|
"a": {
|
||||||
|
"columns": {
|
||||||
|
"number": {"type": "integer"},
|
||||||
|
"name": {"type": "string"}},
|
||||||
|
"indexes": [["number"]]},
|
||||||
|
"b": {
|
||||||
|
"columns": {
|
||||||
|
"number": {"type": "integer"},
|
||||||
|
"name": {"type": "string"}},
|
||||||
|
"indexes": [["number"]]}}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
]
|
||||||
|
m4_divert_pop([PREPARE_TESTS])
|
||||||
|
|
||||||
|
m4_define([REPLICATION_EXAMPLES], [
|
||||||
|
|
||||||
|
OVSDB_CHECK_REPLICATION([insert monitored table, insert excluded table],
|
||||||
|
[replication_schema],
|
||||||
|
[[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "a",
|
||||||
|
"row": {"number": 0, "name": "zero"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "b",
|
||||||
|
"row": {"number": 1, "name": "one"}}]]]],
|
||||||
|
[[7,9c7,8
|
||||||
|
< _uuid name number
|
||||||
|
< ------------------------------------ ---- ------
|
||||||
|
< <0> one 1 @&t@
|
||||||
|
---
|
||||||
|
> _uuid name number
|
||||||
|
> ----- ---- ------]]
|
||||||
|
)
|
||||||
|
|
||||||
|
OVSDB_CHECK_REPLICATION([insert monitored table, update excluded table],
|
||||||
|
[replication_schema],
|
||||||
|
[[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "a",
|
||||||
|
"row": {"number": 0, "name": "zero"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "b",
|
||||||
|
"row": {"number": 1, "name": "one"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "update",
|
||||||
|
"table": "b",
|
||||||
|
"where":[["name","==","one"]],
|
||||||
|
"row": {"number": 2, "name": "two"}}]]]],
|
||||||
|
[[7,9c7,8
|
||||||
|
< _uuid name number
|
||||||
|
< ------------------------------------ ---- ------
|
||||||
|
< <0> two 2 @&t@
|
||||||
|
---
|
||||||
|
> _uuid name number
|
||||||
|
> ----- ---- ------]]
|
||||||
|
)
|
||||||
|
|
||||||
|
OVSDB_CHECK_REPLICATION([update monitored table, insert excluded table],
|
||||||
|
[replication_schema],
|
||||||
|
[[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "a",
|
||||||
|
"row": {"number": 0, "name": "zero"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "update",
|
||||||
|
"table": "a",
|
||||||
|
"where":[["name","==","zero"]],
|
||||||
|
"row": {"number": 1, "name": "one"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "b",
|
||||||
|
"row": {"number": 2, "name": "two"}}]]]],
|
||||||
|
[[7,9c7,8
|
||||||
|
< _uuid name number
|
||||||
|
< ------------------------------------ ---- ------
|
||||||
|
< <0> two 2 @&t@
|
||||||
|
---
|
||||||
|
> _uuid name number
|
||||||
|
> ----- ---- ------]]
|
||||||
|
)
|
||||||
|
|
||||||
|
OVSDB_CHECK_REPLICATION([update monitored table, update excluded table],
|
||||||
|
[replication_schema],
|
||||||
|
[[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "a",
|
||||||
|
"row": {"number": 0, "name": "zero"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "update",
|
||||||
|
"table": "a",
|
||||||
|
"where":[["name","==","zero"]],
|
||||||
|
"row": {"number": 1, "name": "one"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "b",
|
||||||
|
"row": {"number": 2, "name": "two"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "update",
|
||||||
|
"table": "b",
|
||||||
|
"where":[["name","==","two"]],
|
||||||
|
"row": {"number": 3, "name": "three"}}]]]],
|
||||||
|
[[7,9c7,8
|
||||||
|
< _uuid name number
|
||||||
|
< ------------------------------------ ----- ------
|
||||||
|
< <0> three 3 @&t@
|
||||||
|
---
|
||||||
|
> _uuid name number
|
||||||
|
> ----- ---- ------]]
|
||||||
|
)
|
||||||
|
|
||||||
|
OVSDB_CHECK_REPLICATION([delete monitored table, insert excluded table],
|
||||||
|
[replication_schema],
|
||||||
|
[[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "a",
|
||||||
|
"row": {"number": 0, "name": "zero"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "delete",
|
||||||
|
"table": "a",
|
||||||
|
"where":[["name","==","zero"]]}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "b",
|
||||||
|
"row": {"number": 1, "name": "one"}}]]]],
|
||||||
|
[[6,8c6,7
|
||||||
|
< _uuid name number
|
||||||
|
< ------------------------------------ ---- ------
|
||||||
|
< <0> one 1 @&t@
|
||||||
|
---
|
||||||
|
> _uuid name number
|
||||||
|
> ----- ---- ------]]
|
||||||
|
)
|
||||||
|
|
||||||
|
OVSDB_CHECK_REPLICATION([delete monitored table, update excluded table],
|
||||||
|
[replication_schema],
|
||||||
|
[[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "a",
|
||||||
|
"row": {"number": 0, "name": "zero"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "delete",
|
||||||
|
"table": "a",
|
||||||
|
"where":[["name","==","zero"]]}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "insert",
|
||||||
|
"table": "b",
|
||||||
|
"row": {"number": 1, "name": "one"}}]]],
|
||||||
|
[[["mydb",
|
||||||
|
{"op": "update",
|
||||||
|
"table": "b",
|
||||||
|
"where":[["name","==","one"]],
|
||||||
|
"row": {"number": 2, "name": "two"}}]]]],
|
||||||
|
[[6,8c6,7
|
||||||
|
< _uuid name number
|
||||||
|
< ------------------------------------ ---- ------
|
||||||
|
< <0> two 2 @&t@
|
||||||
|
---
|
||||||
|
> _uuid name number
|
||||||
|
> ----- ---- ------]]
|
||||||
|
)
|
||||||
|
|
||||||
|
])
|
@@ -1023,3 +1023,59 @@ m4_define([OVSDB_CHECK_EXECUTION],
|
|||||||
AT_CLEANUP])
|
AT_CLEANUP])
|
||||||
|
|
||||||
EXECUTION_EXAMPLES
|
EXECUTION_EXAMPLES
|
||||||
|
|
||||||
|
AT_BANNER([OVSDB -- ovsdb-server replication table-exclusion (TCP IPv4 sockets)])
|
||||||
|
|
||||||
|
# OVSDB_CHECK_REPLICATION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
|
||||||
|
#
|
||||||
|
# Creates two databases with the given SCHEMA, and starts an
|
||||||
|
# ovsdb-server on each database.
|
||||||
|
# Runs each of the TRANSACTIONS (which should be a quoted list of
|
||||||
|
# quoted strings) against one of the servers with ovsdb-client one at a
|
||||||
|
# time. The server replicates its database to the other ovsdb-server.
|
||||||
|
#
|
||||||
|
# Checks that the difference between the dump of the databases is
|
||||||
|
# OUTPUT, but UUIDs in the output are replaced by markers of the form
|
||||||
|
# <N> where N is a number. The first unique UUID is replaced by <0>,
|
||||||
|
# the next by <1>, and so on.
|
||||||
|
# If a given UUID appears more than once it is always replaced by the
|
||||||
|
# same marker.
|
||||||
|
#
|
||||||
|
# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
|
||||||
|
m4_define([OVSDB_CHECK_REPLICATION],
|
||||||
|
[AT_SETUP([$1])
|
||||||
|
AT_KEYWORDS([ovsdb server tcp replication table-exclusion])
|
||||||
|
$2 > schema
|
||||||
|
AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
|
||||||
|
AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
|
||||||
|
|
||||||
|
AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile="`pwd`"/pid --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl db1], [0], [ignore], [ignore])
|
||||||
|
PARSE_LISTENING_PORT([ovsdb-server1.log], [TCP_PORT1])
|
||||||
|
|
||||||
|
AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile="`pwd`"/pid2 --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl2 --sync-from=tcp:127.0.0.1:$TCP_PORT1 --sync-exclude-tables=mydb:b db2], [0], [ignore], [ignore])
|
||||||
|
PARSE_LISTENING_PORT([ovsdb-server2.log], [TCP_PORT2])
|
||||||
|
|
||||||
|
m4_foreach([txn], [$3],
|
||||||
|
[AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT1 'txn'; sleep 2], [0], [stdout], [ignore],
|
||||||
|
[test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
|
||||||
|
])
|
||||||
|
|
||||||
|
AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT1], [0], [stdout], [ignore],
|
||||||
|
[test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
|
||||||
|
cat stdout >> dump1
|
||||||
|
AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT2], [0], [stdout], [ignore],
|
||||||
|
[test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
|
||||||
|
cat stdout >> dump2
|
||||||
|
|
||||||
|
AT_CHECK([diff dump1 dump2], [1], [stdout], [ignore],
|
||||||
|
[test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
|
||||||
|
cat stdout >> output
|
||||||
|
|
||||||
|
AT_CHECK([${PERL} $srcdir/uuidfilt.pl output], [0], [$4], [ignore],
|
||||||
|
[test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
|
||||||
|
|
||||||
|
OVSDB_SERVER_SHUTDOWN
|
||||||
|
OVSDB_SERVER_SHUTDOWN2
|
||||||
|
AT_CLEANUP])
|
||||||
|
|
||||||
|
REPLICATION_EXAMPLES
|
||||||
|
@@ -143,6 +143,7 @@ m4_include([tests/ovsdb-transaction.at])
|
|||||||
m4_include([tests/ovsdb-execution.at])
|
m4_include([tests/ovsdb-execution.at])
|
||||||
m4_include([tests/ovsdb-trigger.at])
|
m4_include([tests/ovsdb-trigger.at])
|
||||||
m4_include([tests/ovsdb-tool.at])
|
m4_include([tests/ovsdb-tool.at])
|
||||||
|
m4_include([tests/ovsdb-replication.at])
|
||||||
m4_include([tests/ovsdb-server.at])
|
m4_include([tests/ovsdb-server.at])
|
||||||
m4_include([tests/ovsdb-monitor.at])
|
m4_include([tests/ovsdb-monitor.at])
|
||||||
m4_include([tests/ovsdb-idl.at])
|
m4_include([tests/ovsdb-idl.at])
|
||||||
|
Reference in New Issue
Block a user