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