. $(dirname $0)/../../standalone/ceph-helpers.sh
POOL=rbd
+NS=ns
IMAGE=testrbdnbd$$
SIZE=64
DATA=
setup()
{
+ local ns x
+
if [ -e CMakeCache.txt ]; then
# running under cmake build dir
TEMPDIR=`mktemp -d`
DATA=${TEMPDIR}/data
dd if=/dev/urandom of=${DATA} bs=1M count=${SIZE}
- rbd --dest-pool ${POOL} --no-progress import ${DATA} ${IMAGE}
+
+ rbd namespace create ${POOL} ${NS}
+
+ for ns in '' ${NS}; do
+ rbd --dest-pool ${POOL} --dest-namespace "${ns}" --no-progress import \
+ ${DATA} ${IMAGE}
+ done
}
function cleanup()
{
+ local ns s
+
set +e
- rm -Rf ${TMPDIR}
+ rm -Rf ${TEMPDIR}
if [ -n "${DEV}" ]
then
_sudo rbd-nbd unmap ${DEV}
fi
- if rbd -p ${POOL} status ${IMAGE} 2>/dev/null; then
- for s in 0.5 1 2 4 8 16 32; do
- sleep $s
- rbd -p ${POOL} status ${IMAGE} | grep 'Watchers: none' && break
- done
- rbd -p ${POOL} snap purge ${IMAGE}
- rbd -p ${POOL} remove ${IMAGE}
- fi
+
+ for ns in '' ${NS}; do
+ if rbd -p ${POOL} --namespace "${ns}" status ${IMAGE} 2>/dev/null; then
+ for s in 0.5 1 2 4 8 16 32; do
+ sleep $s
+ rbd -p ${POOL} --namespace "${ns}" status ${IMAGE} |
+ grep 'Watchers: none' && break
+ done
+ rbd -p ${POOL} --namespace "${ns}" snap purge ${IMAGE}
+ rbd -p ${POOL} --namespace "${ns}" remove ${IMAGE}
+ fi
+ done
+ rbd namespace remove ${POOL} ${NS}
}
function expect_false()
function get_pid()
{
+ local ns=$1
+
PID=$(rbd-nbd --format xml list-mapped | $XMLSTARLET sel -t -v \
- "//devices/device[pool='${POOL}'][image='${IMAGE}'][device='${DEV}']/id")
+ "//devices/device[pool='${POOL}'][namespace='${ns}'][image='${IMAGE}'][device='${DEV}']/id")
test -n "${PID}"
ps -p ${PID} -o cmd | grep rbd-nbd
}
DEV=
ps -p ${PID} -o cmd | expect_false grep rbd-nbd
+# map/unmap namespace test
+rbd snap create ${POOL}/${NS}/${IMAGE}@snap
+DEV=`_sudo rbd-nbd map ${POOL}/${NS}/${IMAGE}@snap`
+get_pid ${NS}
+_sudo rbd-nbd unmap "${POOL}/${NS}/${IMAGE}@snap"
+rbd-nbd list-mapped | expect_false grep "${DEV} $"
+DEV=
+ps -p ${PID} -o cmd | expect_false grep rbd-nbd
+
# auto unmap test
DEV=`_sudo rbd-nbd map ${POOL}/${IMAGE}`
get_pid
int get_image_or_snap_spec(const po::variables_map &vm, std::string *spec) {
size_t arg_index = 0;
std::string pool_name;
+ std::string nspace_name;
std::string image_name;
std::string snap_name;
int r = utils::get_pool_image_snapshot_names(
- vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, nullptr,
+ vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &nspace_name,
&image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_PERMITTED,
utils::SPEC_VALIDATION_NONE);
if (r < 0) {
spec->append(pool_name);
spec->append("/");
+ if (!nspace_name.empty()) {
+ spec->append(nspace_name);
+ spec->append("/");
+ }
spec->append(image_name);
if (!snap_name.empty()) {
spec->append("@");
bool set_max_part = false;
std::string poolname;
+ std::string nsname;
std::string imgname;
std::string snapname;
std::string devpath;
if (r < 0)
goto close_fd;
+ io_ctx.set_namespace(cfg->nsname);
+
r = rbd.open(io_ctx, image, cfg->imgname.c_str());
if (r < 0)
goto close_fd;
static int parse_imgpath(const std::string &imgpath, Config *cfg,
std::ostream *err_msg) {
- std::regex pattern("^(?:([^/@]+)/)?([^/@]+)(?:@([^/@]+))?$");
+ std::regex pattern("^(?:([^/]+)/(?:([^/@]+)/)?)?([^@]+)(?:@([^/@]+))?$");
std::smatch match;
if (!std::regex_match(imgpath, match, pattern)) {
std::cerr << "rbd-nbd: invalid spec '" << imgpath << "'" << std::endl;
cfg->poolname = match[1];
}
- cfg->imgname = match[2];
+ if (match[2].matched) {
+ cfg->nsname = match[2];
+ }
+
+ cfg->imgname = match[3];
- if (match[3].matched)
- cfg->snapname = match[3];
+ if (match[4].matched)
+ cfg->snapname = match[4];
return 0;
}
} else {
tbl.define_column("id", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("pool", TextTable::LEFT, TextTable::LEFT);
+ tbl.define_column("namespace", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("image", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("snap", TextTable::LEFT, TextTable::LEFT);
tbl.define_column("device", TextTable::LEFT, TextTable::LEFT);
f->open_object_section("device");
f->dump_int("id", pid);
f->dump_string("pool", cfg.poolname);
+ f->dump_string("namespace", cfg.nsname);
f->dump_string("image", cfg.imgname);
f->dump_string("snap", cfg.snapname);
f->dump_string("device", cfg.devpath);
if (cfg.snapname.empty()) {
cfg.snapname = "-";
}
- tbl << pid << cfg.poolname << cfg.imgname << cfg.snapname << cfg.devpath
- << TextTable::endrow;
+ tbl << pid << cfg.poolname << cfg.nsname << cfg.imgname << cfg.snapname
+ << cfg.devpath << TextTable::endrow;
}
}