]> git.proxmox.com Git - ceph.git/blob - ceph/src/os/Transaction.cc
import ceph quincy 17.2.6
[ceph.git] / ceph / src / os / Transaction.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "os/Transaction.h"
5 #include "common/Formatter.h"
6
7 using std::less;
8 using std::list;
9 using std::map;
10 using std::ostream;
11 using std::set;
12 using std::string;
13
14 using ceph::bufferlist;
15 using ceph::decode;
16 using ceph::encode;
17
18 void decode_str_str_map_to_bl(bufferlist::const_iterator& p,
19 bufferlist *out)
20 {
21 auto start = p;
22 __u32 n;
23 decode(n, p);
24 unsigned len = 4;
25 while (n--) {
26 __u32 l;
27 decode(l, p);
28 p += l;
29 len += 4 + l;
30 decode(l, p);
31 p += l;
32 len += 4 + l;
33 }
34 start.copy(len, *out);
35 }
36
37 void decode_str_set_to_bl(bufferlist::const_iterator& p,
38 bufferlist *out)
39 {
40 auto start = p;
41 __u32 n;
42 decode(n, p);
43 unsigned len = 4;
44 while (n--) {
45 __u32 l;
46 decode(l, p);
47 p += l;
48 len += 4 + l;
49 }
50 start.copy(len, *out);
51 }
52
53 namespace ceph::os {
54
55 void Transaction::dump(ceph::Formatter *f)
56 {
57 f->open_array_section("ops");
58 iterator i = begin();
59 int op_num = 0;
60 bool stop_looping = false;
61 while (i.have_op() && !stop_looping) {
62 Transaction::Op *op = i.decode_op();
63 f->open_object_section("op");
64 f->dump_int("op_num", op_num);
65
66 switch (op->op) {
67 case Transaction::OP_NOP:
68 f->dump_string("op_name", "nop");
69 break;
70 case Transaction::OP_CREATE:
71 {
72 coll_t cid = i.get_cid(op->cid);
73 ghobject_t oid = i.get_oid(op->oid);
74 f->dump_string("op_name", "create");
75 f->dump_stream("collection") << cid;
76 f->dump_stream("oid") << oid;
77 }
78 break;
79
80 case Transaction::OP_TOUCH:
81 {
82 coll_t cid = i.get_cid(op->cid);
83 ghobject_t oid = i.get_oid(op->oid);
84 f->dump_string("op_name", "touch");
85 f->dump_stream("collection") << cid;
86 f->dump_stream("oid") << oid;
87 }
88 break;
89
90 case Transaction::OP_WRITE:
91 {
92 coll_t cid = i.get_cid(op->cid);
93 ghobject_t oid = i.get_oid(op->oid);
94 uint64_t off = op->off;
95 uint64_t len = op->len;
96 bufferlist bl;
97 i.decode_bl(bl);
98 f->dump_string("op_name", "write");
99 f->dump_stream("collection") << cid;
100 f->dump_stream("oid") << oid;
101 f->dump_unsigned("length", len);
102 f->dump_unsigned("offset", off);
103 f->dump_unsigned("bufferlist length", bl.length());
104 }
105 break;
106
107 case Transaction::OP_ZERO:
108 {
109 coll_t cid = i.get_cid(op->cid);
110 ghobject_t oid = i.get_oid(op->oid);
111 uint64_t off = op->off;
112 uint64_t len = op->len;
113 f->dump_string("op_name", "zero");
114 f->dump_stream("collection") << cid;
115 f->dump_stream("oid") << oid;
116 f->dump_unsigned("offset", off);
117 f->dump_unsigned("length", len);
118 }
119 break;
120
121 case Transaction::OP_TRIMCACHE:
122 {
123 // deprecated, no-op
124 f->dump_string("op_name", "trim_cache");
125 }
126 break;
127
128 case Transaction::OP_TRUNCATE:
129 {
130 coll_t cid = i.get_cid(op->cid);
131 ghobject_t oid = i.get_oid(op->oid);
132 uint64_t off = op->off;
133 f->dump_string("op_name", "truncate");
134 f->dump_stream("collection") << cid;
135 f->dump_stream("oid") << oid;
136 f->dump_unsigned("offset", off);
137 }
138 break;
139
140 case Transaction::OP_REMOVE:
141 {
142 coll_t cid = i.get_cid(op->cid);
143 ghobject_t oid = i.get_oid(op->oid);
144 f->dump_string("op_name", "remove");
145 f->dump_stream("collection") << cid;
146 f->dump_stream("oid") << oid;
147 }
148 break;
149
150 case Transaction::OP_SETATTR:
151 {
152 coll_t cid = i.get_cid(op->cid);
153 ghobject_t oid = i.get_oid(op->oid);
154 string name = i.decode_string();
155 bufferlist bl;
156 i.decode_bl(bl);
157 f->dump_string("op_name", "setattr");
158 f->dump_stream("collection") << cid;
159 f->dump_stream("oid") << oid;
160 f->dump_string("name", name);
161 f->dump_unsigned("length", bl.length());
162 }
163 break;
164
165 case Transaction::OP_SETATTRS:
166 {
167 coll_t cid = i.get_cid(op->cid);
168 ghobject_t oid = i.get_oid(op->oid);
169 map<string, bufferptr> aset;
170 i.decode_attrset(aset);
171 f->dump_string("op_name", "setattrs");
172 f->dump_stream("collection") << cid;
173 f->dump_stream("oid") << oid;
174 f->open_object_section("attr_lens");
175 for (map<string,bufferptr>::iterator p = aset.begin();
176 p != aset.end(); ++p) {
177 f->dump_unsigned(p->first.c_str(), p->second.length());
178 }
179 f->close_section();
180 }
181 break;
182
183 case Transaction::OP_RMATTR:
184 {
185 coll_t cid = i.get_cid(op->cid);
186 ghobject_t oid = i.get_oid(op->oid);
187 string name = i.decode_string();
188 f->dump_string("op_name", "rmattr");
189 f->dump_stream("collection") << cid;
190 f->dump_stream("oid") << oid;
191 f->dump_string("name", name);
192 }
193 break;
194
195 case Transaction::OP_RMATTRS:
196 {
197 coll_t cid = i.get_cid(op->cid);
198 ghobject_t oid = i.get_oid(op->oid);
199 f->dump_string("op_name", "rmattrs");
200 f->dump_stream("collection") << cid;
201 f->dump_stream("oid") << oid;
202 }
203 break;
204
205 case Transaction::OP_CLONE:
206 {
207 coll_t cid = i.get_cid(op->cid);
208 ghobject_t oid = i.get_oid(op->oid);
209 ghobject_t noid = i.get_oid(op->dest_oid);
210 f->dump_string("op_name", "clone");
211 f->dump_stream("collection") << cid;
212 f->dump_stream("src_oid") << oid;
213 f->dump_stream("dst_oid") << noid;
214 }
215 break;
216
217 case Transaction::OP_CLONERANGE:
218 {
219 coll_t cid = i.get_cid(op->cid);
220 ghobject_t oid = i.get_oid(op->oid);
221 ghobject_t noid = i.get_oid(op->dest_oid);
222 uint64_t off = op->off;
223 uint64_t len = op->len;
224 f->dump_string("op_name", "clonerange");
225 f->dump_stream("collection") << cid;
226 f->dump_stream("src_oid") << oid;
227 f->dump_stream("dst_oid") << noid;
228 f->dump_unsigned("offset", off);
229 f->dump_unsigned("len", len);
230 }
231 break;
232
233 case Transaction::OP_CLONERANGE2:
234 {
235 coll_t cid = i.get_cid(op->cid);
236 ghobject_t oid = i.get_oid(op->oid);
237 ghobject_t noid = i.get_oid(op->dest_oid);
238 uint64_t srcoff = op->off;
239 uint64_t len = op->len;
240 uint64_t dstoff = op->dest_off;
241 f->dump_string("op_name", "clonerange2");
242 f->dump_stream("collection") << cid;
243 f->dump_stream("src_oid") << oid;
244 f->dump_stream("dst_oid") << noid;
245 f->dump_unsigned("src_offset", srcoff);
246 f->dump_unsigned("len", len);
247 f->dump_unsigned("dst_offset", dstoff);
248 }
249 break;
250
251 case Transaction::OP_MKCOLL:
252 {
253 coll_t cid = i.get_cid(op->cid);
254 f->dump_string("op_name", "mkcoll");
255 f->dump_stream("collection") << cid;
256 }
257 break;
258
259 case Transaction::OP_COLL_HINT:
260 {
261 using ceph::decode;
262 coll_t cid = i.get_cid(op->cid);
263 uint32_t type = op->hint;
264 f->dump_string("op_name", "coll_hint");
265 f->dump_stream("collection") << cid;
266 f->dump_unsigned("type", type);
267 bufferlist hint;
268 i.decode_bl(hint);
269 auto hiter = hint.cbegin();
270 if (type == Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS) {
271 uint32_t pg_num;
272 uint64_t num_objs;
273 decode(pg_num, hiter);
274 decode(num_objs, hiter);
275 f->dump_unsigned("pg_num", pg_num);
276 f->dump_unsigned("expected_num_objects", num_objs);
277 }
278 }
279 break;
280
281 case Transaction::OP_COLL_SET_BITS:
282 {
283 coll_t cid = i.get_cid(op->cid);
284 f->dump_string("op_name", "coll_set_bits");
285 f->dump_stream("collection") << cid;
286 f->dump_unsigned("bits", op->split_bits);
287 }
288 break;
289
290 case Transaction::OP_RMCOLL:
291 {
292 coll_t cid = i.get_cid(op->cid);
293 f->dump_string("op_name", "rmcoll");
294 f->dump_stream("collection") << cid;
295 }
296 break;
297
298 case Transaction::OP_COLL_ADD:
299 {
300 coll_t ocid = i.get_cid(op->cid);
301 coll_t ncid = i.get_cid(op->dest_cid);
302 ghobject_t oid = i.get_oid(op->oid);
303 f->dump_string("op_name", "collection_add");
304 f->dump_stream("src_collection") << ocid;
305 f->dump_stream("dst_collection") << ncid;
306 f->dump_stream("oid") << oid;
307 }
308 break;
309
310 case Transaction::OP_COLL_REMOVE:
311 {
312 coll_t cid = i.get_cid(op->cid);
313 ghobject_t oid = i.get_oid(op->oid);
314 f->dump_string("op_name", "collection_remove");
315 f->dump_stream("collection") << cid;
316 f->dump_stream("oid") << oid;
317 }
318 break;
319
320 case Transaction::OP_COLL_MOVE:
321 {
322 coll_t ocid = i.get_cid(op->cid);
323 coll_t ncid = i.get_cid(op->dest_cid);
324 ghobject_t oid = i.get_oid(op->oid);
325 f->open_object_section("collection_move");
326 f->dump_stream("src_collection") << ocid;
327 f->dump_stream("dst_collection") << ncid;
328 f->dump_stream("oid") << oid;
329 f->close_section();
330 }
331 break;
332
333 case Transaction::OP_COLL_SETATTR:
334 {
335 coll_t cid = i.get_cid(op->cid);
336 string name = i.decode_string();
337 bufferlist bl;
338 i.decode_bl(bl);
339 f->dump_string("op_name", "collection_setattr");
340 f->dump_stream("collection") << cid;
341 f->dump_string("name", name);
342 f->dump_unsigned("length", bl.length());
343 }
344 break;
345
346 case Transaction::OP_COLL_RMATTR:
347 {
348 coll_t cid = i.get_cid(op->cid);
349 string name = i.decode_string();
350 f->dump_string("op_name", "collection_rmattr");
351 f->dump_stream("collection") << cid;
352 f->dump_string("name", name);
353 }
354 break;
355
356 case Transaction::OP_COLL_RENAME:
357 {
358 f->dump_string("op_name", "collection_rename");
359 }
360 break;
361
362 case Transaction::OP_OMAP_CLEAR:
363 {
364 coll_t cid = i.get_cid(op->cid);
365 ghobject_t oid = i.get_oid(op->oid);
366 f->dump_string("op_name", "omap_clear");
367 f->dump_stream("collection") << cid;
368 f->dump_stream("oid") << oid;
369 }
370 break;
371
372 case Transaction::OP_OMAP_SETKEYS:
373 {
374 coll_t cid = i.get_cid(op->cid);
375 ghobject_t oid = i.get_oid(op->oid);
376 map<string, bufferlist> aset;
377 i.decode_attrset(aset);
378 f->dump_string("op_name", "omap_setkeys");
379 f->dump_stream("collection") << cid;
380 f->dump_stream("oid") << oid;
381 f->open_object_section("attr_lens");
382 for (map<string, bufferlist>::iterator p = aset.begin();
383 p != aset.end(); ++p) {
384 f->dump_unsigned(p->first.c_str(), p->second.length());
385 }
386 f->close_section();
387 }
388 break;
389
390 case Transaction::OP_OMAP_RMKEYS:
391 {
392 coll_t cid = i.get_cid(op->cid);
393 ghobject_t oid = i.get_oid(op->oid);
394 set<string> keys;
395 i.decode_keyset(keys);
396 f->dump_string("op_name", "omap_rmkeys");
397 f->dump_stream("collection") << cid;
398 f->dump_stream("oid") << oid;
399 f->open_array_section("attrs");
400 for (auto& k : keys) {
401 f->dump_string("", k.c_str());
402 }
403 f->close_section();
404 }
405 break;
406
407 case Transaction::OP_OMAP_SETHEADER:
408 {
409 coll_t cid = i.get_cid(op->cid);
410 ghobject_t oid = i.get_oid(op->oid);
411 bufferlist bl;
412 i.decode_bl(bl);
413 f->dump_string("op_name", "omap_setheader");
414 f->dump_stream("collection") << cid;
415 f->dump_stream("oid") << oid;
416 f->dump_stream("header_length") << bl.length();
417 }
418 break;
419
420 case Transaction::OP_SPLIT_COLLECTION:
421 {
422 coll_t cid = i.get_cid(op->cid);
423 uint32_t bits = op->split_bits;
424 uint32_t rem = op->split_rem;
425 coll_t dest = i.get_cid(op->dest_cid);
426 f->dump_string("op_name", "op_split_collection_create");
427 f->dump_stream("collection") << cid;
428 f->dump_stream("bits") << bits;
429 f->dump_stream("rem") << rem;
430 f->dump_stream("dest") << dest;
431 }
432 break;
433
434 case Transaction::OP_SPLIT_COLLECTION2:
435 {
436 coll_t cid = i.get_cid(op->cid);
437 uint32_t bits = op->split_bits;
438 uint32_t rem = op->split_rem;
439 coll_t dest = i.get_cid(op->dest_cid);
440 f->dump_string("op_name", "op_split_collection");
441 f->dump_stream("collection") << cid;
442 f->dump_stream("bits") << bits;
443 f->dump_stream("rem") << rem;
444 f->dump_stream("dest") << dest;
445 }
446 break;
447
448 case Transaction::OP_MERGE_COLLECTION:
449 {
450 coll_t cid = i.get_cid(op->cid);
451 uint32_t bits = op->split_bits;
452 coll_t dest = i.get_cid(op->dest_cid);
453 f->dump_string("op_name", "op_merge_collection");
454 f->dump_stream("collection") << cid;
455 f->dump_stream("dest") << dest;
456 f->dump_stream("bits") << bits;
457 }
458 break;
459
460 case Transaction::OP_OMAP_RMKEYRANGE:
461 {
462 coll_t cid = i.get_cid(op->cid);
463 ghobject_t oid = i.get_oid(op->oid);
464 string first, last;
465 first = i.decode_string();
466 last = i.decode_string();
467 f->dump_string("op_name", "op_omap_rmkeyrange");
468 f->dump_stream("collection") << cid;
469 f->dump_stream("oid") << oid;
470 f->dump_string("first", first);
471 f->dump_string("last", last);
472 }
473 break;
474
475 case Transaction::OP_COLL_MOVE_RENAME:
476 {
477 coll_t old_cid = i.get_cid(op->cid);
478 ghobject_t old_oid = i.get_oid(op->oid);
479 coll_t new_cid = i.get_cid(op->dest_cid);
480 ghobject_t new_oid = i.get_oid(op->dest_oid);
481 f->dump_string("op_name", "op_coll_move_rename");
482 f->dump_stream("old_collection") << old_cid;
483 f->dump_stream("old_oid") << old_oid;
484 f->dump_stream("new_collection") << new_cid;
485 f->dump_stream("new_oid") << new_oid;
486 }
487 break;
488
489 case Transaction::OP_TRY_RENAME:
490 {
491 coll_t cid = i.get_cid(op->cid);
492 ghobject_t old_oid = i.get_oid(op->oid);
493 ghobject_t new_oid = i.get_oid(op->dest_oid);
494 f->dump_string("op_name", "op_coll_move_rename");
495 f->dump_stream("collection") << cid;
496 f->dump_stream("old_oid") << old_oid;
497 f->dump_stream("new_oid") << new_oid;
498 }
499 break;
500
501 case Transaction::OP_SETALLOCHINT:
502 {
503 coll_t cid = i.get_cid(op->cid);
504 ghobject_t oid = i.get_oid(op->oid);
505 uint64_t expected_object_size = op->expected_object_size;
506 uint64_t expected_write_size = op->expected_write_size;
507 uint32_t alloc_hint_flags = op->hint;
508 f->dump_string("op_name", "op_setallochint");
509 f->dump_stream("collection") << cid;
510 f->dump_stream("oid") << oid;
511 f->dump_stream("expected_object_size") << expected_object_size;
512 f->dump_stream("expected_write_size") << expected_write_size;
513 f->dump_string("alloc_hint_flags", ceph_osd_alloc_hint_flag_string(alloc_hint_flags));
514 }
515 break;
516
517 default:
518 f->dump_string("op_name", "unknown");
519 f->dump_unsigned("op_code", op->op);
520 stop_looping = true;
521 break;
522 }
523 f->close_section();
524 op_num++;
525 }
526 f->close_section();
527 }
528
529 #pragma GCC diagnostic ignored "-Wpragmas"
530 #pragma GCC diagnostic push
531 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
532
533 void Transaction::generate_test_instances(list<Transaction*>& o)
534 {
535 o.push_back(new Transaction);
536
537 Transaction *t = new Transaction;
538 t->nop();
539 o.push_back(t);
540
541 t = new Transaction;
542 coll_t c(spg_t(pg_t(1,2), shard_id_t::NO_SHARD));
543 coll_t c2(spg_t(pg_t(4,5), shard_id_t::NO_SHARD));
544 ghobject_t o1(hobject_t("obj", "", 123, 456, -1, ""));
545 ghobject_t o2(hobject_t("obj2", "", 123, 456, -1, ""));
546 ghobject_t o3(hobject_t("obj3", "", 123, 456, -1, ""));
547 t->touch(c, o1);
548 bufferlist bl;
549 bl.append("some data");
550 t->write(c, o1, 1, bl.length(), bl);
551 t->zero(c, o1, 22, 33);
552 t->truncate(c, o1, 99);
553 t->remove(c, o1);
554 o.push_back(t);
555
556 t = new Transaction;
557 t->setattr(c, o1, "key", bl);
558 map<string,bufferptr,less<>> m;
559 m["a"] = buffer::copy("this", 4);
560 m["b"] = buffer::copy("that", 4);
561 t->setattrs(c, o1, m);
562 t->rmattr(c, o1, "b");
563 t->rmattrs(c, o1);
564
565 t->clone(c, o1, o2);
566 t->clone(c, o1, o3);
567 t->clone_range(c, o1, o2, 1, 12, 99);
568
569 t->create_collection(c, 12);
570 t->collection_move_rename(c, o2, c2, o3);
571 t->remove_collection(c);
572 o.push_back(t);
573 }
574
575 ostream& operator<<(ostream& out, const Transaction& tx) {
576
577 return out << "Transaction(" << &tx << ")";
578 }
579
580 #pragma GCC diagnostic pop
581 #pragma GCC diagnostic warning "-Wpragmas"
582
583 }