[SERVER-29336] Use vendored version of libfaketime when running Jepsen tests Created: 23/May/17  Updated: 30/Oct/23  Resolved: 25/May/17

Status: Closed
Project: Core Server
Component/s: Testing Infrastructure
Affects Version/s: None
Fix Version/s: 3.4.5, 3.5.8

Type: Task Priority: Major - P3
Reporter: Max Hirschhorn Assignee: Max Hirschhorn
Resolution: Fixed Votes: 0
Labels: tig-evgconfig
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Backports
Depends
Related
Backwards Compatibility: Fully Compatible
Backport Requested:
v3.4
Sprint: TIG 2017-05-29
Participants:
Linked BF Score: 0

 Description   

The user_faked_time variable in the fake_clock_gettime() function is declared static. This means that if multiple threads call user_faked_time() concurrently, then it is possible to overwrite different characters of the configurations and cause strange behavior. Using the libfaketimeMT.so.1 shared object would address this, but would come at a heavy price of serializing all calls to fake_clock_gettime() with a mutex. Given that we are running libfaketime with the cache disabled for our Jepsen tests, there's no benefit to these static variables anyway, so there's little point to paying such a heavy performance cost (and risk not being able to detect subtle races). Instead, we should apply a patch similar to the one below to convert all static variables related to caching to thread-specific static variables.



 Comments   
Comment by Githook User [ 26/May/17 ]

Author:

{u'username': u'visemet', u'name': u'Max Hirschhorn', u'email': u'max.hirschhorn@mongodb.com'}

Message: SERVER-29336 Use vendored version of libfaketime when running Jepsen.

(cherry picked from commit 8cd6e2a8af540bbea188c98cfae9139b400af83c)
Branch: v3.4
https://github.com/mongodb/mongo/commit/9d54aa3a3ad026ed373c31f58c4ff849a40dc6ff

Comment by Githook User [ 25/May/17 ]

Author:

{u'username': u'visemet', u'name': u'Max Hirschhorn', u'email': u'max.hirschhorn@mongodb.com'}

Message: SERVER-29336 Use vendored version of libfaketime when running Jepsen.
Branch: master
https://github.com/mongodb/mongo/commit/8cd6e2a8af540bbea188c98cfae9139b400af83c

Comment by Max Hirschhorn [ 23/May/17 ]

From ab0b6d57516aa44c50ca6416931abb77acddceb3 Mon Sep 17 00:00:00 2001
From: Max Hirschhorn <max.hirschhorn@mongodb.com>
Date: Tue, 23 May 2017 14:24:52 -0400
Subject: [PATCH] Use per-thread static variables for caching.
 
This avoids a data race when multiple threads are loading the user
configuration in fake_clock_gettime() concurrently.
---
 src/libfaketime.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)
 
diff --git a/src/libfaketime.c b/src/libfaketime.c
index 617dd25..e9f51c5 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -214,21 +214,21 @@ static int cache_duration = 10;     /* cache fake time input for 10 seconds */
  */
 static struct system_time_s ftpl_starttime = {{0, -1}, {0, -1}, {0, -1}};
 
-static char user_faked_time_fmt[BUFSIZ] = {0};
+static __thread char user_faked_time_fmt[BUFSIZ] = {0};
 
 /* User supplied base time to fake */
-static struct timespec user_faked_time_timespec = {0, -1};
+static __thread struct timespec user_faked_time_timespec = {0, -1};
 /* User supplied base time is set */
-static bool user_faked_time_set = false;
-static char user_faked_time_saved[BUFFERLEN] = {0};
+static __thread bool user_faked_time_set = false;
+static __thread char user_faked_time_saved[BUFFERLEN] = {0};
 
 /* Fractional user offset provided through FAKETIME env. var.*/
-static struct timespec user_offset = {0, -1};
+static __thread struct timespec user_offset = {0, -1};
 /* Speed up or slow down clock */
-static double user_rate = 1.0;
-static bool user_rate_set = false;
-static struct timespec user_per_tick_inc = {0, -1};
-static bool user_per_tick_inc_set = false;
+static __thread double user_rate = 1.0;
+static __thread bool user_rate_set = false;
+static __thread struct timespec user_per_tick_inc = {0, -1};
+static __thread bool user_per_tick_inc_set = false;
 
 enum ft_mode_t {FT_FREEZE, FT_START_AT, FT_NOOP} ft_mode = FT_FREEZE;
 
@@ -1889,8 +1889,8 @@ static void remove_trailing_eols(char *line)
 int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
 {
   /* variables used for caching, introduced in version 0.6 */
-  static time_t last_data_fetch = 0;  /* not fetched previously at first call */
-  static int cache_expired = 1;       /* considered expired at first call */
+  static __thread time_t last_data_fetch = 0;  /* not fetched previously at first call */
+  static __thread int cache_expired = 1;       /* considered expired at first call */
 
   if (dont_fake) return 0;
   /* Per process timers are only sped up or slowed down */
@@ -1989,7 +1989,7 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
 
   if (cache_expired == 1)
   {
-    static char user_faked_time[BUFFERLEN]; /* changed to static for caching in v0.6 */
+    static __thread char user_faked_time[BUFFERLEN]; /* changed to static for caching in v0.6 */
     /* initialize with default or env. variable */
     char *tmp_env;

Generated at Thu Feb 08 04:20:33 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.