From 02abdca1f673c1569762b83b0992e1e1e1ca5bc3 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 15 Jul 2011 12:54:32 -0700 Subject: [PATCH] rgw: multiple fixes, prepare main loop for multithreading --- src/rgw/rgw_common.h | 9 +---- src/rgw/rgw_main.cc | 90 ++++++++++++++++++++++++++------------------ src/rgw/rgw_op.cc | 12 ++++-- src/rgw/rgw_op.h | 2 +- src/rgw/rgw_rest.cc | 15 ++++---- src/rgw/rgw_rest.h | 4 +- 6 files changed, 72 insertions(+), 60 deletions(-) diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index ec62487d5eb..2f3ec4bc147 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -199,13 +199,6 @@ enum http_op { OP_UNKNOWN, }; -struct fcgx_state { - FCGX_ParamArray envp; - FCGX_Stream *in; - FCGX_Stream *out; - FCGX_Stream *err; -}; - class RGWAccessControlPolicy; struct RGWAccessKey { @@ -389,7 +382,7 @@ public: /** Store all the state necessary to complete and respond to an HTTP request*/ struct req_state { - struct fcgx_state *fcgx; + FCGX_Request *fcgx; http_op op; bool content_started; int format; diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index d6ab2be6235..3b8372dfd35 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -51,45 +51,18 @@ static void godown_alarm(int signum) _exit(0); } -/* - * start up the RADOS connection and then handle HTTP messages as they come in - */ -int main(int argc, const char **argv) +static int rgw_req_handler() { - struct fcgx_state fcgx; - - curl_global_init(CURL_GLOBAL_ALL); - - // dout() messages will be sent to stderr, but FCGX wants messages on stdout - // Redirect stderr to stdout. - TEMP_FAILURE_RETRY(close(STDERR_FILENO)); - if (TEMP_FAILURE_RETRY(dup2(STDOUT_FILENO, STDERR_FILENO) < 0)) { - int err = errno; - cout << "failed to redirect stderr to stdout: " << cpp_strerror(err) - << std::endl; - return ENOSYS; - } - - vector args; - argv_to_vec(argc, argv, args); - env_to_vec(args); - global_init(args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0); - common_init_finish(g_ceph_context); - - RGWStoreManager store_manager; - - if (!store_manager.init("rados", g_ceph_context)) { - derr << "Couldn't init storage provider (RADOS)" << dendl; - return EIO; - } - - sighandler_usr1 = signal(SIGUSR1, godown_handler); - sighandler_alrm = signal(SIGALRM, godown_alarm); - + FCGX_Request fcgx; RGWRESTMgr rest; - while (FCGX_Accept(&fcgx.in, &fcgx.out, &fcgx.err, &fcgx.envp) >= 0) - { + FCGX_InitRequest(&fcgx, 0, 0); + + while (1) { + int ret = FCGX_Accept_r(&fcgx); + if (ret < 0) + return ret; + rgw_env.reinit(fcgx.envp); struct req_state *s = new req_state; @@ -97,7 +70,6 @@ int main(int argc, const char **argv) RGWOp *op = NULL; int init_error = 0; RGWHandler *handler = rest.get_handler(s, &fcgx, &init_error); - int ret; if (init_error != 0) { abort_early(s, init_error); @@ -140,7 +112,51 @@ done: handler->put_op(op); delete s; + FCGX_Finish_r(&fcgx); } + + return 0; +} + +/* + * start up the RADOS connection and then handle HTTP messages as they come in + */ +int main(int argc, const char **argv) +{ + curl_global_init(CURL_GLOBAL_ALL); + + // dout() messages will be sent to stderr, but FCGX wants messages on stdout + // Redirect stderr to stdout. + TEMP_FAILURE_RETRY(close(STDERR_FILENO)); + if (TEMP_FAILURE_RETRY(dup2(STDOUT_FILENO, STDERR_FILENO) < 0)) { + int err = errno; + cout << "failed to redirect stderr to stdout: " << cpp_strerror(err) + << std::endl; + return ENOSYS; + } + + vector args; + argv_to_vec(argc, argv, args); + env_to_vec(args); + global_init(args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0); + common_init_finish(g_ceph_context); + + sighandler_usr1 = signal(SIGUSR1, godown_handler); + sighandler_alrm = signal(SIGALRM, godown_alarm); + + FCGX_Init(); + + RGWStoreManager store_manager; + + if (!store_manager.init("rados", g_ceph_context)) { + derr << "Couldn't init storage provider (RADOS)" << dendl; + return EIO; + } + + int ret = rgw_req_handler(); + if (ret < 0) + return -ret; + return 0; } diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 2936561d46f..6471883f041 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -452,8 +452,13 @@ void RGWDeleteBucket::execute() { ret = -EINVAL; - if (s->bucket) - ret = rgw_remove_bucket(s->user.user_id, s->bucket_str, true); + if (s->bucket) { + ret = rgwstore->delete_bucket(s->user.user_id, s->bucket_str); + + if (ret == 0) { + ret = rgw_remove_bucket(s->user.user_id, s->bucket_str, false); + } + } send_response(); } @@ -1378,7 +1383,7 @@ done: send_response(); } -int RGWHandler::init(struct req_state *_s, struct fcgx_state *fcgx) +int RGWHandler::init(struct req_state *_s, FCGX_Request *fcgx) { s = _s; @@ -1391,7 +1396,6 @@ int RGWHandler::init(struct req_state *_s, struct fcgx_state *fcgx) RGW_LOG(20) << p << dendl; } } - s->fcgx = fcgx; return 0; } diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index af5d23a312d..97abd907eb6 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -554,7 +554,7 @@ protected: public: RGWHandler() {} virtual ~RGWHandler() {} - virtual int init(struct req_state *_s, struct fcgx_state *fcgx); + virtual int init(struct req_state *_s, FCGX_Request *fcgx); virtual RGWOp *get_op() = 0; virtual void put_op(RGWOp *op) = 0; diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc index 0311c4869f2..ae817af1196 100644 --- a/src/rgw/rgw_rest.cc +++ b/src/rgw/rgw_rest.cc @@ -664,12 +664,9 @@ static int validate_object_name(const char *object) return 0; } -int RGWHandler_REST::init(struct req_state *s, struct fcgx_state *fcgx) +int RGWHandler_REST::preprocess(struct req_state *s, FCGX_Request *fcgx) { - int ret = RGWHandler::init(s, fcgx); - if (ret < 0) - return ret; - + s->fcgx = fcgx; s->path_name = rgw_env.get("SCRIPT_NAME"); s->path_name_url = rgw_env.get("REQUEST_URI"); int pos = s->path_name_url.find('?'); @@ -698,7 +695,7 @@ int RGWHandler_REST::init(struct req_state *s, struct fcgx_state *fcgx) s->op = OP_UNKNOWN; init_entities_from_header(s); - ret = validate_bucket_name(s->bucket_str.c_str()); + int ret = validate_bucket_name(s->bucket_str.c_str()); if (ret) return ret; ret = validate_object_name(s->object_str.c_str()); @@ -795,11 +792,13 @@ RGWRESTMgr::~RGWRESTMgr() delete m_s3_handler; } -RGWHandler *RGWRESTMgr::get_handler(struct req_state *s, struct fcgx_state *fcgx, +RGWHandler *RGWRESTMgr::get_handler(struct req_state *s, FCGX_Request *fcgx, int *init_error) { RGWHandler *handler; + *init_error = RGWHandler_REST::preprocess(s, fcgx); + if (s->prot_flags & RGW_REST_OPENSTACK) handler = m_os_handler; else if (s->prot_flags & RGW_REST_OPENSTACK_AUTH) @@ -807,7 +806,7 @@ RGWHandler *RGWRESTMgr::get_handler(struct req_state *s, struct fcgx_state *fcgx else handler = m_s3_handler; - *init_error = handler->init(s, fcgx); + handler->init(s, fcgx); return handler; } diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h index dd64d3cdb02..0355dbdb5b3 100644 --- a/src/rgw/rgw_rest.h +++ b/src/rgw/rgw_rest.h @@ -143,7 +143,7 @@ public: RGWOp *get_op(); void put_op(RGWOp *op); - int init(struct req_state *s, struct fcgx_state *fcgx); + static int preprocess(struct req_state *s, FCGX_Request *fcgx); virtual bool authorize() = 0; }; @@ -159,7 +159,7 @@ class RGWRESTMgr { public: RGWRESTMgr(); ~RGWRESTMgr(); - RGWHandler *get_handler(struct req_state *s, struct fcgx_state *fcgx, + RGWHandler *get_handler(struct req_state *s, FCGX_Request *fcgx, int *init_error); };