]> git.proxmox.com Git - ceph.git/blame_incremental - ceph/src/rgw/rgw_period_puller.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / rgw / rgw_period_puller.cc
... / ...
CommitLineData
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 "rgw_rados.h"
5#include "rgw_zone.h"
6#include "rgw_rest_conn.h"
7#include "common/ceph_json.h"
8#include "common/errno.h"
9
10#include "services/svc_zone.h"
11
12#define dout_subsys ceph_subsys_rgw
13
14#undef dout_prefix
15#define dout_prefix (*_dout << "rgw period puller: ")
16
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
24namespace {
25
26// pull the given period over the connection
27int pull_period(const DoutPrefixProvider *dpp, RGWRESTConn* conn, const std::string& period_id,
28 const std::string& realm_id, RGWPeriod& period,
29 optional_yield y)
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)
43 int r = conn->forward(dpp, user, info, nullptr, MAX_REST_RESPONSE, nullptr, &data, y);
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 ldpp_dout(dpp, -1) << "request failed: " << cpp_strerror(-r) << dendl;
52 return r;
53 }
54
55 try {
56 decode_json_obj(period, &parser);
57 } catch (const JSONDecoder::err& e) {
58 ldpp_dout(dpp, -1) << "failed to decode JSON input: "
59 << e.what() << dendl;
60 return -EINVAL;
61 }
62 return 0;
63}
64
65} // anonymous namespace
66
67int RGWPeriodPuller::pull(const DoutPrefixProvider *dpp, const std::string& period_id, RGWPeriod& period,
68 optional_yield y)
69{
70 // try to read the period from rados
71 period.set_id(period_id);
72 period.set_epoch(0);
73 int r = period.init(dpp, cct, svc.sysobj, y);
74 if (r < 0) {
75 if (svc.zone->is_meta_master()) {
76 // can't pull if we're the master
77 ldpp_dout(dpp, 1) << "metadata master failed to read period "
78 << period_id << " from local storage: " << cpp_strerror(r) << dendl;
79 return r;
80 }
81 ldpp_dout(dpp, 14) << "pulling period " << period_id
82 << " from master" << dendl;
83 // request the period from the master zone
84 r = pull_period(dpp, svc.zone->get_master_conn(), period_id,
85 svc.zone->get_realm().get_id(), period, y);
86 if (r < 0) {
87 ldpp_dout(dpp, -1) << "failed to pull period " << period_id << dendl;
88 return r;
89 }
90 // write the period to rados
91 r = period.store_info(dpp, true, y);
92 if (r == -EEXIST) {
93 r = 0;
94 } else if (r < 0) {
95 ldpp_dout(dpp, -1) << "failed to store period " << period_id << dendl;
96 return r;
97 }
98 // update latest epoch
99 r = period.update_latest_epoch(dpp, period.get_epoch(), y);
100 if (r == -EEXIST) {
101 // already have this epoch (or a more recent one)
102 return 0;
103 }
104 if (r < 0) {
105 ldpp_dout(dpp, -1) << "failed to update latest_epoch for period "
106 << period_id << dendl;
107 return r;
108 }
109 // reflect period objects if this is the latest version
110 if (svc.zone->get_realm().get_current_period() == period_id) {
111 r = period.reflect(dpp, y);
112 if (r < 0) {
113 return r;
114 }
115 }
116 ldpp_dout(dpp, 14) << "period " << period_id
117 << " pulled and written to local storage" << dendl;
118 } else {
119 ldpp_dout(dpp, 14) << "found period " << period_id
120 << " in local storage" << dendl;
121 }
122 return 0;
123}