[ovs-dev] [PATCH v3 3/9] uuid: Allow record/replay of generated UUIDs.
Ilya Maximets
i.maximets at ovn.org
Thu May 27 13:29:01 UTC 2021
This is required for the stream record/replay functionality of
ovsdb-server. With record/replay of UUIDs we could record all
incoming transactions and replay them later while being sure
that ovsdb-server will generate exactly same UUIDs for all the
data updates.
Signed-off-by: Ilya Maximets <i.maximets at ovn.org>
Acked-by: Dumitru Ceara <dceara at redhat.com>
---
lib/uuid.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/lib/uuid.c b/lib/uuid.c
index 13d20ac64..8a16606da 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -26,11 +26,16 @@
#include "aes128.h"
#include "entropy.h"
+#include "fatal-signal.h"
+#include "openvswitch/vlog.h"
+#include "ovs-replay.h"
#include "ovs-thread.h"
#include "sha1.h"
#include "timeval.h"
#include "util.h"
+VLOG_DEFINE_THIS_MODULE(uuid);
+
static struct aes128 key;
static uint64_t counter[2];
BUILD_ASSERT_DECL(sizeof counter == 16);
@@ -54,6 +59,63 @@ uuid_init(void)
pthread_once(&once, do_init);
}
+/* Record/replay of uuid generation. */
+static replay_file_t uuid_replay_file;
+static int uuid_replay_seqno;
+
+static void
+uuid_replay_file_close(void *aux OVS_UNUSED)
+{
+ ovs_replay_file_close(uuid_replay_file);
+}
+
+static void
+uuid_replay_file_open(void)
+{
+ int error;
+
+ ovs_replay_lock();
+ error = ovs_replay_file_open("__uuid_generate", &uuid_replay_file,
+ &uuid_replay_seqno);
+ ovs_replay_unlock();
+ if (error) {
+ VLOG_FATAL("failed to open uuid replay file: %s.",
+ ovs_strerror(error));
+ }
+ fatal_signal_add_hook(uuid_replay_file_close, NULL, NULL, true);
+}
+
+static void
+uuid_replay_file_read(struct uuid *uuid)
+{
+ int norm_seqno = ovs_replay_normalized_seqno(uuid_replay_seqno);
+ int retval, len;
+
+ ovs_replay_lock();
+ ovs_assert(norm_seqno == ovs_replay_seqno());
+ ovs_assert(ovs_replay_seqno_is_read(uuid_replay_seqno));
+
+ retval = ovs_replay_read(uuid_replay_file, uuid, sizeof *uuid,
+ &len, &uuid_replay_seqno, true);
+ if (retval || len != sizeof *uuid) {
+ VLOG_FATAL("failed to read from replay file: %s.",
+ ovs_strerror(retval));
+ }
+ ovs_replay_unlock();
+}
+
+static void
+uuid_replay_file_write(struct uuid *uuid)
+{
+ int retval;
+
+ retval = ovs_replay_write(uuid_replay_file, uuid, sizeof *uuid, true);
+ if (retval) {
+ VLOG_FATAL("failed to write uuid to replay file: %s.",
+ ovs_strerror(retval));
+ }
+}
+
/* Generates a new random UUID in 'uuid'.
*
* We go to some trouble to ensure as best we can that the generated UUID has
@@ -82,10 +144,16 @@ void
uuid_generate(struct uuid *uuid)
{
static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
+ enum ovs_replay_state replay_state = ovs_replay_get_state();
uint64_t copy[2];
uuid_init();
+ if (replay_state == OVS_REPLAY_READ) {
+ uuid_replay_file_read(uuid);
+ return;
+ }
+
/* Copy out the counter's current value, then increment it. */
ovs_mutex_lock(&mutex);
copy[0] = counter[0];
@@ -99,6 +167,10 @@ uuid_generate(struct uuid *uuid)
aes128_encrypt(&key, copy, uuid);
uuid_set_bits_v4(uuid);
+
+ if (replay_state == OVS_REPLAY_WRITE) {
+ uuid_replay_file_write(uuid);
+ }
}
struct uuid
@@ -276,6 +348,10 @@ do_init(void)
uint8_t random_seed[16];
struct timeval now;
+ if (ovs_replay_is_active()) {
+ uuid_replay_file_open();
+ }
+
/* Get seed data. */
get_entropy_or_die(random_seed, sizeof random_seed);
xgettimeofday(&now);
--
2.26.3
More information about the dev
mailing list