diff -Nru ceph-0.80.9/debian/changelog ceph-0.80.9/debian/changelog --- ceph-0.80.9/debian/changelog 2015-03-11 02:14:37.000000000 -0700 +++ ceph-0.80.9/debian/changelog 2015-04-06 15:46:01.000000000 -0700 @@ -1,3 +1,13 @@ +ceph (0.80.9-0ubuntu0.14.04.2) trusty; urgency=medium + + [ Billy Olsen ] + * Fix memory leak in rados.py (LP: #1425164) + - d/p/fix-python-rados-memleak.patch: patches the rados.py Ioctx + class to remove circular dependencies which prevent python from + garbage collecting object references. + + -- Billy Olsen Mon, 06 Apr 2015 15:43:58 -0700 + ceph (0.80.9-0ubuntu0.14.04.1) trusty; urgency=medium [ James Page ] diff -Nru ceph-0.80.9/debian/patches/fix-python-rados-memleak.patch ceph-0.80.9/debian/patches/fix-python-rados-memleak.patch --- ceph-0.80.9/debian/patches/fix-python-rados-memleak.patch 1969-12-31 17:00:00.000000000 -0700 +++ ceph-0.80.9/debian/patches/fix-python-rados-memleak.patch 2015-04-06 15:43:06.000000000 -0700 @@ -0,0 +1,98 @@ +From 236c2f5748dbb34a3a2800eb4df048916bf7a6ec Mon Sep 17 00:00:00 2001 +From: Billy Olsen +Date: Mon, 2 Feb 2015 16:24:59 -0700 +Subject: [PATCH 1/1] Fix memory leak in python rados bindings + +A circular reference was inadvertently created when using the +CFUNCTYPE binding for callbacks for the asynchronous i/o callbacks. +This commit refactors the usage of the callbacks such that the +Ioctx object does not have a class reference to the callbacks. + +Fixes: #10723 +Backport: giant, firefly, dumpling +Signed-off-by: Billy Olsen +Reviewed-by: Dan Mick +Reviewed-by: Josh Durgin +(cherry picked from commit 60b019f69aa0e39d276c669698c92fc890599f50) + +rados.py: keep reference to python callbacks + +If we don't keep a reference to these, the librados aio calls will +segfault since the python-level callbacks will have been garbage +collected. Passing them to aio_create_completion() does not take a +reference to them. Keep a reference in the python Completion object +associated with the request, since they need the same lifetime. + +This fixes a regression from 60b019f69aa0e39d276c669698c92fc890599f50. + +Fixes: #10775 +Backport: dumpling, firefly, giant +Signed-off-by: Josh Durgin +(cherry picked from commit 36d37aadbbbece28d70e827511f1a473d851463d) +--- + src/pybind/rados.py | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/pybind/rados.py b/src/pybind/rados.py +index ec68919..e3f8435 100644 +--- a/src/pybind/rados.py ++++ b/src/pybind/rados.py +@@ -829,11 +829,14 @@ class Snap(object): + + class Completion(object): + """completion object""" +- def __init__(self, ioctx, rados_comp, oncomplete, onsafe): ++ def __init__(self, ioctx, rados_comp, oncomplete, onsafe, ++ complete_cb, safe_cb): + self.rados_comp = rados_comp + self.oncomplete = oncomplete + self.onsafe = onsafe + self.ioctx = ioctx ++ self.complete_cb = complete_cb ++ self.safe_cb = safe_cb + + def wait_for_safe(self): + """ +@@ -879,6 +882,8 @@ class Completion(object): + run_in_thread(self.ioctx.librados.rados_aio_release, + (self.rados_comp,)) + ++RADOS_CB = CFUNCTYPE(c_int, c_void_p, c_void_p) ++ + class Ioctx(object): + """rados.Ioctx object""" + def __init__(self, name, librados, io): +@@ -889,9 +894,6 @@ class Ioctx(object): + self.locator_key = "" + self.safe_cbs = {} + self.complete_cbs = {} +- RADOS_CB = CFUNCTYPE(c_int, c_void_p, c_void_p) +- self.__aio_safe_cb_c = RADOS_CB(self.__aio_safe_cb) +- self.__aio_complete_cb_c = RADOS_CB(self.__aio_complete_cb) + self.lock = threading.Lock() + + def __enter__(self): +@@ -944,16 +946,17 @@ class Ioctx(object): + complete_cb = None + safe_cb = None + if oncomplete: +- complete_cb = self.__aio_complete_cb_c ++ complete_cb = RADOS_CB(self.__aio_complete_cb) + if onsafe: +- safe_cb = self.__aio_safe_cb_c ++ safe_cb = RADOS_CB(self.__aio_safe_cb) + ret = run_in_thread(self.librados.rados_aio_create_completion, + (c_void_p(0), complete_cb, safe_cb, + byref(completion))) + if ret < 0: + raise make_ex(ret, "error getting a completion") + with self.lock: +- completion_obj = Completion(self, completion, oncomplete, onsafe) ++ completion_obj = Completion(self, completion, oncomplete, onsafe, ++ complete_cb, safe_cb) + if oncomplete: + self.complete_cbs[completion.value] = completion_obj + if onsafe: +-- +2.1.0 + diff -Nru ceph-0.80.9/debian/patches/series ceph-0.80.9/debian/patches/series --- ceph-0.80.9/debian/patches/series 2015-03-10 14:30:02.000000000 -0700 +++ ceph-0.80.9/debian/patches/series 2015-04-06 15:43:06.000000000 -0700 @@ -1,3 +1,4 @@ virtualenv-never-download modules.patch increaseFileLimit.patch +fix-python-rados-memleak.patch