Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / rgw / rgw_process.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 "common/errno.h"
5 #include "common/Throttle.h"
6 #include "common/WorkQueue.h"
7
8 #include "rgw_rados.h"
9 #include "rgw_rest.h"
10 #include "rgw_frontend.h"
11 #include "rgw_request.h"
12 #include "rgw_process.h"
13 #include "rgw_loadgen.h"
14 #include "rgw_client_io.h"
15
16 #define dout_subsys ceph_subsys_rgw
17
18 void RGWProcess::RGWWQ::_dump_queue()
19 {
20   if (!g_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
21     return;
22   }
23   deque<RGWRequest *>::iterator iter;
24   if (process->m_req_queue.empty()) {
25     dout(20) << "RGWWQ: empty" << dendl;
26     return;
27   }
28   dout(20) << "RGWWQ:" << dendl;
29   for (iter = process->m_req_queue.begin();
30        iter != process->m_req_queue.end(); ++iter) {
31     dout(20) << "req: " << hex << *iter << dec << dendl;
32   }
33 } /* RGWProcess::RGWWQ::_dump_queue */
34
35
36 int rgw_process_authenticated(RGWHandler_REST * const handler,
37                               RGWOp *& op,
38                               RGWRequest * const req,
39                               req_state * const s,
40                               const bool skip_retarget)
41 {
42   req->log(s, "init permissions");
43   int ret = handler->init_permissions(op);
44   if (ret < 0) {
45     return ret;
46   }
47
48   /**
49    * Only some accesses support website mode, and website mode does NOT apply
50    * if you are using the REST endpoint either (ergo, no authenticated access)
51    */
52   if (! skip_retarget) {
53     req->log(s, "recalculating target");
54     ret = handler->retarget(op, &op);
55     if (ret < 0) {
56       return ret;
57     }
58     req->op = op;
59   } else {
60     req->log(s, "retargeting skipped because of SubOp mode");
61   }
62
63   /* If necessary extract object ACL and put them into req_state. */
64   req->log(s, "reading permissions");
65   ret = handler->read_permissions(op);
66   if (ret < 0) {
67     return ret;
68   }
69
70   req->log(s, "init op");
71   ret = op->init_processing();
72   if (ret < 0) {
73     return ret;
74   }
75
76   req->log(s, "verifying op mask");
77   ret = op->verify_op_mask();
78   if (ret < 0) {
79     return ret;
80   }
81
82   req->log(s, "verifying op permissions");
83   ret = op->verify_permission();
84   if (ret < 0) {
85     if (s->system_request) {
86       dout(2) << "overriding permissions due to system operation" << dendl;
87     } else if (s->auth.identity->is_admin_of(s->user->user_id)) {
88       dout(2) << "overriding permissions due to admin operation" << dendl;
89     } else {
90       return ret;
91     }
92   }
93
94   req->log(s, "verifying op params");
95   ret = op->verify_params();
96   if (ret < 0) {
97     return ret;
98   }
99
100   req->log(s, "pre-executing");
101   op->pre_exec();
102
103   req->log(s, "executing");
104   op->execute();
105
106   req->log(s, "completing");
107   op->complete();
108
109   return 0;
110 }
111
112 int process_request(RGWRados* const store,
113                     RGWREST* const rest,
114                     RGWRequest* const req,
115                     const std::string& frontend_prefix,
116                     const rgw_auth_registry_t& auth_registry,
117                     RGWRestfulIO* const client_io,
118                     OpsLogSocket* const olog)
119 {
120   int ret = 0;
121
122   client_io->init(g_ceph_context);
123
124   req->log_init();
125
126   dout(1) << "====== starting new request req=" << hex << req << dec
127           << " =====" << dendl;
128   perfcounter->inc(l_rgw_req);
129
130   RGWEnv& rgw_env = client_io->get_env();
131
132   RGWUserInfo userinfo;
133
134   struct req_state rstate(g_ceph_context, &rgw_env, &userinfo);
135   struct req_state *s = &rstate;
136
137   RGWObjectCtx rados_ctx(store, s);
138   s->obj_ctx = &rados_ctx;
139
140   s->req_id = store->unique_id(req->id);
141   s->trans_id = store->unique_trans_id(req->id);
142   s->host_id = store->host_id;
143
144   req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str());
145
146   RGWOp* op = NULL;
147   int init_error = 0;
148   bool should_log = false;
149   RGWRESTMgr *mgr;
150   RGWHandler_REST *handler = rest->get_handler(store, s,
151                                                auth_registry,
152                                                frontend_prefix,
153                                                client_io, &mgr, &init_error);
154   if (init_error != 0) {
155     abort_early(s, NULL, init_error, NULL);
156     goto done;
157   }
158   dout(10) << "handler=" << typeid(*handler).name() << dendl;
159
160   should_log = mgr->get_logging();
161
162   req->log_format(s, "getting op %d", s->op);
163   op = handler->get_op(store);
164   if (!op) {
165     abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED, handler);
166     goto done;
167   }
168
169   req->op = op;
170   dout(10) << "op=" << typeid(*op).name() << dendl;
171
172   s->op_type = op->get_type();
173
174   req->log(s, "verifying requester");
175   ret = op->verify_requester(auth_registry);
176   if (ret < 0) {
177     dout(10) << "failed to authorize request" << dendl;
178     abort_early(s, NULL, ret, handler);
179     goto done;
180   }
181
182   /* FIXME: remove this after switching all handlers to the new authentication
183    * infrastructure. */
184   if (nullptr == s->auth.identity) {
185     s->auth.identity = rgw::auth::transform_old_authinfo(s);
186   }
187
188   req->log(s, "normalizing buckets and tenants");
189   ret = handler->postauth_init();
190   if (ret < 0) {
191     dout(10) << "failed to run post-auth init" << dendl;
192     abort_early(s, op, ret, handler);
193     goto done;
194   }
195
196   if (s->user->suspended) {
197     dout(10) << "user is suspended, uid=" << s->user->user_id << dendl;
198     abort_early(s, op, -ERR_USER_SUSPENDED, handler);
199     goto done;
200   }
201
202   ret = rgw_process_authenticated(handler, op, req, s);
203   if (ret < 0) {
204     abort_early(s, op, ret, handler);
205     goto done;
206   }
207 done:
208   try {
209     client_io->complete_request();
210   } catch (rgw::io::Exception& e) {
211     dout(0) << "ERROR: client_io->complete_request() returned "
212             << e.what() << dendl;
213   }
214
215   if (should_log) {
216     rgw_log_op(store, rest, s, (op ? op->name() : "unknown"), olog);
217   }
218
219   int http_ret = s->err.http_ret;
220   int op_ret = 0;
221   if (op) {
222     op_ret = op->get_ret();
223   }
224
225   req->log_format(s, "op status=%d", op_ret);
226   req->log_format(s, "http status=%d", http_ret);
227
228   if (handler)
229     handler->put_op(op);
230   rest->put_handler(handler);
231
232   dout(1) << "====== req done req=" << hex << req << dec
233           << " op status=" << op_ret
234           << " http_status=" << http_ret
235           << " ======"
236           << dendl;
237
238   return (ret < 0 ? ret : s->err.ret);
239 } /* process_request */