]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab ft=cpp | |
3 | ||
4 | #include "svc_bilog_rados.h" | |
5 | #include "svc_bi_rados.h" | |
6 | ||
7 | #include "cls/rgw/cls_rgw_client.h" | |
8 | ||
9f95a23c TL |
9 | #define dout_subsys ceph_subsys_rgw |
10 | ||
20effc67 TL |
11 | using namespace std; |
12 | ||
9f95a23c TL |
13 | RGWSI_BILog_RADOS::RGWSI_BILog_RADOS(CephContext *cct) : RGWServiceInstance(cct) |
14 | { | |
15 | } | |
16 | ||
17 | void RGWSI_BILog_RADOS::init(RGWSI_BucketIndex_RADOS *bi_rados_svc) | |
18 | { | |
19 | svc.bi = bi_rados_svc; | |
20 | } | |
21 | ||
b3b6e05e | 22 | int RGWSI_BILog_RADOS::log_trim(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, int shard_id, string& start_marker, string& end_marker) |
9f95a23c TL |
23 | { |
24 | RGWSI_RADOS::Pool index_pool; | |
25 | map<int, string> bucket_objs; | |
26 | ||
27 | BucketIndexShardsManager start_marker_mgr; | |
28 | BucketIndexShardsManager end_marker_mgr; | |
29 | ||
b3b6e05e | 30 | int r = svc.bi->open_bucket_index(dpp, bucket_info, shard_id, &index_pool, &bucket_objs, nullptr); |
9f95a23c TL |
31 | if (r < 0) { |
32 | return r; | |
33 | } | |
34 | ||
35 | r = start_marker_mgr.from_string(start_marker, shard_id); | |
36 | if (r < 0) { | |
37 | return r; | |
38 | } | |
39 | ||
40 | r = end_marker_mgr.from_string(end_marker, shard_id); | |
41 | if (r < 0) { | |
42 | return r; | |
43 | } | |
44 | ||
45 | return CLSRGWIssueBILogTrim(index_pool.ioctx(), start_marker_mgr, end_marker_mgr, bucket_objs, | |
46 | cct->_conf->rgw_bucket_index_max_aio)(); | |
47 | } | |
48 | ||
b3b6e05e | 49 | int RGWSI_BILog_RADOS::log_start(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, int shard_id) |
9f95a23c TL |
50 | { |
51 | RGWSI_RADOS::Pool index_pool; | |
52 | map<int, string> bucket_objs; | |
b3b6e05e | 53 | int r = svc.bi->open_bucket_index(dpp, bucket_info, shard_id, &index_pool, &bucket_objs, nullptr); |
9f95a23c TL |
54 | if (r < 0) |
55 | return r; | |
56 | ||
57 | return CLSRGWIssueResyncBucketBILog(index_pool.ioctx(), bucket_objs, cct->_conf->rgw_bucket_index_max_aio)(); | |
58 | } | |
59 | ||
b3b6e05e | 60 | int RGWSI_BILog_RADOS::log_stop(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, int shard_id) |
9f95a23c TL |
61 | { |
62 | RGWSI_RADOS::Pool index_pool; | |
63 | map<int, string> bucket_objs; | |
b3b6e05e | 64 | int r = svc.bi->open_bucket_index(dpp, bucket_info, shard_id, &index_pool, &bucket_objs, nullptr); |
9f95a23c TL |
65 | if (r < 0) |
66 | return r; | |
67 | ||
68 | return CLSRGWIssueBucketBILogStop(index_pool.ioctx(), bucket_objs, cct->_conf->rgw_bucket_index_max_aio)(); | |
69 | } | |
70 | ||
71 | static void build_bucket_index_marker(const string& shard_id_str, | |
72 | const string& shard_marker, | |
73 | string *marker) { | |
74 | if (marker) { | |
75 | *marker = shard_id_str; | |
76 | marker->append(BucketIndexShardsManager::KEY_VALUE_SEPARATOR); | |
77 | marker->append(shard_marker); | |
78 | } | |
79 | } | |
80 | ||
b3b6e05e | 81 | int RGWSI_BILog_RADOS::log_list(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, int shard_id, string& marker, uint32_t max, |
9f95a23c TL |
82 | std::list<rgw_bi_log_entry>& result, bool *truncated) |
83 | { | |
b3b6e05e | 84 | ldpp_dout(dpp, 20) << __func__ << ": " << bucket_info.bucket << " marker " << marker << " shard_id=" << shard_id << " max " << max << dendl; |
9f95a23c TL |
85 | result.clear(); |
86 | ||
87 | RGWSI_RADOS::Pool index_pool; | |
88 | map<int, string> oids; | |
89 | map<int, cls_rgw_bi_log_list_ret> bi_log_lists; | |
b3b6e05e | 90 | int r = svc.bi->open_bucket_index(dpp, bucket_info, shard_id, &index_pool, &oids, nullptr); |
9f95a23c TL |
91 | if (r < 0) |
92 | return r; | |
93 | ||
94 | BucketIndexShardsManager marker_mgr; | |
95 | bool has_shards = (oids.size() > 1 || shard_id >= 0); | |
96 | // If there are multiple shards for the bucket index object, the marker | |
97 | // should have the pattern '{shard_id_1}#{shard_marker_1},{shard_id_2}# | |
98 | // {shard_marker_2}...', if there is no sharding, the bi_log_list should | |
99 | // only contain one record, and the key is the bucket instance id. | |
100 | r = marker_mgr.from_string(marker, shard_id); | |
101 | if (r < 0) | |
102 | return r; | |
103 | ||
104 | r = CLSRGWIssueBILogList(index_pool.ioctx(), marker_mgr, max, oids, bi_log_lists, cct->_conf->rgw_bucket_index_max_aio)(); | |
105 | if (r < 0) | |
106 | return r; | |
107 | ||
108 | map<int, list<rgw_bi_log_entry>::iterator> vcurrents; | |
109 | map<int, list<rgw_bi_log_entry>::iterator> vends; | |
110 | if (truncated) { | |
111 | *truncated = false; | |
112 | } | |
113 | map<int, cls_rgw_bi_log_list_ret>::iterator miter = bi_log_lists.begin(); | |
114 | for (; miter != bi_log_lists.end(); ++miter) { | |
115 | int shard_id = miter->first; | |
116 | vcurrents[shard_id] = miter->second.entries.begin(); | |
117 | vends[shard_id] = miter->second.entries.end(); | |
118 | if (truncated) { | |
119 | *truncated = (*truncated || miter->second.truncated); | |
120 | } | |
121 | } | |
122 | ||
123 | size_t total = 0; | |
124 | bool has_more = true; | |
125 | map<int, list<rgw_bi_log_entry>::iterator>::iterator viter; | |
126 | map<int, list<rgw_bi_log_entry>::iterator>::iterator eiter; | |
127 | while (total < max && has_more) { | |
128 | has_more = false; | |
129 | ||
130 | viter = vcurrents.begin(); | |
131 | eiter = vends.begin(); | |
132 | ||
133 | for (; total < max && viter != vcurrents.end(); ++viter, ++eiter) { | |
134 | assert (eiter != vends.end()); | |
135 | ||
136 | int shard_id = viter->first; | |
137 | list<rgw_bi_log_entry>::iterator& liter = viter->second; | |
138 | ||
139 | if (liter == eiter->second){ | |
140 | continue; | |
141 | } | |
142 | rgw_bi_log_entry& entry = *(liter); | |
143 | if (has_shards) { | |
144 | char buf[16]; | |
145 | snprintf(buf, sizeof(buf), "%d", shard_id); | |
146 | string tmp_id; | |
147 | build_bucket_index_marker(buf, entry.id, &tmp_id); | |
148 | entry.id.swap(tmp_id); | |
149 | } | |
150 | marker_mgr.add(shard_id, entry.id); | |
151 | result.push_back(entry); | |
152 | total++; | |
153 | has_more = true; | |
154 | ++liter; | |
155 | } | |
156 | } | |
157 | ||
158 | if (truncated) { | |
159 | for (viter = vcurrents.begin(), eiter = vends.begin(); viter != vcurrents.end(); ++viter, ++eiter) { | |
160 | assert (eiter != vends.end()); | |
161 | *truncated = (*truncated || (viter->second != eiter->second)); | |
162 | } | |
163 | } | |
164 | ||
165 | // Refresh marker, if there are multiple shards, the output will look like | |
166 | // '{shard_oid_1}#{shard_marker_1},{shard_oid_2}#{shard_marker_2}...', | |
167 | // if there is no sharding, the simply marker (without oid) is returned | |
168 | if (has_shards) { | |
169 | marker_mgr.to_string(&marker); | |
170 | } else { | |
171 | if (!result.empty()) { | |
172 | marker = result.rbegin()->id; | |
173 | } | |
174 | } | |
175 | ||
176 | return 0; | |
177 | } | |
178 | ||
b3b6e05e TL |
179 | int RGWSI_BILog_RADOS::get_log_status(const DoutPrefixProvider *dpp, |
180 | const RGWBucketInfo& bucket_info, | |
9f95a23c | 181 | int shard_id, |
f67539c2 TL |
182 | map<int, string> *markers, |
183 | optional_yield y) | |
9f95a23c TL |
184 | { |
185 | vector<rgw_bucket_dir_header> headers; | |
186 | map<int, string> bucket_instance_ids; | |
b3b6e05e | 187 | int r = svc.bi->cls_bucket_head(dpp, bucket_info, shard_id, &headers, &bucket_instance_ids, y); |
9f95a23c TL |
188 | if (r < 0) |
189 | return r; | |
190 | ||
191 | ceph_assert(headers.size() == bucket_instance_ids.size()); | |
192 | ||
193 | auto iter = headers.begin(); | |
194 | map<int, string>::iterator viter = bucket_instance_ids.begin(); | |
195 | ||
196 | for(; iter != headers.end(); ++iter, ++viter) { | |
197 | if (shard_id >= 0) { | |
198 | (*markers)[shard_id] = iter->max_marker; | |
199 | } else { | |
200 | (*markers)[viter->first] = iter->max_marker; | |
201 | } | |
202 | } | |
203 | ||
204 | return 0; | |
205 | } | |
206 |