#include <dirent.h>
#include <sys/xattr.h>
#include <sys/uio.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#ifdef __linux__
#include <limits.h>
#include <map>
#include <vector>
+#include <thread>
TEST(LibCephFS, OpenEmptyComponent) {
ceph_shutdown(cmount);
}
+
+static void shutdown_racer_func()
+{
+ const int niter = 32;
+ struct ceph_mount_info *cmount;
+ int i;
+
+ for (i = 0; i < niter; ++i) {
+ ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+ ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+ ASSERT_EQ(0, ceph_conf_parse_env(cmount, NULL));
+ ASSERT_EQ(ceph_mount(cmount, "/"), 0);
+ ceph_shutdown(cmount);
+ }
+}
+
+// See tracker #20988
+TEST(LibCephFS, ShutdownRace)
+{
+ const int nthreads = 128;
+ std::thread threads[nthreads];
+
+ // Need a bunch of fd's for this test
+ struct rlimit rold, rnew;
+ ASSERT_EQ(getrlimit(RLIMIT_NOFILE, &rold), 0);
+ rnew = rold;
+ rnew.rlim_cur = rnew.rlim_max;
+ ASSERT_EQ(setrlimit(RLIMIT_NOFILE, &rnew), 0);
+
+ for (int i = 0; i < nthreads; ++i)
+ threads[i] = std::thread(shutdown_racer_func);
+
+ for (int i = 0; i < nthreads; ++i)
+ threads[i].join();
+ ASSERT_EQ(setrlimit(RLIMIT_NOFILE, &rold), 0);
+}