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