1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
6 #include <boost/container/flat_map.hpp>
7 #include "common/ceph_time.h"
8 #include "common/Formatter.h"
10 #undef FMT_HEADER_ONLY
11 #define FMT_HEADER_ONLY 1
12 #include <fmt/format.h>
14 #include "rgw/rgw_basic_types.h"
16 #define CEPH_RGW_REMOVE 'r'
17 #define CEPH_RGW_UPDATE 'u'
18 #define CEPH_RGW_TAG_TIMEOUT 120
19 #define CEPH_RGW_DIR_SUGGEST_LOG_OP 0x80
20 #define CEPH_RGW_DIR_SUGGEST_OP_MASK 0x7f
24 using ceph::operator <<;
26 struct rgw_zone_set_entry
{
28 std::optional
<std::string
> location_key
;
30 bool operator<(const rgw_zone_set_entry
& e
) const {
37 return (location_key
< e
.location_key
);
40 rgw_zone_set_entry() {}
41 rgw_zone_set_entry(const std::string
& _zone
,
42 std::optional
<std::string
> _location_key
) : zone(_zone
),
43 location_key(_location_key
) {}
44 rgw_zone_set_entry(const std::string
& s
) {
48 void from_str(const std::string
& s
);
49 std::string
to_str() const;
51 void encode(ceph::buffer::list
&bl
) const;
52 void decode(ceph::buffer::list::const_iterator
&bl
);
54 void dump(ceph::Formatter
*f
) const;
55 void decode_json(JSONObj
*obj
);
57 WRITE_CLASS_ENCODER(rgw_zone_set_entry
)
60 std::set
<rgw_zone_set_entry
> entries
;
62 void encode(ceph::buffer::list
&bl
) const {
63 /* no ENCODE_START, ENCODE_END for backward compatibility */
64 ceph::encode(entries
, bl
);
66 void decode(ceph::buffer::list::const_iterator
&bl
) {
67 /* no DECODE_START, DECODE_END for backward compatibility */
68 ceph::decode(entries
, bl
);
71 void insert(const std::string
& zone
, std::optional
<std::string
> location_key
);
72 bool exists(const std::string
& zone
, std::optional
<std::string
> location_key
) const;
74 WRITE_CLASS_ENCODER(rgw_zone_set
)
76 /* backward compatibility, rgw_zone_set needs to encode/decode the same as std::set */
77 void encode_json(const char *name
, const rgw_zone_set
& zs
, ceph::Formatter
*f
);
78 void decode_json_obj(rgw_zone_set
& zs
, JSONObj
*obj
);
81 enum RGWPendingState
{
82 CLS_RGW_STATE_PENDING_MODIFY
= 0,
83 CLS_RGW_STATE_COMPLETE
= 1,
84 CLS_RGW_STATE_UNKNOWN
= 2,
90 CLS_RGW_OP_CANCEL
= 2,
91 CLS_RGW_OP_UNKNOWN
= 3,
92 CLS_RGW_OP_LINK_OLH
= 4,
93 CLS_RGW_OP_LINK_OLH_DM
= 5, /* creation of delete marker */
94 CLS_RGW_OP_UNLINK_INSTANCE
= 6,
95 CLS_RGW_OP_SYNCSTOP
= 7,
96 CLS_RGW_OP_RESYNC
= 8,
100 RGW_BILOG_FLAG_VERSIONED_OP
= 0x1,
103 enum RGWCheckMTimeType
{
104 CLS_RGW_CHECK_TIME_MTIME_EQ
= 0,
105 CLS_RGW_CHECK_TIME_MTIME_LT
= 1,
106 CLS_RGW_CHECK_TIME_MTIME_LE
= 2,
107 CLS_RGW_CHECK_TIME_MTIME_GT
= 3,
108 CLS_RGW_CHECK_TIME_MTIME_GE
= 4,
111 #define ROUND_BLOCK_SIZE 4096
113 inline uint64_t cls_rgw_get_rounded_size(uint64_t size
) {
114 return (size
+ ROUND_BLOCK_SIZE
- 1) & ~(ROUND_BLOCK_SIZE
- 1);
118 * This takes a std::string that either wholly contains a delimiter or is a
119 * path that ends with a delimiter and appends a new character to the
120 * end such that when a we request bucket-index entries *after* this,
121 * we'll get the next object after the "subdirectory". This works
122 * because we append a '\xFF' charater, and no valid UTF-8 character
123 * can contain that byte, so no valid entries can be skipped.
125 inline std::string
cls_rgw_after_delim(const std::string
& path
) {
126 // assert: ! path.empty()
127 return path
+ '\xFF';
130 struct rgw_bucket_pending_info
{
131 RGWPendingState state
;
132 ceph::real_time timestamp
;
135 rgw_bucket_pending_info() : state(CLS_RGW_STATE_PENDING_MODIFY
), op(0) {}
137 void encode(ceph::buffer::list
&bl
) const {
138 ENCODE_START(2, 2, bl
);
139 uint8_t s
= (uint8_t)state
;
141 encode(timestamp
, bl
);
145 void decode(ceph::buffer::list::const_iterator
&bl
) {
146 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl
);
149 state
= (RGWPendingState
)s
;
150 decode(timestamp
, bl
);
154 void dump(ceph::Formatter
*f
) const;
155 void decode_json(JSONObj
*obj
);
156 static void generate_test_instances(std::list
<rgw_bucket_pending_info
*>& o
);
158 WRITE_CLASS_ENCODER(rgw_bucket_pending_info
)
161 // categories of objects stored in a bucket index (b-i) and used to
162 // differentiate their associated statistics (bucket stats, and in
163 // some cases user stats)
164 enum class RGWObjCategory
: uint8_t {
165 None
= 0, // b-i entries for delete markers; also used in
166 // testing and for default values in default
169 Main
= 1, // b-i entries for standard objs
171 Shadow
= 2, // presumfably intended for multipart shadow
172 // uploads; not currently used in the codebase
174 MultiMeta
= 3, // b-i entries for multipart upload metadata objs
178 struct rgw_bucket_dir_entry_meta
{
179 RGWObjCategory category
;
181 ceph::real_time mtime
;
184 std::string owner_display_name
;
185 std::string content_type
;
186 uint64_t accounted_size
;
187 std::string user_data
;
188 std::string storage_class
;
191 rgw_bucket_dir_entry_meta() :
192 category(RGWObjCategory::None
), size(0), accounted_size(0), appendable(false) { }
194 void encode(ceph::buffer::list
&bl
) const {
195 ENCODE_START(7, 3, bl
);
196 encode(category
, bl
);
201 encode(owner_display_name
, bl
);
202 encode(content_type
, bl
);
203 encode(accounted_size
, bl
);
204 encode(user_data
, bl
);
205 encode(storage_class
, bl
);
206 encode(appendable
, bl
);
210 void decode(ceph::buffer::list::const_iterator
&bl
) {
211 DECODE_START_LEGACY_COMPAT_LEN(6, 3, 3, bl
);
212 decode(category
, bl
);
217 decode(owner_display_name
, bl
);
219 decode(content_type
, bl
);
221 decode(accounted_size
, bl
);
223 accounted_size
= size
;
225 decode(user_data
, bl
);
227 decode(storage_class
, bl
);
229 decode(appendable
, bl
);
232 void dump(ceph::Formatter
*f
) const;
233 void decode_json(JSONObj
*obj
);
234 static void generate_test_instances(std::list
<rgw_bucket_dir_entry_meta
*>& o
);
236 WRITE_CLASS_ENCODER(rgw_bucket_dir_entry_meta
)
239 void encode_packed_val(T val
, ceph::buffer::list
& bl
)
242 if ((uint64_t)val
< 0x80) {
243 encode((uint8_t)val
, bl
);
245 unsigned char c
= 0x80;
247 if ((uint64_t)val
< 0x100) {
250 encode((uint8_t)val
, bl
);
251 } else if ((uint64_t)val
<= 0x10000) {
254 encode((uint16_t)val
, bl
);
255 } else if ((uint64_t)val
<= 0x1000000) {
258 encode((uint32_t)val
, bl
);
262 encode((uint64_t)val
, bl
);
268 void decode_packed_val(T
& val
, ceph::buffer::list::const_iterator
& bl
)
310 throw ceph::buffer::malformed_input();
314 struct rgw_bucket_entry_ver
{
318 rgw_bucket_entry_ver() : pool(-1), epoch(0) {}
320 void encode(ceph::buffer::list
&bl
) const {
321 ENCODE_START(1, 1, bl
);
322 encode_packed_val(pool
, bl
);
323 encode_packed_val(epoch
, bl
);
326 void decode(ceph::buffer::list::const_iterator
&bl
) {
328 decode_packed_val(pool
, bl
);
329 decode_packed_val(epoch
, bl
);
332 void dump(ceph::Formatter
*f
) const;
333 void decode_json(JSONObj
*obj
);
334 static void generate_test_instances(std::list
<rgw_bucket_entry_ver
*>& o
);
336 WRITE_CLASS_ENCODER(rgw_bucket_entry_ver
)
338 struct cls_rgw_obj_key
{
340 std::string instance
;
343 cls_rgw_obj_key(const std::string
&_name
) : name(_name
) {}
344 cls_rgw_obj_key(const std::string
& n
, const std::string
& i
) : name(n
), instance(i
) {}
346 std::string
to_string() const {
347 return fmt::format("{}({})", name
, instance
);
354 void set(const std::string
& _name
) {
358 bool operator==(const cls_rgw_obj_key
& k
) const {
359 return (name
.compare(k
.name
) == 0) &&
360 (instance
.compare(k
.instance
) == 0);
363 bool operator<(const cls_rgw_obj_key
& k
) const {
364 int r
= name
.compare(k
.name
);
366 r
= instance
.compare(k
.instance
);
371 bool operator<=(const cls_rgw_obj_key
& k
) const {
375 std::ostream
& operator<<(std::ostream
& out
) const {
380 void encode(ceph::buffer::list
&bl
) const {
381 ENCODE_START(1, 1, bl
);
383 encode(instance
, bl
);
386 void decode(ceph::buffer::list::const_iterator
&bl
) {
389 decode(instance
, bl
);
392 void dump(ceph::Formatter
*f
) const {
393 f
->dump_string("name", name
);
394 f
->dump_string("instance", instance
);
396 void decode_json(JSONObj
*obj
);
397 static void generate_test_instances(std::list
<cls_rgw_obj_key
*>& ls
) {
398 ls
.push_back(new cls_rgw_obj_key
);
399 ls
.push_back(new cls_rgw_obj_key
);
400 ls
.back()->name
= "name";
401 ls
.back()->instance
= "instance";
404 WRITE_CLASS_ENCODER(cls_rgw_obj_key
)
407 struct rgw_bucket_dir_entry
{
408 /* a versioned object instance */
409 static constexpr uint16_t FLAG_VER
= 0x1;
410 /* the last object instance of a versioned object */
411 static constexpr uint16_t FLAG_CURRENT
= 0x2;
413 static constexpr uint16_t FLAG_DELETE_MARKER
= 0x4;
414 /* object is versioned, a placeholder for the plain entry */
415 static constexpr uint16_t FLAG_VER_MARKER
= 0x8;
416 /* object is a proxy; it is not listed in the bucket index but is a
417 * prefix ending with a delimiter, perhaps common to multiple
418 * entries; it is only useful when a delimiter is used and
419 * represents a "subdirectory" (again, ending in a delimiter) that
420 * may contain one or more actual entries/objects */
421 static constexpr uint16_t FLAG_COMMON_PREFIX
= 0x8000;
424 rgw_bucket_entry_ver ver
;
427 rgw_bucket_dir_entry_meta meta
;
428 std::multimap
<std::string
, rgw_bucket_pending_info
> pending_map
;
432 uint64_t versioned_epoch
;
434 rgw_bucket_dir_entry() :
435 exists(false), index_ver(0), flags(0), versioned_epoch(0) {}
437 void encode(ceph::buffer::list
&bl
) const {
438 ENCODE_START(8, 3, bl
);
439 encode(key
.name
, bl
);
440 encode(ver
.epoch
, bl
);
443 encode(pending_map
, bl
);
446 encode_packed_val(index_ver
, bl
);
448 encode(key
.instance
, bl
);
450 encode(versioned_epoch
, bl
);
453 void decode(ceph::buffer::list::const_iterator
&bl
) {
454 DECODE_START_LEGACY_COMPAT_LEN(8, 3, 3, bl
);
455 decode(key
.name
, bl
);
456 decode(ver
.epoch
, bl
);
459 decode(pending_map
, bl
);
469 decode_packed_val(index_ver
, bl
);
473 decode(key
.instance
, bl
);
479 decode(versioned_epoch
, bl
);
484 bool is_current() const {
486 rgw_bucket_dir_entry::FLAG_VER
| rgw_bucket_dir_entry::FLAG_CURRENT
;
487 return (flags
& rgw_bucket_dir_entry::FLAG_VER
) == 0 ||
488 (flags
& test_flags
) == test_flags
;
490 bool is_delete_marker() const {
491 return (flags
& rgw_bucket_dir_entry::FLAG_DELETE_MARKER
) != 0;
493 bool is_visible() const {
494 return is_current() && !is_delete_marker();
496 bool is_valid() const {
497 return (flags
& rgw_bucket_dir_entry::FLAG_VER_MARKER
) == 0;
499 bool is_common_prefix() const {
500 return flags
& rgw_bucket_dir_entry::FLAG_COMMON_PREFIX
;
503 void dump(ceph::Formatter
*f
) const;
504 void decode_json(JSONObj
*obj
);
505 static void generate_test_instances(std::list
<rgw_bucket_dir_entry
*>& o
);
507 WRITE_CLASS_ENCODER(rgw_bucket_dir_entry
)
509 enum class BIIndexType
: uint8_t {
516 struct rgw_bucket_category_stats
;
518 struct rgw_cls_bi_entry
{
521 ceph::buffer::list data
;
523 rgw_cls_bi_entry() : type(BIIndexType::Invalid
) {}
525 void encode(ceph::buffer::list
& bl
) const {
526 ENCODE_START(1, 1, bl
);
533 void decode(ceph::buffer::list::const_iterator
& bl
) {
537 type
= (BIIndexType
)c
;
543 void dump(ceph::Formatter
*f
) const;
544 void decode_json(JSONObj
*obj
, cls_rgw_obj_key
*effective_key
= NULL
);
546 bool get_info(cls_rgw_obj_key
*key
, RGWObjCategory
*category
,
547 rgw_bucket_category_stats
*accounted_stats
);
549 WRITE_CLASS_ENCODER(rgw_cls_bi_entry
)
552 CLS_RGW_OLH_OP_UNKNOWN
= 0,
553 CLS_RGW_OLH_OP_LINK_OLH
= 1,
554 CLS_RGW_OLH_OP_UNLINK_OLH
= 2, /* object does not exist */
555 CLS_RGW_OLH_OP_REMOVE_INSTANCE
= 3,
558 struct rgw_bucket_olh_log_entry
{
565 rgw_bucket_olh_log_entry() : epoch(0), op(CLS_RGW_OLH_OP_UNKNOWN
), delete_marker(false) {}
568 void encode(ceph::buffer::list
&bl
) const {
569 ENCODE_START(1, 1, bl
);
571 encode((__u8
)op
, bl
);
574 encode(delete_marker
, bl
);
577 void decode(ceph::buffer::list::const_iterator
&bl
) {
585 decode(delete_marker
, bl
);
588 static void generate_test_instances(std::list
<rgw_bucket_olh_log_entry
*>& o
);
589 void dump(ceph::Formatter
*f
) const;
590 void decode_json(JSONObj
*obj
);
592 WRITE_CLASS_ENCODER(rgw_bucket_olh_log_entry
)
594 struct rgw_bucket_olh_entry
{
598 std::map
<uint64_t, std::vector
<struct rgw_bucket_olh_log_entry
> > pending_log
;
601 bool pending_removal
;
603 rgw_bucket_olh_entry() : delete_marker(false), epoch(0), exists(false), pending_removal(false) {}
605 void encode(ceph::buffer::list
&bl
) const {
606 ENCODE_START(1, 1, bl
);
608 encode(delete_marker
, bl
);
610 encode(pending_log
, bl
);
613 encode(pending_removal
, bl
);
616 void decode(ceph::buffer::list::const_iterator
&bl
) {
619 decode(delete_marker
, bl
);
621 decode(pending_log
, bl
);
624 decode(pending_removal
, bl
);
627 void dump(ceph::Formatter
*f
) const;
628 void decode_json(JSONObj
*obj
);
630 WRITE_CLASS_ENCODER(rgw_bucket_olh_entry
)
632 struct rgw_bi_log_entry
{
635 std::string instance
;
636 ceph::real_time timestamp
;
637 rgw_bucket_entry_ver ver
;
639 RGWPendingState state
;
642 uint16_t bilog_flags
;
643 std::string owner
; /* only being set if it's a delete marker */
644 std::string owner_display_name
; /* only being set if it's a delete marker */
645 rgw_zone_set zones_trace
;
647 rgw_bi_log_entry() : op(CLS_RGW_OP_UNKNOWN
), state(CLS_RGW_STATE_PENDING_MODIFY
), index_ver(0), bilog_flags(0) {}
649 void encode(ceph::buffer::list
&bl
) const {
650 ENCODE_START(4, 1, bl
);
653 encode(timestamp
, bl
);
656 uint8_t c
= (uint8_t)op
;
660 encode_packed_val(index_ver
, bl
);
661 encode(instance
, bl
);
662 encode(bilog_flags
, bl
);
664 encode(owner_display_name
, bl
);
665 encode(zones_trace
, bl
);
668 void decode(ceph::buffer::list::const_iterator
&bl
) {
672 decode(timestamp
, bl
);
679 state
= (RGWPendingState
)c
;
680 decode_packed_val(index_ver
, bl
);
682 decode(instance
, bl
);
683 decode(bilog_flags
, bl
);
687 decode(owner_display_name
, bl
);
690 decode(zones_trace
, bl
);
694 void dump(ceph::Formatter
*f
) const;
695 void decode_json(JSONObj
*obj
);
696 static void generate_test_instances(std::list
<rgw_bi_log_entry
*>& o
);
698 bool is_versioned() {
699 return ((bilog_flags
& RGW_BILOG_FLAG_VERSIONED_OP
) != 0);
702 WRITE_CLASS_ENCODER(rgw_bi_log_entry
)
704 struct rgw_bucket_category_stats
{
706 uint64_t total_size_rounded
;
707 uint64_t num_entries
;
708 uint64_t actual_size
{0}; //< account for compression, encryption
710 rgw_bucket_category_stats() : total_size(0), total_size_rounded(0), num_entries(0) {}
712 void encode(ceph::buffer::list
&bl
) const {
713 ENCODE_START(3, 2, bl
);
714 encode(total_size
, bl
);
715 encode(total_size_rounded
, bl
);
716 encode(num_entries
, bl
);
717 encode(actual_size
, bl
);
720 void decode(ceph::buffer::list::const_iterator
&bl
) {
721 DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl
);
722 decode(total_size
, bl
);
723 decode(total_size_rounded
, bl
);
724 decode(num_entries
, bl
);
726 decode(actual_size
, bl
);
728 actual_size
= total_size
;
732 void dump(ceph::Formatter
*f
) const;
733 static void generate_test_instances(std::list
<rgw_bucket_category_stats
*>& o
);
735 WRITE_CLASS_ENCODER(rgw_bucket_category_stats
)
737 enum class cls_rgw_reshard_status
: uint8_t {
743 inline std::string
to_string(const cls_rgw_reshard_status status
)
746 case cls_rgw_reshard_status::NOT_RESHARDING
:
747 return "not-resharding";
748 case cls_rgw_reshard_status::IN_PROGRESS
:
749 return "in-progress";
750 case cls_rgw_reshard_status::DONE
:
753 return "Unknown reshard status";
756 struct cls_rgw_bucket_instance_entry
{
757 using RESHARD_STATUS
= cls_rgw_reshard_status
;
759 cls_rgw_reshard_status reshard_status
{RESHARD_STATUS::NOT_RESHARDING
};
760 std::string new_bucket_instance_id
;
761 int32_t num_shards
{-1};
763 void encode(ceph::buffer::list
& bl
) const {
764 ENCODE_START(1, 1, bl
);
765 encode((uint8_t)reshard_status
, bl
);
766 encode(new_bucket_instance_id
, bl
);
767 encode(num_shards
, bl
);
771 void decode(ceph::buffer::list::const_iterator
& bl
) {
775 reshard_status
= (cls_rgw_reshard_status
)s
;
776 decode(new_bucket_instance_id
, bl
);
777 decode(num_shards
, bl
);
781 void dump(ceph::Formatter
*f
) const;
782 static void generate_test_instances(std::list
<cls_rgw_bucket_instance_entry
*>& o
);
785 reshard_status
= RESHARD_STATUS::NOT_RESHARDING
;
786 new_bucket_instance_id
.clear();
789 void set_status(const std::string
& new_instance_id
,
790 int32_t new_num_shards
,
791 cls_rgw_reshard_status s
) {
793 new_bucket_instance_id
= new_instance_id
;
794 num_shards
= new_num_shards
;
797 bool resharding() const {
798 return reshard_status
!= RESHARD_STATUS::NOT_RESHARDING
;
800 bool resharding_in_progress() const {
801 return reshard_status
== RESHARD_STATUS::IN_PROGRESS
;
804 WRITE_CLASS_ENCODER(cls_rgw_bucket_instance_entry
)
806 struct rgw_bucket_dir_header
{
807 std::map
<RGWObjCategory
, rgw_bucket_category_stats
> stats
;
808 uint64_t tag_timeout
;
811 std::string max_marker
;
812 cls_rgw_bucket_instance_entry new_instance
;
815 rgw_bucket_dir_header() : tag_timeout(0), ver(0), master_ver(0), syncstopped(false) {}
817 void encode(ceph::buffer::list
&bl
) const {
818 ENCODE_START(7, 2, bl
);
820 encode(tag_timeout
, bl
);
822 encode(master_ver
, bl
);
823 encode(max_marker
, bl
);
824 encode(new_instance
, bl
);
825 encode(syncstopped
,bl
);
828 void decode(ceph::buffer::list::const_iterator
&bl
) {
829 DECODE_START_LEGACY_COMPAT_LEN(6, 2, 2, bl
);
832 decode(tag_timeout
, bl
);
838 decode(master_ver
, bl
);
843 decode(max_marker
, bl
);
846 decode(new_instance
, bl
);
848 new_instance
= cls_rgw_bucket_instance_entry();
851 decode(syncstopped
,bl
);
855 void dump(ceph::Formatter
*f
) const;
856 static void generate_test_instances(std::list
<rgw_bucket_dir_header
*>& o
);
858 bool resharding() const {
859 return new_instance
.resharding();
861 bool resharding_in_progress() const {
862 return new_instance
.resharding_in_progress();
865 WRITE_CLASS_ENCODER(rgw_bucket_dir_header
)
867 struct rgw_bucket_dir
{
868 rgw_bucket_dir_header header
;
869 boost::container::flat_map
<std::string
, rgw_bucket_dir_entry
> m
;
871 void encode(ceph::buffer::list
&bl
) const {
872 ENCODE_START(2, 2, bl
);
877 void decode(ceph::buffer::list::const_iterator
&bl
) {
878 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl
);
883 void dump(ceph::Formatter
*f
) const;
884 static void generate_test_instances(std::list
<rgw_bucket_dir
*>& o
);
886 WRITE_CLASS_ENCODER(rgw_bucket_dir
)
888 struct rgw_usage_data
{
890 uint64_t bytes_received
;
892 uint64_t successful_ops
;
894 rgw_usage_data() : bytes_sent(0), bytes_received(0), ops(0), successful_ops(0) {}
895 rgw_usage_data(uint64_t sent
, uint64_t received
) : bytes_sent(sent
), bytes_received(received
), ops(0), successful_ops(0) {}
897 void encode(ceph::buffer::list
& bl
) const {
898 ENCODE_START(1, 1, bl
);
899 encode(bytes_sent
, bl
);
900 encode(bytes_received
, bl
);
902 encode(successful_ops
, bl
);
906 void decode(ceph::buffer::list::const_iterator
& bl
) {
908 decode(bytes_sent
, bl
);
909 decode(bytes_received
, bl
);
911 decode(successful_ops
, bl
);
915 void aggregate(const rgw_usage_data
& usage
) {
916 bytes_sent
+= usage
.bytes_sent
;
917 bytes_received
+= usage
.bytes_received
;
919 successful_ops
+= usage
.successful_ops
;
922 WRITE_CLASS_ENCODER(rgw_usage_data
)
925 struct rgw_usage_log_entry
{
927 rgw_user payer
; /* if empty, same as owner */
930 rgw_usage_data total_usage
; /* this one is kept for backwards compatibility */
931 std::map
<std::string
, rgw_usage_data
> usage_map
;
933 rgw_usage_log_entry() : epoch(0) {}
934 rgw_usage_log_entry(std::string
& o
, std::string
& b
) : owner(o
), bucket(b
), epoch(0) {}
935 rgw_usage_log_entry(std::string
& o
, std::string
& p
, std::string
& b
) : owner(o
), payer(p
), bucket(b
), epoch(0) {}
937 void encode(ceph::buffer::list
& bl
) const {
938 ENCODE_START(3, 1, bl
);
939 encode(owner
.to_str(), bl
);
942 encode(total_usage
.bytes_sent
, bl
);
943 encode(total_usage
.bytes_received
, bl
);
944 encode(total_usage
.ops
, bl
);
945 encode(total_usage
.successful_ops
, bl
);
946 encode(usage_map
, bl
);
947 encode(payer
.to_str(), bl
);
952 void decode(ceph::buffer::list::const_iterator
& bl
) {
959 decode(total_usage
.bytes_sent
, bl
);
960 decode(total_usage
.bytes_received
, bl
);
961 decode(total_usage
.ops
, bl
);
962 decode(total_usage
.successful_ops
, bl
);
964 usage_map
[""] = total_usage
;
966 decode(usage_map
, bl
);
976 void aggregate(const rgw_usage_log_entry
& e
,
977 std::map
<std::string
, bool> *categories
= NULL
) {
985 for (auto iter
= e
.usage_map
.begin(); iter
!= e
.usage_map
.end(); ++iter
) {
986 if (!categories
|| !categories
->size() || categories
->count(iter
->first
)) {
987 add(iter
->first
, iter
->second
);
992 void sum(rgw_usage_data
& usage
,
993 std::map
<std::string
, bool>& categories
) const {
994 usage
= rgw_usage_data();
995 for (auto iter
= usage_map
.begin(); iter
!= usage_map
.end(); ++iter
) {
996 if (!categories
.size() || categories
.count(iter
->first
)) {
997 usage
.aggregate(iter
->second
);
1002 void add(const std::string
& category
, const rgw_usage_data
& data
) {
1003 usage_map
[category
].aggregate(data
);
1004 total_usage
.aggregate(data
);
1007 void dump(ceph::Formatter
* f
) const;
1008 static void generate_test_instances(std::list
<rgw_usage_log_entry
*>& o
);
1011 WRITE_CLASS_ENCODER(rgw_usage_log_entry
)
1013 struct rgw_usage_log_info
{
1014 std::vector
<rgw_usage_log_entry
> entries
;
1016 void encode(ceph::buffer::list
& bl
) const {
1017 ENCODE_START(1, 1, bl
);
1018 encode(entries
, bl
);
1022 void decode(ceph::buffer::list::const_iterator
& bl
) {
1023 DECODE_START(1, bl
);
1024 decode(entries
, bl
);
1028 rgw_usage_log_info() {}
1030 WRITE_CLASS_ENCODER(rgw_usage_log_info
)
1032 struct rgw_user_bucket
{
1036 rgw_user_bucket() {}
1037 rgw_user_bucket(const std::string
& u
, const std::string
& b
) : user(u
), bucket(b
) {}
1039 void encode(ceph::buffer::list
& bl
) const {
1040 ENCODE_START(1, 1, bl
);
1046 void decode(ceph::buffer::list::const_iterator
& bl
) {
1047 DECODE_START(1, bl
);
1053 bool operator<(const rgw_user_bucket
& ub2
) const {
1054 int comp
= user
.compare(ub2
.user
);
1058 return bucket
.compare(ub2
.bucket
) < 0;
1063 WRITE_CLASS_ENCODER(rgw_user_bucket
)
1065 enum cls_rgw_gc_op
{
1067 CLS_RGW_GC_DEL_BUCKET
,
1070 struct cls_rgw_obj
{
1072 cls_rgw_obj_key key
;
1076 cls_rgw_obj(std::string
& _p
, cls_rgw_obj_key
& _k
) : pool(_p
), key(_k
) {}
1078 void encode(ceph::buffer::list
& bl
) const {
1079 ENCODE_START(2, 1, bl
);
1081 encode(key
.name
, bl
);
1087 void decode(ceph::buffer::list::const_iterator
& bl
) {
1088 DECODE_START(2, bl
);
1090 decode(key
.name
, bl
);
1092 if (struct_v
>= 2) {
1098 void dump(ceph::Formatter
*f
) const {
1099 f
->dump_string("pool", pool
);
1100 f
->dump_string("oid", key
.name
);
1101 f
->dump_string("key", loc
);
1102 f
->dump_string("instance", key
.instance
);
1104 static void generate_test_instances(std::list
<cls_rgw_obj
*>& ls
) {
1105 ls
.push_back(new cls_rgw_obj
);
1106 ls
.push_back(new cls_rgw_obj
);
1107 ls
.back()->pool
= "mypool";
1108 ls
.back()->key
.name
= "myoid";
1109 ls
.back()->loc
= "mykey";
1112 WRITE_CLASS_ENCODER(cls_rgw_obj
)
1114 struct cls_rgw_obj_chain
{
1115 std::list
<cls_rgw_obj
> objs
;
1117 cls_rgw_obj_chain() {}
1119 void push_obj(const std::string
& pool
, const cls_rgw_obj_key
& key
, const std::string
& loc
) {
1124 objs
.push_back(obj
);
1127 void encode(ceph::buffer::list
& bl
) const {
1128 ENCODE_START(1, 1, bl
);
1133 void decode(ceph::buffer::list::const_iterator
& bl
) {
1134 DECODE_START(1, bl
);
1139 void dump(ceph::Formatter
*f
) const {
1140 f
->open_array_section("objs");
1141 for (std::list
<cls_rgw_obj
>::const_iterator p
= objs
.begin(); p
!= objs
.end(); ++p
) {
1142 f
->open_object_section("obj");
1148 static void generate_test_instances(std::list
<cls_rgw_obj_chain
*>& ls
) {
1149 ls
.push_back(new cls_rgw_obj_chain
);
1153 return objs
.empty();
1156 WRITE_CLASS_ENCODER(cls_rgw_obj_chain
)
1158 struct cls_rgw_gc_obj_info
1161 cls_rgw_obj_chain chain
;
1162 ceph::real_time time
;
1164 cls_rgw_gc_obj_info() {}
1166 void encode(ceph::buffer::list
& bl
) const {
1167 ENCODE_START(1, 1, bl
);
1174 void decode(ceph::buffer::list::const_iterator
& bl
) {
1175 DECODE_START(1, bl
);
1182 void dump(ceph::Formatter
*f
) const {
1183 f
->dump_string("tag", tag
);
1184 f
->open_object_section("chain");
1187 f
->dump_stream("time") << time
;
1189 static void generate_test_instances(std::list
<cls_rgw_gc_obj_info
*>& ls
) {
1190 ls
.push_back(new cls_rgw_gc_obj_info
);
1191 ls
.push_back(new cls_rgw_gc_obj_info
);
1192 ls
.back()->tag
= "footag";
1193 ceph_timespec ts
{init_le32(21), init_le32(32)};
1194 ls
.back()->time
= ceph::real_clock::from_ceph_timespec(ts
);
1197 WRITE_CLASS_ENCODER(cls_rgw_gc_obj_info
)
1199 struct cls_rgw_lc_obj_head
1201 time_t start_date
= 0;
1204 cls_rgw_lc_obj_head() {}
1206 void encode(ceph::buffer::list
& bl
) const {
1207 ENCODE_START(1, 1, bl
);
1208 uint64_t t
= start_date
;
1214 void decode(ceph::buffer::list::const_iterator
& bl
) {
1215 DECODE_START(1, bl
);
1218 start_date
= static_cast<time_t>(t
);
1223 void dump(ceph::Formatter
*f
) const;
1224 static void generate_test_instances(std::list
<cls_rgw_lc_obj_head
*>& ls
);
1226 WRITE_CLASS_ENCODER(cls_rgw_lc_obj_head
)
1228 struct cls_rgw_lc_entry
{
1230 uint64_t start_time
; // if in_progress
1234 : start_time(0), status(0) {}
1236 cls_rgw_lc_entry(const cls_rgw_lc_entry
& rhs
) = default;
1238 cls_rgw_lc_entry(const std::string
& b
, uint64_t t
, uint32_t s
)
1239 : bucket(b
), start_time(t
), status(s
) {};
1241 void encode(bufferlist
& bl
) const {
1242 ENCODE_START(1, 1, bl
);
1244 encode(start_time
, bl
);
1249 void decode(bufferlist::const_iterator
& bl
) {
1250 DECODE_START(1, bl
);
1252 decode(start_time
, bl
);
1257 WRITE_CLASS_ENCODER(cls_rgw_lc_entry
);
1259 struct cls_rgw_reshard_entry
1261 ceph::real_time time
;
1263 std::string bucket_name
;
1264 std::string bucket_id
;
1265 std::string new_instance_id
;
1266 uint32_t old_num_shards
{0};
1267 uint32_t new_num_shards
{0};
1269 cls_rgw_reshard_entry() {}
1271 void encode(ceph::buffer::list
& bl
) const {
1272 ENCODE_START(1, 1, bl
);
1275 encode(bucket_name
, bl
);
1276 encode(bucket_id
, bl
);
1277 encode(new_instance_id
, bl
);
1278 encode(old_num_shards
, bl
);
1279 encode(new_num_shards
, bl
);
1283 void decode(ceph::buffer::list::const_iterator
& bl
) {
1284 DECODE_START(1, bl
);
1287 decode(bucket_name
, bl
);
1288 decode(bucket_id
, bl
);
1289 decode(new_instance_id
, bl
);
1290 decode(old_num_shards
, bl
);
1291 decode(new_num_shards
, bl
);
1295 void dump(ceph::Formatter
*f
) const;
1296 static void generate_test_instances(std::list
<cls_rgw_reshard_entry
*>& o
);
1298 static void generate_key(const std::string
& tenant
, const std::string
& bucket_name
, std::string
*key
);
1299 void get_key(std::string
*key
) const;
1301 WRITE_CLASS_ENCODER(cls_rgw_reshard_entry
)