]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/tools/rbd/action/List.cc
import ceph 15.2.14
[ceph.git] / ceph / src / tools / rbd / action / List.cc
index fbac3e106559190dd7d1aa6641e0c4e02c198cc3..65ab03752adaf4bcc8df8c44075369c13b886a5b 100644 (file)
@@ -11,6 +11,7 @@
 #include "common/Formatter.h"
 #include "common/TextTable.h"
 #include <iostream>
+#include <boost/bind.hpp>
 #include <boost/program_options.hpp>
 #include "global/global_context.h"
 
@@ -33,6 +34,7 @@ struct WorkerEntry {
   librbd::RBD::AioCompletion* completion;
   WorkerState state;
   string name;
+  string id;
 
   WorkerEntry() {
     state = STATE_IDLE;
@@ -45,15 +47,23 @@ int list_process_image(librados::Rados* rados, WorkerEntry* w, bool lflag, Forma
 {
   int r = 0;
   librbd::image_info_t info;
-  std::string pool, image, snap, parent;
+  std::string parent;
 
   // handle second-nth trips through loop
-  r = w->img.parent_info(&pool, &image, &snap);
-  if (r < 0 && r != -ENOENT)
+  librbd::linked_image_spec_t parent_image_spec;
+  librbd::snap_spec_t parent_snap_spec;
+  r = w->img.get_parent(&parent_image_spec, &parent_snap_spec);
+  if (r < 0 && r != -ENOENT) {
     return r;
+  }
+
   bool has_parent = false;
   if (r != -ENOENT) {
-    parent = pool + "/" + image + "@" + snap;
+    parent = parent_image_spec.pool_name + "/";
+    if (!parent_image_spec.pool_namespace.empty()) {
+      parent += parent_image_spec.pool_namespace + "/";
+    }
+    parent +=  parent_image_spec.image_name + "@" + parent_snap_spec.name;
     has_parent = true;
   }
 
@@ -77,12 +87,14 @@ int list_process_image(librados::Rados* rados, WorkerEntry* w, bool lflag, Forma
   if (f) {
     f->open_object_section("image");
     f->dump_string("image", w->name);
+    f->dump_string("id", w->id);
     f->dump_unsigned("size", info.size);
     if (has_parent) {
       f->open_object_section("parent");
-      f->dump_string("pool", pool);
-      f->dump_string("image", image);
-      f->dump_string("snapshot", snap);
+      f->dump_string("pool", parent_image_spec.pool_name);
+      f->dump_string("pool_namespace", parent_image_spec.pool_namespace);
+      f->dump_string("image", parent_image_spec.image_name);
+      f->dump_string("snapshot", parent_snap_spec.name);
       f->close_section();
     }
     f->dump_int("format", old_format ? 1 : 2);
@@ -91,7 +103,7 @@ int list_process_image(librados::Rados* rados, WorkerEntry* w, bool lflag, Forma
     f->close_section();
   } else {
     tbl << w->name
-        << stringify(si_t(info.size))
+        << stringify(byte_u_t(info.size))
         << parent
         << ((old_format) ? '1' : '2')
         << ""                         // protect doesn't apply to images
@@ -101,6 +113,10 @@ int list_process_image(librados::Rados* rados, WorkerEntry* w, bool lflag, Forma
 
   std::vector<librbd::snap_info_t> snaplist;
   if (w->img.snap_list(snaplist) >= 0 && !snaplist.empty()) {
+    snaplist.erase(remove_if(snaplist.begin(),
+                             snaplist.end(),
+                             boost::bind(utils::is_not_user_snap_namespace, &w->img, _1)),
+                   snaplist.end());
     for (std::vector<librbd::snap_info_t>::iterator s = snaplist.begin();
          s != snaplist.end(); ++s) {
       bool is_protected;
@@ -110,20 +126,27 @@ int list_process_image(librados::Rados* rados, WorkerEntry* w, bool lflag, Forma
       r = w->img.snap_is_protected(s->name.c_str(), &is_protected);
       if (r < 0)
         return r;
-      if (w->img.parent_info(&pool, &image, &snap) >= 0) {
-        parent = pool + "/" + image + "@" + snap;
+      if (w->img.get_parent(&parent_image_spec, &parent_snap_spec) >= 0) {
+        parent = parent_image_spec.pool_name + "/";
+        if (!parent_image_spec.pool_namespace.empty()) {
+          parent += parent_image_spec.pool_namespace + "/";
+        }
+        parent +=  parent_image_spec.image_name + "@" + parent_snap_spec.name;
         has_parent = true;
       }
       if (f) {
         f->open_object_section("snapshot");
         f->dump_string("image", w->name);
+        f->dump_string("id", w->id);
         f->dump_string("snapshot", s->name);
+        f->dump_unsigned("snapshot_id", s->id);
         f->dump_unsigned("size", s->size);
         if (has_parent) {
           f->open_object_section("parent");
-          f->dump_string("pool", pool);
-          f->dump_string("image", image);
-          f->dump_string("snapshot", snap);
+          f->dump_string("pool", parent_image_spec.pool_name);
+          f->dump_string("pool_namespace", parent_image_spec.pool_namespace);
+          f->dump_string("image", parent_image_spec.image_name);
+          f->dump_string("snapshot", parent_snap_spec.name);
           f->close_section();
         }
         f->dump_int("format", old_format ? 1 : 2);
@@ -131,7 +154,7 @@ int list_process_image(librados::Rados* rados, WorkerEntry* w, bool lflag, Forma
         f->close_section();
       } else {
         tbl << w->name + "@" + s->name
-            << stringify(si_t(s->size))
+            << stringify(byte_u_t(s->size))
             << parent
             << ((old_format) ? '1' : '2')
             << (is_protected ? "yes" : "")
@@ -141,16 +164,23 @@ int list_process_image(librados::Rados* rados, WorkerEntry* w, bool lflag, Forma
     }
   }
 
-  return r < 0 ? r : 0;
+  return 0;
 }
 
-int do_list(std::string &pool_name, bool lflag, int threads, Formatter *f) {
+int do_list(const std::string &pool_name, const std::string& namespace_name,
+            bool lflag, Formatter *f) {
   std::vector<WorkerEntry*> workers;
-  std::vector<std::string> names;
+  std::vector<librbd::image_spec_t> images;
   librados::Rados rados;
   librbd::RBD rbd;
   librados::IoCtx ioctx;
 
+  int r = utils::init(pool_name, namespace_name, &rados, &ioctx);
+  if (r < 0) {
+    return r;
+  }
+
+  int threads = g_conf().get_val<uint64_t>("rbd_concurrent_management_ops");
   if (threads < 1) {
     threads = 1;
   }
@@ -158,24 +188,20 @@ int do_list(std::string &pool_name, bool lflag, int threads, Formatter *f) {
     threads = 32;
   }
 
-  int r = utils::init(pool_name, &rados, &ioctx);
-  if (r < 0) {
-    return r;
-  }
+  utils::disable_cache();
 
-  r = rbd.list(ioctx, names);
+  r = rbd.list2(ioctx, &images);
   if (r < 0)
     return r;
 
   if (!lflag) {
     if (f)
       f->open_array_section("images");
-    for (std::vector<std::string>::const_iterator i = names.begin();
-       i != names.end(); ++i) {
+    for (auto& image : images) {
        if (f)
-        f->dump_string("name", *i);
+        f->dump_string("name", image.name);
        else
-        std::cout << *i << std::endl;
+        std::cout << image.name << std::endl;
     }
     if (f) {
       f->close_section();
@@ -190,18 +216,19 @@ int do_list(std::string &pool_name, bool lflag, int threads, Formatter *f) {
     f->open_array_section("images");
   } else {
     tbl.define_column("NAME", TextTable::LEFT, TextTable::LEFT);
-    tbl.define_column("SIZE", TextTable::RIGHT, TextTable::RIGHT);
+    tbl.define_column("SIZE", TextTable::LEFT, TextTable::RIGHT);
     tbl.define_column("PARENT", TextTable::LEFT, TextTable::LEFT);
-    tbl.define_column("FMT", TextTable::RIGHT, TextTable::RIGHT);
+    tbl.define_column("FMT", TextTable::LEFT, TextTable::RIGHT);
     tbl.define_column("PROT", TextTable::LEFT, TextTable::LEFT);
     tbl.define_column("LOCK", TextTable::LEFT, TextTable::LEFT);
   }
 
-  for (int left = 0; left < std::min(threads, (int)names.size()); left++) {
+  for (size_t left = 0; left < std::min<size_t>(threads, images.size());
+       left++) {
     workers.push_back(new WorkerEntry());
   }
 
-  auto i = names.begin();
+  auto i = images.begin();
   while (true) {
     size_t workers_idle = 0;
     for (auto comp : workers) {
@@ -213,13 +240,15 @@ int do_list(std::string &pool_name, bool lflag, int threads, Formatter *f) {
          comp->completion = nullptr;
          // we want it to fall through in this case
        case STATE_IDLE:
-         if (i == names.end()) {
+         if (i == images.end()) {
            workers_idle++;
            continue;
          }
-         comp->name = *i;
+         comp->name = i->name;
+          comp->id = i->id;
          comp->completion = new librbd::RBD::AioCompletion(nullptr, nullptr);
-         r = rbd.aio_open_read_only(ioctx, comp->img, i->c_str(), NULL, comp->completion);
+         r = rbd.aio_open_read_only(ioctx, comp->img, i->name.c_str(), nullptr,
+                                     comp->completion);
          i++;
          comp->state = STATE_OPENED;
          break;
@@ -232,18 +261,17 @@ int do_list(std::string &pool_name, bool lflag, int threads, Formatter *f) {
          r = comp->completion->get_return_value();
          comp->completion->release();
          if (r < 0) {
-           if (r != -ENOENT) {
-             std::cerr << "rbd: error opening " << *i << ": " << cpp_strerror(r)
-                       << std::endl;
-           }
+           std::cerr << "rbd: error opening " << comp->name << ": "
+                      << cpp_strerror(r) << std::endl;
+
            // in any event, continue to next image
            comp->state = STATE_IDLE;
            continue;
          }
          r = list_process_image(&rados, comp, lflag, f, tbl);
          if (r < 0) {
-             std::cerr << "rbd: error processing image  " << comp->name << ": " << cpp_strerror(r)
-                       << std::endl;
+             std::cerr << "rbd: error processing image " << comp->name << ": "
+                        << cpp_strerror(r) << std::endl;
          }
          comp->completion = new librbd::RBD::AioCompletion(nullptr, nullptr);
          r = comp->img.aio_close(comp->completion);
@@ -259,7 +287,7 @@ int do_list(std::string &pool_name, bool lflag, int threads, Formatter *f) {
   if (f) {
     f->close_section();
     f->flush(std::cout);
-  } else if (!names.empty()) {
+  } else if (!images.empty()) {
     std::cout << tbl;
   }
 
@@ -276,25 +304,32 @@ void get_arguments(po::options_description *positional,
                    po::options_description *options) {
   options->add_options()
     ("long,l", po::bool_switch(), "long listing format");
-  at::add_pool_options(positional, options);
+  at::add_pool_options(positional, options, true);
   at::add_format_options(options);
 }
 
-int execute(const po::variables_map &vm) {
+int execute(const po::variables_map &vm,
+            const std::vector<std::string> &ceph_global_init_args) {
+  std::string pool_name;
+  std::string namespace_name;
   size_t arg_index = 0;
-  std::string pool_name = utils::get_pool_name(vm, &arg_index);
+  int r = utils::get_pool_and_namespace_names(vm, true, false, &pool_name,
+                                              &namespace_name, &arg_index);
+  if (r < 0) {
+    return r;
+  }
 
   at::Format::Formatter formatter;
-  int r = utils::get_formatter(vm, &formatter);
+  r = utils::get_formatter(vm, &formatter);
   if (r < 0) {
     return r;
   }
 
-  r = do_list(pool_name, vm["long"].as<bool>(),
-              g_conf->get_val<int64_t>("rbd_concurrent_management_ops"),
+  r = do_list(pool_name, namespace_name, vm["long"].as<bool>(),
               formatter.get());
   if (r < 0) {
-    std::cerr << "rbd: list: " << cpp_strerror(r) << std::endl;
+    std::cerr << "rbd: listing images failed: " << cpp_strerror(r)
+              << std::endl;
     return r;
   }