]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
libcephfs: add ceph_mds_command
authorJohn Spray <john.spray@redhat.com>
Thu, 18 Sep 2014 17:57:11 +0000 (18:57 +0100)
committerJohn Spray <john.spray@redhat.com>
Wed, 8 Oct 2014 10:58:19 +0000 (11:58 +0100)
Wraps the equivalent fn in Client.

Signed-off-by: John Spray <john.spray@redhat.com>
src/include/cephfs/libcephfs.h
src/libcephfs.cc

index 282f41b4f9b45ef0717c6550587f85344eae0c14..ca386a9f652e52d188f13ceed5d1a21c7d9325cb 100644 (file)
@@ -150,9 +150,20 @@ int ceph_create(struct ceph_mount_info **cmount, const char * const id);
  */
 int ceph_create_with_context(struct ceph_mount_info **cmount, struct CephContext *conf);
 
+/**
+ * Initialize the filesystem client (but do not mount the filesystem yet)
+ *
+ * @returns 0 on success, negative error code on failure
+ */
+int ceph_init(struct ceph_mount_info *cmount);
+
+
 /**
  * Perform a mount using the path for the root of the mount.
  *
+ * It is optional to call ceph_init before this.  If ceph_init has
+ * not already been called, it will be called in the course of this operation.
+ *
  * @param cmount the mount info handle
  * @param root the path for the root of the mount.  This can be an existing
  *            directory within the ceph cluster, but most likely it will
@@ -161,6 +172,38 @@ int ceph_create_with_context(struct ceph_mount_info **cmount, struct CephContext
  */
 int ceph_mount(struct ceph_mount_info *cmount, const char *root);
 
+
+/**
+ * Execute a management command remotely on an MDS.
+ *
+ * Must have called ceph_init or ceph_mount before calling this.
+ *
+ * @param mds_spec string representing rank, MDS name, GID or '*'
+ * @param cmd array of null-terminated strings
+ * @param cmdlen length of cmd array
+ * @param inbuf non-null-terminated input data to command
+ * @param inbuflen length in octets of inbuf
+ * @param outbuf populated with pointer to buffer (command output data)
+ * @param outbuflen length of allocated outbuf
+ * @param outs populated with pointer to buffer (command error strings)
+ * @param outslen length of allocated outs
+ *
+ * @return 0 on success, negative error code on failure
+ *
+ */
+int ceph_mds_command(struct ceph_mount_info *cmount,
+    const char *mds_spec,
+    const char **cmd,
+    size_t cmdlen,
+    const char *inbuf, size_t inbuflen,
+    char **outbuf, size_t *outbuflen,
+    char **outs, size_t *outslen);
+
+/**
+ * Free a buffer, such as those used for output arrays from ceph_mds_command
+ */
+void ceph_buffer_free(char *buf);
+
 /**
  * Unmount a mount handle.
  *
index 9fd050946cc926c5855d1be099ba42135df754dc..871dbcfe2e38dba8ce70848b27d44a7fe9019c6c 100644 (file)
@@ -64,15 +64,12 @@ public:
     }
   }
 
-  int mount(const std::string &mount_root)
+  int init()
   {
-    int ret;
-    
-    if (mounted)
-      return -EISCONN;
-
     common_init_finish(cct);
 
+    int ret;
+
     //monmap
     monclient = new MonClient(cct);
     ret = -1000;
@@ -97,19 +94,35 @@ public:
       goto fail;
 
     inited = true;
-
-    ret = client->mount(mount_root);
-    if (ret)
-      goto fail;
-
-    mounted = true;
     return 0;
 
-  fail:
+    fail:
     shutdown();
     return ret;
   }
 
+  int mount(const std::string &mount_root)
+  {
+    int ret;
+    
+    if (mounted)
+      return -EISCONN;
+
+    ret = init();
+    if (ret != 0) {
+      return ret;
+    }
+
+    ret = client->mount(mount_root);
+    if (ret) {
+      shutdown();
+      return ret;
+    } else {
+      mounted = true;
+      return 0;
+    }
+  }
+
   int unmount()
   {
     if (!mounted)
@@ -144,6 +157,11 @@ public:
     }
   }
 
+  bool is_initialized() const
+  {
+    return inited;
+  }
+
   bool is_mounted()
   {
     return mounted;
@@ -225,6 +243,34 @@ private:
   std::string cwd;
 };
 
+static void do_out_buffer(bufferlist& outbl, char **outbuf, size_t *outbuflen)
+{
+  if (outbuf) {
+    if (outbl.length() > 0) {
+      *outbuf = (char *)malloc(outbl.length());
+      memcpy(*outbuf, outbl.c_str(), outbl.length());
+    } else {
+      *outbuf = NULL;
+    }
+  }
+  if (outbuflen)
+    *outbuflen = outbl.length();
+}
+
+static void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen)
+{
+  if (outbuf) {
+    if (outbl.length() > 0) {
+      *outbuf = (char *)malloc(outbl.length());
+      memcpy(*outbuf, outbl.c_str(), outbl.length());
+    } else {
+      *outbuf = NULL;
+    }
+  }
+  if (outbuflen)
+    *outbuflen = outbl.length();
+}
+
 extern "C" const char *ceph_version(int *pmajor, int *pminor, int *ppatch)
 {
   int major, minor, patch;
@@ -316,6 +362,57 @@ extern "C" int ceph_conf_get(struct ceph_mount_info *cmount, const char *option,
   return cmount->conf_get(option, buf, len);
 }
 
+extern "C" int ceph_mds_command(struct ceph_mount_info *cmount,
+    const char *mds_spec,
+    const char **cmd,
+    size_t cmdlen,
+    const char *inbuf, size_t inbuflen,
+    char **outbuf, size_t *outbuflen,
+    char **outsbuf, size_t *outsbuflen)
+{
+  bufferlist inbl;
+  bufferlist outbl;
+  std::vector<string> cmdv;
+  std::string outs;
+
+  if (!cmount->is_initialized()) {
+    return -ENOTCONN;
+  }
+
+  // Construct inputs
+  for (size_t i = 0; i < cmdlen; ++i) {
+    cmdv.push_back(cmd[i]);
+  }
+  inbl.append(inbuf, inbuflen);
+
+  // Issue remote command
+  C_SaferCond cond;
+  int r = cmount->get_client()->mds_command(
+      mds_spec,
+      cmdv, inbl,
+      &outbl, &outs,
+      &cond);
+
+  if (r != 0) {
+    goto out;
+  }
+
+  // Wait for completion
+  r = cond.wait();
+
+  // Construct outputs
+  do_out_buffer(outbl, outbuf, outbuflen);
+  do_out_buffer(outs, outsbuf, outsbuflen);
+
+out:
+  return r;
+}
+
+extern "C" int ceph_init(struct ceph_mount_info *cmount)
+{
+  return cmount->init();
+}
+
 extern "C" int ceph_mount(struct ceph_mount_info *cmount, const char *root)
 {
   std::string mount_root;
@@ -1517,3 +1614,10 @@ extern "C" uint64_t ceph_ll_get_internal_offset(class ceph_mount_info *cmount,
 {
   return (cmount->get_client()->ll_get_internal_offset(in, blockno));
 }
+
+extern "C" void ceph_buffer_free(char *buf)
+{
+  if (buf) {
+    free(buf);
+  }
+}