From: Mykola Golub Date: Sun, 25 Nov 2018 17:27:28 +0000 (+0200) Subject: rbd-nbd: support namespaces X-Git-Tag: v14.1.0~717^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=efae1c7a79693af97af0d40e8545ecd9338fd885;p=ceph.git rbd-nbd: support namespaces Fixes: http://tracker.ceph.com/issues/24609 Signed-off-by: Mykola Golub --- diff --git a/qa/workunits/rbd/rbd-nbd.sh b/qa/workunits/rbd/rbd-nbd.sh index 900a6075644..eebfe93e352 100755 --- a/qa/workunits/rbd/rbd-nbd.sh +++ b/qa/workunits/rbd/rbd-nbd.sh @@ -4,6 +4,7 @@ set -ex . $(dirname $0)/../../standalone/ceph-helpers.sh POOL=rbd +NS=ns IMAGE=testrbdnbd$$ SIZE=64 DATA= @@ -28,6 +29,8 @@ _sudo() setup() { + local ns x + if [ -e CMakeCache.txt ]; then # running under cmake build dir @@ -49,25 +52,38 @@ setup() 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() @@ -77,8 +93,10 @@ 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 } @@ -195,6 +213,15 @@ rbd-nbd list-mapped | expect_false grep "${DEV} $" 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 diff --git a/src/tools/rbd/action/Nbd.cc b/src/tools/rbd/action/Nbd.cc index dfe7a9f25fd..5c55adea4e7 100644 --- a/src/tools/rbd/action/Nbd.cc +++ b/src/tools/rbd/action/Nbd.cc @@ -58,10 +58,11 @@ static int call_nbd_cmd(const po::variables_map &vm, 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) { @@ -70,6 +71,10 @@ int get_image_or_snap_spec(const po::variables_map &vm, std::string *spec) { 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("@"); diff --git a/src/tools/rbd_nbd/rbd-nbd.cc b/src/tools/rbd_nbd/rbd-nbd.cc index 1dbe7e00f6d..cce44e4f7be 100644 --- a/src/tools/rbd_nbd/rbd-nbd.cc +++ b/src/tools/rbd_nbd/rbd-nbd.cc @@ -74,6 +74,7 @@ struct Config { bool set_max_part = false; std::string poolname; + std::string nsname; std::string imgname; std::string snapname; std::string devpath; @@ -715,6 +716,8 @@ static int do_map(int argc, const char *argv[], Config *cfg) 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; @@ -928,7 +931,7 @@ static int do_unmap(const std::string &devpath) 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; @@ -939,10 +942,14 @@ static int parse_imgpath(const std::string &imgpath, Config *cfg, 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; } @@ -967,6 +974,7 @@ static int do_list_mapped_devices(const std::string &format, bool pretty_format) } 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); @@ -980,6 +988,7 @@ static int do_list_mapped_devices(const std::string &format, bool pretty_format) 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); @@ -989,8 +998,8 @@ static int do_list_mapped_devices(const std::string &format, bool pretty_format) 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; } }