1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
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.
14 #include "common/ceph_json.h"
15 #include "common/strtol.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"
27 #define dout_context g_ceph_context
28 #define dout_subsys ceph_subsys_rgw
29 #define REPLICA_INPUT_MAX_LEN (512*1024)
31 static int parse_to_utime(string
& in
, utime_t
& out
) {
34 int ret
= utime_t::parse_date(in
.c_str(), &sec
, &nsec
);
38 out
= utime_t(sec
, nsec
);
42 void 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");
52 dout(5) << "Error - invalid parameter list" << dendl
;
61 shard
= (int)strict_strtol(id_str
.c_str(), 10, &err
);
63 dout(5) << "Error parsing id parameter - " << id_str
<< ", err " << err
<< dendl
;
68 if (parse_to_utime(time
, ut
) < 0) {
74 RGWReplicaObjectLogger
rl(store
, pool
, prefix
);
76 list
<RGWReplicaItemMarker
> markers
;
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
;
83 http_ret
= rl
.update_bound(shard
, daemon_id
, marker
, ut
, &markers
);
86 void RGWOp_OBJLog_GetBounds::execute() {
87 string id
= s
->info
.args
.get("id");
90 dout(5) << " Error - invalid parameter list" << dendl
;
98 shard
= (int)strict_strtol(id
.c_str(), 10, &err
);
100 dout(5) << "Error parsing id parameter - " << id
<< ", err " << err
<< dendl
;
106 RGWReplicaObjectLogger
rl(store
, pool
, prefix
);
107 http_ret
= rl
.get_bounds(shard
, bounds
);
110 void RGWOp_OBJLog_GetBounds::send_response() {
111 set_req_state_err(s
, http_ret
);
118 encode_json("bounds", bounds
, s
->formatter
);
122 void RGWOp_OBJLog_DeleteBounds::execute() {
123 string id
= s
->info
.args
.get("id"),
124 daemon_id
= s
->info
.args
.get("daemon_id");
127 s
->info
.args
.get_bool("purge-all", &purge_all
, false);
130 (!purge_all
&& daemon_id
.empty())) {
131 dout(5) << "Error - invalid parameter list" << dendl
;
139 shard
= (int)strict_strtol(id
.c_str(), 10, &err
);
141 dout(5) << "Error parsing id parameter - " << id
<< ", err " << err
<< dendl
;
146 RGWReplicaObjectLogger
rl(store
, pool
, prefix
);
147 http_ret
= rl
.delete_bound(shard
, daemon_id
, purge_all
);
150 static int bucket_instance_to_bucket(RGWRados
*store
, const string
& bucket_instance
, rgw_bucket
& bucket
) {
151 RGWBucketInfo bucket_info
;
154 RGWObjectCtx
obj_ctx(store
);
155 int r
= store
->get_bucket_instance_info(obj_ctx
, bucket_instance
, bucket_info
, &mtime
, NULL
);
157 dout(5) << "could not get bucket instance info for bucket=" << bucket_instance
<< ": " << cpp_strerror(r
) << dendl
;
163 bucket
= bucket_info
.bucket
;
167 void 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");
173 if (marker
.empty() ||
176 dout(5) << "Error - invalid parameter list" << dendl
;
183 if (parse_to_utime(time
, ut
) < 0) {
189 http_ret
= rgw_bucket_parse_bucket_instance(bucket_instance
, &bucket_instance
, &shard_id
);
191 dout(5) << "failed to parse bucket instance" << dendl
;
197 if ((http_ret
= bucket_instance_to_bucket(store
, bucket_instance
, bucket
)) < 0) {
201 RGWReplicaBucketLogger
rl(store
);
203 list
<RGWReplicaItemMarker
> markers
;
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
;
210 http_ret
= rl
.update_bound(bucket
, shard_id
, daemon_id
, marker
, ut
, &markers
);
213 void RGWOp_BILog_GetBounds::execute() {
214 string bucket_instance
= s
->info
.args
.get("bucket-instance");
219 http_ret
= rgw_bucket_parse_bucket_instance(bucket_instance
, &bucket_instance
, &shard_id
);
221 dout(5) << "failed to parse bucket instance" << dendl
;
225 if ((http_ret
= bucket_instance_to_bucket(store
, bucket_instance
, bucket
)) < 0)
228 RGWReplicaBucketLogger
rl(store
);
229 http_ret
= rl
.get_bounds(bucket
, shard_id
, bounds
);
232 void RGWOp_BILog_GetBounds::send_response() {
233 set_req_state_err(s
, http_ret
);
240 encode_json("bounds", bounds
, s
->formatter
);
244 void RGWOp_BILog_DeleteBounds::execute() {
245 string bucket_instance
= s
->info
.args
.get("bucket-instance");
246 string daemon_id
= s
->info
.args
.get("daemon_id");
249 s
->info
.args
.get_bool("purge-all", &purge_all
, false);
251 if (daemon_id
.empty() && !purge_all
) {
252 dout(5) << "Error - invalid parameter list" << dendl
;
258 http_ret
= rgw_bucket_parse_bucket_instance(bucket_instance
, &bucket_instance
, &shard_id
);
260 dout(5) << "failed to parse bucket instance" << dendl
;
266 if ((http_ret
= bucket_instance_to_bucket(store
, bucket_instance
, bucket
)) < 0) {
270 RGWReplicaBucketLogger
rl(store
);
271 http_ret
= rl
.delete_bound(bucket
, shard_id
, daemon_id
, purge_all
);
274 RGWOp
*RGWHandler_ReplicaLog::op_get() {
276 string type
= s
->info
.args
.get("type", &exists
);
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");
292 RGWOp
*RGWHandler_ReplicaLog::op_delete() {
294 string type
= s
->info
.args
.get("type", &exists
);
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");
310 RGWOp
*RGWHandler_ReplicaLog::op_post() {
312 string type
= s
->info
.args
.get("type", &exists
);
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");