#include "rgw_os_lib.h"
#include "rgw_auth_s3.h"
#include "rgw_lib.h"
+#include "rgw_lib_frontend.h"
#include <errno.h>
#include <sstream>
#define dout_subsys ceph_subsys_rgw
-using std::string;
+bool global_stop = false;
-static std::mutex librgw_mtx;
+namespace rgw {
-bool global_stop = false;
+ using std::string;
-RGWLib librgw; /* XXX initialize? */
+ static std::mutex librgw_mtx;
-class C_InitTimeout : public Context {
-public:
- C_InitTimeout() {}
- void finish(int r) {
- derr << "Initialization timeout, failed to initialize" << dendl;
- exit(1);
- }
-};
+ RGWLib librgw; /* XXX initialize? */
-void RGWLibProcess::checkpoint()
-{
+ class C_InitTimeout : public Context {
+ public:
+ C_InitTimeout() {}
+ void finish(int r) {
+ derr << "Initialization timeout, failed to initialize" << dendl;
+ exit(1);
+ }
+ };
+
+ void RGWLibProcess::checkpoint()
+ {
m_tp.drain(&req_wq);
-}
+ }
-void RGWLibProcess::run()
-{
- /* XXX */
-}
+ void RGWLibProcess::run()
+ {
+ /* XXX */
+ }
-void RGWLibProcess::handle_request(RGWRequest* r)
-{
- /*
- * invariant: valid requests are derived from RGWLibRequst
- */
- RGWLibRequest* req = static_cast<RGWLibRequest*>(r);
+ void RGWLibProcess::handle_request(RGWRequest* r)
+ {
+ /*
+ * invariant: valid requests are derived from RGWLibRequst
+ */
+ RGWLibRequest* req = static_cast<RGWLibRequest*>(r);
- // XXX move RGWLibIO and timing setup into process_request
+ // XXX move RGWLibIO and timing setup into process_request
#if 0 /* XXX */
- utime_t tm = ceph_clock_now(NULL);
+ utime_t tm = ceph_clock_now(NULL);
#endif
- RGWLibIO io_ctx;
+ RGWLibIO io_ctx;
- int ret = process_request(req, &io_ctx);
- if (ret < 0) {
- /* we don't really care about return code */
- dout(20) << "process_request() returned " << ret << dendl;
+ int ret = process_request(req, &io_ctx);
+ if (ret < 0) {
+ /* we don't really care about return code */
+ dout(20) << "process_request() returned " << ret << dendl;
- }
- delete req;
-} /* handle_request */
+ }
+ delete req;
+ } /* handle_request */
-int RGWLibProcess::process_request(RGWLibRequest* req)
-{
- // XXX move RGWLibIO and timing setup into process_request
+ int RGWLibProcess::process_request(RGWLibRequest* req)
+ {
+ // XXX move RGWLibIO and timing setup into process_request
#if 0 /* XXX */
- utime_t tm = ceph_clock_now(NULL);
+ utime_t tm = ceph_clock_now(NULL);
#endif
- RGWLibIO io_ctx;
-
- int ret = process_request(req, &io_ctx);
- if (ret < 0) {
- /* we don't really care about return code */
- dout(20) << "process_request() returned " << ret << dendl;
- }
- return ret;
-} /* process_request */
-
-static inline void abort_req(struct req_state *s, RGWOp *op, int err_no)
-{
- if (!s)
- return;
-
- /* XXX the dump_errno and dump_bucket_from_state behaviors in
- * the abort_early (rgw_rest.cc) might be valuable, but aren't
- * safe to call presently as they return HTTP data */
+ RGWLibIO io_ctx;
- perfcounter->inc(l_rgw_failed_req);
-} /* abort_req */
+ int ret = process_request(req, &io_ctx);
+ if (ret < 0) {
+ /* we don't really care about return code */
+ dout(20) << "process_request() returned " << ret << dendl;
+ }
+ return ret;
+ } /* process_request */
+
+ static inline void abort_req(struct req_state *s, RGWOp *op, int err_no)
+ {
+ if (!s)
+ return;
+
+ /* XXX the dump_errno and dump_bucket_from_state behaviors in
+ * the abort_early (rgw_rest.cc) might be valuable, but aren't
+ * safe to call presently as they return HTTP data */
+
+ perfcounter->inc(l_rgw_failed_req);
+ } /* abort_req */
+
+ int RGWLibProcess::process_request(RGWLibRequest* req, RGWLibIO* io)
+ {
+ int ret = 0;
+ bool should_log = true; // XXX
+
+ dout(1) << "====== " << __func__
+ << " starting new request req=" << hex << req << dec
+ << " ======" << dendl;
+
+ /*
+ * invariant: valid requests are derived from RGWOp--well-formed
+ * requests should have assigned RGWRequest::op in their descendant
+ * constructor--if not, the compiler can find it, at the cost of
+ * a runtime check
+ */
+ RGWOp *op = (req->op) ? req->op : dynamic_cast<RGWOp*>(req);
+ if (! op) {
+ dout(1) << "failed to derive cognate RGWOp (invalid op?)" << dendl;
+ return -EINVAL;
+ }
-int RGWLibProcess::process_request(RGWLibRequest* req, RGWLibIO* io)
-{
- int ret = 0;
- bool should_log = true; // XXX
-
- dout(1) << "====== " << __func__
- << " starting new request req=" << hex << req << dec
- << " ======" << dendl;
-
- /*
- * invariant: valid requests are derived from RGWOp--well-formed
- * requests should have assigned RGWRequest::op in their descendant
- * constructor--if not, the compiler can find it, at the cost of
- * a runtime check
- */
- RGWOp *op = (req->op) ? req->op : dynamic_cast<RGWOp*>(req);
- if (! op) {
- dout(1) << "failed to derive cognate RGWOp (invalid op?)" << dendl;
- return -EINVAL;
- }
+ io->init(req->cct);
- io->init(req->cct);
+ perfcounter->inc(l_rgw_req);
- perfcounter->inc(l_rgw_req);
+ RGWEnv& rgw_env = io->get_env();
- RGWEnv& rgw_env = io->get_env();
+ /* XXX
+ * until major refactoring of req_state and req_info, we need
+ * to build their RGWEnv boilerplate from the RGWLibRequest,
+ * pre-staging any strings (HTTP_HOST) that provoke a crash when
+ * not found
+ */
- /* XXX
- * until major refactoring of req_state and req_info, we need
- * to build their RGWEnv boilerplate from the RGWLibRequest,
- * pre-staging any strings (HTTP_HOST) that provoke a crash when
- * not found
- */
+ /* XXX for now, use ""; could be a legit hostname, or, in future,
+ * perhaps a tenant (Yehuda) */
+ rgw_env.set("HTTP_HOST", "");
- /* XXX for now, use ""; could be a legit hostname, or, in future,
- * perhaps a tenant (Yehuda) */
- rgw_env.set("HTTP_HOST", "");
+ /* XXX and -then- bloat up req_state with string copies from it */
+ struct req_state rstate(req->cct, &rgw_env, req->get_user());
+ struct req_state *s = &rstate;
- /* XXX and -then- bloat up req_state with string copies from it */
- struct req_state rstate(req->cct, &rgw_env, req->get_user());
- struct req_state *s = &rstate;
+ // XXX fix this
+ s->cio = io;
- // XXX fix this
- s->cio = io;
+ RGWObjectCtx rados_ctx(store, s); // XXX holds std::map
- RGWObjectCtx rados_ctx(store, s); // XXX holds std::map
+ /* XXX and -then- stash req_state pointers everywhere they are needed */
+ ret = req->init(rgw_env, &rados_ctx, io, s);
+ if (ret < 0) {
+ dout(10) << "failed to initialize request" << dendl;
+ abort_req(s, op, ret);
+ goto done;
+ }
- /* XXX and -then- stash req_state pointers everywhere they are needed */
- ret = req->init(rgw_env, &rados_ctx, io, s);
- if (ret < 0) {
- dout(10) << "failed to initialize request" << dendl;
- abort_req(s, op, ret);
- goto done;
- }
+ /* req is-a RGWOp, currently initialized separately */
+ ret = req->op_init();
+ if (ret < 0) {
+ dout(10) << "failed to initialize RGWOp" << dendl;
+ abort_req(s, op, ret);
+ goto done;
+ }
- /* req is-a RGWOp, currently initialized separately */
- ret = req->op_init();
- if (ret < 0) {
- dout(10) << "failed to initialize RGWOp" << dendl;
- abort_req(s, op, ret);
- goto done;
- }
+ /* XXX authorize does less here then in the REST path, e.g.,
+ * the user's info is cached, but still incomplete */
+ req->log(s, "authorizing");
+ ret = req->authorize();
+ if (ret < 0) {
+ dout(10) << "failed to authorize request" << dendl;
+ abort_req(s, op, ret);
+ goto done;
+ }
- /* XXX authorize does less here then in the REST path, e.g.,
- * the user's info is cached, but still incomplete */
- req->log(s, "authorizing");
- ret = req->authorize();
- if (ret < 0) {
- dout(10) << "failed to authorize request" << dendl;
- abort_req(s, op, ret);
- goto done;
- }
+ req->log(s, "reading op permissions");
+ ret = req->read_permissions(op);
+ if (ret < 0) {
+ abort_req(s, op, ret);
+ goto done;
+ }
- req->log(s, "reading op permissions");
- ret = req->read_permissions(op);
- if (ret < 0) {
- abort_req(s, op, ret);
- goto done;
- }
+ req->log(s, "init op");
+ ret = op->init_processing();
+ if (ret < 0) {
+ abort_req(s, op, ret);
+ goto done;
+ }
- req->log(s, "init op");
- ret = op->init_processing();
- if (ret < 0) {
- abort_req(s, op, ret);
- goto done;
- }
+ req->log(s, "verifying op mask");
+ ret = op->verify_op_mask();
+ if (ret < 0) {
+ abort_req(s, op, ret);
+ goto done;
+ }
- req->log(s, "verifying op mask");
- ret = op->verify_op_mask();
- if (ret < 0) {
- abort_req(s, op, ret);
- goto done;
- }
+ req->log(s, "verifying op permissions");
+ ret = op->verify_permission();
+ if (ret < 0) {
+ if (s->system_request) {
+ dout(2) << "overriding permissions due to system operation" << dendl;
+ } else {
+ abort_req(s, op, ret);
+ goto done;
+ }
+ }
- req->log(s, "verifying op permissions");
- ret = op->verify_permission();
- if (ret < 0) {
- if (s->system_request) {
- dout(2) << "overriding permissions due to system operation" << dendl;
- } else {
+ req->log(s, "verifying op params");
+ ret = op->verify_params();
+ if (ret < 0) {
abort_req(s, op, ret);
goto done;
}
- }
- req->log(s, "verifying op params");
- ret = op->verify_params();
- if (ret < 0) {
- abort_req(s, op, ret);
- goto done;
- }
-
- req->log(s, "executing");
- op->pre_exec();
- op->execute();
- op->complete();
+ req->log(s, "executing");
+ op->pre_exec();
+ op->execute();
+ op->complete();
-done:
- int r = io->complete_request();
- if (r < 0) {
- dout(0) << "ERROR: io->complete_request() returned " << r << dendl;
- }
- if (should_log) {
- rgw_log_op(store, s, (op ? op->name() : "unknown"), olog);
- }
+ done:
+ int r = io->complete_request();
+ if (r < 0) {
+ dout(0) << "ERROR: io->complete_request() returned " << r << dendl;
+ }
+ if (should_log) {
+ rgw_log_op(store, s, (op ? op->name() : "unknown"), olog);
+ }
- int http_ret = s->err.http_ret;
+ int http_ret = s->err.http_ret;
- req->log_format(s, "http status=%d", http_ret);
+ req->log_format(s, "http status=%d", http_ret);
- dout(1) << "====== " << __func__
- << " req done req=" << hex << req << dec << " http_status="
- << http_ret
- << " ======" << dendl;
+ dout(1) << "====== " << __func__
+ << " req done req=" << hex << req << dec << " http_status="
+ << http_ret
+ << " ======" << dendl;
- return (ret < 0 ? ret : s->err.ret);
-} /* process_request */
+ return (ret < 0 ? ret : s->err.ret);
+ } /* process_request */
-int RGWLibProcess::start_request(RGWLibContinuedReq* req)
-{
+ int RGWLibProcess::start_request(RGWLibContinuedReq* req)
+ {
- dout(1) << "====== " << __func__
- << " starting new continued request req=" << hex << req << dec
- << " ======" << dendl;
-
- /*
- * invariant: valid requests are derived from RGWOp--well-formed
- * requests should have assigned RGWRequest::op in their descendant
- * constructor--if not, the compiler can find it, at the cost of
- * a runtime check
- */
- RGWOp *op = (req->op) ? req->op : dynamic_cast<RGWOp*>(req);
- if (! op) {
- dout(1) << "failed to derive cognate RGWOp (invalid op?)" << dendl;
- return -EINVAL;
- }
+ dout(1) << "====== " << __func__
+ << " starting new continued request req=" << hex << req << dec
+ << " ======" << dendl;
- struct req_state* s = req->get_state();
+ /*
+ * invariant: valid requests are derived from RGWOp--well-formed
+ * requests should have assigned RGWRequest::op in their descendant
+ * constructor--if not, the compiler can find it, at the cost of
+ * a runtime check
+ */
+ RGWOp *op = (req->op) ? req->op : dynamic_cast<RGWOp*>(req);
+ if (! op) {
+ dout(1) << "failed to derive cognate RGWOp (invalid op?)" << dendl;
+ return -EINVAL;
+ }
- /* req is-a RGWOp, currently initialized separately */
- int ret = req->op_init();
- if (ret < 0) {
- dout(10) << "failed to initialize RGWOp" << dendl;
- abort_req(s, op, ret);
- goto done;
- }
+ struct req_state* s = req->get_state();
- /* XXX authorize does less here then in the REST path, e.g.,
- * the user's info is cached, but still incomplete */
- req->log(s, "authorizing");
- ret = req->authorize();
- if (ret < 0) {
- dout(10) << "failed to authorize request" << dendl;
- abort_req(s, op, ret);
- goto done;
- }
+ /* req is-a RGWOp, currently initialized separately */
+ int ret = req->op_init();
+ if (ret < 0) {
+ dout(10) << "failed to initialize RGWOp" << dendl;
+ abort_req(s, op, ret);
+ goto done;
+ }
- req->log(s, "reading op permissions");
- ret = req->read_permissions(op);
- if (ret < 0) {
- abort_req(s, op, ret);
- goto done;
- }
+ /* XXX authorize does less here then in the REST path, e.g.,
+ * the user's info is cached, but still incomplete */
+ req->log(s, "authorizing");
+ ret = req->authorize();
+ if (ret < 0) {
+ dout(10) << "failed to authorize request" << dendl;
+ abort_req(s, op, ret);
+ goto done;
+ }
- req->log(s, "init op");
- ret = op->init_processing();
- if (ret < 0) {
- abort_req(s, op, ret);
- goto done;
- }
+ req->log(s, "reading op permissions");
+ ret = req->read_permissions(op);
+ if (ret < 0) {
+ abort_req(s, op, ret);
+ goto done;
+ }
- req->log(s, "verifying op mask");
- ret = op->verify_op_mask();
- if (ret < 0) {
- abort_req(s, op, ret);
- goto done;
- }
+ req->log(s, "init op");
+ ret = op->init_processing();
+ if (ret < 0) {
+ abort_req(s, op, ret);
+ goto done;
+ }
- req->log(s, "verifying op permissions");
- ret = op->verify_permission();
- if (ret < 0) {
- if (s->system_request) {
- dout(2) << "overriding permissions due to system operation" << dendl;
- } else {
+ req->log(s, "verifying op mask");
+ ret = op->verify_op_mask();
+ if (ret < 0) {
abort_req(s, op, ret);
goto done;
}
- }
- req->log(s, "verifying op params");
- ret = op->verify_params();
- if (ret < 0) {
- abort_req(s, op, ret);
- goto done;
- }
+ req->log(s, "verifying op permissions");
+ ret = op->verify_permission();
+ if (ret < 0) {
+ if (s->system_request) {
+ dout(2) << "overriding permissions due to system operation" << dendl;
+ } else {
+ abort_req(s, op, ret);
+ goto done;
+ }
+ }
- op->pre_exec();
- req->exec_start();
+ req->log(s, "verifying op params");
+ ret = op->verify_params();
+ if (ret < 0) {
+ abort_req(s, op, ret);
+ goto done;
+ }
-done:
- return (ret < 0 ? ret : s->err.ret);
-}
+ op->pre_exec();
+ req->exec_start();
-int RGWLibProcess::finish_request(RGWLibContinuedReq* req)
-{
- RGWOp *op = (req->op) ? req->op : dynamic_cast<RGWOp*>(req);
- if (! op) {
- dout(1) << "failed to derive cognate RGWOp (invalid op?)" << dendl;
- return -EINVAL;
+ done:
+ return (ret < 0 ? ret : s->err.ret);
}
- int ret = req->exec_finish();
- int op_ret = op->get_ret();
-
- dout(1) << "====== " << __func__
- << " finishing continued request req=" << hex << req << dec
- << " op status=" << op_ret
- << " ======" << dendl;
-
- return ret;
-}
-
-int RGWLibFrontend::init()
-{
- pprocess = new RGWLibProcess(g_ceph_context, &env,
- g_conf->rgw_thread_pool_size, conf);
- return 0;
-}
-
-int RGWLib::init()
-{
- vector<const char*> args;
- return init(args);
-}
+ int RGWLibProcess::finish_request(RGWLibContinuedReq* req)
+ {
+ RGWOp *op = (req->op) ? req->op : dynamic_cast<RGWOp*>(req);
+ if (! op) {
+ dout(1) << "failed to derive cognate RGWOp (invalid op?)" << dendl;
+ return -EINVAL;
+ }
-int RGWLib::init(vector<const char*>& args)
-{
- int r = 0;
+ int ret = req->exec_finish();
+ int op_ret = op->get_ret();
- /* alternative default for module */
- vector<const char *> def_args;
- def_args.push_back("--debug-rgw=1/5");
- def_args.push_back("--keyring=$rgw_data/keyring");
- def_args.push_back("--log-file=/var/log/radosgw/$cluster-$name.log");
+ dout(1) << "====== " << __func__
+ << " finishing continued request req=" << hex << req << dec
+ << " op status=" << op_ret
+ << " ======" << dendl;
- global_init(&def_args, args,
- CEPH_ENTITY_TYPE_CLIENT,
- CODE_ENVIRONMENT_DAEMON,
- CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS);
+ return ret;
+ }
- Mutex mutex("main");
- SafeTimer init_timer(g_ceph_context, mutex);
- init_timer.init();
- mutex.Lock();
- init_timer.add_event_after(g_conf->rgw_init_timeout, new C_InitTimeout);
- mutex.Unlock();
+ int RGWLibFrontend::init()
+ {
+ pprocess = new RGWLibProcess(g_ceph_context, &env,
+ g_conf->rgw_thread_pool_size, conf);
+ return 0;
+ }
- common_init_finish(g_ceph_context);
+ int RGWLib::init()
+ {
+ vector<const char*> args;
+ return init(args);
+ }
- rgw_tools_init(g_ceph_context);
+ int RGWLib::init(vector<const char*>& args)
+ {
+ int r = 0;
- rgw_init_resolver();
+ /* alternative default for module */
+ vector<const char *> def_args;
+ def_args.push_back("--debug-rgw=1/5");
+ def_args.push_back("--keyring=$rgw_data/keyring");
+ def_args.push_back("--log-file=/var/log/radosgw/$cluster-$name.log");
- store = RGWStoreManager::get_storage(g_ceph_context,
- g_conf->rgw_enable_gc_threads, g_conf->rgw_enable_quota_threads);
+ global_init(&def_args, args,
+ CEPH_ENTITY_TYPE_CLIENT,
+ CODE_ENVIRONMENT_DAEMON,
+ CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS);
- if (!store) {
+ Mutex mutex("main");
+ SafeTimer init_timer(g_ceph_context, mutex);
+ init_timer.init();
mutex.Lock();
- init_timer.cancel_all_events();
- init_timer.shutdown();
+ init_timer.add_event_after(g_conf->rgw_init_timeout, new C_InitTimeout);
mutex.Unlock();
- derr << "Couldn't init storage provider (RADOS)" << dendl;
- return EIO;
- }
+ common_init_finish(g_ceph_context);
- r = rgw_perf_start(g_ceph_context);
+ rgw_tools_init(g_ceph_context);
- rgw_rest_init(g_ceph_context, store->region);
+ rgw_init_resolver();
- mutex.Lock();
- init_timer.cancel_all_events();
- init_timer.shutdown();
- mutex.Unlock();
+ store = RGWStoreManager::get_storage(g_ceph_context,
+ g_conf->rgw_enable_gc_threads, g_conf->rgw_enable_quota_threads);
- if (r)
- return 1;
+ if (!store) {
+ mutex.Lock();
+ init_timer.cancel_all_events();
+ init_timer.shutdown();
+ mutex.Unlock();
- rgw_user_init(store);
- rgw_bucket_init(store->meta_mgr);
- rgw_log_usage_init(g_ceph_context, store);
+ derr << "Couldn't init storage provider (RADOS)" << dendl;
+ return EIO;
+ }
- // XXX ex-RGWRESTMgr_lib, mgr->set_logging(true)
+ r = rgw_perf_start(g_ceph_context);
- if (!g_conf->rgw_ops_log_socket_path.empty()) {
- olog = new OpsLogSocket(g_ceph_context, g_conf->rgw_ops_log_data_backlog);
- olog->init(g_conf->rgw_ops_log_socket_path);
- }
+ rgw_rest_init(g_ceph_context, store->region);
- int port = 80;
- RGWProcessEnv env = { store, &rest, olog, port };
+ mutex.Lock();
+ init_timer.cancel_all_events();
+ init_timer.shutdown();
+ mutex.Unlock();
- fec = new RGWFrontendConfig("librgw");
- fe = new RGWLibFrontend(env, fec);
+ if (r)
+ return 1;
- fe->init();
- if (r < 0) {
- derr << "ERROR: failed initializing frontend" << dendl;
- return -r;
- }
+ rgw_user_init(store);
+ rgw_bucket_init(store->meta_mgr);
+ rgw_log_usage_init(g_ceph_context, store);
- fe->run();
+ // XXX ex-RGWRESTMgr_lib, mgr->set_logging(true)
- return 0;
-} /* RGWLib::init() */
+ if (!g_conf->rgw_ops_log_socket_path.empty()) {
+ olog = new OpsLogSocket(g_ceph_context, g_conf->rgw_ops_log_data_backlog);
+ olog->init(g_conf->rgw_ops_log_socket_path);
+ }
-int RGWLib::stop()
-{
- derr << "shutting down" << dendl;
+ int port = 80;
+ RGWProcessEnv env = { store, &rest, olog, port };
- fe->stop();
+ fec = new RGWFrontendConfig("librgw");
+ fe = new RGWLibFrontend(env, fec);
- fe->join();
+ fe->init();
+ if (r < 0) {
+ derr << "ERROR: failed initializing frontend" << dendl;
+ return -r;
+ }
- delete fe;
+ fe->run();
- rgw_log_usage_finalize();
+ return 0;
+ } /* RGWLib::init() */
- delete olog;
+ int RGWLib::stop()
+ {
+ derr << "shutting down" << dendl;
- RGWStoreManager::close_storage(store);
+ fe->stop();
- rgw_tools_cleanup();
- rgw_shutdown_resolver();
+ fe->join();
- rgw_perf_stop(g_ceph_context);
+ delete fe;
- dout(1) << "final shutdown" << dendl;
- g_ceph_context->put();
+ rgw_log_usage_finalize();
- ceph::crypto::shutdown();
+ delete olog;
- return 0;
-} /* RGWLib::stop() */
+ RGWStoreManager::close_storage(store);
-int RGWLibIO::set_uid(RGWRados *store, const rgw_user& uid)
-{
- int ret = rgw_get_user_info_by_uid(store, uid, user_info, NULL);
- if (ret < 0) {
- derr << "ERROR: failed reading user info: uid=" << uid << " ret="
- << ret << dendl;
- }
- return ret;
-}
+ rgw_tools_cleanup();
+ rgw_shutdown_resolver();
-int RGWLibRequest::read_permissions(RGWOp *op) {
- int ret =
- rgw_build_bucket_policies(librgw.get_store(), get_state());
- if (ret < 0) {
- ldout(get_state()->cct, 10) << "read_permissions on "
- << get_state()->bucket << ":"
- << get_state()->object
- << " only_bucket=" << only_bucket()
- << " ret=" << ret << dendl;
- if (ret == -ENODATA)
- ret = -EACCES;
- }
+ rgw_perf_stop(g_ceph_context);
- return ret;
-} /* RGWLibRequest::read_permissions */
+ dout(1) << "final shutdown" << dendl;
+ g_ceph_context->put();
-int RGWHandler_Lib::authorize()
-{
- /* TODO: handle
- * 1. subusers
- * 2. anonymous access
- * 3. system access
- * 4. ?
- *
- * Much or all of this depends on handling the cached authorization
- * correctly (e.g., dealing with keystone) at mount time.
- */
- s->perm_mask = RGW_PERM_FULL_CONTROL;
-
- // populate the owner info
- s->owner.set_id(s->user->user_id);
- s->owner.set_name(s->user->display_name);
+ ceph::crypto::shutdown();
- return 0;
-} /* RGWHandler_Lib::authorize */
+ return 0;
+ } /* RGWLib::stop() */
+
+ int RGWLibIO::set_uid(RGWRados *store, const rgw_user& uid)
+ {
+ int ret = rgw_get_user_info_by_uid(store, uid, user_info, NULL);
+ if (ret < 0) {
+ derr << "ERROR: failed reading user info: uid=" << uid << " ret="
+ << ret << dendl;
+ }
+ return ret;
+ }
+
+ int RGWLibRequest::read_permissions(RGWOp* op) {
+ int ret =
+ rgw_build_bucket_policies(librgw.get_store(), get_state());
+ if (ret < 0) {
+ ldout(get_state()->cct, 10) << "read_permissions on "
+ << get_state()->bucket << ":"
+ << get_state()->object
+ << " only_bucket=" << only_bucket()
+ << " ret=" << ret << dendl;
+ if (ret == -ENODATA)
+ ret = -EACCES;
+ }
+ return ret;
+ } /* RGWLibRequest::read_permissions */
+
+ int RGWHandler_Lib::authorize()
+ {
+ /* TODO: handle
+ * 1. subusers
+ * 2. anonymous access
+ * 3. system access
+ * 4. ?
+ *
+ * Much or all of this depends on handling the cached authorization
+ * correctly (e.g., dealing with keystone) at mount time.
+ */
+ s->perm_mask = RGW_PERM_FULL_CONTROL;
+
+ // populate the owner info
+ s->owner.set_id(s->user->user_id);
+ s->owner.set_name(s->user->display_name);
+
+ return 0;
+ } /* RGWHandler_Lib::authorize */
/* global RGW library object */
-static RGWLib rgwlib;
+ static RGWLib rgwlib;
+
+} /* namespace rgw */
extern "C" {
int librgw_init()
{
+ using namespace rgw;
+
return rgwlib.init();
}
int librgw_create(librgw_t* rgw, int argc, char **argv)
{
+ using namespace rgw;
+
if (! g_ceph_context) {
std::lock_guard<std::mutex> lg(librgw_mtx);
if (! g_ceph_context) {
void librgw_shutdown(librgw_t rgw)
{
+ using namespace rgw;
+
CephContext* cct = static_cast<CephContext*>(rgw);
#if 0
rgwlib.stop();
#include "rgw_bucket.h"
#include "rgw_file.h"
+#include "rgw_lib_frontend.h"
#define dout_subsys ceph_subsys_rgw
using namespace rgw;
-extern RGWLib librgw;
+namespace rgw {
-const string RGWFileHandle::root_name = "/";
+ extern RGWLib librgw;
-atomic<uint32_t> RGWLibFS::fs_inst;
+ const string RGWFileHandle::root_name = "/";
-LookupFHResult RGWLibFS::stat_bucket(RGWFileHandle* parent,
- const char *path, uint32_t flags)
-{
- LookupFHResult fhr{nullptr, 0};
- std::string bucket_name{path};
- RGWStatBucketRequest req(cct, get_user(), bucket_name);
+ atomic<uint32_t> RGWLibFS::fs_inst;
- int rc = librgw.get_fe()->execute_req(&req);
- if ((rc == 0) &&
- (req.get_ret() == 0) &&
- (req.matched())) {
- fhr = lookup_fh(parent, path,
- RGWFileHandle::FLAG_CREATE|
- RGWFileHandle::FLAG_BUCKET);
- }
- return fhr;
-}
+ LookupFHResult RGWLibFS::stat_bucket(RGWFileHandle* parent,
+ const char *path, uint32_t flags)
+ {
+ LookupFHResult fhr{nullptr, 0};
+ std::string bucket_name{path};
+ RGWStatBucketRequest req(cct, get_user(), bucket_name);
-LookupFHResult RGWLibFS::stat_leaf(RGWFileHandle* parent,
- const char *path,
- uint32_t flags)
-{
- /* find either-of <object_name>, <object_name/>, only one of
- * which should exist; atomicity? */
- LookupFHResult fhr{nullptr, 0};
- std::string object_name{path};
-
- for (auto ix : { 0, 1 }) {
- switch (ix) {
- case 0:
- {
- RGWStatObjRequest req(cct, get_user(),
- parent->bucket_name(), object_name,
- RGWStatObjRequest::FLAG_NONE);
- int rc = librgw.get_fe()->execute_req(&req);
- if ((rc == 0) &&
- (req.get_ret() == 0)) {
- fhr = lookup_fh(parent, path, RGWFileHandle::FLAG_NONE);
- goto done;
- }
+ int rc = librgw.get_fe()->execute_req(&req);
+ if ((rc == 0) &&
+ (req.get_ret() == 0) &&
+ (req.matched())) {
+ fhr = lookup_fh(parent, path,
+ RGWFileHandle::FLAG_CREATE|
+ RGWFileHandle::FLAG_BUCKET);
}
- break;
- case 1:
- {
- RGWStatLeafRequest req(cct, get_user(), parent, object_name);
- int rc = librgw.get_fe()->execute_req(&req);
- if ((rc == 0) &&
- (req.get_ret() == 0)) {
- if (req.matched) {
- fhr = lookup_fh(parent, path,
- RGWFileHandle::FLAG_CREATE|
- ((req.is_dir) ?
- RGWFileHandle::FLAG_DIRECTORY :
- RGWFileHandle::FLAG_NONE));
+ return fhr;
+ }
+
+ LookupFHResult RGWLibFS::stat_leaf(RGWFileHandle* parent,
+ const char *path,
+ uint32_t flags)
+ {
+ /* find either-of <object_name>, <object_name/>, only one of
+ * which should exist; atomicity? */
+ LookupFHResult fhr{nullptr, 0};
+ std::string object_name{path};
+
+ for (auto ix : { 0, 1 }) {
+ switch (ix) {
+ case 0:
+ {
+ RGWStatObjRequest req(cct, get_user(),
+ parent->bucket_name(), object_name,
+ RGWStatObjRequest::FLAG_NONE);
+ int rc = librgw.get_fe()->execute_req(&req);
+ if ((rc == 0) &&
+ (req.get_ret() == 0)) {
+ fhr = lookup_fh(parent, path, RGWFileHandle::FLAG_NONE);
+ goto done;
+ }
+ }
+ break;
+ case 1:
+ {
+ RGWStatLeafRequest req(cct, get_user(), parent, object_name);
+ int rc = librgw.get_fe()->execute_req(&req);
+ if ((rc == 0) &&
+ (req.get_ret() == 0)) {
+ if (req.matched) {
+ fhr = lookup_fh(parent, path,
+ RGWFileHandle::FLAG_CREATE|
+ ((req.is_dir) ?
+ RGWFileHandle::FLAG_DIRECTORY :
+ RGWFileHandle::FLAG_NONE));
+ }
}
}
- }
- break;
- default:
- /* not reached */
break;
+ default:
+ /* not reached */
+ break;
+ }
+ }
+ done:
+ return fhr;
+ } /* RGWLibFS::stat_leaf */
+
+ bool RGWFileHandle::reclaim() {
+ fs->fh_cache.remove(fh.fh_hk.object, this, cohort::lru::FLAG_NONE);
+ return true;
+ } /* RGWFileHandle::reclaim */
+
+ int RGWFileHandle::write(uint64_t off, size_t len, size_t *bytes_written,
+ void *buffer)
+ {
+ using std::get;
+ lock_guard guard(mtx);
+
+ int rc = 0;
+ buffer::list bl;
+ bl.push_back(
+ buffer::create_static(len, static_cast<char*>(buffer)));
+
+ file* f = get<file>(&variant_type);
+ if (! f)
+ return -EISDIR;
+
+ if (! f->write_req) {
+ /* start */
+ std::string object_name = full_object_name();
+ f->write_req =
+ new RGWWriteRequest(fs->get_context(), fs->get_user(), this,
+ bucket_name(), object_name);
+ rc = librgw.get_fe()->start_req(f->write_req);
}
- }
-done:
- return fhr;
-} /* RGWLibFS::stat_leaf */
-
-bool RGWFileHandle::reclaim() {
- fs->fh_cache.remove(fh.fh_hk.object, this, cohort::lru::FLAG_NONE);
- return true;
-} /* RGWFileHandle::reclaim */
-
-int RGWFileHandle::write(uint64_t off, size_t len, size_t *bytes_written,
- void *buffer)
-{
- using std::get;
- lock_guard guard(mtx);
-
- int rc = 0;
- buffer::list bl;
- bl.push_back(
- buffer::create_static(len, static_cast<char*>(buffer)));
- file* f = get<file>(&variant_type);
- if (! f)
- return -EISDIR;
+ f->write_req->put_data(off, bl);
+ rc = f->write_req->exec_continue();
- if (! f->write_req) {
- /* start */
- std::string object_name = full_object_name();
- f->write_req =
- new RGWWriteRequest(fs->get_context(), fs->get_user(), this,
- bucket_name(), object_name);
- rc = librgw.get_fe()->start_req(f->write_req);
- }
+ size_t min_size = off + len;
+ if (min_size > get_size())
+ set_size(min_size);
- f->write_req->put_data(off, bl);
- rc = f->write_req->exec_continue();
+ *bytes_written = (rc == 0) ? len : 0;
+ return rc;
+ } /* RGWFileHandle::write */
- size_t min_size = off + len;
- if (min_size > get_size())
- set_size(min_size);
+ int RGWFileHandle::close()
+ {
+ lock_guard guard(mtx);
- *bytes_written = (rc == 0) ? len : 0;
- return rc;
-} /* RGWFileHandle::write */
+ int rc = 0;
+ file* f = get<file>(&variant_type);
+ if (f && (f->write_req)) {
+ rc = librgw.get_fe()->finish_req(f->write_req);
+ if (! rc) {
+ rc = f->write_req->get_ret();
+ }
+ delete f->write_req;
+ f->write_req = nullptr;
+ }
-int RGWFileHandle::close()
-{
- lock_guard guard(mtx);
+ flags &= ~FLAG_OPEN;
+ return rc;
+ } /* RGWFileHandle::close */
- int rc = 0;
- file* f = get<file>(&variant_type);
- if (f && (f->write_req)) {
- rc = librgw.get_fe()->finish_req(f->write_req);
- if (! rc) {
- rc = f->write_req->get_ret();
- }
- delete f->write_req;
- f->write_req = nullptr;
+ RGWFileHandle::file::~file()
+ {
+ delete write_req;
}
- flags &= ~FLAG_OPEN;
- return rc;
-} /* RGWFileHandle::close */
-
-RGWFileHandle::file::~file()
-{
- delete write_req;
-}
+ int RGWWriteRequest::exec_start() {
+ struct req_state* s = get_state();
-int RGWWriteRequest::exec_start() {
- struct req_state* s = get_state();
+ // XXX check this
+ need_calc_md5 = (dlo_manifest == NULL) && (slo_info == NULL);
- // XXX check this
- need_calc_md5 = (dlo_manifest == NULL) && (slo_info == NULL);
+ perfcounter->inc(l_rgw_put);
+ op_ret = -EINVAL;
- perfcounter->inc(l_rgw_put);
- op_ret = -EINVAL;
+ // XXX check this
+ if (s->object.empty()) {
+ goto done;
+ }
- // XXX check this
- if (s->object.empty()) {
- goto done;
- }
+ op_ret = get_params();
+ if (op_ret < 0)
+ goto done;
- op_ret = get_params();
- if (op_ret < 0)
- goto done;
+ op_ret = get_system_versioning_params(s, &olh_epoch, &version_id);
+ if (op_ret < 0) {
+ goto done;
+ }
- op_ret = get_system_versioning_params(s, &olh_epoch, &version_id);
- if (op_ret < 0) {
- goto done;
- }
+ /* user-supplied MD5 check skipped (not supplied) */
+ /* early quota check skipped--we don't have size yet */
+ /* skipping user-supplied etag--we might have one in future, but
+ * like data it and other attrs would arrive after open */
+ processor = select_processor(*static_cast<RGWObjectCtx *>(s->obj_ctx),
+ &multipart);
+ op_ret = processor->prepare(get_store(), NULL);
- /* user-supplied MD5 check skipped (not supplied) */
- /* early quota check skipped--we don't have size yet */
- /* skipping user-supplied etag--we might have one in future, but
- * like data it and other attrs would arrive after open */
- processor = select_processor(*static_cast<RGWObjectCtx *>(s->obj_ctx),
- &multipart);
- op_ret = processor->prepare(get_store(), NULL);
+ done:
+ return op_ret;
+ } /* exec_start */
-done:
- return op_ret;
-} /* exec_start */
-
-int RGWWriteRequest::exec_continue()
-{
- struct req_state* s = get_state();
- op_ret = 0;
+ int RGWWriteRequest::exec_continue()
+ {
+ struct req_state* s = get_state();
+ op_ret = 0;
#if 0 // TODO: check offsets
- if (next_off != last_off)
- return -EIO;
+ if (next_off != last_off)
+ return -EIO;
#endif
- size_t len = data.length();
- if (! len)
- return 0;
-
- /* XXX won't see multipart */
- bool need_to_wait = (ofs == 0) && multipart;
- bufferlist orig_data;
+ size_t len = data.length();
+ if (! len)
+ return 0;
- if (need_to_wait) {
- orig_data = data;
- }
+ /* XXX won't see multipart */
+ bool need_to_wait = (ofs == 0) && multipart;
+ bufferlist orig_data;
- op_ret = put_data_and_throttle(processor, data, ofs,
- (need_calc_md5 ? &hash : NULL), need_to_wait);
- if (op_ret < 0) {
- if (!need_to_wait || op_ret != -EEXIST) {
- ldout(s->cct, 20) << "processor->thottle_data() returned ret="
- << op_ret << dendl;
- goto done;
+ if (need_to_wait) {
+ orig_data = data;
}
- ldout(s->cct, 5) << "NOTICE: processor->throttle_data() returned -EEXIST, need to restart write" << dendl;
+ op_ret = put_data_and_throttle(processor, data, ofs,
+ (need_calc_md5 ? &hash : NULL), need_to_wait);
+ if (op_ret < 0) {
+ if (!need_to_wait || op_ret != -EEXIST) {
+ ldout(s->cct, 20) << "processor->thottle_data() returned ret="
+ << op_ret << dendl;
+ goto done;
+ }
- /* restore original data */
- data.swap(orig_data);
+ ldout(s->cct, 5) << "NOTICE: processor->throttle_data() returned -EEXIST, need to restart write" << dendl;
- /* restart processing with different oid suffix */
- dispose_processor(processor);
- processor = select_processor(*static_cast<RGWObjectCtx *>(s->obj_ctx),
- &multipart);
+ /* restore original data */
+ data.swap(orig_data);
- string oid_rand;
- char buf[33];
- gen_rand_alphanumeric(get_store()->ctx(), buf, sizeof(buf) - 1);
- oid_rand.append(buf);
+ /* restart processing with different oid suffix */
+ dispose_processor(processor);
+ processor = select_processor(*static_cast<RGWObjectCtx *>(s->obj_ctx),
+ &multipart);
- op_ret = processor->prepare(get_store(), &oid_rand);
- if (op_ret < 0) {
- ldout(s->cct, 0) << "ERROR: processor->prepare() returned "
- << op_ret << dendl;
- goto done;
- }
+ string oid_rand;
+ char buf[33];
+ gen_rand_alphanumeric(get_store()->ctx(), buf, sizeof(buf) - 1);
+ oid_rand.append(buf);
- op_ret = put_data_and_throttle(processor, data, ofs, NULL, false);
+ op_ret = processor->prepare(get_store(), &oid_rand);
+ if (op_ret < 0) {
+ ldout(s->cct, 0) << "ERROR: processor->prepare() returned "
+ << op_ret << dendl;
+ goto done;
+ }
+
+ op_ret = put_data_and_throttle(processor, data, ofs, NULL, false);
+ if (op_ret < 0) {
+ goto done;
+ }
+ }
+ bytes_written += len;
+
+ done:
+ return op_ret;
+ } /* exec_continue */
+
+ int RGWWriteRequest::exec_finish()
+ {
+ bufferlist bl, aclbl;
+ map<string, bufferlist> attrs;
+ map<string, string>::iterator iter;
+ char calc_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
+ unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE];
+ struct req_state* s = get_state();
+
+ s->obj_size = ofs; // XXX check ofs
+ perfcounter->inc(l_rgw_put_b, s->obj_size);
+
+ op_ret = get_store()->check_quota(s->bucket_owner.get_id(), s->bucket,
+ user_quota, bucket_quota, s->obj_size);
if (op_ret < 0) {
goto done;
}
- }
- bytes_written += len;
-
-done:
- return op_ret;
-} /* exec_continue */
-
-int RGWWriteRequest::exec_finish()
-{
- bufferlist bl, aclbl;
- map<string, bufferlist> attrs;
- map<string, string>::iterator iter;
- char calc_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
- unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE];
- struct req_state* s = get_state();
-
- s->obj_size = ofs; // XXX check ofs
- perfcounter->inc(l_rgw_put_b, s->obj_size);
-
- op_ret = get_store()->check_quota(s->bucket_owner.get_id(), s->bucket,
- user_quota, bucket_quota, s->obj_size);
- if (op_ret < 0) {
- goto done;
- }
- if (need_calc_md5) {
- processor->complete_hash(&hash);
- }
- hash.Final(m);
+ if (need_calc_md5) {
+ processor->complete_hash(&hash);
+ }
+ hash.Final(m);
- buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5);
- etag = calc_md5;
+ buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5);
+ etag = calc_md5;
#if 0 /* XXX only in PostObj currently */
- if (supplied_md5_b64 && strcmp(calc_md5, supplied_md5)) {
- op_ret = -ERR_BAD_DIGEST;
- goto done;
- }
+ if (supplied_md5_b64 && strcmp(calc_md5, supplied_md5)) {
+ op_ret = -ERR_BAD_DIGEST;
+ goto done;
+ }
#endif
- policy.encode(aclbl);
+ policy.encode(aclbl);
- attrs[RGW_ATTR_ACL] = aclbl;
+ attrs[RGW_ATTR_ACL] = aclbl;
- /* XXX most of the following cases won't currently arise */
- if (unlikely(!! dlo_manifest)) {
- op_ret = encode_dlo_manifest_attr(dlo_manifest, attrs);
- if (op_ret < 0) {
- ldout(s->cct, 0) << "bad user manifest: " << dlo_manifest << dendl;
- goto done;
+ /* XXX most of the following cases won't currently arise */
+ if (unlikely(!! dlo_manifest)) {
+ op_ret = encode_dlo_manifest_attr(dlo_manifest, attrs);
+ if (op_ret < 0) {
+ ldout(s->cct, 0) << "bad user manifest: " << dlo_manifest << dendl;
+ goto done;
+ }
+ complete_etag(hash, &etag);
+ ldout(s->cct, 10) << __func__ << ": calculated md5 for user manifest: "
+ << etag << dendl;
}
- complete_etag(hash, &etag);
- ldout(s->cct, 10) << __func__ << ": calculated md5 for user manifest: "
- << etag << dendl;
- }
- if (unlikely(!! slo_info)) {
- bufferlist manifest_bl;
- ::encode(*slo_info, manifest_bl);
- attrs[RGW_ATTR_SLO_MANIFEST] = manifest_bl;
+ if (unlikely(!! slo_info)) {
+ bufferlist manifest_bl;
+ ::encode(*slo_info, manifest_bl);
+ attrs[RGW_ATTR_SLO_MANIFEST] = manifest_bl;
- hash.Update((byte *)slo_info->raw_data, slo_info->raw_data_len);
- complete_etag(hash, &etag);
- ldout(s->cct, 10) << __func__ << ": calculated md5 for user manifest: "
- << etag << dendl;
- }
+ hash.Update((byte *)slo_info->raw_data, slo_info->raw_data_len);
+ complete_etag(hash, &etag);
+ ldout(s->cct, 10) << __func__ << ": calculated md5 for user manifest: "
+ << etag << dendl;
+ }
- if (supplied_etag && etag.compare(supplied_etag) != 0) {
- op_ret = -ERR_UNPROCESSABLE_ENTITY;
- goto done;
- }
- bl.append(etag.c_str(), etag.size() + 1);
- attrs[RGW_ATTR_ETAG] = bl;
-
- for (iter = s->generic_attrs.begin(); iter != s->generic_attrs.end();
- ++iter) {
- bufferlist& attrbl = attrs[iter->first];
- const string& val = iter->second;
- attrbl.append(val.c_str(), val.size() + 1);
- }
+ if (supplied_etag && etag.compare(supplied_etag) != 0) {
+ op_ret = -ERR_UNPROCESSABLE_ENTITY;
+ goto done;
+ }
+ bl.append(etag.c_str(), etag.size() + 1);
+ attrs[RGW_ATTR_ETAG] = bl;
+
+ for (iter = s->generic_attrs.begin(); iter != s->generic_attrs.end();
+ ++iter) {
+ bufferlist& attrbl = attrs[iter->first];
+ const string& val = iter->second;
+ attrbl.append(val.c_str(), val.size() + 1);
+ }
- rgw_get_request_metadata(s->cct, s->info, attrs);
- encode_delete_at_attr(delete_at, attrs);
+ rgw_get_request_metadata(s->cct, s->info, attrs);
+ encode_delete_at_attr(delete_at, attrs);
- /* Add a custom metadata to expose the information whether an object
- * is an SLO or not. Appending the attribute must be performed AFTER
- * processing any input from user in order to prohibit overwriting. */
- if (unlikely(!! slo_info)) {
- bufferlist slo_userindicator_bl;
- ::encode("True", slo_userindicator_bl);
- attrs[RGW_ATTR_SLO_UINDICATOR] = slo_userindicator_bl;
- }
+ /* Add a custom metadata to expose the information whether an object
+ * is an SLO or not. Appending the attribute must be performed AFTER
+ * processing any input from user in order to prohibit overwriting. */
+ if (unlikely(!! slo_info)) {
+ bufferlist slo_userindicator_bl;
+ ::encode("True", slo_userindicator_bl);
+ attrs[RGW_ATTR_SLO_UINDICATOR] = slo_userindicator_bl;
+ }
- op_ret = processor->complete(etag, &mtime, 0, attrs, delete_at, if_match,
- if_nomatch);
- if (! op_ret) {
- /* update stats */
- rgw_fh->set_mtime({mtime, 0});
- rgw_fh->set_size(bytes_written);
- }
+ op_ret = processor->complete(etag, &mtime, 0, attrs, delete_at, if_match,
+ if_nomatch);
+ if (! op_ret) {
+ /* update stats */
+ rgw_fh->set_mtime({mtime, 0});
+ rgw_fh->set_size(bytes_written);
+ }
-done:
- dispose_processor(processor);
- perfcounter->tinc(l_rgw_put_lat,
- (ceph_clock_now(s->cct) - s->time));
- return op_ret;
-} /* exec_finish */
+ done:
+ dispose_processor(processor);
+ perfcounter->tinc(l_rgw_put_lat,
+ (ceph_clock_now(s->cct) - s->time));
+ return op_ret;
+ } /* exec_finish */
+
+} /* namespace rgw */
/* librgw */
extern "C" {
#include "rgw_process.h"
#include "rgw_rest_s3.h" // RGW_Auth_S3
-
-class RGWLibFrontendConfig;
-class RGWLibFrontend;
class OpsLogSocket;
-class RGWLib {
- RGWFrontendConfig* fec;
- RGWLibFrontend* fe;
- OpsLogSocket* olog;
- RGWREST rest; // XXX needed for RGWProcessEnv
- RGWProcessEnv env;
- RGWRados* store;
-
-public:
- RGWLib() {}
- ~RGWLib() {}
+namespace rgw {
- RGWRados* get_store() { return store; }
+ class RGWLibFrontendConfig;
+ class RGWLibFrontend;
- RGWLibFrontend* get_fe() { return fe; }
+ class RGWLib {
+ RGWFrontendConfig* fec;
+ RGWLibFrontend* fe;
+ OpsLogSocket* olog;
+ RGWREST rest; // XXX needed for RGWProcessEnv
+ RGWProcessEnv env;
+ RGWRados* store;
- int init();
- int init(vector<const char *>& args);
- int stop();
-};
+ public:
+ RGWLib() {}
+ ~RGWLib() {}
-extern RGWLib librgw;
+ RGWRados* get_store() { return store; }
-/* request interface */
+ RGWLibFrontend* get_fe() { return fe; }
-class RGWLibIO : public RGWClientIO
-{
- RGWUserInfo user_info;
-public:
- RGWLibIO() {
- get_env().set("HTTP_HOST", "");
- }
- RGWLibIO(const RGWUserInfo &_user_info)
- : user_info(_user_info) {}
-
- virtual void init_env(CephContext *cct) {}
-
- const RGWUserInfo& get_user() {
- return user_info;
- }
-
- int set_uid(RGWRados* store, const rgw_user& uid);
-
- int write_data(const char *buf, int len);
- int read_data(char *buf, int len);
- int send_status(int status, const char *status_name);
- int send_100_continue();
- int complete_header();
- int send_content_length(uint64_t len);
-
- int complete_request() { /* XXX */
- return 0;
+ int init();
+ int init(vector<const char *>& args);
+ int stop();
};
-}; /* RGWLibIO */
-
-/* XXX */
-class RGWRESTMgr_Lib : public RGWRESTMgr {
-public:
- RGWRESTMgr_Lib() {}
- virtual ~RGWRESTMgr_Lib() {}
-}; /* RGWRESTMgr_Lib */
+ extern RGWLib librgw;
-/* XXX */
-class RGWHandler_Lib : public RGWHandler {
- friend class RGWRESTMgr_Lib;
-public:
-
- virtual int authorize();
-
- RGWHandler_Lib() {}
- virtual ~RGWHandler_Lib() {}
- static int init_from_header(struct req_state *s);
-}; /* RGWHandler_Lib */
+/* request interface */
-class RGWLibRequest : public RGWRequest,
- public RGWHandler_Lib {
-public:
- CephContext* cct;
- RGWUserInfo* user;
+ class RGWLibIO : public RGWClientIO
+ {
+ RGWUserInfo user_info;
+ public:
+ RGWLibIO() {
+ get_env().set("HTTP_HOST", "");
+ }
+ RGWLibIO(const RGWUserInfo &_user_info)
+ : user_info(_user_info) {}
- /* unambiguiously return req_state */
- inline struct req_state* get_state() { return this->RGWRequest::s; }
+ virtual void init_env(CephContext *cct) {}
- RGWLibRequest(CephContext* _cct, RGWUserInfo* _user)
- : RGWRequest(0), cct(_cct), user(_user)
- {}
+ const RGWUserInfo& get_user() {
+ return user_info;
+ }
- RGWUserInfo* get_user() { return user; }
+ int set_uid(RGWRados* store, const rgw_user& uid);
- /* 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;
+ int write_data(const char *buf, int len);
+ int read_data(char *buf, int len);
+ int send_status(int status, const char *status_name);
+ int send_100_continue();
+ int complete_header();
+ int send_content_length(uint64_t len);
- /* descendant initializer responsible to call RGWOp::init()--which
- * descendants are required to inherit */
- virtual int op_init() = 0;
+ int complete_request() { /* XXX */
+ return 0;
+ };
- int init(const RGWEnv& rgw_env, RGWObjectCtx* rados_ctx,
- RGWLibIO* io, struct req_state* _s) {
+ }; /* RGWLibIO */
- RGWRequest::init_state(_s);
- RGWHandler::init(rados_ctx->store, _s, io);
+/* XXX */
+ class RGWRESTMgr_Lib : public RGWRESTMgr {
+ public:
+ RGWRESTMgr_Lib() {}
+ virtual ~RGWRESTMgr_Lib() {}
+ }; /* RGWRESTMgr_Lib */
- /* fixup _s->req */
- _s->req = this;
+/* XXX */
+ class RGWHandler_Lib : public RGWHandler {
+ friend class RGWRESTMgr_Lib;
+ public:
- log_init();
+ virtual int authorize();
- get_state()->obj_ctx = rados_ctx;
- get_state()->req_id = store->unique_id(id);
- get_state()->trans_id = store->unique_trans_id(id);
+ RGWHandler_Lib() {}
+ virtual ~RGWHandler_Lib() {}
+ static int init_from_header(struct req_state *s);
+ }; /* RGWHandler_Lib */
- log_format(_s, "initializing for trans_id = %s",
- get_state()->trans_id.c_str());
+ class RGWLibRequest : public RGWRequest,
+ public RGWHandler_Lib {
+ public:
+ CephContext* cct;
+ RGWUserInfo* user;
- int ret = header_init();
- if (ret == 0) {
- ret = init_from_header(_s);
- }
- return ret;
- }
+ /* unambiguiously return req_state */
+ inline struct req_state* get_state() { return this->RGWRequest::s; }
- virtual bool only_bucket() = 0;
+ RGWLibRequest(CephContext* _cct, RGWUserInfo* _user)
+ : RGWRequest(0), cct(_cct), user(_user)
+ {}
- virtual int read_permissions(RGWOp *op);
+ RGWUserInfo* get_user() { return user; }
virtual int postauth_init() { return 0; }
-}; /* RGWLibRequest */
+ /* 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;
-class RGWLibContinuedReq : public RGWLibRequest {
- RGWLibIO io_ctx;
- struct req_state rstate;
- RGWObjectCtx rados_ctx;
-public:
+ /* descendant initializer responsible to call RGWOp::init()--which
+ * descendants are required to inherit */
+ virtual int op_init() = 0;
-RGWLibContinuedReq(CephContext* _cct, RGWUserInfo* _user)
- : RGWLibRequest(_cct, _user), io_ctx(),
- rstate(_cct, &io_ctx.get_env(), _user), rados_ctx(librgw.get_store(),
- &rstate)
- {
- io_ctx.init(_cct);
+ int init(const RGWEnv& rgw_env, RGWObjectCtx* rados_ctx,
+ RGWLibIO* io, struct req_state* _s) {
- RGWRequest::init_state(&rstate);
- RGWHandler::init(rados_ctx.store, &rstate, &io_ctx);
+ RGWRequest::init_state(_s);
+ RGWHandler::init(rados_ctx->store, _s, io);
/* fixup _s->req */
- get_state()->req = this;
+ _s->req = this;
log_init();
- get_state()->obj_ctx = &rados_ctx;
+ 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(get_state(), "initializing for trans_id = %s",
+ log_format(_s, "initializing for trans_id = %s",
get_state()->trans_id.c_str());
- }
-
- inline RGWRados* get_store() { return store; }
- virtual int execute() final { abort(); }
- virtual int exec_start() = 0;
- virtual int exec_continue() = 0;
- virtual int exec_finish() = 0;
-
-}; /* RGWLibContinuedReq */
+ int ret = header_init();
+ if (ret == 0) {
+ ret = init_from_header(_s);
+ }
+ return ret;
+ }
-class RGWLibProcess : public RGWProcess {
- RGWAccessKey access_key;
-public:
- RGWLibProcess(CephContext* cct, RGWProcessEnv* pe, int num_threads,
- RGWFrontendConfig* _conf) :
- RGWProcess(cct, pe, num_threads, _conf) {}
+ virtual bool only_bucket() = 0;
- void run();
- void checkpoint();
+ virtual int read_permissions(RGWOp *op);
- void enqueue_req(RGWLibRequest* req) {
+ }; /* RGWLibRequest */
- lsubdout(g_ceph_context, rgw, 10)
- << __func__ << " enqueue request req=" << hex << req << dec << dendl;
+ class RGWLibContinuedReq : public RGWLibRequest {
+ RGWLibIO io_ctx;
+ struct req_state rstate;
+ RGWObjectCtx rados_ctx;
+ public:
- req_throttle.get(1);
- req_wq.queue(req);
- } /* enqueue_req */
+ RGWLibContinuedReq(CephContext* _cct, RGWUserInfo* _user)
+ : RGWLibRequest(_cct, _user), io_ctx(),
+ rstate(_cct, &io_ctx.get_env(), _user), rados_ctx(librgw.get_store(),
+ &rstate)
+ {
+ io_ctx.init(_cct);
- /* "regular" requests */
- void handle_request(RGWRequest* req); // async handler, deletes req
- int process_request(RGWLibRequest* req);
- int process_request(RGWLibRequest* req, RGWLibIO* io);
- void set_access_key(RGWAccessKey& key) { access_key = key; }
+ RGWRequest::init_state(&rstate);
+ RGWHandler::init(rados_ctx.store, &rstate, &io_ctx);
- /* requests w/continue semantics */
- int start_request(RGWLibContinuedReq* req);
- int finish_request(RGWLibContinuedReq* req);
-}; /* RGWLibProcess */
+ /* fixup _s->req */
+ get_state()->req = this;
-class RGWLibFrontend : public RGWProcessFrontend {
-public:
- RGWLibFrontend(RGWProcessEnv& pe, RGWFrontendConfig *_conf)
- : RGWProcessFrontend(pe, _conf) {}
+ log_init();
- int init();
+ get_state()->obj_ctx = &rados_ctx;
+ get_state()->req_id = store->unique_id(id);
+ get_state()->trans_id = store->unique_trans_id(id);
- inline void enqueue_req(RGWLibRequest* req) {
- static_cast<RGWLibProcess*>(pprocess)->enqueue_req(req); // async
- }
+ log_format(get_state(), "initializing for trans_id = %s",
+ get_state()->trans_id.c_str());
+ }
- inline int execute_req(RGWLibRequest* req) {
- return static_cast<RGWLibProcess*>(pprocess)->process_request(req); // !async
- }
+ inline RGWRados* get_store() { return store; }
- inline int start_req(RGWLibContinuedReq* req) {
- return static_cast<RGWLibProcess*>(pprocess)->start_request(req);
- }
+ virtual int execute() final { abort(); }
+ virtual int exec_start() = 0;
+ virtual int exec_continue() = 0;
+ virtual int exec_finish() = 0;
- inline int finish_req(RGWLibContinuedReq* req) {
- return static_cast<RGWLibProcess*>(pprocess)->finish_request(req);
- }
+ }; /* RGWLibContinuedReq */
-}; /* RGWLibFrontend */
+} /* namespace rgw */
#endif /* RGW_LIB_H */
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_LIB_FRONTEND_H
+#define RGW_LIB_FRONTEND_H
+
+#include <boost/container/flat_map.hpp>
+
+#include "rgw_lib.h"
+#include "rgw_file.h"
+
+namespace rgw {
+
+ class RGWLibProcess : public RGWProcess {
+ RGWAccessKey access_key;
+ public:
+ RGWLibProcess(CephContext* cct, RGWProcessEnv* pe, int num_threads,
+ RGWFrontendConfig* _conf) :
+ RGWProcess(cct, pe, num_threads, _conf) {}
+
+ void run();
+ void checkpoint();
+
+ void enqueue_req(RGWLibRequest* req) {
+
+ lsubdout(g_ceph_context, rgw, 10)
+ << __func__ << " enqueue request req="
+ << hex << req << dec << dendl;
+
+ req_throttle.get(1);
+ req_wq.queue(req);
+ } /* enqueue_req */
+
+ /* "regular" requests */
+ void handle_request(RGWRequest* req); // async handler, deletes req
+ int process_request(RGWLibRequest* req);
+ int process_request(RGWLibRequest* req, RGWLibIO* io);
+ void set_access_key(RGWAccessKey& key) { access_key = key; }
+
+ /* requests w/continue semantics */
+ int start_request(RGWLibContinuedReq* req);
+ int finish_request(RGWLibContinuedReq* req);
+ }; /* RGWLibProcess */
+
+ class RGWLibFrontend : public RGWProcessFrontend {
+ public:
+ RGWLibFrontend(RGWProcessEnv& pe, RGWFrontendConfig *_conf)
+ : RGWProcessFrontend(pe, _conf) {}
+
+ int init();
+
+ inline void enqueue_req(RGWLibRequest* req) {
+ static_cast<RGWLibProcess*>(pprocess)->enqueue_req(req); // async
+ }
+
+ inline int execute_req(RGWLibRequest* req) {
+ return static_cast<RGWLibProcess*>(pprocess)->process_request(req); // !async
+ }
+
+ inline int start_req(RGWLibContinuedReq* req) {
+ return static_cast<RGWLibProcess*>(pprocess)->start_request(req);
+ }
+
+ inline int finish_req(RGWLibContinuedReq* req) {
+ return static_cast<RGWLibProcess*>(pprocess)->finish_request(req);
+ }
+
+ }; /* RGWLibFrontend */
+
+} /* namespace rgw */
+
+#endif /* RGW_LIB_FRONTEND_H */
#include "rgw_rest_user.h"
#include "rgw_os_lib.h"
#include "rgw_file.h"
+#include "rgw_lib_frontend.h"
+namespace rgw {
/* static */
-int RGWHandler_Lib::init_from_header(struct req_state *s)
-{
- string req;
- string first;
-
- 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 {
- p = s->info.request_params.c_str();
- }
-
- s->info.args.set(p);
- s->info.args.parse();
-
- if (*req_name != '/')
- return 0;
+ int RGWHandler_Lib::init_from_header(struct req_state *s)
+ {
+ string req;
+ string first;
+
+ 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 {
+ p = s->info.request_params.c_str();
+ }
- req_name++;
+ s->info.args.set(p);
+ s->info.args.parse();
- if (!*req_name)
- return 0;
+ if (*req_name != '/')
+ return 0;
+
+ req_name++;
- req = req_name;
- int pos = req.find('/');
- if (pos >= 0) {
- first = req.substr(0, pos);
- } else {
- first = req;
- }
+ if (!*req_name)
+ return 0;
- if (s->bucket_name.empty()) {
- s->bucket_name = std::move(first);
+ req = req_name;
+ int pos = req.find('/');
if (pos >= 0) {
- // XXX ugh, another copy
- string encoded_obj_str = req.substr(pos+1);
- s->object = rgw_obj_key(encoded_obj_str, s->info.args.get("versionId"));
+ first = req.substr(0, pos);
+ } else {
+ first = req;
}
- } else {
- s->object = rgw_obj_key(req_name, s->info.args.get("versionId"));
- }
- return 0;
-} /* init_from_header */
+
+ if (s->bucket_name.empty()) {
+ s->bucket_name = std::move(first);
+ if (pos >= 0) {
+ // XXX ugh, another copy
+ string encoded_obj_str = req.substr(pos+1);
+ s->object = rgw_obj_key(encoded_obj_str, s->info.args.get("versionId"));
+ }
+ } else {
+ s->object = rgw_obj_key(req_name, s->info.args.get("versionId"));
+ }
+ return 0;
+ } /* init_from_header */
+
+} /* namespace rgw */