ceph/src/libceph.cc

381 lines
8.2 KiB
C++

#include "client/libceph.h"
#include <string.h>
#include <fcntl.h>
#include <iostream>
#include "common/Mutex.h"
#include "messages/MMonMap.h"
#include "common/common_init.h"
#include "msg/SimpleMessenger.h"
#include "client/Client.h"
/* ************* ************* ************* *************
* C interface
*/
extern "C" const char *ceph_version(int *major, int *minor, int *patch)
{
if (major)
*major = CEPH_VERSION_MAJOR;
if (minor)
*minor = CEPH_VERSION_MINOR;
if (patch)
*patch = CEPH_VERSION_PATCH;
return CEPH_VERSION;
}
static Mutex ceph_client_mutex("ceph_client");
static int client_initialized = 0;
static int client_mount = 0;
static Client *client = NULL;
static MonClient *monclient = NULL;
static SimpleMessenger *messenger = NULL;
extern "C" int ceph_initialize(int argc, const char **argv)
{
ceph_client_mutex.Lock();
if (!client_initialized) {
//create everything to start a client
vector<const char*> args;
argv_to_vec(argc, argv, args);
common_init(args, "libceph", false, true);
if (g_conf.clock_tare) g_clock.tare();
//monmap
monclient = new MonClient();
if (monclient->build_initial_monmap() < 0) {
delete monclient;
return -1; //error!
}
//network connection
messenger = new SimpleMessenger();
messenger->register_entity(entity_name_t::CLIENT());
//at last the client
client = new Client(messenger, monclient);
messenger->start();
client->init();
}
++client_initialized;
ceph_client_mutex.Unlock();
return 0;
}
extern "C" void ceph_deinitialize()
{
ceph_client_mutex.Lock();
--client_initialized;
if(!client_initialized) {
client->unmount();
client->shutdown();
delete client;
messenger->wait();
messenger->destroy();
delete monclient;
}
ceph_client_mutex.Unlock();
}
extern "C" int ceph_mount()
{
int ret;
Mutex::Locker lock(ceph_client_mutex);
if(!client_mount) {
ret = client->mount();
if (ret!=0)
return ret;
}
++client_mount;
return 0;
}
extern "C" int ceph_umount()
{
Mutex::Locker lock(ceph_client_mutex);
--client_mount;
if (!client_mount)
return client->unmount();
return 0;
}
extern "C" int ceph_statfs(const char *path, struct statvfs *stbuf)
{
return client->statfs(path, stbuf);
}
extern "C" int ceph_get_local_osd()
{
return client->get_local_osd();
}
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);
}
/*if we want to extern C this, we need to convert it to const char*,
which will mean storing it somewhere or else making the caller
responsible for delete-ing a c-string they didn't create*/
void ceph_getcwd(string& cwd)
{
client->getcwd(cwd);
}
extern "C" int ceph_opendir(const char *name, DIR **dirpp)
{
return client->opendir(name, dirpp);
}
extern "C" int ceph_closedir(DIR *dirp)
{
return client->closedir(dirp);
}
extern "C" int ceph_readdir_r(DIR *dirp, struct dirent *de)
{
return client->readdir_r(dirp, de);
}
extern "C" int ceph_readdirplus_r(DIR *dirp, struct dirent *de, struct stat *st, int *stmask)
{
return client->readdirplus_r(dirp, de, st, stmask);
}
extern "C" int ceph_getdents(DIR *dirp, char *buf, int buflen)
{
return client->getdents(dirp, buf, buflen);
}
extern "C" int ceph_getdnames(DIR *dirp, char *buf, int buflen)
{
return client->getdnames(dirp, buf, buflen);
}
extern "C" void ceph_rewinddir(DIR *dirp)
{
client->rewinddir(dirp);
}
extern "C" loff_t ceph_telldir(DIR *dirp)
{
return client->telldir(dirp);
}
extern "C" void ceph_seekdir(DIR *dirp, loff_t offset)
{
client->seekdir(dirp, offset);
}
extern "C" int ceph_link (const char *existing, const char *newname)
{
return client->link(existing, newname);
}
extern "C" int ceph_unlink (const char *path)
{
return client->unlink(path);
}
extern "C" int ceph_rename(const char *from, const char *to)
{
return client->rename(from, to);
}
// dirs
extern "C" int ceph_mkdir(const char *path, mode_t mode)
{
return client->mkdir(path, mode);
}
extern "C" int ceph_mkdirs(const char *path, mode_t mode)
{
return client->mkdirs(path, mode);
}
extern "C" int ceph_rmdir(const char *path)
{
return client->rmdir(path);
}
// symlinks
extern "C" int ceph_readlink(const char *path, char *buf, loff_t size)
{
return client->readlink(path, buf, size);
}
extern "C" int ceph_symlink(const char *existing, const char *newname)
{
return client->symlink(existing, newname);
}
// inode stuff
extern "C" int ceph_lstat(const char *path, struct stat *stbuf)
{
return client->lstat(path, stbuf);
}
extern "C" int ceph_lstat_precise(const char *path, stat_precise *stbuf)
{
return client->lstat_precise(path, (Client::stat_precise*)stbuf);
}
extern "C" int ceph_setattr(const char *relpath, struct stat *attr, int 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)
{
return client->chmod(path, mode);
}
extern "C" int ceph_chown(const char *path, uid_t uid, gid_t gid)
{
return client->chown(path, uid, gid);
}
extern "C" int ceph_utime(const char *path, struct utimbuf *buf)
{
return client->utime(path, buf);
}
extern "C" int ceph_truncate(const char *path, loff_t size)
{
return client->truncate(path, size);
}
// file ops
extern "C" int ceph_mknod(const char *path, mode_t mode, dev_t rdev)
{
return client->mknod(path, mode, rdev);
}
extern "C" int ceph_open(const char *path, int flags, mode_t mode)
{
return client->open(path, flags, mode);
}
extern "C" int ceph_close(int fd)
{
return client->close(fd);
}
extern "C" loff_t ceph_lseek(int fd, loff_t offset, int whence)
{
return client->lseek(fd, offset, whence);
}
extern "C" int ceph_read(int fd, char *buf, loff_t size, loff_t offset)
{
return client->read(fd, buf, size, offset);
}
extern "C" int ceph_write(int fd, const char *buf, loff_t size, loff_t offset)
{
return client->write(fd, buf, size, offset);
}
extern "C" int ceph_ftruncate(int fd, loff_t size)
{
return client->ftruncate(fd, size);
}
extern "C" int ceph_fsync(int fd, bool syncdataonly)
{
return client->fsync(fd, syncdataonly);
}
extern "C" int ceph_fstat(int fd, struct stat *stbuf)
{
return client->fstat(fd, stbuf);
}
extern "C" int ceph_sync_fs()
{
return client->sync_fs();
}
extern "C" int ceph_get_file_stripe_unit(int fh)
{
return client->get_file_stripe_unit(fh);
}
extern "C" int ceph_get_file_replication(const char *path) {
int fd = client->open(path, O_RDONLY);
int rep = client->get_file_replication(fd);
client->close(fd);
return rep;
}
extern "C" int ceph_get_default_preferred_pg(int fd)
{
return client->get_default_preferred_pg(fd);
}
extern "C" int ceph_set_default_file_stripe_unit(int stripe)
{
client->set_default_file_stripe_unit(stripe);
return 0;
}
extern "C" int ceph_set_default_file_stripe_count(int count)
{
client->set_default_file_stripe_unit(count);
return 0;
}
extern "C" int ceph_set_default_object_size(int size)
{
client->set_default_object_size(size);
return 0;
}
extern "C" int ceph_set_default_file_replication(int replication)
{
client->set_default_file_replication(replication);
return 0;
}
extern "C" int ceph_set_default_preferred_pg(int pg)
{
client->set_default_preferred_pg(pg);
return 0;
}
extern "C" int ceph_get_file_stripe_address(int fh, loff_t offset, char *buf, int buflen)
{
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;
}