We were using a per-process counter combined with the pid. A short
running process can easily loop through and reuse the same pid later.
Instead, go for 48 bits of randomness and the pid. This way if we get
a dup pid we'll only get a dup nonce once out of 2^48 tries.
Avoids #3630 when running a libcephfs test in a loop (so that the pid
is eventually reused). This is a better fix than the broken
8b599083705c2495810c00f9f5fd5bb8ace7f32e. The real solution on the MDS
side involves cleaning up the msgr/MDS interaction with session
shutdown.
Signed-off-by: Sage Weil <sage@inktank.com>
#include <string.h>
#include <string>
+#include "auth/Crypto.h"
#include "client/Client.h"
#include "include/cephfs/libcephfs.h"
#include "common/Mutex.h"
extern "C" int ceph_create_with_context(struct ceph_mount_info **cmount, CephContext *cct)
{
- // Function-static variables are thread-safe in gcc and in the forthcoming C++ standard
- static int nonce_seed = 0;
+ uint64_t nonce = 0;
+
+ // 6 bytes of random and 2 bytes of pid
+ get_random_bytes((char*)&nonce, sizeof(nonce));
+ nonce &= ~0xffff;
+ nonce |= (uint64_t)getpid();
- uint64_t nonce = (uint64_t)++nonce_seed * 1000000ull + (uint64_t)getpid();
*cmount = new struct ceph_mount_info(nonce, cct);
return 0;
}