]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | } | |
224ce89b WB |
86 | // update latest epoch |
87 | r = period.update_latest_epoch(period.get_epoch()); | |
7c673cae | 88 | if (r == -EEXIST) { |
224ce89b WB |
89 | // already have this epoch (or a more recent one) |
90 | return 0; | |
91 | } | |
92 | if (r < 0) { | |
7c673cae FG |
93 | lderr(store->ctx()) << "failed to update latest_epoch for period " |
94 | << period_id << dendl; | |
95 | return r; | |
96 | } | |
224ce89b WB |
97 | // reflect period objects if this is the latest version |
98 | r = period.reflect(); | |
99 | if (r < 0) { | |
100 | return r; | |
101 | } | |
7c673cae FG |
102 | ldout(store->ctx(), 14) << "period " << period_id |
103 | << " pulled and written to local storage" << dendl; | |
104 | } else { | |
105 | ldout(store->ctx(), 14) << "found period " << period_id | |
106 | << " in local storage" << dendl; | |
107 | } | |
108 | return 0; | |
109 | } |