]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_rest_replica_log.cc
update sources to v12.2.1
[ceph.git] / ceph / src / rgw / rgw_rest_replica_log.cc
CommitLineData
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) 2013 eNovance SAS <licensing@enovance.com>
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#include "common/ceph_json.h"
15#include "common/strtol.h"
16#include "rgw_rest.h"
17#include "rgw_op.h"
18#include "rgw_rest_s3.h"
19#include "rgw_replica_log.h"
20#include "rgw_metadata.h"
21#include "rgw_bucket.h"
22#include "rgw_rest_replica_log.h"
23#include "rgw_client_io.h"
24#include "common/errno.h"
25#include "include/assert.h"
26
27#define dout_context g_ceph_context
28#define dout_subsys ceph_subsys_rgw
29#define REPLICA_INPUT_MAX_LEN (512*1024)
30
31static int parse_to_utime(string& in, utime_t& out) {
32 uint64_t sec = 0;
33 uint64_t nsec = 0;
34 int ret = utime_t::parse_date(in.c_str(), &sec, &nsec);
35 if (ret < 0)
36 return ret;
37
38 out = utime_t(sec, nsec);
39 return 0;
40}
41
42void RGWOp_OBJLog_SetBounds::execute() {
43 string id_str = s->info.args.get("id"),
44 marker = s->info.args.get("marker"),
45 time = s->info.args.get("time"),
46 daemon_id = s->info.args.get("daemon_id");
47
48 if (id_str.empty() ||
49 marker.empty() ||
50 time.empty() ||
51 daemon_id.empty()) {
52 dout(5) << "Error - invalid parameter list" << dendl;
53 http_ret = -EINVAL;
54 return;
55 }
56
57 int shard;
58 string err;
59 utime_t ut;
60
61 shard = (int)strict_strtol(id_str.c_str(), 10, &err);
62 if (!err.empty()) {
63 dout(5) << "Error parsing id parameter - " << id_str << ", err " << err << dendl;
64 http_ret = -EINVAL;
65 return;
66 }
67
68 if (parse_to_utime(time, ut) < 0) {
69 http_ret = -EINVAL;
70 return;
71 }
72
73 string pool;
74 RGWReplicaObjectLogger rl(store, pool, prefix);
75 bufferlist bl;
76 list<RGWReplicaItemMarker> markers;
77
78 if ((http_ret = rgw_rest_get_json_input(store->ctx(), s, markers, REPLICA_INPUT_MAX_LEN, NULL)) < 0) {
79 dout(5) << "Error - retrieving input data - " << http_ret << dendl;
80 return;
81 }
82
83 http_ret = rl.update_bound(shard, daemon_id, marker, ut, &markers);
84}
85
86void RGWOp_OBJLog_GetBounds::execute() {
87 string id = s->info.args.get("id");
88
89 if (id.empty()) {
90 dout(5) << " Error - invalid parameter list" << dendl;
91 http_ret = -EINVAL;
92 return;
93 }
94
95 int shard;
96 string err;
97
98 shard = (int)strict_strtol(id.c_str(), 10, &err);
99 if (!err.empty()) {
100 dout(5) << "Error parsing id parameter - " << id << ", err " << err << dendl;
101 http_ret = -EINVAL;
102 return;
103 }
104
105 string pool;
106 RGWReplicaObjectLogger rl(store, pool, prefix);
107 http_ret = rl.get_bounds(shard, bounds);
108}
109
110void RGWOp_OBJLog_GetBounds::send_response() {
111 set_req_state_err(s, http_ret);
112 dump_errno(s);
113 end_header(s);
114
115 if (http_ret < 0)
116 return;
117
118 encode_json("bounds", bounds, s->formatter);
119 flusher.flush();
120}
121
122void RGWOp_OBJLog_DeleteBounds::execute() {
123 string id = s->info.args.get("id"),
124 daemon_id = s->info.args.get("daemon_id");
125 bool purge_all;
126
127 s->info.args.get_bool("purge-all", &purge_all, false);
128
129 if (id.empty() ||
130 (!purge_all && daemon_id.empty())) {
131 dout(5) << "Error - invalid parameter list" << dendl;
132 http_ret = -EINVAL;
133 return;
134 }
135
136 int shard;
137 string err;
138
139 shard = (int)strict_strtol(id.c_str(), 10, &err);
140 if (!err.empty()) {
141 dout(5) << "Error parsing id parameter - " << id << ", err " << err << dendl;
142 http_ret = -EINVAL;
143 }
144
145 string pool;
146 RGWReplicaObjectLogger rl(store, pool, prefix);
147 http_ret = rl.delete_bound(shard, daemon_id, purge_all);
148}
149
150static int bucket_instance_to_bucket(RGWRados *store, const string& bucket_instance, rgw_bucket& bucket) {
151 RGWBucketInfo bucket_info;
152 real_time mtime;
153
154 RGWObjectCtx obj_ctx(store);
155 int r = store->get_bucket_instance_info(obj_ctx, bucket_instance, bucket_info, &mtime, NULL);
156 if (r < 0) {
157 dout(5) << "could not get bucket instance info for bucket=" << bucket_instance << ": " << cpp_strerror(r) << dendl;
158 if (r == -ENOENT)
159 return r;
160 return -EINVAL;
161 }
162
163 bucket = bucket_info.bucket;
164 return 0;
165}
166
167void RGWOp_BILog_SetBounds::execute() {
168 string bucket_instance = s->info.args.get("bucket-instance"),
169 marker = s->info.args.get("marker"),
170 time = s->info.args.get("time"),
171 daemon_id = s->info.args.get("daemon_id");
172
173 if (marker.empty() ||
174 time.empty() ||
175 daemon_id.empty()) {
176 dout(5) << "Error - invalid parameter list" << dendl;
177 http_ret = -EINVAL;
178 return;
179 }
180
181 utime_t ut;
182
183 if (parse_to_utime(time, ut) < 0) {
184 http_ret = -EINVAL;
185 return;
186 }
187
188 int shard_id;
189 http_ret = rgw_bucket_parse_bucket_instance(bucket_instance, &bucket_instance, &shard_id);
190 if (http_ret < 0) {
191 dout(5) << "failed to parse bucket instance" << dendl;
192 return;
193 }
194
195 rgw_bucket bucket;
196
197 if ((http_ret = bucket_instance_to_bucket(store, bucket_instance, bucket)) < 0) {
198 return;
199 }
200
201 RGWReplicaBucketLogger rl(store);
202 bufferlist bl;
203 list<RGWReplicaItemMarker> markers;
204
205 if ((http_ret = rgw_rest_get_json_input(store->ctx(), s, markers, REPLICA_INPUT_MAX_LEN, NULL)) < 0) {
206 dout(5) << "Error - retrieving input data - " << http_ret << dendl;
207 return;
208 }
209
210 http_ret = rl.update_bound(bucket, shard_id, daemon_id, marker, ut, &markers);
211}
212
213void RGWOp_BILog_GetBounds::execute() {
214 string bucket_instance = s->info.args.get("bucket-instance");
215 rgw_bucket bucket;
216
217 int shard_id;
218
219 http_ret = rgw_bucket_parse_bucket_instance(bucket_instance, &bucket_instance, &shard_id);
220 if (http_ret < 0) {
221 dout(5) << "failed to parse bucket instance" << dendl;
222 return;
223 }
224
225 if ((http_ret = bucket_instance_to_bucket(store, bucket_instance, bucket)) < 0)
226 return;
227
228 RGWReplicaBucketLogger rl(store);
229 http_ret = rl.get_bounds(bucket, shard_id, bounds);
230}
231
232void RGWOp_BILog_GetBounds::send_response() {
233 set_req_state_err(s, http_ret);
234 dump_errno(s);
235 end_header(s);
236
237 if (http_ret < 0)
238 return;
239
240 encode_json("bounds", bounds, s->formatter);
241 flusher.flush();
242}
243
244void RGWOp_BILog_DeleteBounds::execute() {
245 string bucket_instance = s->info.args.get("bucket-instance");
246 string daemon_id = s->info.args.get("daemon_id");
247 bool purge_all;
248
249 s->info.args.get_bool("purge-all", &purge_all, false);
250
251 if (daemon_id.empty() && !purge_all) {
252 dout(5) << "Error - invalid parameter list" << dendl;
253 http_ret = -EINVAL;
254 return;
255 }
256
257 int shard_id;
258 http_ret = rgw_bucket_parse_bucket_instance(bucket_instance, &bucket_instance, &shard_id);
259 if (http_ret < 0) {
260 dout(5) << "failed to parse bucket instance" << dendl;
261 return;
262 }
263
264 rgw_bucket bucket;
265
266 if ((http_ret = bucket_instance_to_bucket(store, bucket_instance, bucket)) < 0) {
267 return;
268 }
269
270 RGWReplicaBucketLogger rl(store);
271 http_ret = rl.delete_bound(bucket, shard_id, daemon_id, purge_all);
272}
273
274RGWOp *RGWHandler_ReplicaLog::op_get() {
275 bool exists;
276 string type = s->info.args.get("type", &exists);
277
278 if (!exists) {
279 return NULL;
280 }
281
282 if (type.compare("metadata") == 0) {
283 return new RGWOp_OBJLog_GetBounds(META_REPLICA_LOG_OBJ_PREFIX, "mdlog");
284 } else if (type.compare("bucket-index") == 0) {
285 return new RGWOp_BILog_GetBounds;
286 } else if (type.compare("data") == 0) {
287 return new RGWOp_OBJLog_GetBounds(DATA_REPLICA_LOG_OBJ_PREFIX, "datalog");
288 }
289 return NULL;
290}
291
292RGWOp *RGWHandler_ReplicaLog::op_delete() {
293 bool exists;
294 string type = s->info.args.get("type", &exists);
295
296 if (!exists) {
297 return NULL;
298 }
299
300 if (type.compare("metadata") == 0)
301 return new RGWOp_OBJLog_DeleteBounds(META_REPLICA_LOG_OBJ_PREFIX, "mdlog");
302 else if (type.compare("bucket-index") == 0)
303 return new RGWOp_BILog_DeleteBounds;
304 else if (type.compare("data") == 0)
305 return new RGWOp_OBJLog_DeleteBounds(DATA_REPLICA_LOG_OBJ_PREFIX, "datalog");
306
307 return NULL;
308}
309
310RGWOp *RGWHandler_ReplicaLog::op_post() {
311 bool exists;
312 string type = s->info.args.get("type", &exists);
313
314 if (!exists) {
315 return NULL;
316 }
317
318 if (type.compare("metadata") == 0) {
319 return new RGWOp_OBJLog_SetBounds(META_REPLICA_LOG_OBJ_PREFIX, "mdlog");
320 } else if (type.compare("bucket-index") == 0) {
321 return new RGWOp_BILog_SetBounds;
322 } else if (type.compare("data") == 0) {
323 return new RGWOp_OBJLog_SetBounds(DATA_REPLICA_LOG_OBJ_PREFIX, "datalog");
324 }
325 return NULL;
326}
327