diff --git a/src/pybind/rados/rados.pyx b/src/pybind/rados/rados.pyx index 017b2e027ff..740732c6d75 100644 --- a/src/pybind/rados/rados.pyx +++ b/src/pybind/rados/rados.pyx @@ -223,6 +223,9 @@ cdef extern from "rados/librados.h" nogil: int rados_nobjects_list_next(rados_list_ctx_t ctx, const char **entry, const char **key, const char **nspace) void rados_nobjects_list_close(rados_list_ctx_t ctx) + int rados_ioctx_pool_requires_alignment2(rados_ioctx_t io, int * requires) + int rados_ioctx_pool_required_alignment2(rados_ioctx_t io, uint64_t * alignment) + int rados_ioctx_snap_rollback(rados_ioctx_t io, const char * oid, const char * snapname) int rados_ioctx_snap_create(rados_ioctx_t io, const char * snapname) int rados_ioctx_snap_remove(rados_ioctx_t io, const char * snapname) @@ -3791,6 +3794,32 @@ returned %d, but should return zero on success." % (self.name, ret)) free(c_keys) free(c_vals) + def alignment(self): + """ + Returns pool alignment + + :returns: + Number of alignment bytes required by the current pool, or None if + alignment is not required. + """ + cdef: + int requires = 0 + uint64_t _alignment + + with nogil: + ret = rados_ioctx_pool_requires_alignment2(self.io, &requires) + if ret != 0: + raise make_ex(ret, "error checking alignment") + + alignment = None + if requires: + with nogil: + ret = rados_ioctx_pool_required_alignment2(self.io, &_alignment) + if ret != 0: + raise make_ex(ret, "error querying alignment") + alignment = _alignment + return alignment + def set_object_locator(func): def retfunc(self, *args, **kwargs): diff --git a/src/test/pybind/test_rados.py b/src/test/pybind/test_rados.py index 378fdf08cb2..098e5ef15ff 100644 --- a/src/test/pybind/test_rados.py +++ b/src/test/pybind/test_rados.py @@ -899,6 +899,41 @@ class TestIoctx(object): status = {'result': 'unknown', 'test': 'running'} self.rados.service_daemon_update(status) + def test_alignment(self): + eq(self.ioctx.alignment(), None) + + +class TestIoctxEc(object): + + def setUp(self): + self.rados = Rados(conffile='') + self.rados.connect() + self.pool = 'test-ec' + self.profile = 'testprofile-%s' % self.pool + cmd = {"prefix": "osd erasure-code-profile set", + "name": self.profile, "profile": ["k=2", "m=1", "crush-failure-domain=osd"]} + ret, buf, out = self.rados.mon_command(json.dumps(cmd), b'', timeout=30) + eq(ret, 0, msg=out) + # create ec pool with profile created above + cmd = {'prefix': 'osd pool create', 'pg_num': 8, 'pgp_num': 8, + 'pool': self.pool, 'pool_type': 'erasure', + 'erasure_code_profile': self.profile} + ret, buf, out = self.rados.mon_command(json.dumps(cmd), b'', timeout=30) + eq(ret, 0, msg=out) + assert self.rados.pool_exists(self.pool) + self.ioctx = self.rados.open_ioctx(self.pool) + + def tearDown(self): + cmd = {"prefix": "osd unset", "key": "noup"} + self.rados.mon_command(json.dumps(cmd), b'') + self.ioctx.close() + self.rados.delete_pool(self.pool) + self.rados.shutdown() + + def test_alignment(self): + eq(self.ioctx.alignment(), 8192) + + class TestIoctx2(object): def setUp(self):