From 4867148531e19b80e8c00a97ddecb92989b2a818 Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Fri, 2 Oct 2015 12:50:47 -0400 Subject: [PATCH] librgw: wire up request initializers There's some tricky overloading induced by multiple inheritance, also this design makes repeatedly shared handles in current framework very visible. The most important non-boilerplate is in descendant RGWRequest initializers (rgw_lib.h), which need to set up req_state appropriately for their action/op. Signed-off-by: Matt Benjamin --- src/rgw/librgw.cc | 35 ++++++++++++++++++++--------------- src/rgw/rgw_file.h | 33 +++++++++++++++++++++++++++++---- src/rgw/rgw_lib.h | 30 +++++++++++++++++++++++++++++- src/rgw/rgw_rest_lib.cc | 3 +++ src/rgw/rgw_rest_lib.h | 2 ++ 5 files changed, 83 insertions(+), 20 deletions(-) diff --git a/src/rgw/librgw.cc b/src/rgw/librgw.cc index 074360cda1be7..f0cb7b01a1145 100644 --- a/src/rgw/librgw.cc +++ b/src/rgw/librgw.cc @@ -377,13 +377,13 @@ int process_request(RGWRados* store, RGWREST* rest, RGWRequest* base_req, RGWLibIO* io, OpsLogSocket* olog) { int ret = 0; + bool should_log = true; // XXX RGWLibRequest *req = static_cast(base_req); + RGWOp *op = reinterpret_cast(req); // req->op is already correct io->init(req->cct); - req->log_init(); - dout(1) << "====== " << __func__ << " starting new request req=" << hex << req << dec << " ======" << dendl; @@ -392,23 +392,27 @@ int process_request(RGWRados* store, RGWREST* rest, RGWRequest* base_req, RGWEnv& rgw_env = io->get_env(); - struct req_state rstate(req->cct, &rgw_env); + struct req_state rstate(req->cct, &rgw_env); // XXX many machines on ix struct req_state *s = &rstate; - req->init_state(s); - - RGWObjectCtx rados_ctx(store, s); - s->obj_ctx = &rados_ctx; - - s->req_id = store->unique_id(req->id); - s->trans_id = store->unique_trans_id(req->id); + RGWObjectCtx rados_ctx(store, s); // XXX holds std::map - req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str()); - - /* XXX programmer is enforcing (for now) */ - RGWOp *op = reinterpret_cast(req); // req->op is already correct + /* initialize req--runs process_request boilerplate, then the local + * equivalent of *REST*::init_from_header(...) */ + ret = req->init(rgw_env, &rados_ctx, io, s); + if (ret < 0) { + dout(10) << "failed to initialize request" << dendl; + abort_early(s, op, ret, nullptr); + goto done; + } - bool should_log = true; + /* req is-a RGWOp, currently initialized separately */ + ret = req->op_init(); + if (ret < 0) { + dout(10) << "failed to initialize RGWOp" << dendl; + abort_early(s, op, ret, nullptr); + goto done; + } // just checks the HTTP header, and that the user can access the gateway // may be able to skip this after MOUNT (revalidate the user info) @@ -425,6 +429,7 @@ int process_request(RGWRados* store, RGWREST* rest, RGWRequest* base_req, abort_early(s, op, -ERR_USER_SUSPENDED, nullptr); goto done; } + req->log(s, "reading permissions"); ret = req->read_permissions(op); if (ret < 0) { diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index 850846ee66195..e19fe29f41b2a 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -24,13 +24,38 @@ public: RGWListBucketsRequest(CephContext* _cct, char *_user_id, rgw_readdir_cb _rcb, void* _cb_arg, uint64_t* _offset) : RGWLibRequest(_cct), user_id(_user_id), offset(_offset), cb_arg(_cb_arg), - rcb(_rcb) { - dialect_handler = this; // op->dialect_handler = handler - op = this; // req->op = op - } + rcb(_rcb) {} virtual bool only_bucket() { return false; } + virtual int op_init() { + // assign store, s, and dialect_handler + RGWObjectCtx* rados_ctx + = static_cast(get_state()->obj_ctx); + // framework promises to call op_init after parent init + assert(rados_ctx); + RGWOp::init(rados_ctx->store, get_state(), this); + op = this; // assign self as op: REQUIRED + return 0; + } + + virtual int header_init() { + + struct req_state* s = get_state(); + s->info.method = "GET"; + + /* XXX derp derp derp */ + s->relative_uri = "/"; + s->info.request_uri = "/"; // XXX + s->info.effective_uri = "/"; + s->info.request_params = ""; +#warning fix host and domain request params (used nfsv4 client?) + s->info.host = "10.1.1.220"; + s->info.domain = ""; /* XXX fixme */ + + return 0; + } + int operator()(const std::string& name, const std::string& marker) { rcb(name.c_str(), cb_arg, (*offset)++); return 0; diff --git a/src/rgw/rgw_lib.h b/src/rgw/rgw_lib.h index a8fb517d41c44..968bc53d1f762 100644 --- a/src/rgw/rgw_lib.h +++ b/src/rgw/rgw_lib.h @@ -124,12 +124,40 @@ public: CephContext* cct; /* unambiguiously return req_state */ - struct req_state* get_state() { return this->RGWRequest::s; } + inline struct req_state* get_state() { return this->RGWRequest::s; } RGWLibRequest(CephContext* _cct) : RGWRequest(0), cct(_cct) {} + /* descendant equivalent of *REST*::init_from_header(...): + * prepare request for execute()--should mean, fixup URI-alikes + * and any other expected stat vars in local req_state, for + * now */ + virtual int header_init() = 0; + + /* descendant initializer responsible to call RGWOp::init()--which + * descendants are required to inherit */ + virtual int op_init() = 0; + + int init(const RGWEnv& rgw_env, RGWObjectCtx* rados_ctx, + RGWLibIO* io, struct req_state* _s) { + + RGWRequest::init_state(_s); + RGWHandler::init(rados_ctx->store, _s, io); + + log_init(); + + get_state()->obj_ctx = rados_ctx; + get_state()->req_id = store->unique_id(id); + get_state()->trans_id = store->unique_trans_id(id); + + log_format(_s, "initializing for trans_id = %s", + get_state()->trans_id.c_str()); + + return header_init(); + } + virtual bool only_bucket() = 0; virtual int read_permissions(RGWOp *op); diff --git a/src/rgw/rgw_rest_lib.cc b/src/rgw/rgw_rest_lib.cc index edcd6b5208007..531720dfc1f59 100644 --- a/src/rgw/rgw_rest_lib.cc +++ b/src/rgw/rgw_rest_lib.cc @@ -9,6 +9,7 @@ /* XXX going away ! */ +#warning kill me /* static */ int RGWHandler_Lib::init_from_header(struct req_state *s) { @@ -18,6 +19,8 @@ int RGWHandler_Lib::init_from_header(struct req_state *s) const char *req_name = s->relative_uri.c_str(); const char *p; + /* skip request_params parsing, rgw_file should not be + * seeing any */ if (*req_name == '?') { p = req_name; } else { diff --git a/src/rgw/rgw_rest_lib.h b/src/rgw/rgw_rest_lib.h index 1c5767011c723..6ea5e7278cf32 100644 --- a/src/rgw/rgw_rest_lib.h +++ b/src/rgw/rgw_rest_lib.h @@ -9,6 +9,8 @@ #include "rgw_common.h" #include "rgw_lib.h" +#warning move to rgw_file...I think...there is no REST here + /* RGWOps */ -- 2.39.5