Skip to content

Commit

Permalink
Connect and shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
johnl committed Sep 22, 2012
0 parents commit 99a7f99
Show file tree
Hide file tree
Showing 10 changed files with 204 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tmp/
ceph.conf
ceph.keyring
5 changes: 5 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require "rake/extensiontask"

Rake::ExtensionTask.new("rados") do |ext|
ext.lib_dir = File.join 'lib', 'rados'
end
81 changes: 81 additions & 0 deletions ext/rados/cluster.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <rados_ext.h>
#include <rados/librados.h>
#include <cluster.h>
#include <errno.h>

VALUE cRadosCluster;
extern VALUE mRados, cRadosError;

#define GET_CLUSTER(self) \
rados_cluster_wrapper *wrapper; \
Data_Get_Struct(self, rados_cluster_wrapper, wrapper)


static void rb_rados_cluster_mark(void * wrapper) {
rados_cluster_wrapper * w = wrapper;
if (w) {
rb_gc_mark(w->active_thread);
}
}

static VALUE nogvl_close(void *ptr) {
rados_cluster_wrapper *wrapper;
wrapper = ptr;
if (wrapper->connected) {
wrapper->active_thread = Qnil;
wrapper->connected = 0;
// FIXME: need rados_aio_flush() on all open contexts first
rados_shutdown(*wrapper->cluster);
}
xfree(wrapper->cluster);
return Qnil;
}


static void rb_rados_cluster_free(void * ptr) {
rados_cluster_wrapper *wrapper = (rados_cluster_wrapper *)ptr;

nogvl_close(wrapper);
xfree(ptr);
}

static VALUE allocate(VALUE klass) {
VALUE obj;
rados_cluster_wrapper * wrapper;
obj = Data_Make_Struct(klass, rados_cluster_wrapper, rb_rados_cluster_mark, rb_rados_cluster_free, wrapper);
wrapper->active_thread = Qnil;
wrapper->connected = 0; // means that a database connection is open
wrapper->initialized = 0; // means that that the wrapper is initialized
wrapper->cluster = (rados_t*)xmalloc(sizeof(rados_t));
return obj;
}

static VALUE initialize_ext(VALUE self) {
int err;
GET_CLUSTER(self);

// FIXME: can specify user id here for auth!
err = rados_create(wrapper->cluster, NULL);
if (err < 0) {
rb_raise(cRadosError, "cannot create a cluster handle: %s", strerror(-err));
}
// FIXME: Allow specifying config filename
err = rados_conf_read_file(*wrapper->cluster, NULL);
if (err < 0) {
rb_raise(cRadosError, "cannot read config file: %s", strerror(-err));
}
// FIXME: should release global lock
err = rados_connect(*wrapper->cluster);
if (err < 0) {
rb_raise(cRadosError, "cannot connect: %s", strerror(-err));
}
wrapper->connected = 1;

return self;
}

void init_rados_cluster() {
cRadosCluster = rb_define_class_under(mRados, "Cluster", rb_cObject);
rb_define_alloc_func(cRadosCluster, allocate);
rb_define_private_method(cRadosCluster, "initialize_ext", initialize_ext, 0);
}
42 changes: 42 additions & 0 deletions ext/rados/cluster.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef RADOS_CLUSTER_H
#define RADOS_CLUSTER_H

/*
* partial emulation of the 1.9 rb_thread_blocking_region under 1.8,
* this is enough for dealing with blocking I/O functions in the
* presence of threads.
*/
#ifndef HAVE_RB_THREAD_BLOCKING_REGION

#include <rubysig.h>
#define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
typedef void rb_unblock_function_t(void *);
typedef VALUE rb_blocking_function_t(void *);
static VALUE
rb_thread_blocking_region(
rb_blocking_function_t *func, void *data1,
RB_MYSQL_UNUSED rb_unblock_function_t *ubf,
RB_MYSQL_UNUSED void *data2)
{
VALUE rv;

TRAP_BEG;
rv = func(data1);
TRAP_END;

return rv;
}

#endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */

void init_rados_cluster();

typedef struct {
VALUE active_thread; /* rb_thread_current() or Qnil */
int reconnect_enabled;
int connected;
int initialized;
rados_t *cluster;
} rados_cluster_wrapper;

#endif
20 changes: 20 additions & 0 deletions ext/rados/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# encoding: UTF-8
require 'mkmf'

$CFLAGS='-Wall'

# 1.9-only
have_func('rb_thread_blocking_region')
have_func('rb_wait_for_single_fd')

if have_header('rados.h') then
prefix = nil
elsif have_header('rados/librados.h') then
prefix = 'rados'
else
abort "rados.h is missing. please check your installation of rados and try again.\n-----"
end

have_library("rados")

create_makefile('rados/rados')
11 changes: 11 additions & 0 deletions ext/rados/rados_ext.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <rados_ext.h>

VALUE mRados, cRadosError;

/* Ruby Extension initializer */
void Init_rados() {
mRados = rb_define_module("Rados");
cRadosError = rb_const_get(mRados, rb_intern("Error"));

init_rados_cluster();
}
25 changes: 25 additions & 0 deletions ext/rados/rados_ext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef RADOS_EXT
#define RADOS_EXT

// tell rbx not to use it's caching compat layer
// by doing this we're making a promize to RBX that
// we'll never modify the pointers we get back from RSTRING_PTR
#define RSTRING_NOT_MODIFIED
#include <ruby.h>
#include <fcntl.h>

#ifndef HAVE_UINT
#define HAVE_UINT
typedef unsigned short ushort;
typedef unsigned int uint;
#endif

#include <rados/librados.h>

#ifdef HAVE_RUBY_ENCODING_H
#include <ruby/encoding.h>
#endif

#include <cluster.h>

#endif
6 changes: 6 additions & 0 deletions lib/rados.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Rados
class Error < StandardError ; end
end

require 'rados/rados'
require 'rados/cluster'
11 changes: 11 additions & 0 deletions lib/rados/cluster.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Rados
# Cluster represents a connection to a Ceph cluster
class Cluster
# Requires :config_file with a path to the ceph config file
def initialize(options = {})
@config_file = options[:config_file]
initialize_ext
options
end
end
end
Binary file added lib/rados/rados.so
Binary file not shown.

0 comments on commit 99a7f99

Please sign in to comment.