]>
Commit | Line | Data |
---|---|---|
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 |
17 | RGWPeriodPuller::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 |
24 | namespace { |
25 | ||
26 | // pull the given period over the connection | |
b3b6e05e | 27 | int 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 | 67 | int 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 | } |