diff options
author | Ilya Maximets <i.maximets@ovn.org> | 2023-03-27 21:42:57 +0200 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2023-04-24 22:34:56 +0200 |
commit | a73b0206ba6f3991ac1550c7c07f11fa4237a898 (patch) | |
tree | 18855c652f75aad299b9d32abce058728f43133a /ovsdb/storage.c | |
parent | 5575539f6c98cbec91f955805ae079899396f521 (diff) | |
download | openvswitch-a73b0206ba6f3991ac1550c7c07f11fa4237a898.tar.gz |
ovsdb: Check for ephemeral columns before writing a new schema.
Clustered databases do not support ephemeral columns, but ovsdb-server
checks for them after the conversion result is read from the storage.
It's much easier to recover if this constraint is checked before writing
to the storage instead.
It's not a big problem, because the check is always performed by the
native ovsdb clients before sending a conversion request. But the
server, in general, should not trust clients to do the right thing.
Check in the update_schema() remains, because we shouldn't blindly
trust the storage.
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Acked-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'ovsdb/storage.c')
-rw-r--r-- | ovsdb/storage.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/ovsdb/storage.c b/ovsdb/storage.c index e8f95ce64..6c395106c 100644 --- a/ovsdb/storage.c +++ b/ovsdb/storage.c @@ -623,7 +623,7 @@ ovsdb_storage_store_snapshot(struct ovsdb_storage *storage, struct ovsdb_write * OVS_WARN_UNUSED_RESULT ovsdb_storage_write_schema_change(struct ovsdb_storage *storage, - const struct json *schema, + const struct ovsdb_schema *schema, const struct json *data, const struct uuid *prereq, struct uuid *resultp) @@ -633,13 +633,23 @@ ovsdb_storage_write_schema_change(struct ovsdb_storage *storage, if (storage->error) { w->error = ovsdb_error_clone(storage->error); } else if (storage->raft) { - struct json *txn_json = json_array_create_2(json_clone(schema), - json_clone(data)); - w->command = raft_command_execute(storage->raft, txn_json, - prereq, &result); - json_destroy(txn_json); + /* Clustered storage doesn't support ephemeral columns. */ + w->error = ovsdb_schema_check_for_ephemeral_columns(schema); + if (!w->error) { + struct json *schema_json, *txn_json; + + schema_json = ovsdb_schema_to_json(schema); + txn_json = json_array_create_2(schema_json, json_clone(data)); + w->command = raft_command_execute(storage->raft, txn_json, + prereq, &result); + json_destroy(txn_json); + } } else if (storage->log) { - w->error = ovsdb_storage_store_snapshot__(storage, schema, data, 0); + struct json *schema_json = ovsdb_schema_to_json(schema); + + w->error = ovsdb_storage_store_snapshot__(storage, schema_json, + data, 0); + json_destroy(schema_json); } else { /* When 'error' and 'command' are both null, it indicates that the * command is complete. This is fine since this unbacked storage drops |