]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-nbd: support namespaces 25260/head
authorMykola Golub <mgolub@suse.com>
Sun, 25 Nov 2018 17:27:28 +0000 (19:27 +0200)
committerMykola Golub <mgolub@suse.com>
Sun, 25 Nov 2018 17:29:19 +0000 (19:29 +0200)
Fixes: http://tracker.ceph.com/issues/24609
Signed-off-by: Mykola Golub <mgolub@suse.com>
qa/workunits/rbd/rbd-nbd.sh
src/tools/rbd/action/Nbd.cc
src/tools/rbd_nbd/rbd-nbd.cc

index 900a6075644bb483705e662052b8bad1c30f5fce..eebfe93e35295226825ef80cc3c616da864e2f4a 100755 (executable)
@@ -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
index dfe7a9f25fd0ed9ea14f507b4185b5fd187c296f..5c55adea4e765f54e67505ec7375d1db41868712 100644 (file)
@@ -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("@");
index 1dbe7e00f6d6da54feb73651dba44ca629ed39f1..cce44e4f7beb00780bb9aec78ffff5cf1352b6ce 100644 (file)
@@ -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;
     }
   }