]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: add method to get the fsid of a cluster
authorJosh Durgin <josh.durgin@inktank.com>
Thu, 9 Aug 2012 02:13:45 +0000 (19:13 -0700)
committerJosh Durgin <josh.durgin@inktank.com>
Thu, 9 Aug 2012 18:14:39 +0000 (11:14 -0700)
This will be used by OpenStack to check whether two components
have access to the same backend cluster.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
src/include/rados/librados.h
src/include/rados/librados.hpp
src/librados/RadosClient.cc
src/librados/RadosClient.h
src/librados/librados.cc
src/pybind/rados.py
src/test/pybind/test_rados.py
src/test/rados-api/misc.cc

index 897471a469419934949e0cce3034c19c9964d6df..6660b61e35de7d867bddbcbef58f40cc30f86b5c 100644 (file)
@@ -349,6 +349,19 @@ int rados_conf_get(rados_t cluster, const char *option, char *buf, size_t len);
  */
 int rados_cluster_stat(rados_t cluster, struct rados_cluster_stat_t *result);
 
+/**
+ * Get the fsid of the cluster as a hexadecimal string.
+ *
+ * The fsid is a unique id of an entire Ceph cluster.
+ *
+ * @param cluster where to get the fsid
+ * @param buf where to write the fsid
+ * @param len the size of buf in bytes (should be 37)
+ * @returns 0 on success, negative error code on failure
+ * @returns -ERANGE if the buffer is too short to contain the
+ * fsid
+ */
+int rados_cluster_fsid(rados_t cluster, char *buf, size_t len);
 
 /**
  * @defgroup librados_h_pools Pools
index 3a3f4775103c344db54b8ee63a6345ec9101d00c..d9545d467560eb00e0ad984528042ef226c92432 100644 (file)
@@ -518,6 +518,7 @@ namespace librados
                        std::string& category,
                       std::map<std::string, stats_map>& stats);
     int cluster_stat(cluster_stat_t& result);
+    int cluster_fsid(std::string *fsid);
 
     /* pool aio */
     static PoolAsyncCompletion *pool_async_create_completion();
index e70033623c67ff93e65d0635bbd13711a0946d83..a2e4463400c559c50084c530c9ada0c60a4ae8c2 100644 (file)
@@ -103,6 +103,17 @@ int librados::RadosClient::pool_get_name(uint64_t pool_id, std::string *s)
   return 0;
 }
 
+int librados::RadosClient::get_fsid(std::string *s)
+{
+  if (!s)
+    return -EINVAL;
+  Mutex::Locker l(lock);
+  ostringstream oss;
+  oss << osdmap.get_fsid();
+  *s = oss.str();
+  return 0;
+}
+
 int librados::RadosClient::connect()
 {
   common_init_finish(cct);
index 3ca6153df5b88e6c291c378b8f53b059935c0e6d..1f39f22fb3f31fef90bc7dc1e41dde990b9637b0 100644 (file)
@@ -76,6 +76,7 @@ public:
 
   int create_ioctx(const char *name, IoCtxImpl **io);
 
+  int get_fsid(std::string *s);
   int64_t lookup_pool(const char *name);
   const char *get_pool_name(int64_t pool_id);
   int pool_get_auid(uint64_t pool_id, unsigned long long *auid);
index 69ba440d5de8f5dc963546a871719a84db3af902..4c7426aead2073d6ba347fbb0506adba54460e15 100644 (file)
@@ -1254,6 +1254,11 @@ int librados::Rados::cluster_stat(cluster_stat_t& result)
   return r;
 }
 
+int librados::Rados::cluster_fsid(string *fsid)
+{
+  return client->get_fsid(fsid);
+}
+
 librados::PoolAsyncCompletion *librados::Rados::pool_async_create_completion()
 {
   PoolAsyncCompletionImpl *c = new PoolAsyncCompletionImpl;
@@ -1447,6 +1452,18 @@ extern "C" int rados_pool_reverse_lookup(rados_t cluster, int64_t id,
   return name.length();
 }
 
+extern "C" int rados_cluster_fsid(rados_t cluster, char *buf,
+                                 size_t maxlen)
+{
+  librados::RadosClient *radosp = (librados::RadosClient *)cluster;
+  std::string fsid;
+  radosp->get_fsid(&fsid);
+  if (fsid.length() >= maxlen)
+    return -ERANGE;
+  strcpy(buf, fsid.c_str());
+  return fsid.length();
+}
+
 extern "C" int rados_pool_list(rados_t cluster, char *buf, size_t len)
 {
   librados::RadosClient *client = (librados::RadosClient *)cluster;
index 4ef77ad32891e4ebadeb9287444c2bd2ec966b3a..5dbf998cef6af38d1d5427d0b93ff0dd17f98345 100755 (executable)
@@ -242,6 +242,17 @@ Rados object in state %s." % (self.state))
                 break
         return filter(lambda name: name != '', c_names.raw.split('\0'))
 
+    def get_fsid(self):
+        self.require_state("connected")
+        fsid_len = 36
+        fsid = create_string_buffer(fsid_len + 1)
+        ret = self.librados.rados_cluster_fsid(self.cluster,
+                                               byref(fsid),
+                                               fsid_len + 1)
+        if ret < 0:
+            raise make_ex(ret, "error getting cluster fsid")
+        return fsid.value
+
     def open_ioctx(self, ioctx_name):
         self.require_state("connected")
         if not isinstance(ioctx_name, str):
index c91dea904e80e296edaaa00b6a583c53e13f9683..dab50cff2ae628aff063bab93ecfa41a52e6f610 100644 (file)
@@ -3,7 +3,7 @@ from rados import (Rados, Object, ObjectExists, ObjectNotFound,
                    ANONYMOUS_AUID, ADMIN_AUID)
 import threading
 
-class TestPool(object):
+class TestRados(object):
 
     def setUp(self):
         self.rados = Rados(conffile='')
@@ -51,6 +51,10 @@ class TestPool(object):
         eq(set(['a' * 500]), self.list_non_default_pools())
         self.rados.delete_pool('a' * 500)
 
+    def test_get_fsid(self):
+        fsid = self.rados.get_fsid()
+        eq(len(fsid), 36)
+
 class TestIoctx(object):
 
     def setUp(self):
index a1feeed2f11840c9da681211a8ec99e96a0ed927..0821ec0778482f3ec55882a685659c8af9248766 100644 (file)
@@ -27,6 +27,19 @@ TEST(LibRadosMisc, VersionPP) {
   Rados::version(&major, &minor, &extra);
 }
 
+TEST(LibRadosMisc, ClusterFSID) {
+  rados_t cluster;
+  std::string pool_name = get_temp_pool_name();
+  ASSERT_EQ("", create_one_pool(pool_name, &cluster));
+
+  char fsid[37];
+  ASSERT_EQ(-ERANGE, rados_cluster_fsid(cluster, fsid, sizeof(fsid) - 1));
+  ASSERT_EQ(sizeof(fsid) - 1,
+            (size_t)rados_cluster_fsid(cluster, fsid, sizeof(fsid)));
+
+  ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
+}
+
 static std::string read_key_from_tmap(IoCtx& ioctx, const std::string &obj,
                                      const std::string &key)
 {