From 908ec9b54ccc21bd9d5fd362d90250e30726a65d Mon Sep 17 00:00:00 2001 From: Li Wei Date: Mon, 5 Feb 2024 11:32:13 +0900 Subject: [PATCH] DAOS-15120 crt: Misc d_rand-related fixes - Remove duplicate d_srand calls in crt. - Use tv_nsec instead of tv_nsec / 1e3 when calling d_srand, for this reduces the chance of seed collisions among daos_engine processes. - Replace rand calls in libgurt and libpool with d_rand. - Remove d_randn (introduced by this author), since lrand48_r doesn't return the lowest bits from Xi, and the % method is therefore sufficient for our purposes. Signed-off-by: Li Wei Required-githooks: true --- src/cart/crt_init.c | 13 ++++--------- src/common/rsvc.c | 4 ++-- src/gurt/misc.c | 15 +-------------- src/include/gurt/common.h | 1 - src/pool/cli.c | 4 +--- src/pool/srv_util.c | 6 +++--- 6 files changed, 11 insertions(+), 32 deletions(-) diff --git a/src/cart/crt_init.c b/src/cart/crt_init.c index aa5716e71b5..6cd722cdc98 100644 --- a/src/cart/crt_init.c +++ b/src/cart/crt_init.c @@ -9,7 +9,6 @@ */ #include #include -#include #include #include "crt_internal.h" @@ -68,6 +67,7 @@ crt_lib_init(void) { int rc; uint64_t start_rpcid; + struct timespec now; rc = D_RWLOCK_INIT(&crt_gdata.cg_rwlock, NULL); D_ASSERT(rc == 0); @@ -82,7 +82,9 @@ crt_lib_init(void) crt_gdata.cg_inited = 0; crt_gdata.cg_primary_prov = CRT_PROV_OFI_TCP_RXM; - d_srand(d_timeus_secdiff(0) + getpid()); + rc = d_gettime(&now); + D_ASSERTF(rc == 0, "d_gettime: " DF_RC "\n", DP_RC(rc)); + d_srand(now.tv_sec * 1000 * 1000 * 1000 + now.tv_nsec + getpid()); start_rpcid = ((uint64_t)d_rand()) << 32; crt_gdata.cg_rpcid = start_rpcid; @@ -610,8 +612,6 @@ crt_init_opt(crt_group_id_t grpid, uint32_t flags, crt_init_options_t *opt) char *domain_env = NULL; char *auth_key; char *auth_key_env = NULL; - struct timeval now; - unsigned int seed; char *path; bool server = flags & CRT_FLAG_BIT_SERVER; int rc = 0; @@ -673,11 +673,6 @@ crt_init_opt(crt_group_id_t grpid, uint32_t flags, crt_init_options_t *opt) D_RWLOCK_WRLOCK(&crt_gdata.cg_rwlock); if (crt_gdata.cg_inited == 0) { - /* feed a seed for pseudo-random number generator */ - gettimeofday(&now, NULL); - seed = (unsigned int)(now.tv_sec * 1000000 + now.tv_usec); - d_srand(seed); - crt_gdata.cg_server = server; crt_gdata.cg_auto_swim_disable = (flags & CRT_FLAG_BIT_AUTO_SWIM_DISABLE) ? 1 : 0; diff --git a/src/common/rsvc.c b/src/common/rsvc.c index 65e9eb50087..5ec33f0f6ee 100644 --- a/src/common/rsvc.c +++ b/src/common/rsvc.c @@ -91,7 +91,7 @@ rsvc_client_choose(struct rsvc_client *client, crt_endpoint_t *ep) chosen = client->sc_leader_index; } else { if (client->sc_next < 0) - client->sc_next = d_randn(client->sc_ranks->rl_nr); + client->sc_next = d_rand() % client->sc_ranks->rl_nr; chosen = client->sc_next; /* The hintless search is a round robin of all replicas. */ client->sc_next++; @@ -148,7 +148,7 @@ rsvc_client_process_error(struct rsvc_client *client, int rc, * search. */ D_DEBUG(DB_MD, "give up leader rank %u\n", ep->ep_rank); - client->sc_next = d_randn(client->sc_ranks->rl_nr); + client->sc_next = d_rand() % client->sc_ranks->rl_nr; if (client->sc_next == leader_index) { client->sc_next++; client->sc_next %= client->sc_ranks->rl_nr; diff --git a/src/gurt/misc.c b/src/gurt/misc.c index d92055a905d..807480fae8b 100644 --- a/src/gurt/misc.c +++ b/src/gurt/misc.c @@ -57,19 +57,6 @@ d_rand() return result; } -/* Return a random integer in [0, n), where n must be positive. */ -long int -d_randn(long int n) -{ - long int i; - - D_ASSERT(n > 0); - i = ((double)d_rand() / D_RAND_MAX) * n; - if (i >= n) - i = 0; - return i; -} - /* Developer/debug version, poison memory on free. * This tries several ways to access the buffer size however none of them are perfect so for now * this is no in release builds. @@ -544,7 +531,7 @@ d_rank_list_shuffle(d_rank_list_t *rank_list) return; for (i = 0; i < rank_list->rl_nr; i++) { - j = rand() % rank_list->rl_nr; + j = d_rand() % rank_list->rl_nr; tmp = rank_list->rl_ranks[i]; rank_list->rl_ranks[i] = rank_list->rl_ranks[j]; rank_list->rl_ranks[j] = tmp; diff --git a/src/include/gurt/common.h b/src/include/gurt/common.h index 164421174a0..d4784b57bf9 100644 --- a/src/include/gurt/common.h +++ b/src/include/gurt/common.h @@ -82,7 +82,6 @@ extern "C" { void d_srand(long int); long int d_rand(void); -long int d_randn(long int n); /* Instruct the compiler these are allocation functions that return a pointer, and if possible * which function needs to be used to free them. diff --git a/src/pool/cli.c b/src/pool/cli.c index 22516be7a27..6a4ccfbb7b1 100644 --- a/src/pool/cli.c +++ b/src/pool/cli.c @@ -1631,9 +1631,7 @@ choose_map_refresh_rank(struct map_refresh_arg *arg) if (arg->mra_i == -1) { /* Let i be a random integer in [0, n). */ - i = ((double)rand() / RAND_MAX) * n; - if (i == n) - i = 0; + i = d_rand() % n; } else { /* Continue the round robin. */ i = arg->mra_i; diff --git a/src/pool/srv_util.c b/src/pool/srv_util.c index 9df333e16c1..52e3496f732 100644 --- a/src/pool/srv_util.c +++ b/src/pool/srv_util.c @@ -392,7 +392,7 @@ init_reconf_map(struct pool_map *map, d_rank_list_t *replicas, d_rank_t self, /* Shuffle rmap.rcm_domains for randomness in replica placement. */ for (i = 0; i < rmap.rcm_domains_len; i++) { - int j = i + d_randn(rmap.rcm_domains_len - i); + int j = i + d_rand() % (rmap.rcm_domains_len - i); D_ASSERTF(i <= j && j < rmap.rcm_domains_len, "i=%d j=%d len=%d\n", i, j, rmap.rcm_domains_len); @@ -441,7 +441,7 @@ find_vacancy_in_domain(struct reconf_domain *rdomain, d_rank_list_t *replicas) if ((engine->do_comp.co_status & POOL_SVC_MAP_STATES) && !d_rank_list_find(replicas, engine->do_comp.co_rank, NULL /* idx */)) { /* Pick this vacant engine with a probability of 1/n. */ - if (d_randn(n) == 0) + if (d_rand() % n == 0) return engine->do_comp.co_rank; n--; } @@ -478,7 +478,7 @@ find_replica_in_domain(struct reconf_domain *rdomain, d_rank_list_t *replicas, d if ((engine->do_comp.co_status & POOL_SVC_MAP_STATES) && engine->do_comp.co_rank != self && d_rank_list_find(replicas, engine->do_comp.co_rank, NULL /* idx */)) { - if (d_randn(n) == 0) + if (d_rand() % n == 0) return engine->do_comp.co_rank; n--; }