Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / tools / scratchtoolpp.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software 
11  * Foundation.  See file COPYING.
12  * 
13  */
14
15 #include "include/types.h"
16 #include "include/rados/librados.hpp"
17
18 using namespace librados;
19
20 #include <iostream>
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <time.h>
25
26 #pragma GCC diagnostic ignored "-Wpragmas"
27 #pragma GCC diagnostic push
28 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
29
30 void buf_to_hex(const unsigned char *buf, int len, char *str)
31 {
32   str[0] = '\0';
33   for (int i = 0; i < len; i++) {
34     sprintf(&str[i*2], "%02x", (int)buf[i]);
35   }
36 }
37
38 class C_Watch : public WatchCtx {
39 public:
40   C_Watch() {}
41   void notify(uint8_t opcode, uint64_t ver, bufferlist& bl) override {
42     cout << "C_Watch::notify() opcode=" << (int)opcode << " ver=" << ver << std::endl;
43   }
44 };
45
46 void testradospp_milestone(void)
47 {
48   int c;
49   cout << "*** press enter to continue ***" << std::endl;
50   while ((c = getchar()) != EOF) {
51     if (c == '\n')
52       break;
53   }
54 }
55
56 int main(int argc, const char **argv) 
57 {
58   Rados rados;
59   if (rados.init(NULL) < 0) {
60      cerr << "couldn't initialize rados!" << std::endl;
61      exit(1);
62   }
63
64   if (rados.conf_read_file(NULL)) {
65      cerr << "couldn't read configuration file." << std::endl;
66      exit(1);
67   }
68   rados.conf_parse_argv(argc, argv);
69
70   if (!rados.conf_set("config option that doesn't exist",
71                      "some random value")) {
72     printf("error: succeeded in setting nonexistent config option\n");
73     exit(1);
74   }
75   if (rados.conf_set("log to stderr", "true")) {
76     printf("error: error setting log_to_stderr\n");
77     exit(1);
78   }
79   std::string tmp;
80   if (rados.conf_get("log to stderr", tmp)) {
81     printf("error: failed to read log_to_stderr from config\n");
82     exit(1);
83   }
84   if (tmp != "true") {
85     printf("error: new setting for log_to_stderr failed to take effect.\n");
86     exit(1);
87   }
88
89   if (rados.connect()) {
90     printf("error connecting\n");
91     exit(1);
92   }
93
94   cout << "rados_initialize completed" << std::endl;
95   testradospp_milestone();
96
97   time_t tm;
98   bufferlist bl, bl2, blf;
99   char buf[128];
100
101   time(&tm);
102   snprintf(buf, 128, "%s", ctime(&tm));
103   bl.append(buf, strlen(buf));
104   blf.append(buf, 16);
105
106   const char *oid = "bar";
107
108   int r = rados.pool_create("foo");
109   cout << "pool_create result = " << r << std::endl;
110
111   IoCtx io_ctx;
112   r = rados.ioctx_create("foo", io_ctx);
113   cout << "ioctx_create result = " << r << std::endl;
114
115   r = io_ctx.write(oid, bl, bl.length(), 0);
116   uint64_t objver = io_ctx.get_last_version();
117   assert(objver > 0);
118   cout << "io_ctx.write returned " << r << " last_ver=" << objver << std::endl;
119
120   uint64_t stat_size;
121   time_t stat_mtime;
122   r = io_ctx.stat(oid, &stat_size, &stat_mtime);
123   cout << "io_ctx.stat returned " << r << " size = " << stat_size << " mtime = " << stat_mtime << std::endl;
124
125   r = io_ctx.stat(oid, NULL, NULL);
126   cout << "io_ctx.stat(does_not_exist) = " << r << std::endl;
127
128   uint64_t handle;
129   C_Watch wc;
130   r = io_ctx.watch(oid, objver, &handle, &wc);
131   cout << "io_ctx.watch returned " << r << std::endl;
132
133   testradospp_milestone();
134   io_ctx.set_notify_timeout(7);
135   bufferlist notify_bl;
136   r = io_ctx.notify(oid, objver, notify_bl);
137   cout << "io_ctx.notify returned " << r << std::endl;
138   testradospp_milestone();
139
140   r = io_ctx.notify(oid, objver, notify_bl);
141   cout << "io_ctx.notify returned " << r << std::endl;
142   testradospp_milestone();
143
144   r = io_ctx.unwatch(oid, handle);
145   cout << "io_ctx.unwatch returned " << r << std::endl;
146   testradospp_milestone();
147
148   r = io_ctx.notify(oid, objver, notify_bl);
149   cout << "io_ctx.notify returned " << r << std::endl;
150   testradospp_milestone();
151   io_ctx.set_assert_version(objver);
152
153   r = io_ctx.write(oid, bl, bl.length() - 1, 0);
154   cout << "io_ctx.write returned " << r << std::endl;
155
156   r = io_ctx.write(oid, bl, bl.length() - 2, 0);
157   cout << "io_ctx.write returned " << r << std::endl;
158   r = io_ctx.write(oid, bl, bl.length() - 3, 0);
159   cout << "rados.write returned " << r << std::endl;
160   r = io_ctx.append(oid, bl, bl.length());
161   cout << "rados.write returned " << r << std::endl;
162   r = io_ctx.write_full(oid, blf);
163   cout << "rados.write_full returned " << r << std::endl;
164   r = io_ctx.read(oid, bl, bl.length(), 0);
165   cout << "rados.read returned " << r << std::endl;
166   r = io_ctx.trunc(oid, 8);
167   cout << "rados.trunc returned " << r << std::endl;
168   r = io_ctx.read(oid, bl, bl.length(), 0);
169   cout << "rados.read returned " << r << std::endl;
170   r = io_ctx.exec(oid, "crypto", "md5", bl, bl2);
171   cout << "exec returned " << r <<  " buf size=" << bl2.length() << std::endl;
172   const unsigned char *md5 = (const unsigned char *)bl2.c_str();
173   char md5_str[bl2.length()*2 + 1];
174   buf_to_hex(md5, bl2.length(), md5_str);
175   cout << "md5 result=" << md5_str << std::endl;
176
177   // test assert_version
178   r = io_ctx.read(oid, bl, 0, 1);
179   assert(r >= 0);
180   uint64_t v = io_ctx.get_last_version();
181   cout << oid << " version is " << v << std::endl;
182   assert(v > 0);
183   io_ctx.set_assert_version(v);
184   r = io_ctx.read(oid, bl, 0, 1);
185   assert(r >= 0);
186   io_ctx.set_assert_version(v - 1);
187   r = io_ctx.read(oid, bl, 0, 1);
188   assert(r == -ERANGE);
189   io_ctx.set_assert_version(v + 1);
190   r = io_ctx.read(oid, bl, 0, 1);
191   assert(r == -EOVERFLOW);
192
193   r = io_ctx.exec(oid, "crypto", "sha1", bl, bl2);
194   cout << "exec returned " << r << std::endl;
195   const unsigned char *sha1 = (const unsigned char *)bl2.c_str();
196   char sha1_str[bl2.length()*2 + 1];
197   buf_to_hex(sha1, bl2.length(), sha1_str);
198   cout << "sha1 result=" << sha1_str << std::endl;
199
200   r = io_ctx.exec(oid, "acl", "set", bl, bl2);
201   cout << "exec (set) returned " << r << std::endl;
202   r = io_ctx.exec(oid, "acl", "get", bl, bl2);
203   cout << "exec (get) returned " << r << std::endl;
204   if (bl2.length() > 0) {
205     cout << "attr=" << bl2.c_str() << std::endl;
206   }
207
208   int size = io_ctx.read(oid, bl2, 128, 0);
209   if (size <= 0) {
210     cout << "failed to read oid " << oid << "." << std::endl;
211     exit(1);
212   }
213   if (size > 4096) {
214     cout << "read too many bytes from oid " << oid << "." << std::endl;
215     exit(1);
216   }
217   char rbuf[size + 1];
218   memcpy(rbuf, bl2.c_str(), size);
219   rbuf[size] = '\0';
220   cout << "read result='" << rbuf << "'" << std::endl;
221   cout << "size=" << size << std::endl;
222
223   const char *oid2 = "jjj10.rbd";
224   r = io_ctx.exec(oid2, "rbd", "snap_list", bl, bl2);
225   cout << "snap_list result=" << r << std::endl;
226   r = io_ctx.exec(oid2, "rbd", "snap_add", bl, bl2);
227   cout << "snap_add result=" << r << std::endl;
228
229   if (r > 0) {
230     char *s = bl2.c_str();
231     for (int i=0; i<r; i++, s += strlen(s) + 1)
232       cout << s << std::endl;
233   }
234
235   cout << "compound operation..." << std::endl;
236   ObjectWriteOperation o;
237   o.write(0, bl);
238   o.setxattr("foo", bl2);
239   r = io_ctx.operate(oid, &o);
240   cout << "operate result=" << r << std::endl;
241
242   cout << "cmpxattr" << std::endl;
243   bufferlist val;
244   val.append("foo");
245   r = io_ctx.setxattr(oid, "foo", val);
246   assert(r >= 0);
247   {
248     ObjectReadOperation o;
249     o.cmpxattr("foo", CEPH_OSD_CMPXATTR_OP_EQ, val);
250     r = io_ctx.operate(oid, &o, &bl2);
251     cout << " got " << r << " wanted >= 0" << std::endl;
252     assert(r >= 0);
253   }
254   val.append("...");
255   {
256     ObjectReadOperation o;
257     o.cmpxattr("foo", CEPH_OSD_CMPXATTR_OP_EQ, val);
258     r = io_ctx.operate(oid, &o, &bl2);
259     cout << " got " << r << " wanted " << -ECANCELED << " (-ECANCELED)" << std::endl;
260     assert(r == -ECANCELED);
261   }
262
263   io_ctx.locator_set_key(string());
264
265   cout << "iterating over objects..." << std::endl;
266   int num_objs = 0;
267   for (NObjectIterator iter = io_ctx.nobjects_begin();
268        iter != io_ctx.nobjects_end(); ++iter) {
269     num_objs++;
270     cout << "'" << *iter << "'" << std::endl;
271   }
272   cout << "iterated over " << num_objs << " objects." << std::endl;
273   map<string, bufferlist> attrset;
274   io_ctx.getxattrs(oid, attrset);
275
276   map<string, bufferlist>::iterator it;
277   for (it = attrset.begin(); it != attrset.end(); ++it) {
278     cout << "xattr: " << it->first << std::endl;
279   }
280
281   r = io_ctx.remove(oid);
282   cout << "remove result=" << r << std::endl;
283
284   r = rados.pool_delete("foo");
285   cout << "pool_delete result=" << r << std::endl;
286
287   rados.shutdown();
288
289   return 0;
290 }
291
292 #pragma GCC diagnostic pop
293 #pragma GCC diagnostic warning "-Wpragmas"