]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_process.cc
update sources to v12.2.4
[ceph.git] / ceph / src / rgw / rgw_process.cc
CommitLineData
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 "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
18void 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
36int 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
112int 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{
3a9019d9 120 int ret = client_io->init(g_ceph_context);
7c673cae
FG
121
122 req->log_init();
123
124 dout(1) << "====== starting new request req=" << hex << req << dec
125 << " =====" << dendl;
126 perfcounter->inc(l_rgw_req);
127
128 RGWEnv& rgw_env = client_io->get_env();
129
130 RGWUserInfo userinfo;
131
132 struct req_state rstate(g_ceph_context, &rgw_env, &userinfo);
133 struct req_state *s = &rstate;
134
135 RGWObjectCtx rados_ctx(store, s);
136 s->obj_ctx = &rados_ctx;
137
3a9019d9
FG
138 if (ret < 0) {
139 s->cio = client_io;
140 abort_early(s, nullptr, ret, nullptr);
141 return ret;
142 }
143
7c673cae
FG
144 s->req_id = store->unique_id(req->id);
145 s->trans_id = store->unique_trans_id(req->id);
146 s->host_id = store->host_id;
147
148 req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str());
149
3a9019d9 150 RGWOp* op = nullptr;
7c673cae
FG
151 int init_error = 0;
152 bool should_log = false;
153 RGWRESTMgr *mgr;
154 RGWHandler_REST *handler = rest->get_handler(store, s,
155 auth_registry,
156 frontend_prefix,
157 client_io, &mgr, &init_error);
158 if (init_error != 0) {
3a9019d9 159 abort_early(s, nullptr, init_error, nullptr);
7c673cae
FG
160 goto done;
161 }
162 dout(10) << "handler=" << typeid(*handler).name() << dendl;
163
164 should_log = mgr->get_logging();
165
166 req->log_format(s, "getting op %d", s->op);
167 op = handler->get_op(store);
168 if (!op) {
169 abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED, handler);
170 goto done;
171 }
172
173 req->op = op;
174 dout(10) << "op=" << typeid(*op).name() << dendl;
175
176 s->op_type = op->get_type();
177
178 req->log(s, "verifying requester");
179 ret = op->verify_requester(auth_registry);
180 if (ret < 0) {
181 dout(10) << "failed to authorize request" << dendl;
182 abort_early(s, NULL, ret, handler);
183 goto done;
184 }
185
186 /* FIXME: remove this after switching all handlers to the new authentication
187 * infrastructure. */
188 if (nullptr == s->auth.identity) {
189 s->auth.identity = rgw::auth::transform_old_authinfo(s);
190 }
191
192 req->log(s, "normalizing buckets and tenants");
193 ret = handler->postauth_init();
194 if (ret < 0) {
195 dout(10) << "failed to run post-auth init" << dendl;
196 abort_early(s, op, ret, handler);
197 goto done;
198 }
199
200 if (s->user->suspended) {
201 dout(10) << "user is suspended, uid=" << s->user->user_id << dendl;
202 abort_early(s, op, -ERR_USER_SUSPENDED, handler);
203 goto done;
204 }
205
206 ret = rgw_process_authenticated(handler, op, req, s);
207 if (ret < 0) {
208 abort_early(s, op, ret, handler);
209 goto done;
210 }
211done:
212 try {
213 client_io->complete_request();
214 } catch (rgw::io::Exception& e) {
215 dout(0) << "ERROR: client_io->complete_request() returned "
216 << e.what() << dendl;
217 }
218
219 if (should_log) {
220 rgw_log_op(store, rest, s, (op ? op->name() : "unknown"), olog);
221 }
222
223 int http_ret = s->err.http_ret;
224 int op_ret = 0;
225 if (op) {
226 op_ret = op->get_ret();
227 }
228
229 req->log_format(s, "op status=%d", op_ret);
230 req->log_format(s, "http status=%d", http_ret);
231
232 if (handler)
233 handler->put_op(op);
234 rest->put_handler(handler);
235
236 dout(1) << "====== req done req=" << hex << req << dec
237 << " op status=" << op_ret
238 << " http_status=" << http_ret
239 << " ======"
240 << dendl;
241
242 return (ret < 0 ? ret : s->err.ret);
243} /* process_request */