- mds: many clustered mds fixes
- auth: many auth_x cleanups, fixes, improvements
- kclient: many bug fixes
+- librados: some cleanup, c++ api now usable
v0.21
int rados_initialize(int argc, const char **argv); /* arguments are optional */
void rados_deinitialize();
-typedef void *rados_list_ctx_t;
-
/* pools */
typedef void *rados_pool_t;
+typedef void *rados_list_ctx_t;
typedef __u64 rados_snap_t;
struct rados_pool_stat_t {
void rados_set_snap(rados_pool_t pool, rados_snap_t snap);
- /* After creating a new rados_list_ctx_t, call this to initialize it*/
-void rados_pool_init_ctx(rados_list_ctx_t *ctx);
- /* Once you've finished with a rados_list_ctx_t, call before you dump it*/
-void rados_pool_close_ctx(rados_list_ctx_t *ctx);
- /* Given a rados_list_ctx_t and its pool, get the next object in sequence*/
-int rados_pool_list_next(rados_pool_t pool, const char **entry, rados_list_ctx_t *ctx);
-
int rados_create_pool(const char *name);
int rados_create_pool_with_auid(const char *name, __u64 auid);
int rados_delete_pool(const rados_pool_t pool);
int rados_change_pool_auid(const rados_pool_t pool, __u64 auid);
+/* objects */
+int rados_list_objects_open(rados_pool_t pool, rados_list_ctx_t *ctx);
+int rados_list_objects_next(rados_list_ctx_t ctx, const char **entry);
+void rados_list_objects_close(rados_list_ctx_t ctx);
+
+
/* snapshots */
int rados_snap_create(const rados_pool_t pool, const char *snapname);
int rados_snap_remove(const rados_pool_t pool, const char *snapname);
int exec(pool_t pool, const std::string& oid, const char *cls, const char *method,
bufferlist& inbl, bufferlist& outbl);
+ /* listing objects */
struct ListCtx {
void *ctx;
ListCtx() : ctx(NULL) {}
};
+ int list_objects_open(pool_t pool, Rados::ListCtx *ctx);
+ int list_objects_more(Rados::ListCtx ctx, int max, std::list<std::string>& entries);
+ void list_objects_close(Rados::ListCtx ctx);
- int list(pool_t pool, int max, std::list<std::string>& entries, Rados::ListCtx& ctx);
int list_pools(std::list<std::string>& v);
int get_pool_stats(std::list<std::string>& v,
std::map<std::string,pool_stat_t>& stats);
int delete_pool(const rados_pool_t& pool);
int change_pool_auid(const rados_pool_t& pool, unsigned long long auid);
- int list(PoolCtx& pool, int max_entries, std::list<object_t>& entries,
- Objecter::ListContext *context);
+ int list(Objecter::ListContext *context, int max_entries);
// --- aio ---
struct AioCompletion {
// IO
-int RadosClient::list(PoolCtx& pool, int max_entries, std::list<object_t>& entries, Objecter::ListContext *context) {
+int RadosClient::list(Objecter::ListContext *context, int max_entries)
+{
Cond cond;
bool done;
int r = 0;
if (context->at_end)
return 0;
- context->pool_id = pool.poolid;
- context->pool_snap_seq = pool.snap_seq;
- context->entries = &entries;
context->max_entries = max_entries;
+
lock.Lock();
objecter->list_objects(context, new C_SafeCond(&mylock, &cond, &done, &r));
lock.Unlock();
return r;
}
-int Rados::list(rados_pool_t pool, int max, std::list<string>& entries, Rados::ListCtx& ctx)
+int Rados::list_objects_open(pool_t pool, Rados::ListCtx *ctx)
+{
+ RadosClient::PoolCtx *p = (RadosClient::PoolCtx *)pool;
+ Objecter::ListContext *h = new Objecter::ListContext;
+ h->pool_id = p->poolid;
+ h->pool_snap_seq = p->snap_seq;
+ ctx->ctx = (void *)h;
+ return 0;
+}
+
+int Rados::list_objects_more(Rados::ListCtx ctx, int max, std::list<string>& entries)
{
if (!client)
return -EINVAL;
- Objecter::ListContext *op;
- if (!ctx.ctx) {
- ctx.ctx = new Objecter::ListContext();
- if (!ctx.ctx)
- return -ENOMEM;
- }
-
- op = (Objecter::ListContext *) ctx.ctx;
- std::list<object_t> e;
- int r = ((RadosClient *)client)->list(*(RadosClient::PoolCtx *)pool, max, e, op);
- while (!e.empty()) {
- entries.push_back(e.front().name.c_str());
- e.pop_front();
+ Objecter::ListContext *h = (Objecter::ListContext *)ctx.ctx;
+ h->list.clear();
+ int r = ((RadosClient *)client)->list(h, max);
+ while (!h->list.empty()) {
+ entries.push_back(h->list.front().name.c_str());
+ h->list.pop_front();
}
return r;
}
+void Rados::list_objects_close(Rados::ListCtx ctx)
+{
+ Objecter::ListContext *h = (Objecter::ListContext *)ctx.ctx;
+ delete h;
+}
+
+
int Rados::create(rados_pool_t pool, const string& o, bool exclusive)
{
if (!client)
}
return ret;
}
-extern "C" void rados_pool_init_ctx(rados_list_ctx_t *ctx)
+
+/* list objects */
+
+extern "C" int rados_list_objects_open(rados_pool_t pool, rados_list_ctx_t *listh)
{
- *ctx = NULL;
+ RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
+ Objecter::ListContext *h = new Objecter::ListContext;
+ h->pool_id = ctx->poolid;
+ h->pool_snap_seq = ctx->snap_seq;
+ *listh = (void *)h;
+ return 0;
}
-extern "C" void rados_pool_close_ctx(rados_list_ctx_t *ctx)
+extern "C" void rados_list_objects_close(rados_list_ctx_t ctx)
{
- if (*ctx) {
- Objecter::ListContext *op = (Objecter::ListContext *)*ctx;
- delete op;
- *ctx = NULL;
- }
+ Objecter::ListContext *op = (Objecter::ListContext *)ctx;
+ delete op;
}
-extern "C" int rados_pool_list_next(rados_pool_t pool, const char **entry, rados_list_ctx_t *listctx)
+extern "C" int rados_list_objects_next(rados_list_ctx_t listctx, const char **entry)
{
+ Objecter::ListContext *h = (Objecter::ListContext *)listctx;
int ret;
- RadosClient::PoolCtx *ctx = (RadosClient::PoolCtx *)pool;
-
- if (!*listctx) {
- *listctx = new Objecter::ListContext;
- if (!*listctx)
- return -ENOMEM;
- }
-
-
- Objecter::ListContext *op = (Objecter::ListContext *)*listctx;
-
- //if the list is non-empty, this method has been called before
- if(!op->list.empty())
- //so let's kill the previously-returned object
- op->list.pop_front();
- if (op->list.empty()) {
- op->list.clear();
- ret = radosp->list(*ctx, RADOS_LIST_MAX_ENTRIES, op->list, op);
- if (!op->list.size()) {
- delete op;
- *listctx = NULL;
+ // if the list is non-empty, this method has been called before
+ if (!h->list.empty())
+ // so let's kill the previously-returned object
+ h->list.pop_front();
+
+ if (h->list.empty()) {
+ ret = radosp->list(h, RADOS_LIST_MAX_ENTRIES);
+ if (!h->list.size())
return -ENOENT;
- }
}
- *entry = op->list.front().name.c_str();
-
+ *entry = h->list.front().name.c_str();
return 0;
}
dout(20) << "pool_id " << list_context->pool_id
<< "\npool_snap_seq " << list_context->pool_snap_seq
<< "\nmax_entries " << list_context->max_entries
- << "\n&entries " << list_context->entries
<< "\nlist_context " << list_context
<< "\nonfinish " << onfinish
<< "\nlist_context->current_pg" << list_context->current_pg
<< ", response.entries " << response.entries << dendl;
if (response_size) {
dout(20) << "got a response with objects, proceeding" << dendl;
- list_context->entries->merge(response.entries);
+ list_context->list.merge(response.entries);
list_context->max_entries -= response_size;
dout(20) << "cleaning up and exiting" << dendl;
if (!list_context->max_entries) {
int pool_id;
int pool_snap_seq;
int max_entries;
- std::list<object_t> *entries;
-
- //silly list for the C interface
std::list<object_t> list;
ListContext() : current_pg(0), cookie(0), starting_pg_num(0),
at_end(false), pool_id(0),
- pool_snap_seq(0), max_entries(0),
- entries(NULL) {}
+ pool_snap_seq(0), max_entries(0) {}
};
struct C_List : public Context {
outstream = new ofstream(nargs[1]);
Rados::ListCtx ctx;
+ rados.list_objects_open(p, &ctx);
while (1) {
list<string> vec;
- ret = rados.list(p, 1 << 10, vec, ctx);
+ ret = rados.list_objects_more(ctx, 1 << 10, vec);
if (ret < 0) {
cerr << "got error: " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
goto out;
for (list<string>::iterator iter = vec.begin(); iter != vec.end(); ++iter)
*outstream << *iter << std::endl;
}
+ rados.list_objects_close(ctx);
if (!stdout)
delete outstream;
}
return r;
- Rados::ListCtx ctx;
#define MAX_ENTRIES 1000
-
+ Rados::ListCtx ctx;
+ rados->list_objects_open(pool, &ctx);
do {
list<string> entries;
- r = rados->list(pool, MAX_ENTRIES, entries, ctx);
+ r = rados->list_objects_more(ctx, MAX_ENTRIES, entries);
if (r < 0)
return r;
}
}
} while (r);
+ rados->list_objects_close(ctx);
set<string>::iterator p;
if (!marker.empty())
r = rados_open_pool("foo", &pool);
printf("rados_open_pool = %d, pool = %p\n", r, pool);
- /* list objects */
- rados_list_ctx_t pctx;
- rados_pool_init_ctx(&pctx);
- const char *poolname;
- while (rados_pool_list_next(pool, &poolname, &pctx) == 0)
- printf("rados_pool_list_next got object '%s'\n", poolname);
- rados_pool_close_ctx(&pctx);
-
/* snapshots */
r = rados_snap_create(pool, "snap1");
printf("rados_snap_create snap1 = %d\n", r);
rados_read(pool, "../b/bb_bb_bb\\foo\\bar", 0, buf2, 128);
+ /* list objects */
+ rados_list_ctx_t h;
+ r = rados_list_objects_open(pool, &h);
+ printf("rados_list_objects_open = %d, h = %p\n", r, h);
+ const char *poolname;
+ while (rados_list_objects_next(h, &poolname) == 0)
+ printf("rados_list_objects_next got object '%s'\n", poolname);
+ rados_list_objects_close(h);
- const char *entry;
- rados_list_ctx_t ctx;
- rados_pool_init_ctx(&ctx);
- while (rados_pool_list_next(pool, &entry, &ctx) >= 0) {
- printf("list entry: %s\n", entry);
- }
- rados_pool_close_ctx(&ctx);
-
/* delete a pool */
r = rados_delete_pool(pool);
printf("rados_delete_pool = %d\n", r);
cout << "size=" << size << std::endl;
Rados::ListCtx ctx;
+ rados.list_objects_open(pool, &ctx);
int entries;
do {
list<string> vec;
- r = rados.list(pool, 2, vec, ctx);
+ r = rados.list_objects_more(ctx, 2, vec);
entries = vec.size();
cout << "list result=" << r << " entries=" << entries << std::endl;
list<string>::iterator iter;
cout << *iter << std::endl;
}
} while (entries);
+ rados.list_objects_close(ctx);
map<string, bufferlist> attrset;