]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/multi_stress_watch.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / test / multi_stress_watch.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 #include "include/rados/librados.h"
3 #include "include/rados/librados.hpp"
4 #include "test/librados/test_cxx.h"
5
6 #include <errno.h>
7
8 #include <mutex>
9 #include <condition_variable>
10 #include <chrono>
11 #include <map>
12 #include <iostream>
13 #include <string>
14 #include <stdlib.h>
15 #include <unistd.h>
16
17 using namespace librados;
18 using std::map;
19 using std::string;
20
21 class WatchNotifyTestCtx : public WatchCtx
22 {
23 public:
24 WatchNotifyTestCtx(std::mutex &lock)
25 : lock{lock} {}
26 void notify(uint8_t opcode, uint64_t ver, bufferlist &bl) override {
27 std::unique_lock locker {lock};
28 notified = true;
29 cond.notify_one();
30 }
31 bool wait() {
32 std::unique_lock locker {lock};
33 return cond.wait_for(locker, std::chrono::seconds(1200),
34 [this] { return notified; });
35 }
36
37 private:
38 bool notified = false;
39 std::mutex& lock;
40 std::condition_variable cond;
41 };
42
43 #pragma GCC diagnostic ignored "-Wpragmas"
44 #pragma GCC diagnostic push
45 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
46
47 void
48 test_loop(Rados &cluster, std::string pool_name, std::string obj_name)
49 {
50 int ret;
51 IoCtx ioctx;
52 ret = cluster.ioctx_create(pool_name.c_str(), ioctx);
53 if (ret < 0) {
54 std::cerr << "ioctx_create " << pool_name << " failed with " << ret << std::endl;
55 exit(1);
56 }
57 ioctx.application_enable("rados", true);
58
59 ret = ioctx.create(obj_name, false);
60 if (ret < 0) {
61 std::cerr << "create failed with " << ret << std::endl;
62 exit(1);
63 }
64
65 std::mutex lock;
66 constexpr int NR_ITERATIONS = 10000;
67 for (int i = 0; i < NR_ITERATIONS; ++i) {
68 std::cout << "Iteration " << i << std::endl;
69 uint64_t handle;
70 WatchNotifyTestCtx ctx{lock};
71 ret = ioctx.watch(obj_name, 0, &handle, &ctx);
72 ceph_assert(!ret);
73 bufferlist bl2;
74 ret = ioctx.notify(obj_name, 0, bl2);
75 ceph_assert(!ret);
76 ceph_assert_always(ctx.wait());
77 ioctx.unwatch(obj_name, handle);
78 }
79 ioctx.close();
80 ret = cluster.pool_delete(pool_name.c_str());
81 if (ret < 0) {
82 std::cerr << "pool_delete failed with " << ret << std::endl;
83 exit(1);
84 }
85 }
86
87 #pragma GCC diagnostic pop
88 #pragma GCC diagnostic warning "-Wpragmas"
89
90 void
91 test_replicated(Rados &cluster, std::string pool_name, const std::string &obj_name)
92 {
93 // May already exist
94 cluster.pool_create(pool_name.c_str());
95
96 test_loop(cluster, pool_name, obj_name);
97 }
98
99 void
100 test_erasure(Rados &cluster, const std::string &pool_name, const std::string &obj_name)
101 {
102 string outs;
103 bufferlist inbl;
104 int ret;
105 ret = cluster.mon_command(
106 "{\"prefix\": \"osd erasure-code-profile set\", \"name\": \"testprofile\", \"profile\": [ \"k=2\", \"m=1\", \"crush-failure-domain=osd\"]}",
107 inbl, NULL, &outs);
108 if (ret < 0) {
109 std::cerr << "mon_command erasure-code-profile set failed with " << ret << std::endl;
110 exit(1);
111 }
112 //std::cout << outs << std::endl;
113
114 outs.clear();
115 ret = cluster.mon_command(
116 "{\"prefix\": \"osd pool create\", \"pool\": \"" + pool_name + "\", \"pool_type\":\"erasure\", \"pg_num\":12, \"pgp_num\":12, \"erasure_code_profile\":\"testprofile\"}",
117 inbl, NULL, &outs);
118 if (ret < 0) {
119 std::cerr << outs << std::endl;
120 std::cerr << "mon_command create pool failed with " << ret << std::endl;
121 exit(1);
122 }
123 //std::cout << outs << std::endl;
124
125 cluster.wait_for_latest_osdmap();
126 test_loop(cluster, pool_name, obj_name);
127 return;
128 }
129
130 int main(int args, char **argv)
131 {
132 if (args != 3 && args != 4) {
133 std::cerr << "Error: " << argv[0] << " [ec|rep] pool_name obj_name" << std::endl;
134 return 1;
135 }
136
137 std::string pool_name, obj_name, type;
138 // For backward compatibility with unmodified teuthology version
139 if (args == 3) {
140 type = "rep";
141 pool_name = argv[1];
142 obj_name = argv[2];
143 } else {
144 type = argv[1];
145 pool_name = argv[2];
146 obj_name = argv[3];
147 }
148 std::cout << "Test type " << type << std::endl;
149 std::cout << "pool_name, obj_name are " << pool_name << ", " << obj_name << std::endl;
150
151 if (type != "ec" && type != "rep") {
152 std::cerr << "Error: " << argv[0] << " Invalid arg must be 'ec' or 'rep' saw " << type << std::endl;
153 return 1;
154 }
155
156 Rados cluster;
157 std::string err = connect_cluster_pp(cluster);
158 if (err.length()) {
159 std::cerr << "Error " << err << std::endl;
160 return 1;
161 }
162
163 if (type == "rep")
164 test_replicated(cluster, pool_name, obj_name);
165 else if (type == "ec")
166 test_erasure(cluster, pool_name, obj_name);
167
168 return 0;
169 }