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