]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
libceph: Change the C++-only functions to be C-compatible.
authorGreg Farnum <gregf@hq.newdream.net>
Fri, 21 Aug 2009 16:31:50 +0000 (09:31 -0700)
committerGreg Farnum <gregf@hq.newdream.net>
Mon, 24 Aug 2009 18:09:51 +0000 (11:09 -0700)
Hypertable: Change to use ceph_getdnames instead of getdir.

Hadoop: Minor updates to use the new C-style functions in libceph.

src/client/hadoop/CephFSInterface.cc
src/client/hypertable/CephBroker.cc
src/client/libceph.cc
src/client/libceph.h

index e6644cb14371cfa6523ca1e5369c24def0f5e25d..f41b1d1750fd5ddb0cb8070799f2f0863d33dc22 100644 (file)
@@ -9,6 +9,8 @@
 #include <sys/stat.h>
 
 using namespace std;
+const static int IP_ADDR_LENGTH = 24;//a buffer size; may want to up for IPv6.
+static int path_size;
 /*
  * Class:     org_apache_hadoop_fs_ceph_CephFileSystem
  * Method:    ceph_initializeClient
@@ -32,6 +34,7 @@ JNIEXPORT jboolean JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1i
     env->ReleaseStringUTFChars(j_debug_level, c_debug_level);
     return false;
   }
+  path_size = 64; //reasonable starting point?
   //construct an arguments array
   const char *argv[10];
   int argc = 0;
@@ -61,9 +64,17 @@ JNIEXPORT jstring JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1ge
 {
   dout(10) << "CephFSInterface: In getcwd" << dendl;
 
-  string path;
-  ceph_getcwd(path);
-  return env->NewStringUTF(path.c_str());
+  char *path = new char[path_size];
+  int r = ceph_getcwd(path, path_size);
+  if (r==-ERANGE) { //path is too short
+    path_size = ceph_getcwd(path, 0) * 1.2; //leave some extra
+    delete path;
+    path = new char[path_size];
+    ceph_getcwd(path, path_size);
+  }
+  jstring j_path = env->NewStringUTF(path);
+  delete path;
+  return j_path;
 }
 
 /*
@@ -463,7 +474,7 @@ JNIEXPORT jboolean JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1k
 JNIEXPORT jboolean JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1stat
 (JNIEnv * env, jobject obj, jstring j_path, jobject j_stat) {
   //setup variables
-  struct Client::stat_precise st;
+  struct stat_precise st;
   const char* c_path = env->GetStringUTFChars(j_path, 0);
   if (c_path == NULL) return false;
 
@@ -482,7 +493,7 @@ JNIEXPORT jboolean JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1s
   jfieldID c_mode_id = env->GetFieldID(cls, "mode", "I");
   if (c_mode_id == NULL) return false;
   //do actual lstat
-  int r = ceph_lstat(c_path, &st);
+  int r = ceph_lstat_precise(c_path, &st);
   env->ReleaseStringUTFChars(j_path, c_path);
 
   if (r < 0) return false; //fail out; file DNE or Ceph broke
@@ -559,10 +570,21 @@ JNIEXPORT jint JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1repli
 JNIEXPORT jstring JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1hosts
 (JNIEnv * env, jobject obj, jint j_fh, jlong j_offset) {
   //get the address
-  string address;
-  ceph_get_file_stripe_address(j_fh, j_offset, address);
+  char *address = new char[IP_ADDR_LENGTH];
+  int r = ceph_get_file_stripe_address(j_fh, j_offset, address, IP_ADDR_LENGTH);
+  if (r == -ERANGE) {//buffer's too small
+    delete address;
+    int size = ceph_get_file_stripe_address(j_fh, j_offset, address, 0);
+    address = new char[size];
+    r = ceph_get_file_stripe_address(j_fh, j_offset, address, size);
+  }
+  if (r != 0) { //some rather worse problem
+    if (r == -EINVAL) return NULL; //ceph thinks there are no OSDs
+  }
   //make java String of address
-  return env->NewStringUTF(address.c_str());
+  jstring j_addr = env->NewStringUTF(address);
+  delete address;
+  return j_addr;
 }
 
 /*
@@ -581,12 +603,12 @@ JNIEXPORT jint JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1setTi
   if (atime!=-1) mask |= CEPH_SETATTR_ATIME;
   //build a struct stat and fill it in!
   //remember to convert from millis to seconds and microseconds
-  Client::stat_precise attr;
+  stat_precise attr;
   attr.st_mtime_sec = mtime / 1000;
   attr.st_mtime_micro = (mtime % 1000) * 1000;
   attr.st_atime_sec = atime / 1000;
   attr.st_atime_micro = (atime % 1000) * 1000;
-  return ceph_setattr(c_path, &attr, mask);
+  return ceph_setattr_precise(c_path, &attr, mask);
 }
 
 /*
index 1b29131ad030a9e938a769c55d151d3ee3044321..ce2477e390152338b49b22f2828860b9d48be79a 100644 (file)
@@ -393,15 +393,33 @@ void CephBroker::readdir(ResponseCallbackReaddir *cb, const char *dname) {
 
   HT_DEBUGF("Readdir dir='%s'", dname);
 
-  //get from ceph in list<string>
+  //get from ceph in a buffer
   make_abs_path(dname, absdir);
-  std::list<String> dir_con;
-  ceph_getdir(absdir.c_str(), dir_con);
 
-  //convert to vector<String>
-  for (std::list<String>::iterator i = dir_con.begin(); i!=dir_con.end(); ++i) {
-    if (!(i->compare(".")==0 || i->compare("..")==0))
-      listing.push_back(*i);
+  DIR *dirp;
+  ceph_opendir(absdir.c_str(), &dirp);
+  int r;
+  int buflen = 100; //good default?
+  char *buf = new char[buflen];
+  string *ent;
+  int bufpos;
+  while (1) {
+    r = ceph_getdnames(dirp, buf, buflen);
+    if (r==-ERANGE) { //expand the buffer
+      delete buf;
+      buflen *= 2;
+      buf = new char[buflen];
+      continue;
+    }
+    if (r==0) break;
+    //if we make it here, we got at least one name, maybe more
+    bufpos = 0;
+    while (bufpos<r) {//make new strings and add them to listing
+      ent = new string(buf+bufpos);
+      listing.push_back(*ent);
+      bufpos+=ent->size()+1;
+      delete ent;
+    }
   }
   cb->response(listing);
 }
index 5b24249f96a9fc5a5fc2ba384c1f09c47cc39986..dfc361926ab39ebd2f4698053405cfc8ecf14a56 100644 (file)
@@ -8,6 +8,7 @@
 #include "messages/MMonMap.h"
 #include "common/common_init.h"
 #include "msg/SimpleMessenger.h"
+#include "Client.h"
 
 /* ************* ************* ************* *************
  * C interface
@@ -83,7 +84,21 @@ extern "C" int ceph_statfs(const char *path, struct statvfs *stbuf)
 {
   return client->statfs(path, stbuf);
 }
-  
+
+extern "C" int ceph_getcwd(char *buf, int buflen)
+{
+  string cwd;
+  client->getcwd(cwd);
+  int size = cwd.size()+1; //need space for null character
+  if (size > buflen) {
+    if (buflen == 0) return size;
+    else return -ERANGE;
+  }
+  size = cwd.copy(buf, size);
+  buf[size] = '\0'; //fill in null character
+  return 0;
+}
+
 extern "C" int ceph_chdir (const char *s)
 {
   return client->chdir(s);
@@ -185,19 +200,25 @@ extern "C" int ceph_symlink(const char *existing, const char *newname)
 }
 
 // inode stuff
-extern "C" int ceph_lstat(const char *path, struct stat *stbuf, struct frag_info_t *dirstat)
+extern "C" int ceph_lstat(const char *path, struct stat *stbuf)
 {
-  return client->lstat(path, stbuf, dirstat);
+  return client->lstat(path, stbuf);
 }
 
-int ceph_lstat(const char *path, Client::stat_precise *stbuf, frag_info_t *dirstat)
+extern "C" int ceph_lstat_precise(const char *path, stat_precise *stbuf)
 {
-  return client->lstat_precise(path, stbuf, dirstat);
+  return client->lstat_precise(path, (Client::stat_precise*)stbuf);
 }
 
-extern "C" int ceph_setattr(const char *relpath, Client::stat_precise *attr, int mask)
+extern "C" int ceph_setattr(const char *relpath, struct stat *attr, int mask)
 {
-  return client->setattr(relpath, attr, mask);
+  Client::stat_precise p_attr = Client::stat_precise(*attr);
+  return client->setattr(relpath, &p_attr, mask);
+}
+
+extern "C" int ceph_setattr_precise(const char *relpath,
+                                   struct stat_precise *attr, int mask) {
+  return client->setattr(relpath, (Client::stat_precise*)attr, mask);
 }
 
 extern "C" int ceph_chmod(const char *path, mode_t mode)
@@ -282,11 +303,18 @@ extern "C" int ceph_get_file_replication(const char *path) {
   return rep;
 }
 
-int ceph_get_file_stripe_address(int fh, loff_t offset, std::string& address) {
-  return client->get_file_stripe_address(fh, offset, address);
-}
-
-int ceph_getdir(const char *relpath, std::list<std::string>& names)
+int ceph_get_file_stripe_address(int fh, loff_t offset, char *buf, int buflen)
 {
-  return client->getdir(relpath, names);
+  string address;
+  int r = client->get_file_stripe_address(fh, offset, address);
+  if (r != 0) return r; //at time of writing, method ONLY returns
+  // 0 or -EINVAL if there are no known osds
+  int len = address.size()+1;
+  if (len > buflen) {
+    if (buflen == 0) return len;
+    else return -ERANGE;
+  }
+  len = address.copy(buf, len, 0);
+  buf[len] = '\0'; // write a null char to terminate c-style string
+  return 0;
 }
index bd010fbdc7ced17cd8937729f1047194ab8cfb30..7c4b2bbfc4570f02fe908e7bb6a1d24c6f7a90d9 100644 (file)
@@ -9,14 +9,25 @@
 #include <unistd.h>
 #include <dirent.h>
 
-#ifdef __cplusplus
-#include <list>
-#include <string>
-#include "Client.h"
-extern "C" {
-#endif
-
-  struct frag_info_t;
+struct frag_info_t;
+struct stat_precise {
+  ino_t st_ino;
+  dev_t st_dev;
+  mode_t st_mode;
+  nlink_t st_nlink;
+  uid_t st_uid;
+  gid_t st_gid;
+  dev_t st_rdev;
+  off_t st_size;
+  blksize_t st_blksize;
+  blkcnt_t st_blocks;
+  time_t st_atime_sec;
+  time_t st_atime_micro;
+  time_t st_mtime_sec;
+  time_t st_mtime_micro;
+  time_t st_ctime_sec;
+  time_t st_ctime_micro;
+};
 int ceph_initialize(int argc, const char **argv);
 void ceph_deinitialize();
 
@@ -25,7 +36,8 @@ int ceph_umount();
 
 int ceph_statfs(const char *path, struct statvfs *stbuf);
 
-int ceph_chdir (const char *s);
+int ceph_getcwd(char *buf, int buflen);
+int ceph_chdir(const char *s);
 
 int ceph_opendir(const char *name, DIR **dirpp);
 int ceph_closedir(DIR *dirp);
@@ -51,9 +63,11 @@ int ceph_readlink(const char *path, char *buf, loff_t size);
 int ceph_symlink(const char *existing, const char *newname);
 
 // inode stuff
-int ceph_lstat(const char *path, struct stat *stbuf, frag_info_t *dirstat=0);
+int ceph_lstat(const char *path, struct stat *stbuf);
+int ceph_lstat_precise(const char *path, struct stat_precise *stbuf);
 
-int ceph_setattr(const char *relpath, Client::stat_precise *attr, int mask);
+int ceph_setattr(const char *relpath, struct stat *attr, int mask);
+int ceph_setattr_precise (const char *relpath, struct stat_precise *stbuf, int mask);
 int ceph_chmod(const char *path, mode_t mode);
 int ceph_chown(const char *path, uid_t uid, gid_t gid);
 int ceph_utime(const char *path, struct utimbuf *buf);
@@ -73,14 +87,6 @@ int ceph_fstat(int fd, struct stat *stbuf);
 int ceph_sync_fs();
 int ceph_get_file_stripe_unit(int fh);
 int ceph_get_file_replication(const char *path);
-#ifdef __cplusplus
-}
-//not for C, sorry!
-int ceph_getdir(const char *relpath, std::list<std::string>& names);
-void ceph_getcwd(std::string& cwd);
-int ceph_get_file_stripe_address(int fd, loff_t offset, std::string& address);
-int ceph_lstat(const char *path, Client::stat_precise *stbuf, frag_info_t *dirstat=0);
-
-#endif
+int ceph_get_file_stripe_address(int fd, loff_t offset, char *buf, int buflen);
 
 #endif