Merge branch 'wip-4982-4983-oloc-rebase'

fixes: #4982
fixes: #4983

Reviewed-by: Samuel Just <sam.just@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>
Reviewed-by: David Zafman <david.zafman@inktank.com>
This commit is contained in:
David Zafman 2013-07-09 16:24:22 -07:00
commit 51dbc389c4
43 changed files with 1127 additions and 896 deletions

View File

@ -657,6 +657,19 @@ int rados_ioctx_get_pool_name(rados_ioctx_t io, char *buf, unsigned maxlen);
* any previously set key
*/
void rados_ioctx_locator_set_key(rados_ioctx_t io, const char *key);
/**
* Set the namespace for objects within an io context
*
* The namespace specification further refines a pool into different
* domains. The mapping of objects to pgs is also based on this
* value.
*
* @param io the io context to change
* @param nspace the name to use as the namespace, or NULL use the
* default namespace
*/
void rados_ioctx_set_namespace(rados_ioctx_t io, const char *nspace);
/** @} obj_loc */
/**

View File

@ -662,6 +662,7 @@ namespace librados
const std::string& get_pool_name() const;
void locator_set_key(const std::string& key);
void set_namespace(const std::string& nspace);
int64_t get_id();

View File

@ -210,6 +210,7 @@ int librados::IoCtxImpl::selfmanaged_snap_rollback_object(const object_t& oid,
::SnapContext& snapc,
uint64_t snapid)
{
utime_t ut = ceph_clock_now(client->cct);
int reply;
Mutex mylock("IoCtxImpl::snap_rollback::mylock");
@ -217,9 +218,13 @@ int librados::IoCtxImpl::selfmanaged_snap_rollback_object(const object_t& oid,
bool done;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &reply);
::ObjectOperation op;
prepare_assert_ops(&op);
op.rollback(snapid);
lock->Lock();
objecter->rollback_object(oid, oloc, snapc, snapid,
ceph_clock_now(client->cct), onack, NULL);
objecter->mutate(oid, oloc,
op, snapc, ut, 0,
onack, NULL, NULL);
lock->Unlock();
mylock.Lock();
@ -364,6 +369,7 @@ int librados::IoCtxImpl::list(Objecter::ListContext *context, int max_entries)
return 0;
context->max_entries = max_entries;
context->nspace = oloc.nspace;
lock->Lock();
objecter->list_objects(context, new C_SafeCond(&mylock, &cond, &done, &r));
@ -379,68 +385,19 @@ int librados::IoCtxImpl::list(Objecter::ListContext *context, int max_entries)
int librados::IoCtxImpl::create(const object_t& oid, bool exclusive)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::create::mylock");
Cond cond;
bool done;
int r;
eversion_t ver;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
lock->Lock();
objecter->create(oid, oloc,
snapc, ut, 0, (exclusive ? CEPH_OSD_OP_FLAG_EXCL : 0),
onack, NULL, &ver);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
::ObjectOperation op;
prepare_assert_ops(&op);
op.create(exclusive);
return operate(oid, &op, NULL);
}
int librados::IoCtxImpl::create(const object_t& oid, bool exclusive,
const std::string& category)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::create::mylock");
Cond cond;
bool done;
int r;
eversion_t ver;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
::ObjectOperation o;
o.create(exclusive ? CEPH_OSD_OP_FLAG_EXCL : 0, category);
lock->Lock();
objecter->mutate(oid, oloc, o, snapc, ut, 0, onack, NULL, &ver);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
::ObjectOperation op;
prepare_assert_ops(&op);
op.create(exclusive, category);
return operate(oid, &op, NULL);
}
/*
@ -473,37 +430,12 @@ int librados::IoCtxImpl::create(const object_t& oid, bool exclusive,
int librados::IoCtxImpl::write(const object_t& oid, bufferlist& bl,
size_t len, uint64_t off)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::write::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
// extra ops?
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->write(oid, oloc,
off, len, snapc, bl, ut, 0,
onack, NULL, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
prepare_assert_ops(&op);
bufferlist mybl;
mybl.substr_of(bl, 0, len);
op.write(off, mybl);
int r = operate(oid, &op, NULL);
if (r < 0)
return r;
@ -512,36 +444,12 @@ int librados::IoCtxImpl::write(const object_t& oid, bufferlist& bl,
int librados::IoCtxImpl::append(const object_t& oid, bufferlist& bl, size_t len)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::append::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->append(oid, oloc,
len, snapc, bl, ut, 0,
onack, NULL, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
prepare_assert_ops(&op);
bufferlist mybl;
mybl.substr_of(bl, 0, len);
op.append(mybl);
int r = operate(oid, &op, NULL);
if (r < 0)
return r;
@ -550,38 +458,10 @@ int librados::IoCtxImpl::append(const object_t& oid, bufferlist& bl, size_t len)
int librados::IoCtxImpl::write_full(const object_t& oid, bufferlist& bl)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::write_full::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->write_full(oid, oloc,
snapc, bl, ut, 0,
onack, NULL, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
prepare_assert_ops(&op);
op.write_full(bl);
return operate(oid, &op, NULL);
}
int librados::IoCtxImpl::clone_range(const object_t& dst_oid,
@ -590,36 +470,10 @@ int librados::IoCtxImpl::clone_range(const object_t& dst_oid,
uint64_t src_offset,
uint64_t len)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::clone_range::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
bufferlist outbl;
lock->Lock();
::ObjectOperation wr;
prepare_assert_ops(&wr);
wr.clone_range(src_oid, src_offset, len, dst_offset);
objecter->mutate(dst_oid, oloc, wr, snapc, ut, 0, onack, NULL, &ver);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
return operate(dst_oid, &wr, NULL);
}
int librados::IoCtxImpl::operate(const object_t& oid, ::ObjectOperation *o,
@ -639,7 +493,7 @@ int librados::IoCtxImpl::operate(const object_t& oid, ::ObjectOperation *o,
if (!o->size())
return 0;
Mutex mylock("IoCtxImpl::mutate::mylock");
Mutex mylock("IoCtxImpl::operate::mylock");
Cond cond;
bool done;
int r;
@ -647,6 +501,8 @@ int librados::IoCtxImpl::operate(const object_t& oid, ::ObjectOperation *o,
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
int op = o->ops[0].op.op;
ldout(client->cct, 10) << ceph_osd_op_name(op) << " oid=" << oid << " nspace=" << oloc.nspace << dendl;
lock->Lock();
objecter->mutate(oid, oloc,
*o, snapc, ut, 0,
@ -657,6 +513,8 @@ int librados::IoCtxImpl::operate(const object_t& oid, ::ObjectOperation *o,
while (!done)
cond.Wait(mylock);
mylock.Unlock();
ldout(client->cct, 10) << "Objecter returned from "
<< ceph_osd_op_name(op) << " r=" << r << dendl;
set_sync_op_version(ver);
@ -669,7 +527,7 @@ int librados::IoCtxImpl::operate_read(const object_t& oid,
if (!o->size())
return 0;
Mutex mylock("IoCtxImpl::mutate::mylock");
Mutex mylock("IoCtxImpl::operate_read::mylock");
Cond cond;
bool done;
int r;
@ -677,6 +535,8 @@ int librados::IoCtxImpl::operate_read(const object_t& oid,
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
int op = o->ops[0].op.op;
ldout(client->cct, 10) << ceph_osd_op_name(op) << " oid=" << oid << " nspace=" << oloc.nspace << dendl;
lock->Lock();
objecter->read(oid, oloc,
*o, snap_seq, pbl, 0,
@ -687,6 +547,8 @@ int librados::IoCtxImpl::operate_read(const object_t& oid,
while (!done)
cond.Wait(mylock);
mylock.Unlock();
ldout(client->cct, 10) << "Objecter returned from "
<< ceph_osd_op_name(op) << " r=" << r << dendl;
set_sync_op_version(ver);
@ -924,172 +786,42 @@ int librados::IoCtxImpl::aio_stat(const object_t& oid, AioCompletionImpl *c,
int librados::IoCtxImpl::remove(const object_t& oid)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::remove::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->remove(oid, oloc,
snapc, ut, 0,
onack, NULL, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
prepare_assert_ops(&op);
op.remove();
return operate(oid, &op, NULL);
}
int librados::IoCtxImpl::trunc(const object_t& oid, uint64_t size)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::write_full::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->trunc(oid, oloc,
snapc, ut, 0,
size, 0,
onack, NULL, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
prepare_assert_ops(&op);
op.truncate(size);
return operate(oid, &op, NULL);
}
int librados::IoCtxImpl::tmap_update(const object_t& oid, bufferlist& cmdbl)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::tmap_update::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
bufferlist outbl;
lock->Lock();
::ObjectOperation wr;
prepare_assert_ops(&wr);
wr.tmap_update(cmdbl);
objecter->mutate(oid, oloc, wr, snapc, ut, 0, onack, NULL, &ver);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
return operate(oid, &wr, NULL);
}
int librados::IoCtxImpl::tmap_put(const object_t& oid, bufferlist& bl)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::tmap_put::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
bufferlist outbl;
lock->Lock();
::ObjectOperation wr;
prepare_assert_ops(&wr);
wr.tmap_put(bl);
objecter->mutate(oid, oloc, wr, snapc, ut, 0, onack, NULL, &ver);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
return operate(oid, &wr, NULL);
}
int librados::IoCtxImpl::tmap_get(const object_t& oid, bufferlist& bl)
{
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::tmap_put::mylock");
Cond cond;
bool done;
int r = 0;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
bufferlist outbl;
lock->Lock();
::ObjectOperation rd;
prepare_assert_ops(&rd);
rd.tmap_get(&bl, NULL);
objecter->read(oid, oloc, rd, snap_seq, 0, 0, onack, &ver);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
return operate_read(oid, &rd, NULL);
}
@ -1097,29 +829,10 @@ int librados::IoCtxImpl::exec(const object_t& oid,
const char *cls, const char *method,
bufferlist& inbl, bufferlist& outbl)
{
Mutex mylock("IoCtxImpl::exec::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
lock->Lock();
::ObjectOperation rd;
prepare_assert_ops(&rd);
rd.call(cls, method, inbl);
objecter->read(oid, oloc, rd, snap_seq, &outbl, 0, onack, &ver);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
return r;
return operate_read(oid, &rd, &outbl);
}
int librados::IoCtxImpl::aio_exec(const object_t& oid, AioCompletionImpl *c,
@ -1146,31 +859,10 @@ int librados::IoCtxImpl::read(const object_t& oid,
if (len > (size_t) INT_MAX)
return -EDOM;
Mutex mylock("IoCtxImpl::read::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->read(oid, oloc,
off, len, snap_seq, &bl, 0,
onack, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
ldout(client->cct, 10) << "Objecter returned from read r=" << r << dendl;
set_sync_op_version(ver);
::ObjectOperation rd;
prepare_assert_ops(&rd);
rd.read(off, len, &bl, NULL);
int r = operate_read(oid, &rd, &bl);
if (r < 0)
return r;
@ -1223,12 +915,11 @@ int librados::IoCtxImpl::sparse_read(const object_t& oid,
if (len > (size_t) INT_MAX)
return -EDOM;
int r;
::ObjectOperation rd;
prepare_assert_ops(&rd);
rd.sparse_read(off, len, &m, &data_bl, NULL);
r = operate_read(oid, &rd, NULL);
int r = operate_read(oid, &rd, NULL);
if (r < 0)
return r;
@ -1237,69 +928,31 @@ int librados::IoCtxImpl::sparse_read(const object_t& oid,
int librados::IoCtxImpl::stat(const object_t& oid, uint64_t *psize, time_t *pmtime)
{
Mutex mylock("IoCtxImpl::stat::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
uint64_t size;
utime_t mtime;
eversion_t ver;
if (!psize)
psize = &size;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->stat(oid, oloc,
snap_seq, psize, &mtime, 0,
onack, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
ldout(client->cct, 10) << "Objecter returned from stat" << dendl;
::ObjectOperation rd;
prepare_assert_ops(&rd);
rd.stat(psize, &mtime, NULL);
int r = operate_read(oid, &rd, NULL);
if (r >= 0 && pmtime) {
*pmtime = mtime.sec();
}
set_sync_op_version(ver);
return r;
}
int librados::IoCtxImpl::getxattr(const object_t& oid,
const char *name, bufferlist& bl)
{
Mutex mylock("IoCtxImpl::getxattr::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->getxattr(oid, oloc,
name, snap_seq, &bl, 0,
onack, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
ldout(client->cct, 10) << "Objecter returned from getxattr" << dendl;
set_sync_op_version(ver);
::ObjectOperation rd;
prepare_assert_ops(&rd);
rd.getxattr(name, &bl, NULL);
int r = operate_read(oid, &rd, NULL);
if (r < 0)
return r;
@ -1308,117 +961,39 @@ int librados::IoCtxImpl::getxattr(const object_t& oid,
int librados::IoCtxImpl::rmxattr(const object_t& oid, const char *name)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::rmxattr::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->removexattr(oid, oloc, name,
snapc, ut, 0,
onack, NULL, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
if (r < 0)
return r;
return 0;
prepare_assert_ops(&op);
op.rmxattr(name);
return operate(oid, &op, NULL);
}
int librados::IoCtxImpl::setxattr(const object_t& oid,
const char *name, bufferlist& bl)
{
utime_t ut = ceph_clock_now(client->cct);
/* can't write to a snapshot */
if (snap_seq != CEPH_NOSNAP)
return -EROFS;
Mutex mylock("IoCtxImpl::setxattr::mylock");
Cond cond;
bool done;
int r;
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
eversion_t ver;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
lock->Lock();
objecter->setxattr(oid, oloc, name,
snapc, bl, ut, 0,
onack, NULL, &ver, pop);
lock->Unlock();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
set_sync_op_version(ver);
if (r < 0)
return r;
return 0;
prepare_assert_ops(&op);
op.setxattr(name, bl);
return operate(oid, &op, NULL);
}
int librados::IoCtxImpl::getxattrs(const object_t& oid,
map<std::string, bufferlist>& attrset)
{
Mutex mylock("IoCtxImpl::getexattrs::mylock");
Cond cond;
bool done;
int r;
eversion_t ver;
::ObjectOperation op;
::ObjectOperation *pop = prepare_assert_ops(&op);
Context *onack = new C_SafeCond(&mylock, &cond, &done, &r);
lock->Lock();
map<string, bufferlist> aset;
objecter->getxattrs(oid, oloc, snap_seq,
aset,
0, onack, &ver, pop);
lock->Unlock();
::ObjectOperation rd;
prepare_assert_ops(&rd);
rd.getxattrs(&aset, NULL);
int r = operate_read(oid, &rd, NULL);
attrset.clear();
mylock.Lock();
while (!done)
cond.Wait(mylock);
mylock.Unlock();
for (map<string,bufferlist>::iterator p = aset.begin(); p != aset.end(); ++p) {
ldout(client->cct, 10) << "IoCtxImpl::getxattrs: xattr=" << p->first << dendl;
attrset[p->first.c_str()] = p->second;
if (r >= 0) {
for (map<string,bufferlist>::iterator p = aset.begin(); p != aset.end(); ++p) {
ldout(client->cct, 10) << "IoCtxImpl::getxattrs: xattr=" << p->first << dendl;
attrset[p->first.c_str()] = p->second;
}
}
set_sync_op_version(ver);
return r;
}
@ -1486,7 +1061,7 @@ int librados::IoCtxImpl::unwatch(const object_t& oid, uint64_t cookie)
{
bufferlist inbl, outbl;
Mutex mylock("IoCtxImpl::watch::mylock");
Mutex mylock("IoCtxImpl::unwatch::mylock");
Cond cond;
bool done;
int r;

View File

@ -1272,6 +1272,11 @@ void librados::IoCtx::locator_set_key(const string& key)
io_ctx_impl->oloc.key = key;
}
void librados::IoCtx::set_namespace(const string& nspace)
{
io_ctx_impl->oloc.nspace = nspace;
}
int64_t librados::IoCtx::get_id()
{
return io_ctx_impl->get_id();
@ -2199,6 +2204,15 @@ extern "C" void rados_ioctx_locator_set_key(rados_ioctx_t io, const char *key)
ctx->oloc.key = "";
}
extern "C" void rados_ioctx_set_namespace(rados_ioctx_t io, const char *nspace)
{
librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
if (nspace)
ctx->oloc.nspace = nspace;
else
ctx->oloc.nspace = "";
}
extern "C" rados_t rados_ioctx_get_cluster(rados_ioctx_t io)
{
librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
@ -2476,6 +2490,7 @@ extern "C" int rados_objects_list_open(rados_ioctx_t io, rados_list_ctx_t *listh
Objecter::ListContext *h = new Objecter::ListContext;
h->pool_id = ctx->poolid;
h->pool_snap_seq = ctx->snap_seq;
h->nspace = ctx->oloc.nspace;
*listh = (void *)new librados::ObjListCtx(ctx, h);
return 0;
}

View File

@ -494,6 +494,8 @@ namespace librbd {
snap_lock.put_read();
ObjectExtent extent(o, 0, off, len, 0);
extent.oloc.pool = data_ctx.get_id();
// XXX: nspace is always default, io_ctx_impl field private
//extent.oloc.nspace = data_ctx.io_ctx_impl->oloc.nspace;
extent.buffer_extents.push_back(make_pair(0, len));
wr->extents.push_back(extent);
{

View File

@ -341,7 +341,10 @@ struct ceph_osd_request_head {
const char *get_type_name() const { return "osd_op"; }
void print(ostream& out) const {
out << "osd_op(" << get_reqid();
out << " " << oid;
out << " ";
if (!oloc.nspace.empty())
out << oloc.nspace << "/";
out << oid;
#if 0
out << " ";

View File

@ -2056,23 +2056,30 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
ds << "\n";
rdata.append(ds);
} else if (prefix == "osd map") {
string poolstr, objstr;
string poolstr, objstr, namespacestr;
cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
cmd_getval(g_ceph_context, cmdmap, "object", objstr);
cmd_getval(g_ceph_context, cmdmap, "nspace", namespacestr);
int64_t pool = osdmap.lookup_pg_pool_name(poolstr.c_str());
if (pool < 0) {
ss << "pool " << poolstr << " does not exist";
r = -ENOENT;
goto reply;
}
object_locator_t oloc(pool);
object_locator_t oloc(pool, namespacestr);
object_t oid(objstr);
pg_t pgid = osdmap.object_locator_to_pg(oid, oloc);
pg_t mpgid = osdmap.raw_pg_to_pg(pgid);
vector<int> up, acting;
osdmap.pg_to_up_acting_osds(mpgid, up, acting);
string fullobjname;
if (!namespacestr.empty())
fullobjname = namespacestr + string("/") + oid.name;
else
fullobjname = oid.name;
ds << "osdmap e" << osdmap.get_epoch()
<< " pool '" << poolstr << "' (" << pool << ") object '" << oid << "' ->"
<< " pool '" << poolstr << "' (" << pool << ") object '" << fullobjname << "' ->"
<< " pg " << pgid << " (" << mpgid << ")"
<< " -> up " << up << " acting " << acting;
rdata.append(ds);

View File

@ -244,7 +244,7 @@ bool DBObjectMap::parse_hobject_key_v0(const string &in, coll_t *c,
pg_t pg;
if (c->is_pg_prefix(pg))
pool = (int64_t)pg.pool();
(*hoid) = hobject_t(name, key, snap, hash, pool);
(*hoid) = hobject_t(name, key, snap, hash, pool, "");
return true;
}

View File

@ -702,7 +702,7 @@ int HashIndex::list_by_hash(const vector<string> &path,
if (j == objects.end() || j->first != *i) {
if (min_count > 0 && out->size() > (unsigned)min_count) {
if (next)
*next = hobject_t("", "", CEPH_NOSNAP, hash_prefix_to_hash(*i), -1);
*next = hobject_t("", "", CEPH_NOSNAP, hash_prefix_to_hash(*i), -1, "");
return 0;
}
*(next_path.rbegin()) = *(i->rbegin());

View File

@ -47,7 +47,8 @@ const string LFNIndex::FILENAME_COOKIE = "long";
const int LFNIndex::FILENAME_PREFIX_LEN = FILENAME_SHORT_LEN - FILENAME_HASH_LEN -
FILENAME_COOKIE.size() -
FILENAME_EXTRA;
void LFNIndex::maybe_inject_failure() {
void LFNIndex::maybe_inject_failure()
{
if (error_injection_enabled) {
if (current_failure > last_failure &&
(((double)(rand() % 10000))/((double)(10000))
@ -62,15 +63,18 @@ void LFNIndex::maybe_inject_failure() {
/* Public methods */
void LFNIndex::set_ref(std::tr1::shared_ptr<CollectionIndex> ref) {
void LFNIndex::set_ref(std::tr1::shared_ptr<CollectionIndex> ref)
{
self_ref = ref;
}
int LFNIndex::init() {
int LFNIndex::init()
{
return _init();
}
int LFNIndex::created(const hobject_t &hoid, const char *path) {
int LFNIndex::created(const hobject_t &hoid, const char *path)
{
vector<string> path_comp;
string short_name;
int r;
@ -83,7 +87,8 @@ int LFNIndex::created(const hobject_t &hoid, const char *path) {
return _created(path_comp, hoid, short_name);
}
int LFNIndex::unlink(const hobject_t &hoid) {
int LFNIndex::unlink(const hobject_t &hoid)
{
WRAP_RETRY(
vector<string> path;
string short_name;
@ -127,7 +132,8 @@ int LFNIndex::lookup(const hobject_t &hoid,
);
}
int LFNIndex::collection_list(vector<hobject_t> *ls) {
int LFNIndex::collection_list(vector<hobject_t> *ls)
{
return _collection_list(ls);
}
@ -137,13 +143,15 @@ int LFNIndex::collection_list_partial(const hobject_t &start,
int max_count,
snapid_t seq,
vector<hobject_t> *ls,
hobject_t *next) {
hobject_t *next)
{
return _collection_list_partial(start, min_count, max_count, seq, ls, next);
}
/* Derived class utility methods */
int LFNIndex::fsync_dir(const vector<string> &path) {
int LFNIndex::fsync_dir(const vector<string> &path)
{
maybe_inject_failure();
int fd = ::open(get_full_path_subdir(path).c_str(), O_RDONLY);
if (fd < 0)
@ -448,7 +456,8 @@ int LFNIndex::list_subdirs(const vector<string> &to_list,
return 0;
}
int LFNIndex::create_path(const vector<string> &to_create) {
int LFNIndex::create_path(const vector<string> &to_create)
{
maybe_inject_failure();
int r = ::mkdir(get_full_path_subdir(to_create).c_str(), 0777);
maybe_inject_failure();
@ -458,7 +467,8 @@ int LFNIndex::create_path(const vector<string> &to_create) {
return 0;
}
int LFNIndex::remove_path(const vector<string> &to_remove) {
int LFNIndex::remove_path(const vector<string> &to_remove)
{
maybe_inject_failure();
int r = ::rmdir(get_full_path_subdir(to_remove).c_str());
maybe_inject_failure();
@ -468,7 +478,8 @@ int LFNIndex::remove_path(const vector<string> &to_remove) {
return 0;
}
int LFNIndex::path_exists(const vector<string> &to_check, int *exists) {
int LFNIndex::path_exists(const vector<string> &to_check, int *exists)
{
string full_path = get_full_path_subdir(to_check);
struct stat buf;
if (::stat(full_path.c_str(), &buf)) {
@ -529,7 +540,8 @@ int LFNIndex::remove_attr_path(const vector<string> &path,
return chain_removexattr(full_path.c_str(), mangled_attr_name.c_str());
}
string LFNIndex::lfn_generate_object_name_keyless(const hobject_t &hoid) {
string LFNIndex::lfn_generate_object_name_keyless(const hobject_t &hoid)
{
char s[FILENAME_MAX_LEN];
char *end = s + sizeof(s);
char *t = s;
@ -569,7 +581,8 @@ string LFNIndex::lfn_generate_object_name_keyless(const hobject_t &hoid) {
static void append_escaped(string::const_iterator begin,
string::const_iterator end,
string *out) {
string *out)
{
for (string::const_iterator i = begin; i != end; ++i) {
if (*i == '\\') {
out->append("\\\\");
@ -585,7 +598,8 @@ static void append_escaped(string::const_iterator begin,
}
}
string LFNIndex::lfn_generate_object_name(const hobject_t &hoid) {
string LFNIndex::lfn_generate_object_name(const hobject_t &hoid)
{
if (index_version == HASH_INDEX_TAG)
return lfn_generate_object_name_keyless(hoid);
if (index_version == HASH_INDEX_TAG_2)
@ -632,7 +646,8 @@ string LFNIndex::lfn_generate_object_name(const hobject_t &hoid) {
return full_name;
}
string LFNIndex::lfn_generate_object_name_poolless(const hobject_t &hoid) {
string LFNIndex::lfn_generate_object_name_poolless(const hobject_t &hoid)
{
if (index_version == HASH_INDEX_TAG)
return lfn_generate_object_name_keyless(hoid);
@ -667,7 +682,8 @@ string LFNIndex::lfn_generate_object_name_poolless(const hobject_t &hoid) {
int LFNIndex::lfn_get_name(const vector<string> &path,
const hobject_t &hoid,
string *mangled_name, string *out_path,
int *exists) {
int *exists)
{
string subdir_path = get_full_path_subdir(path);
string full_name = lfn_generate_object_name(hoid);
int r;
@ -739,7 +755,8 @@ int LFNIndex::lfn_get_name(const vector<string> &path,
int LFNIndex::lfn_created(const vector<string> &path,
const hobject_t &hoid,
const string &mangled_name) {
const string &mangled_name)
{
if (!lfn_is_hashed_filename(mangled_name))
return 0;
string full_path = get_full_path(path, mangled_name);
@ -751,7 +768,8 @@ int LFNIndex::lfn_created(const vector<string> &path,
int LFNIndex::lfn_unlink(const vector<string> &path,
const hobject_t &hoid,
const string &mangled_name) {
const string &mangled_name)
{
if (!lfn_is_hashed_filename(mangled_name)) {
string full_path = get_full_path(path, mangled_name);
maybe_inject_failure();
@ -809,7 +827,8 @@ int LFNIndex::lfn_unlink(const vector<string> &path,
int LFNIndex::lfn_translate(const vector<string> &path,
const string &short_name,
hobject_t *out) {
hobject_t *out)
{
if (!lfn_is_hashed_filename(short_name)) {
return lfn_parse_object_name(short_name, out);
}
@ -826,11 +845,13 @@ int LFNIndex::lfn_translate(const vector<string> &path,
return lfn_parse_object_name(long_name, out);
}
bool LFNIndex::lfn_is_object(const string &short_name) {
bool LFNIndex::lfn_is_object(const string &short_name)
{
return lfn_is_hashed_filename(short_name) || !lfn_is_subdir(short_name, 0);
}
bool LFNIndex::lfn_is_subdir(const string &name, string *demangled) {
bool LFNIndex::lfn_is_subdir(const string &name, string *demangled)
{
if (name.substr(0, SUBDIR_PREFIX.size()) == SUBDIR_PREFIX) {
if (demangled)
*demangled = demangle_path_component(name);
@ -889,7 +910,8 @@ static int parse_object(const char *s, hobject_t& o)
return 0;
}
bool LFNIndex::lfn_parse_object_name_keyless(const string &long_name, hobject_t *out) {
bool LFNIndex::lfn_parse_object_name_keyless(const string &long_name, hobject_t *out)
{
bool r = parse_object(long_name.c_str(), *out);
int64_t pool = -1;
pg_t pg;
@ -986,12 +1008,13 @@ bool LFNIndex::lfn_parse_object_name_poolless(const string &long_name,
pg_t pg;
if (coll().is_pg_prefix(pg))
pool = (int64_t)pg.pool();
(*out) = hobject_t(name, key, snap, hash, pool);
(*out) = hobject_t(name, key, snap, hash, pool, "");
return true;
}
bool LFNIndex::lfn_parse_object_name(const string &long_name, hobject_t *out) {
bool LFNIndex::lfn_parse_object_name(const string &long_name, hobject_t *out)
{
string name;
string key;
string ns;
@ -1072,12 +1095,12 @@ bool LFNIndex::lfn_parse_object_name(const string &long_name, hobject_t *out) {
else
pool = strtoull(pstring.c_str(), NULL, 16);
(*out) = hobject_t(name, key, snap, hash, (int64_t)pool);
out->nspace = ns;
(*out) = hobject_t(name, key, snap, hash, (int64_t)pool, ns);
return true;
}
bool LFNIndex::lfn_is_hashed_filename(const string &name) {
bool LFNIndex::lfn_is_hashed_filename(const string &name)
{
if (name.size() < (unsigned)FILENAME_SHORT_LEN) {
return 0;
}
@ -1089,7 +1112,8 @@ bool LFNIndex::lfn_is_hashed_filename(const string &name) {
}
}
bool LFNIndex::lfn_must_hash(const string &long_name) {
bool LFNIndex::lfn_must_hash(const string &long_name)
{
return (int)long_name.size() >= FILENAME_SHORT_LEN;
}
@ -1143,7 +1167,8 @@ void LFNIndex::build_filename(const char *old_filename, int i, char *filename, i
}
}
string LFNIndex::lfn_get_short_name(const hobject_t &hoid, int i) {
string LFNIndex::lfn_get_short_name(const hobject_t &hoid, int i)
{
string long_name = lfn_generate_object_name(hoid);
assert(lfn_must_hash(long_name));
char buf[FILENAME_SHORT_LEN + 4];
@ -1151,11 +1176,13 @@ string LFNIndex::lfn_get_short_name(const hobject_t &hoid, int i) {
return string(buf);
}
const string &LFNIndex::get_base_path() {
const string &LFNIndex::get_base_path()
{
return base_path;
}
string LFNIndex::get_full_path_subdir(const vector<string> &rel) {
string LFNIndex::get_full_path_subdir(const vector<string> &rel)
{
string retval = get_base_path();
for (vector<string>::const_iterator i = rel.begin();
i != rel.end();
@ -1166,20 +1193,24 @@ string LFNIndex::get_full_path_subdir(const vector<string> &rel) {
return retval;
}
string LFNIndex::get_full_path(const vector<string> &rel, const string &name) {
string LFNIndex::get_full_path(const vector<string> &rel, const string &name)
{
return get_full_path_subdir(rel) + "/" + name;
}
string LFNIndex::mangle_path_component(const string &component) {
string LFNIndex::mangle_path_component(const string &component)
{
return SUBDIR_PREFIX + component;
}
string LFNIndex::demangle_path_component(const string &component) {
string LFNIndex::demangle_path_component(const string &component)
{
return component.substr(SUBDIR_PREFIX.size(), component.size() - SUBDIR_PREFIX.size());
}
int LFNIndex::decompose_full_path(const char *in, vector<string> *out,
hobject_t *hoid, string *shortname) {
hobject_t *hoid, string *shortname)
{
const char *beginning = in + get_base_path().size();
const char *end = beginning;
while (1) {
@ -1202,6 +1233,7 @@ int LFNIndex::decompose_full_path(const char *in, vector<string> *out,
return 0;
}
string LFNIndex::mangle_attr_name(const string &attr) {
string LFNIndex::mangle_attr_name(const string &attr)
{
return PHASH_ATTR_PREFIX + attr;
}

View File

@ -445,9 +445,9 @@ void ObjectStore::Transaction::generate_test_instances(list<ObjectStore::Transac
t = new Transaction;
coll_t c("foocoll");
coll_t c2("foocoll2");
hobject_t o1("obj", "", 123, 456, -1);
hobject_t o2("obj2", "", 123, 456, -1);
hobject_t o3("obj3", "", 123, 456, -1);
hobject_t o1("obj", "", 123, 456, -1, "");
hobject_t o2("obj2", "", 123, 456, -1, "");
hobject_t o3("obj3", "", 123, 456, -1, "");
t->touch(c, o1);
bufferlist bl;
bl.append("some data");

View File

@ -150,6 +150,10 @@ void hobject_t::decode(json_spirit::Value& v)
hash = p.value_.get_int();
else if (p.name_ == "max")
max = p.value_.get_int();
else if (p.name_ == "pool")
pool = p.value_.get_int();
else if (p.name_ == "namespace")
nspace = p.value_.get_str();
}
}
@ -160,6 +164,8 @@ void hobject_t::dump(Formatter *f) const
f->dump_int("snapid", snap);
f->dump_int("hash", hash);
f->dump_int("max", (int)max);
f->dump_int("pool", pool);
f->dump_string("namespace", nspace);
}
void hobject_t::generate_test_instances(list<hobject_t*>& o)
@ -167,9 +173,11 @@ void hobject_t::generate_test_instances(list<hobject_t*>& o)
o.push_back(new hobject_t);
o.push_back(new hobject_t);
o.back()->max = true;
o.push_back(new hobject_t(object_t("oname"), string(), 1, 234, -1));
o.push_back(new hobject_t(object_t("oname2"), string("okey"), CEPH_NOSNAP, 67, 0));
o.push_back(new hobject_t(object_t("oname3"), string("oname3"), CEPH_SNAPDIR, 910, 1));
o.push_back(new hobject_t(object_t("oname"), string(), 1, 234, -1, ""));
o.push_back(new hobject_t(object_t("oname2"), string("okey"), CEPH_NOSNAP,
67, 0, "n1"));
o.push_back(new hobject_t(object_t("oname3"), string("oname3"),
CEPH_SNAPDIR, 910, 1, "n2"));
}
ostream& operator<<(ostream& out, const hobject_t& o)

View File

@ -59,15 +59,15 @@ public:
hobject_t() : snap(0), hash(0), max(false), pool(-1) {}
hobject_t(object_t oid, const string& key, snapid_t snap, uint64_t hash,
int64_t pool) :
int64_t pool, string nspace) :
oid(oid), snap(snap), hash(hash), max(false),
pool(pool),
pool(pool), nspace(nspace),
key(oid.name == key ? string() : key) {}
hobject_t(const sobject_t &soid, const string &key, uint32_t hash,
int64_t pool) :
int64_t pool, string nspace) :
oid(soid.oid), snap(soid.snap), hash(hash), max(false),
pool(pool),
pool(pool), nspace(nspace),
key(soid.oid.name == key ? string() : key) {}
/// @return min hobject_t ret s.t. ret.hash == this->hash
@ -125,9 +125,6 @@ public:
else
return get_filestore_key_u32();
}
void set_filestore_key(uint32_t v) {
hash = _reverse_nibbles(v);
}
const string& get_effective_key() const {
if (key.length())
@ -141,6 +138,10 @@ public:
(*this) = temp;
}
string get_namespace() const {
return nspace;
}
void encode(bufferlist& bl) const;
void decode(bufferlist::iterator& bl);
void decode(json_spirit::Value& v);

View File

@ -1055,6 +1055,7 @@ bool OSD::asok_command(string command, string args, ostream& ss)
f.open_array_section("watch");
f.dump_string("namespace", it->obj.nspace);
f.dump_string("object", it->obj.oid.name);
f.open_object_section("entity_name");
@ -3086,13 +3087,13 @@ void OSD::check_ops_in_flight()
}
// Usage:
// setomapval <pool-id> <obj-name> <key> <val>
// rmomapkey <pool-id> <obj-name> <key>
// setomapheader <pool-id> <obj-name> <header>
// getomap <pool> <obj-name>
// truncobj <pool-id> <obj-name> <newlen>
// injectmdataerr
// injectdataerr
// setomapval <pool-id> [namespace/]<obj-name> <key> <val>
// rmomapkey <pool-id> [namespace/]<obj-name> <key>
// setomapheader <pool-id> [namespace/]<obj-name> <header>
// getomap <pool> [namespace/]<obj-name>
// truncobj <pool-id> [namespace/]<obj-name> <newlen>
// injectmdataerr [namespace/]<obj-name>
// injectdataerr [namespace/]<obj-name>
void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
std::string command, std::string args, ostream &ss)
{
@ -3124,21 +3125,29 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
if (pool < 0 && isdigit(argv[1].c_str()[0]))
pool = atoll(argv[1].c_str());
r = -1;
if (pool >= 0)
r = curmap->object_locator_to_pg(object_t(argv[2]),
object_locator_t(pool), rawpg);
string objname, nspace;
objname = string(argv[2]);
if (pool >= 0) {
std::size_t found = argv[2].find_first_of('/');
if (found != string::npos) {
nspace = argv[2].substr(0, found);
objname = argv[2].substr(found+1);
}
object_locator_t oloc(pool, nspace);
r = curmap->object_locator_to_pg(object_t(objname), oloc, rawpg);
}
if (r < 0) {
ss << "Invalid pool " << argv[1];
return;
}
pgid = curmap->raw_pg_to_pg(rawpg);
hobject_t obj(object_t(argv[2]), string(""), CEPH_NOSNAP, rawpg.ps(), pool);
hobject_t obj(object_t(objname), string(""), CEPH_NOSNAP, rawpg.ps(), pool, nspace);
ObjectStore::Transaction t;
if (command == "setomapval") {
if (argc != 5) {
ss << "usage: setomapval <pool> <obj-name> <key> <val>";
ss << "usage: setomapval <pool> [namespace/]<obj-name> <key> <val>";
return;
}
map<string, bufferlist> newattrs;
@ -3155,7 +3164,7 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
ss << "ok";
} else if (command == "rmomapkey") {
if (argc != 4) {
ss << "usage: rmomapkey <pool> <obj-name> <key>";
ss << "usage: rmomapkey <pool> [namespace/]<obj-name> <key>";
return;
}
set<string> keys;
@ -3169,7 +3178,7 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
ss << "ok";
} else if (command == "setomapheader") {
if (argc != 4) {
ss << "usage: setomapheader <pool> <obj-name> <header>";
ss << "usage: setomapheader <pool> [namespace/]<obj-name> <header>";
return;
}
bufferlist newheader;
@ -3183,7 +3192,7 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
ss << "ok";
} else if (command == "getomap") {
if (argc != 3) {
ss << "usage: getomap <pool> <obj-name>";
ss << "usage: getomap <pool> [namespace/]<obj-name>";
return;
}
//Debug: Output entire omap
@ -3201,7 +3210,7 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
}
} else if (command == "truncobj") {
if (argc != 4) {
ss << "usage: truncobj <pool> <obj-name> <val>";
ss << "usage: truncobj <pool> [namespace/]<obj-name> <val>";
return;
}
t.truncate(coll_t(pgid), obj, atoi(argv[3].c_str()));

View File

@ -64,10 +64,18 @@ ostream& operator<<(ostream& out, const OSDCapMatch& m)
if (m.pool_name.length()) {
out << "pool " << m.pool_name << " ";
}
if (m.is_nspace) {
out << "namespace ";
if (m.nspace.length() == 0)
out << "\"\"";
else
out << m.nspace;
out << " ";
}
return out;
}
bool OSDCapMatch::is_match(const string& pn, int64_t pool_auid, const string& object) const
bool OSDCapMatch::is_match(const string& pn, const string& ns, int64_t pool_auid, const string& object) const
{
if (auid >= 0) {
if (auid != pool_auid)
@ -77,6 +85,10 @@ bool OSDCapMatch::is_match(const string& pn, int64_t pool_auid, const string& ob
if (pool_name != pn)
return false;
}
if (is_nspace) {
if (nspace != ns)
return false;
}
if (object_prefix.length()) {
if (object.find(object_prefix) != 0)
return false;
@ -84,6 +96,19 @@ bool OSDCapMatch::is_match(const string& pn, int64_t pool_auid, const string& ob
return true;
}
bool OSDCapMatch::is_match_all() const
{
if (auid >= 0)
return false;
if (pool_name.length())
return false;
if (is_nspace)
return false;
if (object_prefix.length())
return false;
return true;
}
ostream& operator<<(ostream& out, const OSDCapGrant& g)
{
return out << "grant(" << g.match << g.spec << ")";
@ -93,7 +118,7 @@ ostream& operator<<(ostream& out, const OSDCapGrant& g)
bool OSDCap::allow_all() const
{
for (vector<OSDCapGrant>::const_iterator p = grants.begin(); p != grants.end(); ++p)
if (p->match.is_match(string(), CEPH_AUTH_UID_DEFAULT, string()) && p->spec.allow_all())
if (p->match.is_match_all() && p->spec.allow_all())
return true;
return false;
}
@ -104,7 +129,7 @@ void OSDCap::set_allow_all()
grants.push_back(OSDCapGrant(OSDCapMatch(), OSDCapSpec(OSD_CAP_ANY)));
}
bool OSDCap::is_capable(const string& pool_name, int64_t pool_auid,
bool OSDCap::is_capable(const string& pool_name, const string& ns, int64_t pool_auid,
const string& object, bool op_may_read,
bool op_may_write, bool op_may_class_read,
bool op_may_class_write) const
@ -112,7 +137,7 @@ bool OSDCap::is_capable(const string& pool_name, int64_t pool_auid,
osd_rwxa_t allow = 0;
for (vector<OSDCapGrant>::const_iterator p = grants.begin();
p != grants.end(); ++p) {
if (p->match.is_match(pool_name, pool_auid, object)) {
if (p->match.is_match(pool_name, ns, pool_auid, object)) {
allow = allow | p->spec.allow;
if ((op_may_read && !(allow & OSD_CAP_R)) ||
(op_may_write && !(allow & OSD_CAP_W)) ||
@ -150,18 +175,24 @@ struct OSDCapParser : qi::grammar<Iterator, OSDCap()>
quoted_string %=
lexeme['"' >> +(char_ - '"') >> '"'] |
lexeme['\'' >> +(char_ - '\'') >> '\''];
equoted_string %=
lexeme['"' >> *(char_ - '"') >> '"'] |
lexeme['\'' >> *(char_ - '\'') >> '\''];
unquoted_word %= +char_("a-zA-Z0-9_-");
str %= quoted_string | unquoted_word;
estr %= equoted_string | unquoted_word;
spaces = +lit(' ');
// match := [pool[=]<poolname> | auid <123>] [object_prefix <prefix>]
// match := [pool[=]<poolname> [namespace[=]<namespace>] | auid <123>] [object_prefix <prefix>]
pool_name %= -(spaces >> lit("pool") >> (lit('=') | spaces) >> str);
nspace %= (spaces >> lit("namespace") >> (lit('=') | spaces) >> estr);
auid %= (spaces >> lit("auid") >> spaces >> int_);
object_prefix %= -(spaces >> lit("object_prefix") >> spaces >> str);
match = ( (auid >> object_prefix) [_val = phoenix::construct<OSDCapMatch>(_1, _2)] |
(pool_name >> object_prefix) [_val = phoenix::construct<OSDCapMatch>(_1, _2)]);
(pool_name >> nspace >> object_prefix) [_val = phoenix::construct<OSDCapMatch>(_1, _2, _3)] |
(pool_name >> object_prefix) [_val = phoenix::construct<OSDCapMatch>(_1, _2)]);
// rwxa := * | [r][w][x] [class-read] [class-write]
rwxa =
@ -192,12 +223,13 @@ struct OSDCapParser : qi::grammar<Iterator, OSDCap()>
}
qi::rule<Iterator> spaces;
qi::rule<Iterator, unsigned()> rwxa;
qi::rule<Iterator, string()> quoted_string;
qi::rule<Iterator, string()> quoted_string, equoted_string;
qi::rule<Iterator, string()> unquoted_word;
qi::rule<Iterator, string()> str;
qi::rule<Iterator, string()> str, estr;
qi::rule<Iterator, int()> auid;
qi::rule<Iterator, OSDCapSpec()> capspec;
qi::rule<Iterator, string()> pool_name;
qi::rule<Iterator, string()> nspace;
qi::rule<Iterator, string()> object_prefix;
qi::rule<Iterator, OSDCapMatch()> match;
qi::rule<Iterator, OSDCapGrant()> grant;

View File

@ -73,26 +73,33 @@ ostream& operator<<(ostream& out, const OSDCapSpec& s);
struct OSDCapMatch {
// auid and pool_name are mutually exclusive
// auid and pool_name/nspace are mutually exclusive
int64_t auid;
std::string pool_name;
bool is_nspace; // true if nspace is defined; false if not constrained.
std::string nspace;
std::string object_prefix;
OSDCapMatch() : auid(CEPH_AUTH_UID_DEFAULT) {}
OSDCapMatch(std::string pl, std::string pre) : auid(CEPH_AUTH_UID_DEFAULT), pool_name(pl), object_prefix(pre) {}
OSDCapMatch(uint64_t auid, std::string pre) : auid(auid), object_prefix(pre) {}
OSDCapMatch() : auid(CEPH_AUTH_UID_DEFAULT), is_nspace(false) {}
OSDCapMatch(std::string pl, std::string pre) :
auid(CEPH_AUTH_UID_DEFAULT), pool_name(pl), is_nspace(false), object_prefix(pre) {}
OSDCapMatch(std::string pl, std::string ns, std::string pre) :
auid(CEPH_AUTH_UID_DEFAULT), pool_name(pl), is_nspace(true), nspace(ns), object_prefix(pre) {}
OSDCapMatch(uint64_t auid, std::string pre) : auid(auid), is_nspace(false), object_prefix(pre) {}
/**
* check if given request parameters match our constraints
*
* @param auid requesting user's auid
* @param pool_name pool name
* @param nspace_name namespace name
* @param pool_auid pool's auid
* @param object object name
* @return true if we match, false otherwise
*/
bool is_match(const std::string& pool_name, int64_t pool_auid, const std::string& object) const;
bool is_match(const std::string& pool_name, const std::string& nspace_name, int64_t pool_auid, const std::string& object) const;
bool is_match_all() const;
};
ostream& operator<<(ostream& out, const OSDCapMatch& m);
@ -127,6 +134,7 @@ struct OSDCap {
* against pool, pool auid, and object name prefix.
*
* @param pool_name name of the pool we are accessing
* @param ns name of the namespace we are accessing
* @param pool_auid owner of the pool we are accessing
* @param object name of the object we are accessing
* @param op_may_read whether the operation may need to read
@ -137,7 +145,7 @@ struct OSDCap {
* write class method
* @return true if the operation is allowed, false otherwise
*/
bool is_capable(const string& pool_name, int64_t pool_auid,
bool is_capable(const string& pool_name, const string& ns, int64_t pool_auid,
const string& object, bool op_may_read, bool op_may_write,
bool op_may_class_read, bool op_may_class_write) const;
};

View File

@ -977,26 +977,39 @@ int OSDMap::apply_incremental(const Incremental &inc)
return 0;
}
static string make_hash_str(const string &inkey, const string &nspace)
{
if (nspace.empty())
return inkey;
return nspace + '\037' + inkey;
}
// mapping
int OSDMap::object_locator_to_pg(const object_t& oid, const object_locator_t& loc, pg_t &pg) const
int OSDMap::object_locator_to_pg(
const object_t& oid,
const object_locator_t& loc,
pg_t &pg) const
{
// calculate ps (placement seed)
const pg_pool_t *pool = get_pg_pool(loc.get_pool());
if (!pool)
return -ENOENT;
ps_t ps;
if (loc.key.length())
ps = ceph_str_hash(pool->object_hash, loc.key.c_str(), loc.key.length());
string key;
if (!loc.key.empty())
key = make_hash_str(loc.key, loc.nspace);
else
ps = ceph_str_hash(pool->object_hash, oid.name.c_str(), oid.name.length());
key = make_hash_str(oid.name, loc.nspace);
ps = ceph_str_hash(pool->object_hash, key.c_str(), key.length());
pg = pg_t(ps, loc.get_pool(), -1);
return 0;
}
ceph_object_layout OSDMap::make_object_layout(object_t oid, int pg_pool) const
ceph_object_layout OSDMap::make_object_layout(
object_t oid, int pg_pool, string nspace) const
{
object_locator_t loc(pg_pool);
object_locator_t loc(pg_pool, nspace);
ceph_object_layout ol;
pg_t pgid = object_locator_to_pg(oid, loc);

View File

@ -466,12 +466,13 @@ public:
return object_locator_t(layout.fl_pg_pool);
}
// XXX: not used, mentioned in psim.cc comment
// oid -> pg
ceph_object_layout file_to_object_layout(object_t oid, ceph_file_layout& layout) const {
return make_object_layout(oid, layout.fl_pg_pool);
ceph_object_layout file_to_object_layout(object_t oid, ceph_file_layout& layout, string nspace) const {
return make_object_layout(oid, layout.fl_pg_pool, nspace);
}
ceph_object_layout make_object_layout(object_t oid, int pg_pool) const;
ceph_object_layout make_object_layout(object_t oid, int pg_pool, string nspace) const;
int get_pg_num(int pg_pool) const
{

View File

@ -1340,13 +1340,15 @@ bool PG::op_has_sufficient_caps(OpRequestRef op)
if (key.length() == 0)
key = req->get_oid().name;
bool cap = caps.is_capable(pool.name, pool.auid, key,
bool cap = caps.is_capable(pool.name, req->get_object_locator().nspace,
pool.auid, key,
op->need_read_cap(),
op->need_write_cap(),
op->need_class_read_cap(),
op->need_class_write_cap());
dout(20) << "op_has_sufficient_caps pool=" << pool.id << " (" << pool.name
<< " " << req->get_object_locator().nspace
<< ") owner=" << pool.auid
<< " need_read_cap=" << op->need_read_cap()
<< " need_write_cap=" << op->need_write_cap()

View File

@ -65,9 +65,6 @@ static ostream& _prefix(std::ostream *_dout, PG *pg, int whoami, OSDMapRef osdma
#include <errno.h>
// Blank object locator
static const object_locator_t OLOC_BLANK;
PGLSFilter::PGLSFilter()
{
}
@ -551,6 +548,10 @@ void ReplicatedPG::do_pg_op(OpRequestRef op)
}
}
// skip wrong namespace
if (candidate.get_namespace() != m->get_object_locator().nspace)
continue;
if (filter && !pgls_filter(filter, candidate, filter_out))
continue;
@ -662,7 +663,7 @@ void ReplicatedPG::do_op(OpRequestRef op)
hobject_t head(m->get_oid(), m->get_object_locator().key,
CEPH_NOSNAP, m->get_pg().ps(),
info.pgid.pool());
info.pgid.pool(), m->get_object_locator().nspace);
if (op->may_write() && scrubber.write_blocked_by_scrub(head)) {
dout(20) << __func__ << ": waiting for scrub" << dendl;
@ -690,7 +691,8 @@ void ReplicatedPG::do_op(OpRequestRef op)
// missing snapdir?
hobject_t snapdir(m->get_oid(), m->get_object_locator().key,
CEPH_SNAPDIR, m->get_pg().ps(), info.pgid.pool());
CEPH_SNAPDIR, m->get_pg().ps(), info.pgid.pool(),
m->get_object_locator().nspace);
if (is_missing_object(snapdir)) {
wait_for_missing_object(snapdir, op);
return;
@ -718,8 +720,8 @@ void ReplicatedPG::do_op(OpRequestRef op)
m->get_object_locator().key,
m->get_snapid(),
m->get_pg().ps(),
m->get_object_locator().get_pool()),
m->get_object_locator(),
m->get_object_locator().get_pool(),
m->get_object_locator().nspace),
&obc, can_create, &snapid);
if (r) {
if (r == -EAGAIN) {
@ -733,7 +735,7 @@ void ReplicatedPG::do_op(OpRequestRef op)
assert(!can_create); // only happens on a read
hobject_t soid(m->get_oid(), m->get_object_locator().key,
snapid, m->get_pg().ps(),
info.pgid.pool());
info.pgid.pool(), m->get_object_locator().nspace);
wait_for_missing_object(soid, op);
return;
}
@ -743,13 +745,12 @@ void ReplicatedPG::do_op(OpRequestRef op)
}
// make sure locator is consistent
if (m->get_object_locator() != obc->obs.oi.oloc) {
object_locator_t oloc(obc->obs.oi.soid);
if (m->get_object_locator() != oloc) {
dout(10) << " provided locator " << m->get_object_locator()
<< " != object's " << obc->obs.oi.oloc
<< " on " << obc->obs.oi.soid << dendl;
<< " != object's " << obc->obs.oi.soid << dendl;
osd->clog.warn() << "bad locator " << m->get_object_locator()
<< " on object " << obc->obs.oi.oloc
<< " loc " << m->get_object_locator()
<< " on object " << oloc
<< " op " << *m << "\n";
}
@ -830,38 +831,40 @@ void ReplicatedPG::do_op(OpRequestRef op)
object_locator_t src_oloc;
get_src_oloc(m->get_oid(), m->get_object_locator(), src_oloc);
hobject_t src_oid(osd_op.soid, src_oloc.key, m->get_pg().ps(),
info.pgid.pool());
info.pgid.pool(), m->get_object_locator().nspace);
if (!src_obc.count(src_oid)) {
ObjectContext *sobc;
snapid_t ssnapid;
int r = find_object_context(src_oid, src_oloc, &sobc, false, &ssnapid);
int r = find_object_context(src_oid, &sobc, false, &ssnapid);
if (r == -EAGAIN) {
// missing the specific snap we need; requeue and wait.
hobject_t wait_oid(osd_op.soid.oid, src_oloc.key, ssnapid, m->get_pg().ps(),
info.pgid.pool());
info.pgid.pool(), m->get_object_locator().nspace);
wait_for_missing_object(wait_oid, op);
} else if (r) {
osd->reply_op_error(op, r);
} else if (sobc->obs.oi.oloc.key != obc->obs.oi.oloc.key &&
sobc->obs.oi.oloc.key != obc->obs.oi.soid.oid.name &&
sobc->obs.oi.soid.oid.name != obc->obs.oi.oloc.key) {
dout(1) << " src_oid " << osd_op.soid << " oloc " << sobc->obs.oi.oloc << " != "
<< m->get_oid() << " oloc " << obc->obs.oi.oloc << dendl;
osd->reply_op_error(op, -EINVAL);
} else if (is_degraded_object(sobc->obs.oi.soid) ||
(before_backfill && sobc->obs.oi.soid > backfill_target_info->last_backfill)) {
wait_for_degraded_object(sobc->obs.oi.soid, op);
dout(10) << " writes for " << obc->obs.oi.soid << " now blocked by "
<< sobc->obs.oi.soid << dendl;
obc->get();
obc->blocked_by = sobc;
sobc->get();
sobc->blocking.insert(obc);
} else {
dout(10) << " src_oid " << src_oid << " obc " << src_obc << dendl;
src_obc[src_oid] = sobc;
continue;
if (sobc->obs.oi.soid.get_key() != obc->obs.oi.soid.get_key() &&
sobc->obs.oi.soid.get_key() != obc->obs.oi.soid.oid.name &&
sobc->obs.oi.soid.oid.name != obc->obs.oi.soid.get_key()) {
dout(1) << " src_oid " << sobc->obs.oi.soid << " != "
<< obc->obs.oi.soid << dendl;
osd->reply_op_error(op, -EINVAL);
} else if (is_degraded_object(sobc->obs.oi.soid) ||
(before_backfill && sobc->obs.oi.soid > backfill_target_info->last_backfill)) {
wait_for_degraded_object(sobc->obs.oi.soid, op);
dout(10) << " writes for " << obc->obs.oi.soid << " now blocked by "
<< sobc->obs.oi.soid << dendl;
obc->get();
obc->blocked_by = sobc;
sobc->get();
sobc->blocking.insert(obc);
} else {
dout(10) << " src_oid " << src_oid << " obc " << src_obc << dendl;
src_obc[src_oid] = sobc;
continue;
}
}
// Error cleanup below
} else {
@ -891,11 +894,11 @@ void ReplicatedPG::do_op(OpRequestRef op)
ObjectContext *sobc;
snapid_t ssnapid;
int r = find_object_context(clone_oid, src_oloc, &sobc, false, &ssnapid);
int r = find_object_context(clone_oid, &sobc, false, &ssnapid);
if (r == -EAGAIN) {
// missing the specific snap we need; requeue and wait.
hobject_t wait_oid(clone_oid.oid, src_oloc.key, ssnapid, m->get_pg().ps(),
info.pgid.pool());
info.pgid.pool(), clone_oid.get_namespace());
wait_for_missing_object(wait_oid, op);
} else if (r) {
osd->reply_op_error(op, r);
@ -1497,9 +1500,7 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
// load clone info
bufferlist bl;
ObjectContext *obc = 0;
int r = find_object_context(
coid,
OLOC_BLANK, &obc, false, NULL);
int r = find_object_context(coid, &obc, false, NULL);
if (r == -ENOENT || coid.snap != obc->obs.oi.soid.snap) {
derr << __func__ << "could not find coid " << coid << dendl;
assert(0);
@ -1517,7 +1518,8 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
coid.oid,
coid.get_key(),
coid.hash,
false);
false,
coid.get_namespace());
assert(obc->ssc);
SnapSet& snapset = obc->ssc->snapset;
@ -1644,8 +1646,8 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
hobject_t snapoid(
coid.oid, coid.get_key(),
snapset.head_exists ? CEPH_NOSNAP:CEPH_SNAPDIR, coid.hash,
info.pgid.pool());
ctx->snapset_obc = get_object_context(snapoid, coi.oloc, false);
info.pgid.pool(), coid.get_namespace());
ctx->snapset_obc = get_object_context(snapoid, false);
assert(ctx->snapset_obc->registered);
if (snapset.clones.empty() && !snapset.head_exists) {
@ -2100,10 +2102,11 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
ObjectContext *src_obc = 0;
if (ceph_osd_op_type_multi(op.op)) {
MOSDOp *m = static_cast<MOSDOp *>(ctx->op->request);
object_locator_t src_oloc;
get_src_oloc(soid.oid, (static_cast<MOSDOp *>(ctx->op->request))->get_object_locator(), src_oloc);
get_src_oloc(soid.oid, m->get_object_locator(), src_oloc);
hobject_t src_oid(osd_op.soid, src_oloc.key, soid.hash,
info.pgid.pool());
info.pgid.pool(), src_oloc.nspace);
src_obc = ctx->src_obc[src_oid];
dout(10) << " src_oid " << src_oid << " obc " << src_obc << dendl;
assert(src_obc);
@ -2476,7 +2479,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
if (!ssc) {
ssc = ctx->obc->ssc = get_snapset_context(soid.oid,
soid.get_key(), soid.hash, false);
soid.get_key(), soid.hash, false, soid.get_namespace());
}
assert(ssc);
@ -3409,8 +3412,8 @@ int ReplicatedPG::_rollback_to(OpContext *ctx, ceph_osd_op& op)
ObjectContext *rollback_to;
int ret = find_object_context(
hobject_t(soid.oid, oi.oloc.key, snapid, soid.hash, info.pgid.pool()),
oi.oloc, &rollback_to, false, &cloneid);
hobject_t(soid.oid, soid.get_key(), snapid, soid.hash, info.pgid.pool(), soid.get_namespace()),
&rollback_to, false, &cloneid);
if (ret) {
if (-ENOENT == ret) {
// there's no snapshot here, or there's no object.
@ -3429,7 +3432,7 @@ int ReplicatedPG::_rollback_to(OpContext *ctx, ceph_osd_op& op)
* with not-yet-restored object. We shouldn't have been able
* to get here; recovery should have completed first! */
hobject_t rollback_target(soid.oid, soid.get_key(), cloneid, soid.hash,
info.pgid.pool());
info.pgid.pool(), soid.get_namespace());
assert(is_missing_object(rollback_target));
dout(20) << "_rollback_to attempted to roll back to a missing object "
<< rollback_target << " (requested snapid: ) " << snapid << dendl;
@ -3543,7 +3546,7 @@ void ReplicatedPG::make_writeable(OpContext *ctx)
snaps[i] = snapc.snaps[i];
// prepare clone
object_info_t static_snap_oi(coid, ctx->obs->oi.oloc);
object_info_t static_snap_oi(coid);
object_info_t *snap_oi;
if (is_primary()) {
ctx->clone_obc = new ObjectContext(static_snap_oi, true, NULL);
@ -3786,9 +3789,9 @@ int ReplicatedPG::prepare_transaction(OpContext *ctx)
if (!head_existed) {
// if we logically recreated the head, remove old _snapdir object
hobject_t snapoid(soid.oid, soid.get_key(), CEPH_SNAPDIR, soid.hash,
info.pgid.pool());
info.pgid.pool(), soid.get_namespace());
ctx->snapset_obc = get_object_context(snapoid, ctx->new_obs.oi.oloc, false);
ctx->snapset_obc = get_object_context(snapoid, false);
if (ctx->snapset_obc && ctx->snapset_obc->obs.exists) {
ctx->op_t.remove(coll, snapoid);
dout(10) << " removing old " << snapoid << dendl;
@ -3804,13 +3807,13 @@ int ReplicatedPG::prepare_transaction(OpContext *ctx)
} else if (ctx->new_snapset.clones.size()) {
// save snapset on _snap
hobject_t snapoid(soid.oid, soid.get_key(), CEPH_SNAPDIR, soid.hash,
info.pgid.pool());
info.pgid.pool(), soid.get_namespace());
dout(10) << " final snapset " << ctx->new_snapset
<< " in " << snapoid << dendl;
ctx->log.push_back(pg_log_entry_t(pg_log_entry_t::MODIFY, snapoid, ctx->at_version, old_version,
osd_reqid_t(), ctx->mtime));
ctx->snapset_obc = get_object_context(snapoid, ctx->new_obs.oi.oloc, true);
ctx->snapset_obc = get_object_context(snapoid, true);
ctx->snapset_obc->obs.exists = true;
ctx->snapset_obc->obs.oi.version = ctx->at_version;
ctx->snapset_obc->obs.oi.last_reqid = ctx->reqid;
@ -4213,7 +4216,7 @@ void ReplicatedPG::issue_repop(RepGather *repop, utime_t now,
((static_cast<MOSDOp *>(ctx->op->request))->get_flags() & CEPH_OSD_FLAG_PARALLELEXEC)) {
// replicate original op for parallel execution on replica
assert(0 == "broken implementation, do not use");
wr->oloc = repop->ctx->obs->oi.oloc;
wr->oloc = object_locator_t(repop->ctx->obs->oi.soid);
wr->ops = repop->ctx->ops;
wr->mtime = repop->ctx->mtime;
wr->old_exists = old_exists;
@ -4529,7 +4532,6 @@ ObjectContext *ReplicatedPG::create_object_context(const object_info_t& oi,
}
ObjectContext *ReplicatedPG::get_object_context(const hobject_t& soid,
const object_locator_t& oloc,
bool can_create)
{
map<hobject_t, ObjectContext*>::iterator p = object_contexts.find(soid);
@ -4547,28 +4549,25 @@ ObjectContext *ReplicatedPG::get_object_context(const hobject_t& soid,
return NULL; // -ENOENT!
// new object.
object_info_t oi(soid, oloc);
SnapSetContext *ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, true);
object_info_t oi(soid);
SnapSetContext *ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, true, soid.get_namespace());
return create_object_context(oi, ssc);
}
object_info_t oi(bv);
// if the on-disk oloc is bad/undefined, set up the pool value
if (oi.oloc.get_pool() < 0) {
oi.oloc.pool = info.pgid.pool();
}
assert(oi.soid.pool == (int64_t)info.pgid.pool());
SnapSetContext *ssc = NULL;
if (can_create)
ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, true);
ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, true, soid.get_namespace());
obc = new ObjectContext(oi, true, ssc);
obc->obs.exists = true;
register_object_context(obc);
if (can_create && !obc->ssc)
obc->ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, true);
obc->ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, true, soid.get_namespace());
populate_obc_watchers(obc);
dout(10) << "get_object_context " << obc << " " << soid << " 0 -> 1 read " << obc->obs.oi << dendl;
@ -4601,27 +4600,26 @@ void ReplicatedPG::context_registry_on_change()
int ReplicatedPG::find_object_context(const hobject_t& oid,
const object_locator_t& oloc,
ObjectContext **pobc,
bool can_create,
snapid_t *psnapid)
{
hobject_t head(oid.oid, oid.get_key(), CEPH_NOSNAP, oid.hash,
info.pgid.pool());
info.pgid.pool(), oid.get_namespace());
hobject_t snapdir(oid.oid, oid.get_key(), CEPH_SNAPDIR, oid.hash,
info.pgid.pool());
info.pgid.pool(), oid.get_namespace());
// want the snapdir?
if (oid.snap == CEPH_SNAPDIR) {
// return head or snapdir, whichever exists.
ObjectContext *obc = get_object_context(head, oloc, can_create);
ObjectContext *obc = get_object_context(head, can_create);
if (obc && !obc->obs.exists) {
// ignore it if the obc exists but the object doesn't
put_object_context(obc);
obc = NULL;
}
if (!obc) {
obc = get_object_context(snapdir, oloc, can_create);
obc = get_object_context(snapdir, can_create);
}
if (!obc)
return -ENOENT;
@ -4630,26 +4628,26 @@ int ReplicatedPG::find_object_context(const hobject_t& oid,
// always populate ssc for SNAPDIR...
if (!obc->ssc)
obc->ssc = get_snapset_context(oid.oid, oid.get_key(), oid.hash, true);
obc->ssc = get_snapset_context(oid.oid, oid.get_key(), oid.hash, true, oid.get_namespace());
return 0;
}
// want the head?
if (oid.snap == CEPH_NOSNAP) {
ObjectContext *obc = get_object_context(head, oloc, can_create);
ObjectContext *obc = get_object_context(head, can_create);
if (!obc)
return -ENOENT;
dout(10) << "find_object_context " << oid << " @" << oid.snap << dendl;
*pobc = obc;
if (can_create && !obc->ssc)
obc->ssc = get_snapset_context(oid.oid, oid.get_key(), oid.hash, true);
obc->ssc = get_snapset_context(oid.oid, oid.get_key(), oid.hash, true, oid.get_namespace());
return 0;
}
// we want a snap
SnapSetContext *ssc = get_snapset_context(oid.oid, oid.get_key(), oid.hash, can_create);
SnapSetContext *ssc = get_snapset_context(oid.oid, oid.get_key(), oid.hash, can_create, oid.get_namespace());
if (!ssc)
return -ENOENT;
@ -4659,7 +4657,7 @@ int ReplicatedPG::find_object_context(const hobject_t& oid,
// head?
if (oid.snap > ssc->snapset.seq) {
if (ssc->snapset.head_exists) {
ObjectContext *obc = get_object_context(head, oloc, false);
ObjectContext *obc = get_object_context(head, false);
dout(10) << "find_object_context " << head
<< " want " << oid.snap << " > snapset seq " << ssc->snapset.seq
<< " -- HIT " << obc->obs
@ -4692,7 +4690,7 @@ int ReplicatedPG::find_object_context(const hobject_t& oid,
return -ENOENT;
}
hobject_t soid(oid.oid, oid.get_key(), ssc->snapset.clones[k], oid.hash,
info.pgid.pool());
info.pgid.pool(), oid.get_namespace());
put_snapset_context(ssc); // we're done with ssc
ssc = 0;
@ -4704,7 +4702,7 @@ int ReplicatedPG::find_object_context(const hobject_t& oid,
return -EAGAIN;
}
ObjectContext *obc = get_object_context(soid, oloc, false);
ObjectContext *obc = get_object_context(soid, false);
assert(obc);
// clone
@ -4779,7 +4777,8 @@ void ReplicatedPG::add_object_context_to_pg_stat(ObjectContext *obc, pg_stat_t *
obc->ssc = get_snapset_context(oi.soid.oid,
oi.soid.get_key(),
oi.soid.hash,
false);
false,
oi.soid.get_namespace());
assert(obc->ssc);
// subtract off clone overlap
@ -4811,7 +4810,8 @@ SnapSetContext *ReplicatedPG::create_snapset_context(const object_t& oid)
SnapSetContext *ReplicatedPG::get_snapset_context(const object_t& oid,
const string& key,
ps_t seed,
bool can_create)
bool can_create,
const string& nspace)
{
SnapSetContext *ssc;
map<object_t, SnapSetContext*>::iterator p = snapset_contexts.find(oid);
@ -4820,12 +4820,12 @@ SnapSetContext *ReplicatedPG::get_snapset_context(const object_t& oid,
} else {
bufferlist bv;
hobject_t head(oid, key, CEPH_NOSNAP, seed,
info.pgid.pool());
info.pgid.pool(), nspace);
int r = osd->store->getattr(coll, head, SS_ATTR, bv);
if (r < 0) {
// try _snapset
hobject_t snapdir(oid, key, CEPH_SNAPDIR, seed,
info.pgid.pool());
info.pgid.pool(), nspace);
r = osd->store->getattr(coll, snapdir, SS_ATTR, bv);
if (r < 0 && !can_create)
return NULL;
@ -4946,7 +4946,7 @@ void ReplicatedPG::sub_op_modify(OpRequestRef op)
// TODO: this is severely broken because we don't know whether this object is really lost or
// not. We just always assume that it's not right now.
// Also, we're taking the address of a variable on the stack.
object_info_t oi(soid, m->oloc);
object_info_t oi(soid);
oi.lost = false; // I guess?
oi.version = m->old_version;
oi.size = m->old_size;
@ -5312,7 +5312,7 @@ int ReplicatedPG::prepare_pull(
}
// check snapset
SnapSetContext *ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, false);
SnapSetContext *ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, false, soid.get_namespace());
assert(ssc);
dout(10) << " snapset " << ssc->snapset << dendl;
calc_clone_subsets(ssc->snapset, soid, pg_log.get_missing(), info.last_backfill,
@ -5403,7 +5403,7 @@ void ReplicatedPG::prep_push_to_replica(
return prep_push(prio, obc, soid, peer, pop);
}
SnapSetContext *ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, false);
SnapSetContext *ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, false, soid.get_namespace());
assert(ssc);
dout(15) << "push_to_replica snapset is " << ssc->snapset << dendl;
calc_clone_subsets(ssc->snapset, soid, peer_missing[peer],
@ -5413,7 +5413,7 @@ void ReplicatedPG::prep_push_to_replica(
} else if (soid.snap == CEPH_NOSNAP) {
// pushing head or unversioned object.
// base this on partially on replica's clones?
SnapSetContext *ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, false);
SnapSetContext *ssc = get_snapset_context(soid.oid, soid.get_key(), soid.hash, false, soid.get_namespace());
assert(ssc);
dout(15) << "push_to_replica snapset is " << ssc->snapset << dendl;
calc_head_subsets(obc, ssc->snapset, soid, peer_missing[peer],
@ -5614,7 +5614,8 @@ ObjectRecoveryInfo ReplicatedPG::recalc_subsets(const ObjectRecoveryInfo& recove
SnapSetContext *ssc = get_snapset_context(recovery_info.soid.oid,
recovery_info.soid.get_key(),
recovery_info.soid.hash,
false);
false,
recovery_info.soid.get_namespace());
assert(ssc);
ObjectRecoveryInfo new_info = recovery_info;
new_info.copy_subset.clear();
@ -5719,7 +5720,8 @@ bool ReplicatedPG::handle_pull_response(
ssc = create_snapset_context(hoid.oid);
ssc->snapset = pi.recovery_info.ss;
} else {
ssc = get_snapset_context(hoid.oid, hoid.get_key(), hoid.hash, false);
ssc = get_snapset_context(hoid.oid, hoid.get_key(), hoid.hash, false,
hoid.get_namespace());
assert(ssc);
}
ObjectContext *obc = create_object_context(pi.recovery_info.oi, ssc);
@ -6463,10 +6465,7 @@ ObjectContext *ReplicatedPG::mark_object_lost(ObjectStore::Transaction *t,
pg_log_entry_t e(what, oid, info.last_update, version, osd_reqid_t(), mtime);
pg_log.add(e);
object_locator_t oloc;
oloc.pool = info.pgid.pool();
oloc.key = oid.get_key();
ObjectContext *obc = get_object_context(oid, oloc, true);
ObjectContext *obc = get_object_context(oid, true);
obc->ondisk_write_lock();
@ -7044,11 +7043,7 @@ int ReplicatedPG::recover_primary(int max)
case pg_log_entry_t::LOST_REVERT:
{
if (item.have == latest->reverting_to) {
// I have it locally. Revert.
object_locator_t oloc;
oloc.pool = info.pgid.pool();
oloc.key = soid.get_key();
ObjectContext *obc = get_object_context(soid, oloc, true);
ObjectContext *obc = get_object_context(soid, true);
if (obc->obs.oi.version == latest->version) {
// I'm already reverting
@ -7148,7 +7143,7 @@ int ReplicatedPG::prep_object_replica_pushes(
dout(10) << __func__ << ": on " << soid << dendl;
// NOTE: we know we will get a valid oloc off of disk here.
ObjectContext *obc = get_object_context(soid, OLOC_BLANK, false);
ObjectContext *obc = get_object_context(soid, false);
if (!obc) {
pg_log.missing_add(soid, v, eversion_t());
bool uhoh = true;
@ -7391,7 +7386,7 @@ int ReplicatedPG::recover_backfill(int max)
for (set<hobject_t>::iterator i = add_to_stat.begin();
i != add_to_stat.end();
++i) {
ObjectContext *obc = get_object_context(*i, OLOC_BLANK, false);
ObjectContext *obc = get_object_context(*i, false);
pg_stat_t stat;
add_object_context_to_pg_stat(obc, &stat);
pending_backfill_updates[*i] = stat;
@ -7464,7 +7459,7 @@ void ReplicatedPG::prep_backfill_object_push(
if (!pushing.count(oid))
start_recovery_op(oid);
ObjectContext *obc = get_object_context(oid, OLOC_BLANK, false);
ObjectContext *obc = get_object_context(oid, false);
obc->ondisk_read_lock();
(*pushes)[peer].push_back(PushOp());
prep_push_to_replica(obc, oid, peer, g_conf->osd_recovery_op_priority,

View File

@ -471,8 +471,7 @@ protected:
}
ObjectContext *_lookup_object_context(const hobject_t& oid);
ObjectContext *create_object_context(const object_info_t& oi, SnapSetContext *ssc);
ObjectContext *get_object_context(const hobject_t& soid, const object_locator_t& oloc,
bool can_create);
ObjectContext *get_object_context(const hobject_t& soid, bool can_create);
void register_object_context(ObjectContext *obc) {
if (!obc->registered) {
assert(object_contexts.count(obc->obs.oi.soid) == 0);
@ -487,7 +486,6 @@ protected:
void put_object_context(ObjectContext *obc);
void put_object_contexts(map<hobject_t,ObjectContext*>& obcv);
int find_object_context(const hobject_t& oid,
const object_locator_t& oloc,
ObjectContext **pobc,
bool can_create, snapid_t *psnapid=NULL);
@ -497,7 +495,7 @@ protected:
SnapSetContext *create_snapset_context(const object_t& oid);
SnapSetContext *get_snapset_context(const object_t& oid, const string &key,
ps_t seed, bool can_create);
ps_t seed, bool can_create, const string &nspace);
void register_snapset_context(SnapSetContext *ssc) {
if (!ssc->registered) {
assert(snapset_contexts.count(ssc->oid) == 0);

View File

@ -56,17 +56,18 @@ void osd_reqid_t::generate_test_instances(list<osd_reqid_t*>& o)
void object_locator_t::encode(bufferlist& bl) const
{
ENCODE_START(4, 3, bl);
ENCODE_START(5, 3, bl);
::encode(pool, bl);
int32_t preferred = -1; // tell old code there is no preferred osd (-1).
::encode(preferred, bl);
::encode(key, bl);
::encode(nspace, bl);
ENCODE_FINISH(bl);
}
void object_locator_t::decode(bufferlist::iterator& p)
{
DECODE_START_LEGACY_COMPAT_LEN(4, 3, 3, p);
DECODE_START_LEGACY_COMPAT_LEN(5, 3, 3, p);
if (struct_v < 2) {
int32_t op;
::decode(op, p);
@ -79,6 +80,8 @@ void object_locator_t::decode(bufferlist::iterator& p)
::decode(preferred, p);
}
::decode(key, p);
if (struct_v >= 5)
::decode(nspace, p);
DECODE_FINISH(p);
}
@ -86,14 +89,16 @@ void object_locator_t::dump(Formatter *f) const
{
f->dump_int("pool", pool);
f->dump_string("key", key);
f->dump_string("namespace", nspace);
}
void object_locator_t::generate_test_instances(list<object_locator_t*>& o)
{
o.push_back(new object_locator_t);
o.push_back(new object_locator_t(123));
o.push_back(new object_locator_t(1234, "key"));
o.push_back(new object_locator_t(12, "key2"));
o.push_back(new object_locator_t(1, "n2"));
o.push_back(new object_locator_t(1234, "", "key"));
o.push_back(new object_locator_t(12, "n1", "key2"));
}
@ -1541,7 +1546,7 @@ void pg_info_t::generate_test_instances(list<pg_info_t*>& o)
o.back()->last_update = eversion_t(3, 4);
o.back()->last_complete = eversion_t(5, 6);
o.back()->log_tail = eversion_t(7, 8);
o.back()->last_backfill = hobject_t(object_t("objname"), "key", 123, 456, -1);
o.back()->last_backfill = hobject_t(object_t("objname"), "key", 123, 456, -1, "");
list<pg_stat_t*> s;
pg_stat_t::generate_test_instances(s);
o.back()->stats = *s.back();
@ -1911,7 +1916,7 @@ void pg_log_entry_t::dump(Formatter *f) const
void pg_log_entry_t::generate_test_instances(list<pg_log_entry_t*>& o)
{
o.push_back(new pg_log_entry_t());
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
o.push_back(new pg_log_entry_t(MODIFY, oid, eversion_t(1,2), eversion_t(3,4),
osd_reqid_t(entity_name_t::CLIENT(777), 8, 999), utime_t(8,9)));
}
@ -2114,7 +2119,7 @@ void pg_missing_t::generate_test_instances(list<pg_missing_t*>& o)
{
o.push_back(new pg_missing_t);
o.push_back(new pg_missing_t);
o.back()->add(hobject_t(object_t("foo"), "foo", 123, 456, 0), eversion_t(5, 6), eversion_t(5, 1));
o.back()->add(hobject_t(object_t("foo"), "foo", 123, 456, 0, ""), eversion_t(5, 6), eversion_t(5, 1));
}
ostream& operator<<(ostream& out, const pg_missing_t::item& i)
@ -2568,6 +2573,7 @@ ps_t object_info_t::legacy_object_locator_to_ps(const object_t &oid,
void object_info_t::encode(bufferlist& bl) const
{
object_locator_t myoloc(soid);
map<entity_name_t, watch_info_t> old_watchers;
for (map<pair<uint64_t, entity_name_t>, watch_info_t>::const_iterator i =
watchers.begin();
@ -2577,7 +2583,7 @@ void object_info_t::encode(bufferlist& bl) const
}
ENCODE_START(11, 8, bl);
::encode(soid, bl);
::encode(oloc, bl);
::encode(myoloc, bl); //Retained for compatibility
::encode(category, bl);
::encode(version, bl);
::encode(prior_version, bl);
@ -2600,19 +2606,20 @@ void object_info_t::encode(bufferlist& bl) const
void object_info_t::decode(bufferlist::iterator& bl)
{
object_locator_t myoloc;
DECODE_START_LEGACY_COMPAT_LEN(11, 8, 8, bl);
map<entity_name_t, watch_info_t> old_watchers;
if (struct_v >= 2 && struct_v <= 5) {
sobject_t obj;
::decode(obj, bl);
::decode(oloc, bl);
soid = hobject_t(obj.oid, oloc.key, obj.snap, 0, 0);
soid.hash = legacy_object_locator_to_ps(soid.oid, oloc);
::decode(myoloc, bl);
soid = hobject_t(obj.oid, myoloc.key, obj.snap, 0, 0 , "");
soid.hash = legacy_object_locator_to_ps(soid.oid, myoloc);
} else if (struct_v >= 6) {
::decode(soid, bl);
::decode(oloc, bl);
::decode(myoloc, bl);
if (struct_v == 6) {
hobject_t hoid(soid.oid, oloc.key, soid.snap, soid.hash, 0);
hobject_t hoid(soid.oid, myoloc.key, soid.snap, soid.hash, 0 , "");
soid = hoid;
}
}
@ -2643,7 +2650,7 @@ void object_info_t::decode(bufferlist::iterator& bl)
else
uses_tmap = true;
if (struct_v < 10)
soid.pool = oloc.pool;
soid.pool = myoloc.pool;
if (struct_v >= 11) {
::decode(watchers, bl);
} else {
@ -2663,9 +2670,6 @@ void object_info_t::dump(Formatter *f) const
f->open_object_section("oid");
soid.dump(f);
f->close_section();
f->open_object_section("locator");
oloc.dump(f);
f->close_section();
f->dump_string("category", category);
f->dump_stream("version") << version;
f->dump_stream("prior_version") << prior_version;
@ -3175,9 +3179,9 @@ void ScrubMap::generate_test_instances(list<ScrubMap*>& o)
o.back()->attrs["bar"] = buffer::copy("barval", 6);
list<object*> obj;
object::generate_test_instances(obj);
o.back()->objects[hobject_t(object_t("foo"), "fookey", 123, 456, 0)] = *obj.back();
o.back()->objects[hobject_t(object_t("foo"), "fookey", 123, 456, 0, "")] = *obj.back();
obj.pop_back();
o.back()->objects[hobject_t(object_t("bar"), string(), 123, 456, 0)] = *obj.back();
o.back()->objects[hobject_t(object_t("bar"), string(), 123, 456, 0, "")] = *obj.back();
}
// -- ScrubMap::object --

View File

@ -106,21 +106,27 @@ namespace __gnu_cxx {
struct object_locator_t {
int64_t pool;
string key;
string nspace;
explicit object_locator_t()
: pool(-1) {}
explicit object_locator_t(int64_t po)
: pool(po) {}
explicit object_locator_t(int64_t po, string s)
: pool(po), key(s) {}
explicit object_locator_t(int64_t po, string ns)
: pool(po), nspace(ns) {}
explicit object_locator_t(int64_t po, string ns, string s)
: pool(po), key(s), nspace(ns) {}
explicit object_locator_t(const hobject_t& soid)
: pool(soid.pool), key(soid.get_key()), nspace(soid.nspace) {}
int get_pool() const {
int64_t get_pool() const {
return pool;
}
void clear() {
pool = -1;
key = "";
nspace = "";
}
void encode(bufferlist& bl) const;
@ -131,7 +137,7 @@ struct object_locator_t {
WRITE_CLASS_ENCODER(object_locator_t)
inline bool operator==(const object_locator_t& l, const object_locator_t& r) {
return l.pool == r.pool && l.key == r.key;
return l.pool == r.pool && l.key == r.key && l.nspace == r.nspace;
}
inline bool operator!=(const object_locator_t& l, const object_locator_t& r) {
return !(l == r);
@ -140,6 +146,8 @@ inline bool operator!=(const object_locator_t& l, const object_locator_t& r) {
inline ostream& operator<<(ostream& out, const object_locator_t& loc)
{
out << "@" << loc.pool;
if (loc.nspace.length())
out << ";" << loc.nspace;
if (loc.key.length())
out << ":" << loc.key;
return out;
@ -1590,7 +1598,7 @@ struct pg_ls_response_t {
static void generate_test_instances(list<pg_ls_response_t*>& o) {
o.push_back(new pg_ls_response_t);
o.push_back(new pg_ls_response_t);
o.back()->handle = hobject_t(object_t("hi"), "key", 1, 2, -1);
o.back()->handle = hobject_t(object_t("hi"), "key", 1, 2, -1, "");
o.back()->entries.push_back(make_pair(object_t("one"), string()));
o.back()->entries.push_back(make_pair(object_t("two"), string("twokey")));
}
@ -1788,7 +1796,6 @@ static inline ostream& operator<<(ostream& out, const notify_info_t& n) {
struct object_info_t {
hobject_t soid;
object_locator_t oloc;
string category;
eversion_t version, prior_version;
@ -1827,8 +1834,8 @@ struct object_info_t {
truncate_seq(0), truncate_size(0), uses_tmap(false)
{}
object_info_t(const hobject_t& s, const object_locator_t& o)
: soid(s), oloc(o), size(0),
object_info_t(const hobject_t& s)
: soid(s), size(0),
lost(false), truncate_seq(0), truncate_size(0), uses_tmap(false) {}
object_info_t(bufferlist& bl) {

View File

@ -559,6 +559,7 @@ ObjectCacher::Object *ObjectCacher::get_object(sobject_t oid, ObjectSet *oset,
uint64_t truncate_size,
uint64_t truncate_seq)
{
// XXX: Add handling of nspace in object_locator_t in cache
assert(lock.is_locked());
// have it?
if ((uint32_t)l.pool < objects.size()) {

View File

@ -215,6 +215,7 @@ class ObjectCacher {
object_t get_oid() { return oid.oid; }
snapid_t get_snap() { return oid.snap; }
ObjectSet *get_object_set() { return oset; }
string get_namespace() { return oloc.nspace; }
object_locator_t& get_oloc() { return oloc; }
void set_object_locator(object_locator_t& l) { oloc = l; }

View File

@ -1680,7 +1680,7 @@ void Objecter::list_objects(ListContext *list_context, Context *onfinish) {
C_List *onack = new C_List(list_context, onfinish, bl, this);
object_t oid;
object_locator_t oloc(list_context->pool_id);
object_locator_t oloc(list_context->pool_id, list_context->nspace);
//
Op *o = new Op(oid, oloc, op.ops, CEPH_OSD_FLAG_READ, onack, NULL, NULL);

View File

@ -892,6 +892,7 @@ public:
int64_t pool_id;
int pool_snap_seq;
int max_entries;
string nspace;
std::list<pair<object_t, string> > list;
bufferlist filter;

View File

@ -10,7 +10,7 @@ int main(int argc, char **argv)
{
/*
* you need to create a suitable osdmap first. e.g., for 40 osds,
* $ ./osdmaptool --createsimple .ceph_monmap 40 --clobber .ceph_osdmap
* $ ./osdmaptool --createsimple 40 --clobber .ceph_osdmap
*/
bufferlist bl;
std::string error;
@ -34,12 +34,15 @@ int main(int argc, char **argv)
for (int i=0; i<4; i++)
size[i] = 0;
for (int f = 0; f < 50000; f++) { // files
for (int n = 0; n < 10; n++) { // namespaces
char nspace[20];
snprintf(nspace, sizeof(nspace), "n%d", n);
for (int f = 0; f < 5000; f++) { // files
for (int b = 0; b < 4; b++) { // blocks
char foo[20];
snprintf(foo, sizeof(foo), "%d.%d", f, b);
object_t oid(foo);
ceph_object_layout l = osdmap.make_object_layout(oid, 0);
ceph_object_layout l = osdmap.make_object_layout(oid, 0, nspace);
//osdmap.file_to_object_layout(oid, g_default_file_layout);
vector<int> osds;
pg_t pgid = pg_t(l.ol_pgid);
@ -64,6 +67,7 @@ int main(int argc, char **argv)
}
}
}
}
uint64_t avg = 0;
for (int i=0; i<n; i++) {

View File

@ -148,6 +148,9 @@ void usage(ostream& out)
" specify input or output file (for certain commands)\n"
" --create\n"
" create the pool or directory that was specified\n"
" -N namespace\n"
" --namespace=namespace\n"
" specify the namespace to use for the object\n"
"\n"
"BENCH OPTIONS:\n"
" -t N\n"
@ -1046,7 +1049,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
bool create_pool = false;
const char *pool_name = NULL;
const char *target_pool_name = NULL;
string oloc, target_oloc;
string oloc, target_oloc, nspace;
int concurrent_ios = 16;
int op_size = 1 << 22;
bool cleanup = true;
@ -1178,6 +1181,10 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
return -EINVAL;
}
}
i = opts.find("namespace");
if (i != opts.end()) {
nspace = i->second;
}
// open rados
@ -1231,6 +1238,9 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
if (oloc.size()) {
io_ctx.locator_set_key(oloc);
}
if (!nspace.empty()) {
io_ctx.set_namespace(nspace);
}
if (snapid != CEPH_NOSNAP) {
string name;
ret = io_ctx.snap_get_name(snapid, &name);
@ -2321,6 +2331,8 @@ int main(int argc, const char **argv)
opts["lock-duration"] = val;
} else if (ceph_argparse_witharg(args, i, &val, "--lock-type", (char*)NULL)) {
opts["lock-type"] = val;
} else if (ceph_argparse_witharg(args, i, &val, "-N", "--namespace", (char*)NULL)) {
opts["namespace"] = val;
} else {
if (val[0] == '-')
usage_exit();

View File

@ -283,7 +283,7 @@ public:
// hash
//boost::binomial_distribution<uint32_t> bin(0xFFFFFF, 0.5);
++seq;
return hobject_t(name, string(), rand() & 2 ? CEPH_NOSNAP : rand(), rand() & 0xFF, 0);
return hobject_t(name, string(), rand() & 2 ? CEPH_NOSNAP : rand(), rand() & 0xFF, 0, "");
}
};
@ -506,13 +506,16 @@ TEST_F(StoreTest, HashCollisionTest) {
string base = "";
for (int i = 0; i < 100; ++i) base.append("aaaaa");
set<hobject_t> created;
for (int n = 0; n < 10; ++n) {
char nbuf[100];
sprintf(nbuf, "n%d", n);
for (int i = 0; i < 1000; ++i) {
char buf[100];
sprintf(buf, "%d", i);
if (!(i % 5)) {
cerr << "Object " << i << std::endl;
cerr << "Object n" << n << " "<< i << std::endl;
}
hobject_t hoid(string(buf) + base, string(), CEPH_NOSNAP, 0, 0);
hobject_t hoid(string(buf) + base, string(), CEPH_NOSNAP, 0, 0, string(nbuf));
{
ObjectStore::Transaction t;
t.touch(cid, hoid);
@ -521,6 +524,7 @@ TEST_F(StoreTest, HashCollisionTest) {
}
created.insert(hoid);
}
}
vector<hobject_t> objects;
r = store->collection_list(cid, objects);
ASSERT_EQ(r, 0);
@ -572,7 +576,7 @@ TEST_F(StoreTest, HashCollisionTest) {
TEST_F(StoreTest, OMapTest) {
coll_t cid("blah");
hobject_t hoid("tesomap", "", CEPH_NOSNAP, 0, 0);
hobject_t hoid("tesomap", "", CEPH_NOSNAP, 0, 0, "");
int r;
{
ObjectStore::Transaction t;
@ -668,7 +672,7 @@ TEST_F(StoreTest, OMapTest) {
TEST_F(StoreTest, XattrTest) {
coll_t cid("blah");
hobject_t hoid("tesomap", "", CEPH_NOSNAP, 0, 0);
hobject_t hoid("tesomap", "", CEPH_NOSNAP, 0, 0, "");
bufferlist big;
for (unsigned i = 0; i < 10000; ++i) {
big.append('\0');
@ -770,7 +774,7 @@ void colsplittest(
"",
CEPH_NOSNAP,
i<<common_suffix_size,
0));
0, ""));
}
r = store->apply_transaction(t);
ASSERT_EQ(r, 0);

View File

@ -157,9 +157,22 @@ TEST(LibRadosAio, SimpleWrite) {
memset(buf, 0xcc, sizeof(buf));
ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
my_completion, buf, sizeof(buf), 0));
TestAlarm alarm;
sem_wait(&test_data.m_sem);
sem_wait(&test_data.m_sem);
{
TestAlarm alarm;
sem_wait(&test_data.m_sem);
sem_wait(&test_data.m_sem);
}
rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
set_completion_complete, set_completion_safe, &my_completion));
ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
my_completion, buf, sizeof(buf), 0));
{
TestAlarm alarm;
sem_wait(&test_data.m_sem);
sem_wait(&test_data.m_sem);
}
rados_aio_release(my_completion);
}
@ -176,9 +189,24 @@ TEST(LibRadosAio, SimpleWritePP) {
bl1.append(buf, sizeof(buf));
ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
my_completion, bl1, sizeof(buf), 0));
TestAlarm alarm;
sem_wait(&test_data.m_sem);
sem_wait(&test_data.m_sem);
{
TestAlarm alarm;
sem_wait(&test_data.m_sem);
sem_wait(&test_data.m_sem);
}
delete my_completion;
ASSERT_EQ("", test_data.init());
test_data.m_ioctx.set_namespace("nspace");
my_completion = test_data.m_cluster.aio_create_completion(
(void*)&test_data, set_completion_complete, set_completion_safe);
ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
my_completion, bl1, sizeof(buf), 0));
{
TestAlarm alarm;
sem_wait(&test_data.m_sem);
sem_wait(&test_data.m_sem);
}
delete my_completion;
}
@ -908,6 +936,98 @@ TEST(LibRadosAio, SimpleStatPP) {
delete my_completion2;
}
TEST(LibRadosAio, SimpleStatNS) {
AioTestData test_data;
rados_completion_t my_completion;
ASSERT_EQ("", test_data.init());
ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
set_completion_complete, set_completion_safe, &my_completion));
char buf[128];
memset(buf, 0xcc, sizeof(buf));
ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
my_completion, buf, sizeof(buf), 0));
{
TestAlarm alarm;
sem_wait(&test_data.m_sem);
sem_wait(&test_data.m_sem);
}
rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
char buf2[64];
memset(buf2, 0xbb, sizeof(buf2));
ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
set_completion_complete, set_completion_safe, &my_completion));
ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
my_completion, buf2, sizeof(buf2), 0));
{
TestAlarm alarm;
sem_wait(&test_data.m_sem);
sem_wait(&test_data.m_sem);
}
uint64_t psize;
time_t pmtime;
rados_completion_t my_completion2;
rados_ioctx_set_namespace(test_data.m_ioctx, "");
ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
set_completion_complete, set_completion_safe, &my_completion2));
ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
my_completion2, &psize, &pmtime));
{
TestAlarm alarm;
ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
}
ASSERT_EQ(sizeof(buf), psize);
rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
rados_completion_t my_completion3;
ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
set_completion_complete, set_completion_safe, &my_completion3));
ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
my_completion3, &psize, &pmtime));
{
TestAlarm alarm;
ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
}
ASSERT_EQ(sizeof(buf2), psize);
rados_aio_release(my_completion);
rados_aio_release(my_completion2);
rados_aio_release(my_completion3);
}
TEST(LibRadosAio, SimpleStatPPNS) {
AioTestDataPP test_data;
ASSERT_EQ("", test_data.init());
AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
(void*)&test_data, set_completion_complete, set_completion_safe);
AioCompletion *my_completion_null = NULL;
ASSERT_NE(my_completion, my_completion_null);
char buf[128];
memset(buf, 0xcc, sizeof(buf));
bufferlist bl1;
bl1.append(buf, sizeof(buf));
ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
bl1, sizeof(buf), 0));
{
TestAlarm alarm;
sem_wait(&test_data.m_sem);
sem_wait(&test_data.m_sem);
}
uint64_t psize;
time_t pmtime;
AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
(void*)&test_data, set_completion_complete, set_completion_safe);
ASSERT_NE(my_completion2, my_completion_null);
ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
&psize, &pmtime));
{
TestAlarm alarm;
ASSERT_EQ(0, my_completion2->wait_for_complete());
}
ASSERT_EQ(sizeof(buf), psize);
delete my_completion;
delete my_completion2;
}
TEST(LibRadosAio, StatRemove) {
AioTestData test_data;
rados_completion_t my_completion;

View File

@ -17,6 +17,8 @@ TEST(LibRadosIo, SimpleWrite) {
rados_ioctx_create(cluster, pool_name.c_str(), &ioctx);
memset(buf, 0xcc, sizeof(buf));
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo", buf, sizeof(buf), 0));
rados_ioctx_set_namespace(ioctx, "nspace");
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo", buf, sizeof(buf), 0));
rados_ioctx_destroy(ioctx);
ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
}
@ -32,6 +34,8 @@ TEST(LibRadosIo, SimpleWritePP) {
bufferlist bl;
bl.append(buf, sizeof(buf));
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo", bl, sizeof(buf), 0));
ioctx.set_namespace("nspace");
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo", bl, sizeof(buf), 0));
ioctx.close();
ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
}

View File

@ -47,3 +47,133 @@ TEST(LibRadosList, ListObjectsPP) {
ioctx.close();
ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
}
static void check_list(std::set<std::string>& myset, rados_list_ctx_t& ctx)
{
const char *entry;
while(!myset.empty()) {
ASSERT_EQ(0, rados_objects_list_next(ctx, &entry, NULL));
ASSERT_TRUE(myset.end() != myset.find(std::string(entry)));
myset.erase(std::string(entry));
}
ASSERT_EQ(-ENOENT, rados_objects_list_next(ctx, &entry, NULL));
}
TEST(LibRadosList, ListObjectsNS) {
char buf[128];
rados_t cluster;
rados_ioctx_t ioctx;
std::string pool_name = get_temp_pool_name();
ASSERT_EQ("", create_one_pool(pool_name, &cluster));
rados_ioctx_create(cluster, pool_name.c_str(), &ioctx);
memset(buf, 0xcc, sizeof(buf));
// Create :foo1, :foo2, :foo3, n1:foo1, ns1:foo4, ns1:foo5, ns2:foo6, n2:foo7
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo1", buf, sizeof(buf), 0));
rados_ioctx_set_namespace(ioctx, "ns1");
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo1", buf, sizeof(buf), 0));
rados_ioctx_set_namespace(ioctx, "");
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo2", buf, sizeof(buf), 0));
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo3", buf, sizeof(buf), 0));
rados_ioctx_set_namespace(ioctx, "ns1");
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo4", buf, sizeof(buf), 0));
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo5", buf, sizeof(buf), 0));
rados_ioctx_set_namespace(ioctx, "ns2");
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo6", buf, sizeof(buf), 0));
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo7", buf, sizeof(buf), 0));
std::set<std::string> def, ns1, ns2;
def.insert(std::string("foo1"));
def.insert(std::string("foo2"));
def.insert(std::string("foo3"));
ns1.insert(std::string("foo1"));
ns1.insert(std::string("foo4"));
ns1.insert(std::string("foo5"));
ns2.insert(std::string("foo6"));
ns2.insert(std::string("foo7"));
rados_list_ctx_t ctx;
// Check default namespace ""
rados_ioctx_set_namespace(ioctx, "");
ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx));
check_list(def, ctx);
rados_objects_list_close(ctx);
// Check default namespace "ns1"
rados_ioctx_set_namespace(ioctx, "ns1");
ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx));
check_list(ns1, ctx);
rados_objects_list_close(ctx);
// Check default namespace "ns2"
rados_ioctx_set_namespace(ioctx, "ns2");
ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx));
check_list(ns2, ctx);
rados_objects_list_close(ctx);
rados_ioctx_destroy(ioctx);
ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
}
static void check_listpp(std::set<std::string>& myset, IoCtx& ioctx)
{
ObjectIterator iter(ioctx.objects_begin());
if (myset.empty()) {
ASSERT_EQ((iter == ioctx.objects_end()), true);
return;
}
while(!myset.empty()) {
ASSERT_EQ((iter == ioctx.objects_end()), false);
ASSERT_TRUE(myset.end() != myset.find(std::string((*iter).first)));
myset.erase(std::string((*iter).first));
++iter;
}
ASSERT_EQ((iter == ioctx.objects_end()), true);
}
TEST(LibRadosList, ListObjectsPPNS) {
std::string pool_name = get_temp_pool_name();
Rados cluster;
ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
IoCtx ioctx;
cluster.ioctx_create(pool_name.c_str(), ioctx);
char buf[128];
memset(buf, 0xcc, sizeof(buf));
bufferlist bl1;
bl1.append(buf, sizeof(buf));
// Create :foo1, :foo2, :foo3, n1:foo1, ns1:foo4, ns1:foo5, ns2:foo6, n2:foo7
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo1", bl1, sizeof(buf), 0));
ioctx.set_namespace("ns1");
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo1", bl1, sizeof(buf), 0));
ioctx.set_namespace("");
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo2", bl1, sizeof(buf), 0));
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo3", bl1, sizeof(buf), 0));
ioctx.set_namespace("ns1");
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo4", bl1, sizeof(buf), 0));
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo5", bl1, sizeof(buf), 0));
ioctx.set_namespace("ns2");
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo6", bl1, sizeof(buf), 0));
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo7", bl1, sizeof(buf), 0));
std::set<std::string> def, ns1, ns2;
def.insert(std::string("foo1"));
def.insert(std::string("foo2"));
def.insert(std::string("foo3"));
ns1.insert(std::string("foo1"));
ns1.insert(std::string("foo4"));
ns1.insert(std::string("foo5"));
ns2.insert(std::string("foo6"));
ns2.insert(std::string("foo7"));
ioctx.set_namespace("");
check_listpp(def, ioctx);
ioctx.set_namespace("ns1");
check_listpp(ns1, ioctx);
ioctx.set_namespace("ns2");
check_listpp(ns2, ioctx);
ioctx.close();
ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
}

View File

@ -405,7 +405,7 @@ TEST(LibRadosMisc, BigObjectPP) {
#ifdef __LP64__
// this test only works on 64-bit platforms
ASSERT_EQ(-EFBIG, ioctx.write("foo", bl, 500000000000ull, bl.length()));
ASSERT_EQ(-EFBIG, ioctx.write("foo", bl, bl.length(), 500000000000ull));
#endif
ioctx.close();

View File

@ -46,6 +46,76 @@ TEST(LibRadosStat, StatPP) {
ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
}
TEST(LibRadosStat, StatNS) {
char buf[128];
rados_t cluster;
rados_ioctx_t ioctx;
std::string pool_name = get_temp_pool_name();
ASSERT_EQ("", create_one_pool(pool_name, &cluster));
rados_ioctx_create(cluster, pool_name.c_str(), &ioctx);
memset(buf, 0xcc, sizeof(buf));
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo", buf, sizeof(buf), 0));
ASSERT_EQ((int)sizeof(buf), rados_write(ioctx, "foo2", buf, sizeof(buf), 0));
char buf2[64];
memset(buf2, 0xcc, sizeof(buf2));
rados_ioctx_set_namespace(ioctx, "nspace");
ASSERT_EQ((int)sizeof(buf2), rados_write(ioctx, "foo", buf2, sizeof(buf2), 0));
uint64_t size;
time_t mtime;
rados_ioctx_set_namespace(ioctx, "");
ASSERT_EQ(0, rados_stat(ioctx, "foo", &size, &mtime));
ASSERT_EQ(sizeof(buf), size);
ASSERT_EQ(-ENOENT, rados_stat(ioctx, "nonexistent", &size, &mtime));
rados_ioctx_set_namespace(ioctx, "nspace");
ASSERT_EQ(0, rados_stat(ioctx, "foo", &size, &mtime));
ASSERT_EQ(sizeof(buf2), size);
ASSERT_EQ(-ENOENT, rados_stat(ioctx, "nonexistent", &size, &mtime));
ASSERT_EQ(-ENOENT, rados_stat(ioctx, "foo2", &size, &mtime));
rados_ioctx_destroy(ioctx);
ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
}
TEST(LibRadosStat, StatPPNS) {
char buf[128];
Rados cluster;
std::string pool_name = get_temp_pool_name();
ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
IoCtx ioctx;
cluster.ioctx_create(pool_name.c_str(), ioctx);
memset(buf, 0xcc, sizeof(buf));
bufferlist bl;
bl.append(buf, sizeof(buf));
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo", bl, sizeof(buf), 0));
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo2", bl, sizeof(buf), 0));
char buf2[64];
memset(buf2, 0xbb, sizeof(buf2));
bufferlist bl2;
bl2.append(buf2, sizeof(buf2));
ioctx.set_namespace("nspace");
ASSERT_EQ((int)sizeof(buf2), ioctx.write("foo", bl2, sizeof(buf2), 0));
uint64_t size;
time_t mtime;
ioctx.set_namespace("");
ASSERT_EQ(0, ioctx.stat("foo", &size, &mtime));
ASSERT_EQ(sizeof(buf), size);
ASSERT_EQ(-ENOENT, ioctx.stat("nonexistent", &size, &mtime));
ioctx.set_namespace("nspace");
ASSERT_EQ(0, ioctx.stat("foo", &size, &mtime));
ASSERT_EQ(sizeof(buf2), size);
ASSERT_EQ(-ENOENT, ioctx.stat("nonexistent", &size, &mtime));
ASSERT_EQ(-ENOENT, ioctx.stat("foo2", &size, &mtime));
ioctx.close();
ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
}
TEST(LibRadosStat, ClusterStat) {
rados_t cluster;
std::string pool_name = get_temp_pool_name();

View File

@ -49,7 +49,7 @@ TEST(FlatIndex, collection) {
uint64_t hash = 111;
uint64_t pool = 222;
const std::string object_name(10, 'A');
hobject_t hoid(object_t(object_name), key, CEPH_NOSNAP, hash, pool);
hobject_t hoid(object_t(object_name), key, CEPH_NOSNAP, hash, pool, "");
vector<hobject_t> ls;
ASSERT_DEATH(index.collection_list_partial(hoid, 0, 0, 0, &ls, &hoid), "0");
}
@ -70,7 +70,7 @@ TEST(FlatIndex, created_unlink) {
CollectionIndex::IndexedPath indexed_path;
index->set_ref(index);
const std::string object_name(10, 'A');
hobject_t hoid(object_t(object_name), key, CEPH_NOSNAP, hash, pool);
hobject_t hoid(object_t(object_name), key, CEPH_NOSNAP, hash, pool, "");
int exists;
EXPECT_EQ(0, index->lookup(hoid, &indexed_path, &exists));
EXPECT_EQ(0, exists);
@ -88,7 +88,7 @@ TEST(FlatIndex, created_unlink) {
CollectionIndex::IndexedPath indexed_path;
index->set_ref(index);
const std::string object_name(1024, 'A');
hobject_t hoid(object_t(object_name), key, CEPH_NOSNAP, hash, pool);
hobject_t hoid(object_t(object_name), key, CEPH_NOSNAP, hash, pool, "");
int exists;
EXPECT_EQ(0, index->lookup(hoid, &indexed_path, &exists));
EXPECT_EQ(0, exists);

View File

@ -101,9 +101,9 @@ TEST_F(TestHASH_INDEX_TAG, generate_and_parse_name) {
uint64_t hash = 0xABABABAB;
uint64_t pool = -1;
test_generate_and_parse(hobject_t(object_t(".A/B_\\C.D"), key, CEPH_NOSNAP, hash, pool),
test_generate_and_parse(hobject_t(object_t(".A/B_\\C.D"), key, CEPH_NOSNAP, hash, pool, ""),
"\\.A\\sB_\\\\C.D_head_ABABABAB");
test_generate_and_parse(hobject_t(object_t("DIR_A"), key, CEPH_NOSNAP, hash, pool),
test_generate_and_parse(hobject_t(object_t("DIR_A"), key, CEPH_NOSNAP, hash, pool, ""),
"\\dA_head_ABABABAB");
}
@ -123,11 +123,11 @@ TEST_F(TestHASH_INDEX_TAG_2, generate_and_parse_name) {
{
std::string name(".XA/B_\\C.D");
name[1] = '\0';
hobject_t hoid(object_t(name), key, CEPH_NOSNAP, hash, pool);
hobject_t hoid(object_t(name), key, CEPH_NOSNAP, hash, pool, "");
test_generate_and_parse(hoid, "\\.\\nA\\sB\\u\\\\C.D_KEY_head_ABABABAB");
}
test_generate_and_parse(hobject_t(object_t("DIR_A"), key, CEPH_NOSNAP, hash, pool),
test_generate_and_parse(hobject_t(object_t("DIR_A"), key, CEPH_NOSNAP, hash, pool, ""),
"\\dA_KEY_head_ABABABAB");
}
@ -147,13 +147,13 @@ TEST_F(TestHOBJECT_WITH_POOL, generate_and_parse_name) {
{
std::string name(".XA/B_\\C.D");
name[1] = '\0';
hobject_t hoid(object_t(name), key, CEPH_NOSNAP, hash, pool);
hobject_t hoid(object_t(name), key, CEPH_NOSNAP, hash, pool, "");
hoid.nspace = "NSPACE";
test_generate_and_parse(hoid, "\\.\\nA\\sB\\u\\\\C.D_KEY_head_ABABABAB_NSPACE_cdcdcdcd");
}
{
hobject_t hoid(object_t("DIR_A"), key, CEPH_NOSNAP, hash, pool);
hobject_t hoid(object_t("DIR_A"), key, CEPH_NOSNAP, hash, pool, "");
hoid.nspace = "NSPACE";
test_generate_and_parse(hoid, "\\dA_KEY_head_ABABABAB_NSPACE_cdcdcdcd");

View File

@ -668,7 +668,7 @@ TEST_F(PGLogTest, merge_log) {
bool dirty_info = false;
bool dirty_big_info = false;
hobject_t last_backfill(object_t("oname"), string("key"), 1, 234, 1);
hobject_t last_backfill(object_t("oname"), string("key"), 1, 234, 1, "");
info.last_backfill = last_backfill;
eversion_t stat_version(10, 1);
info.stats.version = stat_version;
@ -826,7 +826,7 @@ TEST_F(PGLogTest, merge_log) {
olog.head = e.version;
}
hobject_t last_backfill(object_t("oname"), string("key"), 1, 234, 1);
hobject_t last_backfill(object_t("oname"), string("key"), 1, 234, 1, "");
info.last_backfill = last_backfill;
eversion_t stat_version(10, 1);
info.stats.version = stat_version;
@ -1035,7 +1035,7 @@ TEST_F(PGLogTest, merge_log) {
olog.head = e.version;
}
hobject_t last_backfill(object_t("oname"), string("key"), 1, 234, 1);
hobject_t last_backfill(object_t("oname"), string("key"), 1, 234, 1, "");
info.last_backfill = last_backfill;
eversion_t stat_version(10, 1);
info.stats.version = stat_version;

View File

@ -239,6 +239,12 @@ int main(int argc, char **argv)
}
}
if (op_weights.empty()) {
cerr << "No operations specified" << std::endl;
//usage();
exit(1);
}
if (min_stride_size < 0)
min_stride_size = size / 10;
if (max_stride_size < 0)

View File

@ -62,6 +62,12 @@ const char *parse_good[] = {
"allow r pool foo object_prefix blah ; allow w auid 5",
"allow class-read object_prefix rbd_children, allow pool libvirt-pool-test rwx",
"allow class-read object_prefix rbd-children, allow pool libvirt_pool_test rwx",
"allow pool foo namespace nfoo rwx, allow pool bar namespace=nbar r",
"allow pool foo namespace=nfoo rwx ; allow pool bar namespace=nbar r",
"allow pool foo namespace nfoo rwx ;allow pool bar namespace nbar r",
"allow pool foo namespace=nfoo rwx; allow pool bar namespace nbar object_prefix rbd r",
"allow pool foo namespace=\"\" rwx; allow pool bar namespace='' object_prefix rbd r",
"allow pool foo namespace \"\" rwx; allow pool bar namespace '' object_prefix rbd r",
0
};
@ -89,6 +95,13 @@ const char *parse_bad[] = {
"allow xrwx pool foo,, allow r pool bar",
";allow rwx pool foo rwx ; allow r pool bar",
"allow rwx pool foo ;allow r pool bar gibberish",
"allow rwx auid 123 pool asdf namespace=foo",
"allow rwx auid 123 namespace",
"allow rwx namespace",
"allow namespace",
"allow namespace=foo",
"allow rwx auid 123 namespace asdf",
"allow wwx pool ''",
0
};
@ -135,7 +148,10 @@ TEST(OSDCap, AllowAll) {
ASSERT_TRUE(cap.parse("allow *", NULL));
ASSERT_TRUE(cap.allow_all());
ASSERT_TRUE(cap.is_capable("foo", 0, "asdf", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "asdf", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "anamespace", 0, "asdf", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "asdf", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "anamespace", 0, "asdf", true, true, true, true));
}
TEST(OSDCap, AllowPool) {
@ -143,8 +159,10 @@ TEST(OSDCap, AllowPool) {
bool r = cap.parse("allow rwx pool foo", NULL);
ASSERT_TRUE(r);
ASSERT_TRUE(cap.is_capable("foo", 0, "", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, true, true));
}
TEST(OSDCap, AllowPools) {
@ -152,10 +170,14 @@ TEST(OSDCap, AllowPools) {
bool r = cap.parse("allow rwx pool foo, allow r pool bar", NULL);
ASSERT_TRUE(r);
ASSERT_TRUE(cap.is_capable("foo", 0, "", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", 0, "", true, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "", true, false, false, false));
ASSERT_FALSE(cap.is_capable("baz", "ns", 0, "", true, false, false, false));
}
TEST(OSDCap, AllowPools2) {
@ -163,9 +185,9 @@ TEST(OSDCap, AllowPools2) {
bool r = cap.parse("allow r, allow rwx pool foo", NULL);
ASSERT_TRUE(r);
ASSERT_TRUE(cap.is_capable("foo", 0, "", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "", true, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, false, false));
}
TEST(OSDCap, ObjectPrefix) {
@ -173,13 +195,13 @@ TEST(OSDCap, ObjectPrefix) {
bool r = cap.parse("allow rwx object_prefix foo", NULL);
ASSERT_TRUE(r);
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "food", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo_bar", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "_foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, " foo ", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "fo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "_foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, " foo ", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "fo", true, true, true, true));
}
TEST(OSDCap, ObjectPoolAndPrefix) {
@ -187,203 +209,324 @@ TEST(OSDCap, ObjectPoolAndPrefix) {
bool r = cap.parse("allow rwx pool bar object_prefix foo", NULL);
ASSERT_TRUE(r);
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "food", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo_bar", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", 0, "food", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", 0, "fo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "food", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "fo", true, true, true, true));
}
TEST(OSDCap, BasicR) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow r", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false));
}
TEST(OSDCap, BasicW) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow w", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false));
}
TEST(OSDCap, BasicX) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow x", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false));
}
TEST(OSDCap, BasicRW) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow rw", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
}
TEST(OSDCap, BasicRX) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow rx", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false));
}
TEST(OSDCap, BasicWX) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow wx", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, false, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false));
}
TEST(OSDCap, BasicRWX) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow rwx", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, false));
}
TEST(OSDCap, BasicRWClassRClassW) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow rw class-read class-write", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, false));
}
TEST(OSDCap, ClassR) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow class-read", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, false, false, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, false, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
}
TEST(OSDCap, ClassW) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow class-write", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
}
TEST(OSDCap, ClassRW) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow class-read class-write", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
}
TEST(OSDCap, BasicRClassR) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow r class-read", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false));
ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, false, false));
}
TEST(OSDCap, PoolClassR) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow pool bar r class-read, allow pool foo rwx", NULL));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false));
ASSERT_TRUE(cap.is_capable("foo", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, true, true, false));
ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("baz", 0, "foo", false, false, false, false));
ASSERT_FALSE(cap.is_capable("baz", 0, "foo", false, false, true, true));
ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, false, false, true));
ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, true, false, true));
ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, true, true, false));
ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, false, false));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, false));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, false));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, false, false));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, false, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, false));
}
TEST(OSDCap, PoolClassRNS) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow pool bar namespace='' r class-read, allow pool foo namespace=ns rwx", NULL));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, false, false));
ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, true, true));
ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, false, true));
ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, false, true));
ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, true, false));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, false));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, false, false));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, true, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, false, true));
ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, false));
}
TEST(OSDCap, NSClassR) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow namespace '' rw class-read class-write, allow namespace test r", NULL));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, false));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, true, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, true, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, false));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, false, true));
ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, false));
ASSERT_TRUE(cap.is_capable("bar", "test", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, false, true, false));
ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, false, false));
ASSERT_TRUE(cap.is_capable("foo", "test", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, false, true, false));
ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, true, true));
ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, false, true));
ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, false, false));
ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", true, false, false, false));
ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, true, false, false));
ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, true, false));
ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, false, true));
}
TEST(OSDCap, OutputParsed)
@ -419,6 +562,14 @@ TEST(OSDCap, OutputParsed)
"osdcap[grant(pool images w)]"},
{"allow pool images x",
"osdcap[grant(pool images x)]"},
{"allow r pool images namespace ''",
"osdcap[grant(pool images namespace \"\" r)]"},
{"allow r pool images namespace foo",
"osdcap[grant(pool images namespace foo r)]"},
{"allow r pool images namespace \"\"",
"osdcap[grant(pool images namespace \"\" r)]"},
{"allow r namespace foo",
"osdcap[grant(namespace foo r)]"},
{"allow pool images r; allow pool rbd rwx",
"osdcap[grant(pool images r),grant(pool rbd rwx)]"},
{"allow pool images r, allow pool rbd rwx",

View File

@ -22,6 +22,7 @@
#include "FakeWriteback.h"
// XXX: Only tests default namespace
struct op_data {
op_data(std::string oid, uint64_t offset, uint64_t len, bool read)
: extent(oid, 0, offset, len, 0), is_read(read)

View File

@ -230,7 +230,7 @@ TEST(pg_missing_t, constructor)
TEST(pg_missing_t, have_missing)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
EXPECT_FALSE(missing.have_missing());
missing.add(oid, eversion_t(), eversion_t());
@ -239,7 +239,7 @@ TEST(pg_missing_t, have_missing)
TEST(pg_missing_t, swap)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
EXPECT_FALSE(missing.have_missing());
missing.add(oid, eversion_t(), eversion_t());
@ -257,7 +257,7 @@ TEST(pg_missing_t, is_missing)
{
// pg_missing_t::is_missing(const hobject_t& oid) const
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
EXPECT_FALSE(missing.is_missing(oid));
missing.add(oid, eversion_t(), eversion_t());
@ -266,7 +266,7 @@ TEST(pg_missing_t, is_missing)
// bool pg_missing_t::is_missing(const hobject_t& oid, eversion_t v) const
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
eversion_t need(10,5);
EXPECT_FALSE(missing.is_missing(oid, eversion_t()));
@ -279,7 +279,7 @@ TEST(pg_missing_t, is_missing)
TEST(pg_missing_t, have_old)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
EXPECT_EQ(eversion_t(), missing.have_old(oid));
missing.add(oid, eversion_t(), eversion_t());
@ -291,8 +291,8 @@ TEST(pg_missing_t, have_old)
TEST(pg_missing_t, add_next_event)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid_other(object_t("other"), "key", 9123, 9456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
hobject_t oid_other(object_t("other"), "key", 9123, 9456, 0, "");
eversion_t version(10,5);
eversion_t prior_version(3,4);
pg_log_entry_t sample_e(pg_log_entry_t::DELETE, oid, version, prior_version,
@ -417,7 +417,7 @@ TEST(pg_missing_t, add_next_event)
TEST(pg_missing_t, revise_need)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
// create a new entry
EXPECT_FALSE(missing.is_missing(oid));
@ -438,7 +438,7 @@ TEST(pg_missing_t, revise_need)
TEST(pg_missing_t, revise_have)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
// a non existing entry means noop
EXPECT_FALSE(missing.is_missing(oid));
@ -458,7 +458,7 @@ TEST(pg_missing_t, revise_have)
TEST(pg_missing_t, add)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
EXPECT_FALSE(missing.is_missing(oid));
eversion_t have(1,1);
@ -473,7 +473,7 @@ TEST(pg_missing_t, rm)
{
// void pg_missing_t::rm(const hobject_t& oid, eversion_t v)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
EXPECT_FALSE(missing.is_missing(oid));
epoch_t epoch = 10;
@ -489,7 +489,7 @@ TEST(pg_missing_t, rm)
}
// void pg_missing_t::rm(const std::map<hobject_t, pg_missing_t::item>::iterator &m)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
EXPECT_FALSE(missing.is_missing(oid));
missing.add(oid, eversion_t(), eversion_t());
@ -504,7 +504,7 @@ TEST(pg_missing_t, got)
{
// void pg_missing_t::got(const hobject_t& oid, eversion_t v)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
// assert if the oid does not exist
EXPECT_THROW(missing.got(oid, eversion_t()), FailedAssertion);
@ -521,7 +521,7 @@ TEST(pg_missing_t, got)
}
// void pg_missing_t::got(const std::map<hobject_t, pg_missing_t::item>::iterator &m)
{
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
pg_missing_t missing;
EXPECT_FALSE(missing.is_missing(oid));
missing.add(oid, eversion_t(), eversion_t());
@ -535,9 +535,9 @@ TEST(pg_missing_t, got)
TEST(pg_missing_t, split_into)
{
uint32_t hash1 = 1;
hobject_t oid1(object_t("objname"), "key1", 123, hash1, 0);
hobject_t oid1(object_t("objname"), "key1", 123, hash1, 0, "");
uint32_t hash2 = 2;
hobject_t oid2(object_t("objname"), "key2", 123, hash2, 0);
hobject_t oid2(object_t("objname"), "key2", 123, hash2, 0, "");
pg_missing_t missing;
missing.add(oid1, eversion_t(), eversion_t());
missing.add(oid2, eversion_t(), eversion_t());

View File

@ -462,7 +462,7 @@ public:
random_string(1+(rand() % 16)),
snapid_t(rand() % 1000),
(rand() & ((~0)<<bits)) | (mask & ~((~0)<<bits)),
0);
0, random_string(rand() % 16));
}
void choose_random_snaps(int num, set<snapid_t> *snaps) {