rgw: multiple fixes, prepare main loop for multithreading

This commit is contained in:
Yehuda Sadeh 2011-07-15 12:54:32 -07:00
parent 5d606c22bd
commit 02abdca1f6
6 changed files with 72 additions and 60 deletions

View File

@ -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;

View File

@ -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<const char*> 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<const char*> 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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
};