mirror of
https://github.com/ceph/ceph
synced 2025-03-06 16:28:28 +00:00
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:
commit
51dbc389c4
@ -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 */
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
{
|
||||
|
@ -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 << " ";
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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()));
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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 --
|
||||
|
@ -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) {
|
||||
|
@ -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()) {
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
10
src/psim.cc
10
src/psim.cc
@ -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++) {
|
||||
|
14
src/rados.cc
14
src/rados.cc
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user