[ovs-dev] [PATCH 1/5] ovsdb-server: Allow using predictable UUIDs.

Ilya Maximets i.maximets at ovn.org
Tue Jun 30 01:24:31 UTC 2020


In some cases for debugability it is useful to be able to generate
exactly same UUIDs in different runs of the application.

For example, this is required for the future stream record/replay
functionality of ovsdb-server.  With predictable 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>
---
 lib/uuid.c           | 34 ++++++++++++++++++++++++++++++++++
 lib/uuid.h           |  1 +
 ovsdb/ovsdb-server.c | 14 ++++++++++++++
 3 files changed, 49 insertions(+)

diff --git a/lib/uuid.c b/lib/uuid.c
index 13d20ac64..6f56fc13f 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -35,6 +35,25 @@ static struct aes128 key;
 static uint64_t counter[2];
 BUILD_ASSERT_DECL(sizeof counter == 16);
 
+/* Non-random seed.
+ *
+ * For testing/debugging reasons it might be useful to have predictable UUIDs
+ * generated by uuid_random() and uuid_generate().
+ *
+ * This variable is intentionally 64bit signed integer in order to use '-1' as
+ * an indicator that it shoudl not be used.  'uuid_set_non_random_seed()' sets
+ * unsigned 32bit value that should be more than enough for testing purposes.
+ * This function should be called before uuid_init() and in the same thread
+ * in order to take effect.
+ * */
+static int64_t non_random_seed = -1;
+
+void
+uuid_set_non_random_seed(uint32_t seed)
+{
+    non_random_seed = seed;
+}
+
 static void do_init(void);
 
 /*
@@ -276,6 +295,21 @@ do_init(void)
     uint8_t random_seed[16];
     struct timeval now;
 
+    if (non_random_seed >= 0) {
+        /* We're requested to have predictable UUIDs, so using non-random
+         * seed for the initialization. */
+        sha1_init(&sha1_ctx);
+        sha1_update_int(&sha1_ctx, non_random_seed);
+        sha1_final(&sha1_ctx, sha1);
+
+        aes128_schedule(&key, sha1);
+
+        /* Seeting initial counter to the same non-random seed. */
+        counter[0] = non_random_seed;
+        counter[1] = 0;
+        return;
+    }
+
     /* Get seed data. */
     get_entropy_or_die(random_seed, sizeof random_seed);
     xgettimeofday(&now);
diff --git a/lib/uuid.h b/lib/uuid.h
index fa49354f6..4abae64ea 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -73,6 +73,7 @@ uuid_prefix(const struct uuid *uuid, int digits)
     return (uuid->parts[0] >> (32 - 4 * digits));
 }
 
+void uuid_set_non_random_seed(uint32_t seed);
 void uuid_init(void);
 void uuid_generate(struct uuid *);
 struct uuid uuid_random(void);
diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
index ef4e996df..42ba0053b 100644
--- a/ovsdb/ovsdb-server.c
+++ b/ovsdb/ovsdb-server.c
@@ -1712,6 +1712,7 @@ parse_options(int argc, char *argv[],
         OPT_SYNC_EXCLUDE,
         OPT_ACTIVE,
         OPT_NO_DBS,
+        OPT_PREDICTABLE_UUIDS,
         VLOG_OPTION_ENUMS,
         DAEMON_OPTION_ENUMS,
         SSL_OPTION_ENUMS,
@@ -1734,6 +1735,8 @@ parse_options(int argc, char *argv[],
         {"sync-exclude-tables", required_argument, NULL, OPT_SYNC_EXCLUDE},
         {"active", no_argument, NULL, OPT_ACTIVE},
         {"no-dbs", no_argument, NULL, OPT_NO_DBS},
+        {"predictable-uuids-with-seed", required_argument, NULL,
+                                        OPT_PREDICTABLE_UUIDS},
         {NULL, 0, NULL, 0},
     };
     char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
@@ -1824,6 +1827,17 @@ parse_options(int argc, char *argv[],
             add_default_db = false;
             break;
 
+        case OPT_PREDICTABLE_UUIDS: {
+            unsigned int seed;
+
+            if (str_to_uint(optarg, 10, &seed)) {
+                uuid_set_non_random_seed(seed);
+                uuid_init();
+            } else {
+                ovs_fatal(0, "Failed to parse non-random seed.");
+            }
+            break;
+        }
         case '?':
             exit(EXIT_FAILURE);
 
-- 
2.25.4



More information about the dev mailing list