From 665a85701177230365e43a351d7722cb2adbde93 Mon Sep 17 00:00:00 2001 From: Orit Wasserman Date: Thu, 23 Apr 2015 17:36:47 +0200 Subject: [PATCH] rgw: civetweb should use unique request id max_req_id was moved to RGWRados and changed to atomic64_t. The same request id resulted in gc giving the same idtag to all objects resulting in a leakage of rados objects. It only kept the last deleted object in it's queue, the previous objects were never freed. Fixes: 10295 Backport: Hammer, Firefly Signed-off-by: Orit Wasserman (cherry picked from commit c262259) Conflicts: src/rgw/rgw_main.cc src/rgw/rgw_rados.h --- src/rgw/rgw_main.cc | 25 ++++++++++++------------- src/rgw/rgw_rados.h | 7 ++++++- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index 24094d4e29a..8c0b40d171a 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -91,7 +91,7 @@ struct RGWRequest RGWOp *op; utime_t ts; - RGWRequest() : id(0), s(NULL), op(NULL) { + RGWRequest(uint64_t id) : id(id), s(NULL), op(NULL) { } virtual ~RGWRequest() {} @@ -152,6 +152,9 @@ public: struct RGWFCGXRequest : public RGWRequest { FCGX_Request fcgx; + + RGWFCGXRequest(uint64_t req_id) : RGWRequest(req_id) {} + }; struct RGWProcessEnv { @@ -222,8 +225,6 @@ protected: } } req_wq; - uint64_t max_req_id; - public: RGWProcess(CephContext *cct, RGWProcessEnv *pe, int num_threads, RGWFrontendConfig *_conf) : store(pe->store), olog(pe->olog), m_tp(cct, "RGWProcess::m_tp", num_threads), @@ -232,8 +233,7 @@ public: conf(_conf), sock_fd(-1), req_wq(this, g_conf->rgw_op_thread_timeout, - g_conf->rgw_op_thread_suicide_timeout, &m_tp), - max_req_id(0) {} + g_conf->rgw_op_thread_suicide_timeout, &m_tp) {} virtual ~RGWProcess() {} virtual void run() = 0; virtual void handle_request(RGWRequest *req) = 0; @@ -310,8 +310,7 @@ void RGWFCGXProcess::run() m_tp.start(); for (;;) { - RGWFCGXRequest *req = new RGWFCGXRequest; - req->id = ++max_req_id; + RGWFCGXRequest *req = new RGWFCGXRequest(store->get_new_req_id()); dout(10) << "allocated request req=" << hex << req << dec << dendl; FCGX_InitRequest(&req->fcgx, sock_fd, 0); req_throttle.get(1); @@ -337,8 +336,8 @@ struct RGWLoadGenRequest : public RGWRequest { atomic_t *fail_flag; - RGWLoadGenRequest(const string& _m, const string& _r, int _cl, - atomic_t *ff) : method(_m), resource(_r), content_length(_cl), fail_flag(ff) {} + RGWLoadGenRequest(uint64_t req_id, const string& _m, const string& _r, int _cl, + atomic_t *ff) : RGWRequest(req_id), method(_m), resource(_r), content_length(_cl), fail_flag(ff) {} }; class RGWLoadGenProcess : public RGWProcess { @@ -439,8 +438,8 @@ done: void RGWLoadGenProcess::gen_request(const string& method, const string& resource, int content_length, atomic_t *fail_flag) { - RGWLoadGenRequest *req = new RGWLoadGenRequest(method, resource, content_length, fail_flag); - req->id = ++max_req_id; + RGWLoadGenRequest *req = new RGWLoadGenRequest(store->get_new_req_id(), method, resource, + content_length, fail_flag); dout(10) << "allocated request req=" << hex << req << dec << dendl; req_throttle.get(1); req_wq.queue(req); @@ -638,7 +637,7 @@ void RGWFCGXProcess::handle_request(RGWRequest *r) RGWFCGXRequest *req = static_cast(r); FCGX_Request *fcgx = &req->fcgx; RGWFCGX client_io(fcgx); - + int ret = process_request(store, rest, req, &client_io, olog); if (ret < 0) { @@ -694,7 +693,7 @@ static int civetweb_callback(struct mg_connection *conn) { RGWREST *rest = pe->rest; OpsLogSocket *olog = pe->olog; - RGWRequest *req = new RGWRequest; + RGWRequest *req = new RGWRequest(store->get_new_req_id()); RGWMongoose client_io(conn, pe->port); client_io.init(g_ceph_context); diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index ff161b837a7..2281f9a80e8 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1208,6 +1208,7 @@ class RGWRados GetObjState() : sent_data(false) {} }; + atomic64_t max_req_id; Mutex lock; SafeTimer *timer; @@ -1296,7 +1297,7 @@ protected: RGWQuotaHandler *quota_handler; public: - RGWRados() : lock("rados_timer_lock"), timer(NULL), + RGWRados() : max_req_id(0), lock("rados_timer_lock"), timer(NULL), gc(NULL), use_gc_thread(false), quota_threads(false), num_watchers(0), watchers(NULL), watch_handles(NULL), watch_initialized(false), @@ -1307,6 +1308,10 @@ public: rest_master_conn(NULL), meta_mgr(NULL), data_log(NULL) {} + uint64_t get_new_req_id() { + return max_req_id.inc(); + } + void set_context(CephContext *_cct) { cct = _cct; } -- 2.47.3