]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_period_puller.cc
import ceph pacific 16.2.5
[ceph.git] / ceph / src / rgw / rgw_period_puller.cc
CommitLineData
7c673cae 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
7c673cae
FG
3
4#include "rgw_rados.h"
11fdf7f2 5#include "rgw_zone.h"
7c673cae
FG
6#include "rgw_rest_conn.h"
7#include "common/ceph_json.h"
8#include "common/errno.h"
9
11fdf7f2
TL
10#include "services/svc_zone.h"
11
7c673cae
FG
12#define dout_subsys ceph_subsys_rgw
13
14#undef dout_prefix
15#define dout_prefix (*_dout << "rgw period puller: ")
16
9f95a23c
TL
17RGWPeriodPuller::RGWPeriodPuller(RGWSI_Zone *zone_svc, RGWSI_SysObj *sysobj_svc)
18{
19 cct = zone_svc->ctx();
20 svc.zone = zone_svc;
21 svc.sysobj = sysobj_svc;
22}
23
7c673cae
FG
24namespace {
25
26// pull the given period over the connection
b3b6e05e 27int pull_period(const DoutPrefixProvider *dpp, RGWRESTConn* conn, const std::string& period_id,
f67539c2
TL
28 const std::string& realm_id, RGWPeriod& period,
29 optional_yield y)
7c673cae
FG
30{
31 rgw_user user;
32 RGWEnv env;
33 req_info info(conn->get_ctx(), &env);
34 info.method = "GET";
35 info.request_uri = "/admin/realm/period";
36
37 auto& params = info.args.get_params();
38 params["realm_id"] = realm_id;
39 params["period_id"] = period_id;
40
41 bufferlist data;
42#define MAX_REST_RESPONSE (128 * 1024)
b3b6e05e 43 int r = conn->forward(dpp, user, info, nullptr, MAX_REST_RESPONSE, nullptr, &data, y);
7c673cae
FG
44 if (r < 0) {
45 return r;
46 }
47
48 JSONParser parser;
49 r = parser.parse(data.c_str(), data.length());
50 if (r < 0) {
51 lderr(conn->get_ctx()) << "request failed: " << cpp_strerror(-r) << dendl;
52 return r;
53 }
54
55 try {
56 decode_json_obj(period, &parser);
9f95a23c 57 } catch (const JSONDecoder::err& e) {
7c673cae 58 lderr(conn->get_ctx()) << "failed to decode JSON input: "
9f95a23c 59 << e.what() << dendl;
7c673cae
FG
60 return -EINVAL;
61 }
62 return 0;
63}
64
65} // anonymous namespace
66
b3b6e05e 67int RGWPeriodPuller::pull(const DoutPrefixProvider *dpp, const std::string& period_id, RGWPeriod& period,
f67539c2 68 optional_yield y)
7c673cae
FG
69{
70 // try to read the period from rados
71 period.set_id(period_id);
72 period.set_epoch(0);
b3b6e05e 73 int r = period.init(dpp, cct, svc.sysobj, y);
7c673cae 74 if (r < 0) {
9f95a23c 75 if (svc.zone->is_meta_master()) {
7c673cae 76 // can't pull if we're the master
b3b6e05e 77 ldpp_dout(dpp, 1) << "metadata master failed to read period "
7c673cae
FG
78 << period_id << " from local storage: " << cpp_strerror(r) << dendl;
79 return r;
80 }
b3b6e05e 81 ldpp_dout(dpp, 14) << "pulling period " << period_id
7c673cae
FG
82 << " from master" << dendl;
83 // request the period from the master zone
b3b6e05e 84 r = pull_period(dpp, svc.zone->get_master_conn(), period_id,
f67539c2 85 svc.zone->get_realm().get_id(), period, y);
7c673cae 86 if (r < 0) {
b3b6e05e 87 ldpp_dout(dpp, -1) << "failed to pull period " << period_id << dendl;
7c673cae
FG
88 return r;
89 }
90 // write the period to rados
b3b6e05e 91 r = period.store_info(dpp, true, y);
7c673cae
FG
92 if (r == -EEXIST) {
93 r = 0;
94 } else if (r < 0) {
b3b6e05e 95 ldpp_dout(dpp, -1) << "failed to store period " << period_id << dendl;
7c673cae
FG
96 return r;
97 }
224ce89b 98 // update latest epoch
b3b6e05e 99 r = period.update_latest_epoch(dpp, period.get_epoch(), y);
7c673cae 100 if (r == -EEXIST) {
224ce89b
WB
101 // already have this epoch (or a more recent one)
102 return 0;
103 }
104 if (r < 0) {
b3b6e05e 105 ldpp_dout(dpp, -1) << "failed to update latest_epoch for period "
7c673cae
FG
106 << period_id << dendl;
107 return r;
108 }
224ce89b 109 // reflect period objects if this is the latest version
9f95a23c 110 if (svc.zone->get_realm().get_current_period() == period_id) {
b3b6e05e 111 r = period.reflect(dpp, y);
28e407b8
AA
112 if (r < 0) {
113 return r;
114 }
224ce89b 115 }
b3b6e05e 116 ldpp_dout(dpp, 14) << "period " << period_id
7c673cae
FG
117 << " pulled and written to local storage" << dendl;
118 } else {
b3b6e05e 119 ldpp_dout(dpp, 14) << "found period " << period_id
7c673cae
FG
120 << " in local storage" << dendl;
121 }
122 return 0;
123}