From: Jason Dillaman Date: Fri, 6 Feb 2015 07:03:03 +0000 (-0500) Subject: librados: add blacklist_add API method X-Git-Tag: v0.93~54^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a616de92d6a48b9eb0af6beefc216ebb919b05f2;p=ceph.git librados: add blacklist_add API method Convenience method to invoke the mon "osd blacklist add" command and validating the result. Signed-off-by: Jason Dillaman --- diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index 0f4a1e576005..e30ab062fada 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -2797,6 +2797,19 @@ CEPH_RADOS_API ssize_t rados_list_lockers(rados_ioctx_t io, const char *o, CEPH_RADOS_API int rados_break_lock(rados_ioctx_t io, const char *o, const char *name, const char *client, const char *cookie); + +/** + * Blacklists the specified client from the OSDs + * + * @param cluster cluster handle + * @param client_address client address + * @param expire_seconds number of seconds to blacklist (0 for default) + * @returns 0 on success, negative error code on failure + */ +CEPH_RADOS_API int rados_blacklist_add(rados_t cluster, + char *client_address, + uint32_t expire_seconds); + /** * @defgroup librados_h_commands Mon/OSD/PG Commands * diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index 77e334b6eca5..e7ea5987d03c 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -1108,6 +1108,9 @@ namespace librados /// get/wait for the most recent osdmap int wait_for_latest_osdmap(); + int blacklist_add(const std::string& client_address, + uint32_t expire_seconds); + /* * pool aio * diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc index ad018325ed93..5af23fab56e6 100644 --- a/src/librados/RadosClient.cc +++ b/src/librados/RadosClient.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -656,6 +657,32 @@ void librados::RadosClient::blacklist_self(bool set) { objecter->blacklist_self(set); } +int librados::RadosClient::blacklist_add(const string& client_address, + uint32_t expire_seconds) +{ + entity_addr_t addr; + if (!addr.parse(client_address.c_str(), 0)) { + lderr(cct) << "unable to parse address " << client_address << dendl; + return -EINVAL; + } + + std::stringstream cmd; + cmd << "{" + << "\"prefix\": \"osd blacklist\", " + << "\"blacklistop\": \"add\", " + << "\"addr\": \"" << client_address << "\""; + if (expire_seconds != 0) { + cmd << ", \"expire\": " << expire_seconds << ".0"; + } + cmd << "}"; + + std::vector cmds; + cmds.push_back(cmd.str()); + bufferlist inbl; + int r = mon_command(cmds, inbl, NULL, NULL); + return r; +} + int librados::RadosClient::mon_command(const vector& cmd, const bufferlist &inbl, bufferlist *outbl, string *outs) diff --git a/src/librados/RadosClient.h b/src/librados/RadosClient.h index 453dc3b57366..f4eb0833c0a5 100644 --- a/src/librados/RadosClient.h +++ b/src/librados/RadosClient.h @@ -109,6 +109,8 @@ public: int pool_delete_async(const char *name, PoolAsyncCompletionImpl *c); + int blacklist_add(const string& client_address, uint32_t expire_seconds); + int mon_command(const vector& cmd, const bufferlist &inbl, bufferlist *outbl, string *outs); int mon_command(int rank, diff --git a/src/librados/librados.cc b/src/librados/librados.cc index 7854ad3cbe77..1bb8c5685d84 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -2126,6 +2126,12 @@ int librados::Rados::wait_for_latest_osdmap() return client->wait_for_latest_osdmap(); } +int librados::Rados::blacklist_add(const std::string& client_address, + uint32_t expire_seconds) +{ + return client->blacklist_add(client_address, expire_seconds); +} + librados::PoolAsyncCompletion *librados::Rados::pool_async_create_completion() { PoolAsyncCompletionImpl *c = new PoolAsyncCompletionImpl; @@ -2471,6 +2477,13 @@ extern "C" int rados_wait_for_latest_osdmap(rados_t cluster) return retval; } +extern "C" int rados_blacklist_add(rados_t cluster, char *client_address, + uint32_t expire_seconds) +{ + librados::RadosClient *radosp = (librados::RadosClient *)cluster; + return radosp->blacklist_add(client_address, expire_seconds); +} + extern "C" int rados_pool_list(rados_t cluster, char *buf, size_t len) { tracepoint(librados, rados_pool_list_enter, cluster, len); diff --git a/src/pybind/rados.py b/src/pybind/rados.py index 41b0c4548e60..85ee8e7793db 100644 --- a/src/pybind/rados.py +++ b/src/pybind/rados.py @@ -5,7 +5,7 @@ Copyright 2011, Hannu Valtonen """ from ctypes import CDLL, c_char_p, c_size_t, c_void_p, c_char, c_int, c_long, \ c_ulong, create_string_buffer, byref, Structure, c_uint64, c_ubyte, \ - pointer, CFUNCTYPE, c_int64, c_uint8 + pointer, CFUNCTYPE, c_int64, c_uint32, c_uint8 from ctypes.util import find_library import ctypes import errno @@ -766,6 +766,24 @@ Rados object in state %s." % self.state) self.require_state("connected") return run_in_thread(self.librados.rados_wait_for_latest_osdmap, (self.cluster,)) + def blacklist_add(self, client_address, expire_seconds = 0): + """ + Blacklist a client from the OSDs + + :param client_address: client address + :type client_address: str + :param expire_seconds: number of seconds to blacklist + :type expire_seconds: int + + :raises: :class:`Error` + """ + self.require_state("connected") + ret = run_in_thread(self.librados.rados_blacklist_add, + (self.cluster, c_char_p(client_address), + c_uint32(expire_seconds))) + if ret < 0: + raise make_ex(ret, "error blacklisting client '%s'" % client_address) + class ObjectIterator(object): """rados.Ioctx Object iterator""" def __init__(self, ioctx): diff --git a/src/test/pybind/test_rados.py b/src/test/pybind/test_rados.py index 4595586e2619..186e34dc34d6 100644 --- a/src/test/pybind/test_rados.py +++ b/src/test/pybind/test_rados.py @@ -65,6 +65,7 @@ class TestRadosStateError(object): assert_raises(RadosStateError, rados.osd_command, 0, '', '') assert_raises(RadosStateError, rados.pg_command, '', '', '') assert_raises(RadosStateError, rados.wait_for_latest_osdmap) + assert_raises(RadosStateError, rados.blacklist_add, '127.0.0.1/123', 0) def test_configuring(self): rados = Rados(conffile='') @@ -173,6 +174,9 @@ class TestRados(object): fsid = self.rados.get_fsid() eq(len(fsid), 36) + def test_blacklist_add(self): + self.rados.blacklist_add("1.2.3.4/123", 1) + class TestIoctx(object): def setUp(self):