diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index eb1a30632b7..4a5be3d1777 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -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 */ /** diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index b6ea0259583..f9c51ab6926 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -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(); diff --git a/src/librados/IoCtxImpl.cc b/src/librados/IoCtxImpl.cc index abeda88d018..b5da027e8f6 100644 --- a/src/librados/IoCtxImpl.cc +++ b/src/librados/IoCtxImpl.cc @@ -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& 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 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::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::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; diff --git a/src/librados/librados.cc b/src/librados/librados.cc index fc2acb4462a..0a36092a3d9 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -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; } diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index 2ab5fd9e91d..41518b67698 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -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); { diff --git a/src/messages/MOSDOp.h b/src/messages/MOSDOp.h index f81691ba9ed..3855670f8eb 100644 --- a/src/messages/MOSDOp.h +++ b/src/messages/MOSDOp.h @@ -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 << " "; diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 192b19ee6ad..cbc7656632b 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -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 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); diff --git a/src/os/DBObjectMap.cc b/src/os/DBObjectMap.cc index 29edfbe1f05..5142f4d7420 100644 --- a/src/os/DBObjectMap.cc +++ b/src/os/DBObjectMap.cc @@ -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; } diff --git a/src/os/HashIndex.cc b/src/os/HashIndex.cc index 17b0f0388b9..86a912bbef2 100644 --- a/src/os/HashIndex.cc +++ b/src/os/HashIndex.cc @@ -702,7 +702,7 @@ int HashIndex::list_by_hash(const vector &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()); diff --git a/src/os/LFNIndex.cc b/src/os/LFNIndex.cc index 887ab1f2b64..edf361a44f0 100644 --- a/src/os/LFNIndex.cc +++ b/src/os/LFNIndex.cc @@ -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 ref) { +void LFNIndex::set_ref(std::tr1::shared_ptr 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 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 path; string short_name; @@ -127,7 +132,8 @@ int LFNIndex::lookup(const hobject_t &hoid, ); } -int LFNIndex::collection_list(vector *ls) { +int LFNIndex::collection_list(vector *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 *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 &path) { +int LFNIndex::fsync_dir(const vector &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 &to_list, return 0; } -int LFNIndex::create_path(const vector &to_create) { +int LFNIndex::create_path(const vector &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 &to_create) { return 0; } -int LFNIndex::remove_path(const vector &to_remove) { +int LFNIndex::remove_path(const vector &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 &to_remove) { return 0; } -int LFNIndex::path_exists(const vector &to_check, int *exists) { +int LFNIndex::path_exists(const vector &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 &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 &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 &path, int LFNIndex::lfn_created(const vector &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 &path, int LFNIndex::lfn_unlink(const vector &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 &path, int LFNIndex::lfn_translate(const vector &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 &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 &rel) { +string LFNIndex::get_full_path_subdir(const vector &rel) +{ string retval = get_base_path(); for (vector::const_iterator i = rel.begin(); i != rel.end(); @@ -1166,20 +1193,24 @@ string LFNIndex::get_full_path_subdir(const vector &rel) { return retval; } -string LFNIndex::get_full_path(const vector &rel, const string &name) { +string LFNIndex::get_full_path(const vector &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 *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 *out, return 0; } -string LFNIndex::mangle_attr_name(const string &attr) { +string LFNIndex::mangle_attr_name(const string &attr) +{ return PHASH_ATTR_PREFIX + attr; } diff --git a/src/os/ObjectStore.cc b/src/os/ObjectStore.cc index eccc90359c5..8426e49901e 100644 --- a/src/os/ObjectStore.cc +++ b/src/os/ObjectStore.cc @@ -445,9 +445,9 @@ void ObjectStore::Transaction::generate_test_instances(listtouch(c, o1); bufferlist bl; bl.append("some data"); diff --git a/src/os/hobject.cc b/src/os/hobject.cc index 515309f5bf4..d6273693c62 100644 --- a/src/os/hobject.cc +++ b/src/os/hobject.cc @@ -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& o) @@ -167,9 +173,11 @@ void hobject_t::generate_test_instances(list& 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) diff --git a/src/os/hobject.h b/src/os/hobject.h index 3c1b0efee44..633e471dffc 100644 --- a/src/os/hobject.h +++ b/src/os/hobject.h @@ -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); diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 1449eeac913..c4efbc3485d 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -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 -// rmomapkey -// setomapheader
-// getomap -// truncobj -// injectmdataerr -// injectdataerr +// setomapval [namespace/] +// rmomapkey [namespace/] +// setomapheader [namespace/]
+// getomap [namespace/] +// truncobj [namespace/] +// injectmdataerr [namespace/] +// injectdataerr [namespace/] 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 "; + ss << "usage: setomapval [namespace/] "; return; } map 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 "; + ss << "usage: rmomapkey [namespace/] "; return; } set 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
"; + ss << "usage: setomapheader [namespace/]
"; 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 "; + ss << "usage: getomap [namespace/]"; 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 "; + ss << "usage: truncobj [namespace/] "; return; } t.truncate(coll_t(pgid), obj, atoi(argv[3].c_str())); diff --git a/src/osd/OSDCap.cc b/src/osd/OSDCap.cc index 87a1490d70d..ee77f0ea43d 100644 --- a/src/osd/OSDCap.cc +++ b/src/osd/OSDCap.cc @@ -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::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::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 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[=] | auid <123>] [object_prefix ] + // match := [pool[=] [namespace[=]] | auid <123>] [object_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(_1, _2)] | - (pool_name >> object_prefix) [_val = phoenix::construct(_1, _2)]); + (pool_name >> nspace >> object_prefix) [_val = phoenix::construct(_1, _2, _3)] | + (pool_name >> object_prefix) [_val = phoenix::construct(_1, _2)]); // rwxa := * | [r][w][x] [class-read] [class-write] rwxa = @@ -192,12 +223,13 @@ struct OSDCapParser : qi::grammar } qi::rule spaces; qi::rule rwxa; - qi::rule quoted_string; + qi::rule quoted_string, equoted_string; qi::rule unquoted_word; - qi::rule str; + qi::rule str, estr; qi::rule auid; qi::rule capspec; qi::rule pool_name; + qi::rule nspace; qi::rule object_prefix; qi::rule match; qi::rule grant; diff --git a/src/osd/OSDCap.h b/src/osd/OSDCap.h index a4ca09b0c4d..3fc7fb67953 100644 --- a/src/osd/OSDCap.h +++ b/src/osd/OSDCap.h @@ -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; }; diff --git a/src/osd/OSDMap.cc b/src/osd/OSDMap.cc index 24f93e37cc6..9eecf173e5b 100644 --- a/src/osd/OSDMap.cc +++ b/src/osd/OSDMap.cc @@ -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); diff --git a/src/osd/OSDMap.h b/src/osd/OSDMap.h index aadbe3c58be..92d1c5bf8a1 100644 --- a/src/osd/OSDMap.h +++ b/src/osd/OSDMap.h @@ -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 { diff --git a/src/osd/PG.cc b/src/osd/PG.cc index acb20fc21c5..46c6f395997 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -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() diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 8b82ccdcbb8..918498edc55 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -65,9 +65,6 @@ static ostream& _prefix(std::ostream *_dout, PG *pg, int whoami, OSDMapRef osdma #include -// 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& ops) ObjectContext *src_obc = 0; if (ceph_osd_op_type_multi(op.op)) { + MOSDOp *m = static_cast(ctx->op->request); object_locator_t src_oloc; - get_src_oloc(soid.oid, (static_cast(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& 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(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::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::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::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, diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index 8c134f5052d..4cedf913217 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -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& 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); diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index 0922026f7af..08f720edc4c 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -56,17 +56,18 @@ void osd_reqid_t::generate_test_instances(list& 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& 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& 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 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& 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& 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 old_watchers; for (map, 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 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& o) o.back()->attrs["bar"] = buffer::copy("barval", 6); list 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 -- diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index ae7ec78e2b9..157098f32c4 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -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& 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) { diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index 0481c6c94de..51fad699555 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -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()) { diff --git a/src/osdc/ObjectCacher.h b/src/osdc/ObjectCacher.h index 4441cfa77cf..ac2833b9ea6 100644 --- a/src/osdc/ObjectCacher.h +++ b/src/osdc/ObjectCacher.h @@ -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; } diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index 1dfeb36e030..45b4573bbb1 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -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); diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index 4b878a4e11a..c1cac88b60e 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -892,6 +892,7 @@ public: int64_t pool_id; int pool_snap_seq; int max_entries; + string nspace; std::list > list; bufferlist filter; diff --git a/src/psim.cc b/src/psim.cc index 89d261a27c8..c1adc7580fb 100644 --- a/src/psim.cc +++ b/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 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 &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(); diff --git a/src/test/filestore/store_test.cc b/src/test/filestore/store_test.cc index abc5c5f1170..87482ef702d 100644 --- a/src/test/filestore/store_test.cc +++ b/src/test/filestore/store_test.cc @@ -283,7 +283,7 @@ public: // hash //boost::binomial_distribution 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 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 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<apply_transaction(t); ASSERT_EQ(r, 0); diff --git a/src/test/librados/aio.cc b/src/test/librados/aio.cc index 835f28763b4..41318b87585 100644 --- a/src/test/librados/aio.cc +++ b/src/test/librados/aio.cc @@ -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; diff --git a/src/test/librados/io.cc b/src/test/librados/io.cc index e09f1764361..f1bcc060355 100644 --- a/src/test/librados/io.cc +++ b/src/test/librados/io.cc @@ -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)); } diff --git a/src/test/librados/list.cc b/src/test/librados/list.cc index a1bea88260b..1ea56c295a4 100644 --- a/src/test/librados/list.cc +++ b/src/test/librados/list.cc @@ -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& 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 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& 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 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)); +} diff --git a/src/test/librados/misc.cc b/src/test/librados/misc.cc index a23c0d23f6e..6cb7cf5452a 100644 --- a/src/test/librados/misc.cc +++ b/src/test/librados/misc.cc @@ -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(); diff --git a/src/test/librados/stat.cc b/src/test/librados/stat.cc index 3811a3795fb..481e4a57e43 100644 --- a/src/test/librados/stat.cc +++ b/src/test/librados/stat.cc @@ -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(); diff --git a/src/test/os/TestFlatIndex.cc b/src/test/os/TestFlatIndex.cc index 5d17c22a877..6db4f6c4aa5 100644 --- a/src/test/os/TestFlatIndex.cc +++ b/src/test/os/TestFlatIndex.cc @@ -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 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); diff --git a/src/test/os/TestLFNIndex.cc b/src/test/os/TestLFNIndex.cc index eeacf1ab8fb..33dbfe532a9 100644 --- a/src/test/os/TestLFNIndex.cc +++ b/src/test/os/TestLFNIndex.cc @@ -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"); diff --git a/src/test/osd/TestPGLog.cc b/src/test/osd/TestPGLog.cc index 085c645f00b..d8ec8d03df2 100644 --- a/src/test/osd/TestPGLog.cc +++ b/src/test/osd/TestPGLog.cc @@ -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; diff --git a/src/test/osd/TestRados.cc b/src/test/osd/TestRados.cc index 3e44129fa33..43530f00828 100644 --- a/src/test/osd/TestRados.cc +++ b/src/test/osd/TestRados.cc @@ -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) diff --git a/src/test/osd/osdcap.cc b/src/test/osd/osdcap.cc index a26a843057e..5f7c607deec 100644 --- a/src/test/osd/osdcap.cc +++ b/src/test/osd/osdcap.cc @@ -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", diff --git a/src/test/osdc/object_cacher_stress.cc b/src/test/osdc/object_cacher_stress.cc index db30de4f4e8..ee71b0e898c 100644 --- a/src/test/osdc/object_cacher_stress.cc +++ b/src/test/osdc/object_cacher_stress.cc @@ -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) diff --git a/src/test/test_osd_types.cc b/src/test/test_osd_types.cc index 80f3ebeb21a..7a43b7b892a 100644 --- a/src/test/test_osd_types.cc +++ b/src/test/test_osd_types.cc @@ -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::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::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()); diff --git a/src/test/test_snap_mapper.cc b/src/test/test_snap_mapper.cc index 9e44ba32d97..41ba0446961 100644 --- a/src/test/test_snap_mapper.cc +++ b/src/test/test_snap_mapper.cc @@ -462,7 +462,7 @@ public: random_string(1+(rand() % 16)), snapid_t(rand() % 1000), (rand() & ((~0)< *snaps) {