Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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     r = period.reflect();
99     if (r < 0) {
100       return r;
101     }
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 }