]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
tools/cephfs: update for FSMap
authorJohn Spray <john.spray@redhat.com>
Wed, 17 Feb 2016 14:57:17 +0000 (14:57 +0000)
committerJohn Spray <john.spray@redhat.com>
Thu, 10 Mar 2016 12:11:23 +0000 (12:11 +0000)
Everywhere we used to take a rank, we now
take a role (<fscid:rank>)

Signed-off-by: John Spray <john.spray@redhat.com>
17 files changed:
src/CMakeLists.txt
src/tools/Makefile-server.am
src/tools/Makefile.am
src/tools/cephfs/DataScan.cc
src/tools/cephfs/DataScan.h
src/tools/cephfs/Dumper.cc
src/tools/cephfs/Dumper.h
src/tools/cephfs/JournalTool.cc
src/tools/cephfs/JournalTool.h
src/tools/cephfs/MDSUtility.cc
src/tools/cephfs/MDSUtility.h
src/tools/cephfs/Resetter.cc
src/tools/cephfs/Resetter.h
src/tools/cephfs/RoleSelector.cc [new file with mode: 0644]
src/tools/cephfs/RoleSelector.h [new file with mode: 0644]
src/tools/cephfs/TableTool.cc
src/tools/cephfs/TableTool.h

index d2b56e66f081d1f4ade84adc197456cf49a30b30..4cf3710b1bc810a2bb0b0a9a3f40c0937f62306e 100644 (file)
@@ -487,6 +487,7 @@ if (WITH_CEPHFS)
     tools/cephfs/EventOutput.cc
     tools/cephfs/Dumper.cc
     tools/cephfs/Resetter.cc
+    tools/cephfs/RoleSelector.cc
     tools/cephfs/MDSUtility.cc)
   add_executable(cephfs-journal-tool ${cephfs_journal_tool_srcs})
   target_link_libraries(cephfs-journal-tool librados mds osdc global
@@ -495,6 +496,7 @@ if (WITH_CEPHFS)
   set(cephfs_table_tool_srcs
     tools/cephfs/cephfs-table-tool.cc
     tools/cephfs/TableTool.cc
+    tools/cephfs/RoleSelector.cc
     tools/cephfs/MDSUtility.cc)
   add_executable(cephfs-table-tool ${cephfs_table_tool_srcs})
   target_link_libraries(cephfs-table-tool librados mds osdc global
@@ -503,6 +505,7 @@ if (WITH_CEPHFS)
   set(cephfs_data_scan_srcs
     tools/cephfs/cephfs-data-scan.cc
     tools/cephfs/DataScan.cc
+    tools/cephfs/RoleSelector.cc
     tools/cephfs/MDSUtility.cc)
   add_executable(cephfs-data-scan ${cephfs_data_scan_srcs})
   target_link_libraries(cephfs-data-scan librados mds osdc global
index 599c5db7011e810befcc5cb1f02da998643f274a..cbdb7150d815e529cb0e875b4a55296681e534d3 100644 (file)
@@ -35,6 +35,7 @@ if WITH_RADOS
 cephfs_journal_tool_SOURCES = \
        tools/cephfs/cephfs-journal-tool.cc \
        tools/cephfs/JournalTool.cc \
+       tools/cephfs/RoleSelector.cc \
        tools/cephfs/JournalFilter.cc \
        tools/cephfs/JournalScanner.cc \
        tools/cephfs/EventOutput.cc \
@@ -47,6 +48,7 @@ bin_PROGRAMS += cephfs-journal-tool
 cephfs_table_tool_SOURCES = \
        tools/cephfs/cephfs-table-tool.cc \
        tools/cephfs/TableTool.cc \
+       tools/cephfs/RoleSelector.cc \
        tools/cephfs/MDSUtility.cc
 cephfs_table_tool_LDADD = $(LIBMDS) $(LIBRADOS) $(CEPH_GLOBAL)
 bin_PROGRAMS += cephfs-table-tool
@@ -54,6 +56,7 @@ bin_PROGRAMS += cephfs-table-tool
 cephfs_data_scan_SOURCES = \
        tools/cephfs/cephfs-data-scan.cc \
        tools/cephfs/DataScan.cc \
+       tools/cephfs/RoleSelector.cc \
        tools/cephfs/MDSUtility.cc
 cephfs_data_scan_LDADD = $(LIBMDS) libcls_cephfs_client.la $(LIBRADOS) $(CEPH_GLOBAL)
 bin_PROGRAMS += cephfs-data-scan
index 0976bee5361ab7226bc4fe5e7225a7f7cef35cf1..e730850f784297417db556296cc3638e503505cc 100644 (file)
@@ -43,7 +43,8 @@ noinst_HEADERS += \
        tools/rados/RadosImport.h \
        tools/ceph_objectstore_tool.h \
        tools/rados/PoolDump.h \
-       tools/cephfs/DataScan.h
+       tools/cephfs/DataScan.h \
+       tools/cephfs/RoleSelector.h
 
 EXTRA_DIST += \
        tools/setup-virtualenv.sh
index 0cf2bddbeac2a6ab7731f23c3172be18df08c65a..dc70ae6a68751124fb3db6ceaef015a5e8ecc2d8 100644 (file)
@@ -36,7 +36,7 @@ void DataScan::usage()
     << "\n"
     << "    --force-corrupt: overrite apparently corrupt structures\n"
     << "    --force-init: write root inodes even if they exist\n"
-    << "    --force-pool: use data pool even if it is not in MDSMap\n"
+    << "    --force-pool: use data pool even if it is not in FSMap\n"
     << "\n"
     << "  cephfs-data-scan scan_frags [--force-corrupt]\n"
     << "\n"
@@ -89,6 +89,15 @@ bool DataScan::parse_kwarg(
     filter_tag = val;
     dout(10) << "Applying tag filter: '" << filter_tag << "'" << dendl;
     return true;
+  } else if (arg == std::string("--filesystem")) {
+    std::shared_ptr<Filesystem> fs;
+    *r = fsmap->parse_filesystem(val, &fs);
+    if (*r != 0) {
+      std::cerr << "Invalid filesystem '" << val << "'" << std::endl;
+      return false;
+    }
+    fscid = fs->fscid;
+    return true;
   } else {
     return false;
   }
@@ -168,6 +177,19 @@ int DataScan::main(const std::vector<const char*> &args)
     return -EINVAL;
   }
 
+  // If caller didn't specify a namespace, try to pick
+  // one if only one exists
+  if (fscid == FS_CLUSTER_ID_NONE) {
+    if (fsmap->get_filesystems().size() == 1) {
+      fscid = fsmap->get_filesystems().begin()->first;
+    } else {
+      std::cerr << "Specify a filesystem with --filesystem" << std::endl;
+      return -EINVAL;
+    }
+  }
+  auto fs =  fsmap->get_filesystem(fscid);
+  assert(fs != nullptr);
+
   // Default to output to metadata pool
   if (driver == NULL) {
     driver = new MetadataDriver();
@@ -178,7 +200,7 @@ int DataScan::main(const std::vector<const char*> &args)
 
   dout(4) << "connecting to RADOS..." << dendl;
   rados.connect();
-  r = driver->init(rados, mdsmap);
+  r = driver->init(rados, fsmap, fscid);
   if (r < 0) {
     return r;
   }
@@ -201,7 +223,7 @@ int DataScan::main(const std::vector<const char*> &args)
         << "' has ID " << data_pool_id << dendl;
     }
 
-    if (!mdsmap->is_data_pool(data_pool_id)) {
+    if (!fs->mds_map.is_data_pool(data_pool_id)) {
       std::cerr << "Warning: pool '" << data_pool_name << "' is not a "
         "CephFS data pool!" << std::endl;
       if (!force_pool) {
@@ -219,7 +241,13 @@ int DataScan::main(const std::vector<const char*> &args)
 
   // Initialize metadata_io from MDSMap for scan_frags
   if (command == "scan_frags") {
-    int const metadata_pool_id = mdsmap->get_metadata_pool();
+    const auto fs = fsmap->get_filesystem(fscid);
+    if (fs == nullptr) {
+      std::cerr << "Filesystem id " << fscid << " does not exist" << std::endl;
+      return -ENOENT;
+    }
+    int const metadata_pool_id = fs->mds_map.get_metadata_pool();
+
     dout(4) << "resolving metadata pool " << metadata_pool_id << dendl;
     std::string metadata_pool_name;
     int r = rados.pool_reverse_lookup(metadata_pool_id, &metadata_pool_name);
@@ -269,7 +297,7 @@ int DataScan::main(const std::vector<const char*> &args)
   } else if (command == "tmap_upgrade") {
     return tmap_upgrade();
   } else if (command == "init") {
-    return driver->init_roots(mdsmap->get_first_data_pool());
+    return driver->init_roots(fs->mds_map.get_first_data_pool());
   } else {
     std::cerr << "Unknown command '" << command << "'" << std::endl;
     return -EINVAL;
@@ -1533,9 +1561,12 @@ int MetadataDriver::inject_linkage(
 }
 
 
-int MetadataDriver::init(librados::Rados &rados, const MDSMap *mdsmap)
+int MetadataDriver::init(
+    librados::Rados &rados, const FSMap *fsmap, fs_cluster_id_t fscid)
 {
-  int const metadata_pool_id = mdsmap->get_metadata_pool();
+  auto fs =  fsmap->get_filesystem(fscid);
+  assert(fs != nullptr);
+  int const metadata_pool_id = fs->mds_map.get_metadata_pool();
 
   dout(4) << "resolving metadata pool " << metadata_pool_id << dendl;
   std::string metadata_pool_name;
@@ -1549,7 +1580,8 @@ int MetadataDriver::init(librados::Rados &rados, const MDSMap *mdsmap)
   return rados.ioctx_create(metadata_pool_name.c_str(), metadata_io);
 }
 
-int LocalFileDriver::init(librados::Rados &rados, const MDSMap *mdsmap)
+int LocalFileDriver::init(
+    librados::Rados &rados, const FSMap *fsmap, fs_cluster_id_t fscid)
 {
   return 0;
 }
index 3b94063f8ae6ddf22434550230b711639427d120..107ab7462ff33d3c8951535eb4eb0388ac6b61e2 100644 (file)
@@ -28,7 +28,10 @@ class RecoveryDriver {
     bool force_init;
 
   public:
-    virtual int init(librados::Rados &rados, const MDSMap *mdsmap) = 0;
+    virtual int init(
+        librados::Rados &rados,
+        const FSMap *fsmap,
+        fs_cluster_id_t fscid) = 0;
 
     void set_force_corrupt(const bool val)
     {
@@ -112,7 +115,10 @@ class LocalFileDriver : public RecoveryDriver
     {}
 
     // Implement RecoveryDriver interface
-    int init(librados::Rados &rados, const MDSMap *mdsmap);
+    int init(
+        librados::Rados &rados,
+        const FSMap *fsmap,
+        fs_cluster_id_t fscid);
 
     int inject_with_backtrace(
         const inode_backtrace_t &bt,
@@ -205,7 +211,10 @@ class MetadataDriver : public RecoveryDriver, public MetadataTool
   public:
 
     // Implement RecoveryDriver interface
-    int init(librados::Rados &rados, const MDSMap *mdsmap);
+    int init(
+        librados::Rados &rados,
+        const FSMap *fsmap,
+        fs_cluster_id_t fscid);
 
     int inject_with_backtrace(
         const inode_backtrace_t &bt,
@@ -224,6 +233,7 @@ class DataScan : public MDSUtility, public MetadataTool
 {
   protected:
     RecoveryDriver *driver;
+    fs_cluster_id_t fscid;
 
     // IoCtx for data pool (where we scrape file backtraces from)
     librados::IoCtx data_io;
@@ -259,7 +269,7 @@ class DataScan : public MDSUtility, public MetadataTool
      */
     int tmap_upgrade();
 
-    // Accept pools which are not in the MDSMap
+    // Accept pools which are not in the FSMap
     bool force_pool;
     // Respond to decode errors by overwriting
     bool force_corrupt;
@@ -301,7 +311,7 @@ class DataScan : public MDSUtility, public MetadataTool
     int main(const std::vector<const char *> &args);
 
     DataScan()
-      : driver(NULL), data_pool_id(-1), n(0), m(1),
+      : driver(NULL), fscid(FS_CLUSTER_ID_NONE), data_pool_id(-1), n(0), m(1),
         force_pool(false), force_corrupt(false),
         force_init(false)
     {
index 3344b0daf6dec393331fd11fe38eeb6bd3f61394..af04bf6169978a85d570cf7573a7ba6cab4ef4a2 100644 (file)
 
 #define HEADER_LEN 4096
 
-int Dumper::init(int rank_)
+int Dumper::init(mds_role_t role_)
 {
-  rank = rank_;
+  role = role_;
 
   int r = MDSUtility::init();
   if (r < 0) {
     return r;
   }
 
-  JournalPointer jp(rank, mdsmap->get_metadata_pool());
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+
+  JournalPointer jp(role.rank, fs->mds_map.get_metadata_pool());
   int jp_load_result = jp.load(objecter);
   if (jp_load_result != 0) {
     std::cerr << "Error loading journal: " << cpp_strerror(jp_load_result) << std::endl;
@@ -75,8 +78,12 @@ int Dumper::dump(const char *dump_file)
 {
   int r = 0;
 
-  Journaler journaler(ino, mdsmap->get_metadata_pool(), CEPH_FS_ONDISK_MAGIC,
-                                       objecter, 0, 0, &timer, &finisher);
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+
+  Journaler journaler(ino, fs->mds_map.get_metadata_pool(),
+                      CEPH_FS_ONDISK_MAGIC, objecter, 0, 0,
+                      &timer, &finisher);
   r = recover_journal(&journaler);
   if (r) {
     return r;
@@ -95,7 +102,7 @@ int Dumper::dump(const char *dump_file)
     char buf[HEADER_LEN];
     memset(buf, 0, sizeof(buf));
     snprintf(buf, HEADER_LEN, "Ceph mds%d journal dump\n start offset %llu (0x%llx)\n       length %llu (0x%llx)\n    write_pos %llu (0x%llx)\n    format %llu\n    trimmed_pos %llu (0x%llx)\n%c",
-           rank, 
+           role.rank, 
            (unsigned long long)start, (unsigned long long)start,
            (unsigned long long)len, (unsigned long long)len,
            (unsigned long long)journaler.last_committed.write_pos, (unsigned long long)journaler.last_committed.write_pos,
@@ -175,6 +182,9 @@ int Dumper::undump(const char *dump_file)
 {
   cout << "undump " << dump_file << std::endl;
   
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+
   int r = 0;
   int fd = ::open(dump_file, O_RDONLY);
   if (fd < 0) {
@@ -235,13 +245,13 @@ int Dumper::undump(const char *dump_file)
   h.magic = CEPH_FS_ONDISK_MAGIC;
 
   h.layout = file_layout_t::get_default();
-  h.layout.pool_id = mdsmap->get_metadata_pool();
+  h.layout.pool_id = fs->mds_map.get_metadata_pool();
   
   bufferlist hbl;
   ::encode(h, hbl);
 
   object_t oid = file_object_t(ino, 0);
-  object_locator_t oloc(mdsmap->get_metadata_pool());
+  object_locator_t oloc(fs->mds_map.get_metadata_pool());
   SnapContext snapc;
 
   cout << "writing header " << oid << std::endl;
index e94c5960eb1034f6f78abe76bebd3a123ed50598..97b56a7751ec853b0a0d1ad73c8f327eaa16d3bc 100644 (file)
@@ -29,16 +29,16 @@ class Journaler;
 
 class Dumper : public MDSUtility {
 private:
-  int rank;
+  mds_role_t role;
   inodeno_t ino;
 
 public:
-  Dumper() : rank(-1), ino(-1)
+  Dumper() : ino(-1)
   {}
 
-  void handle_mds_map(MMDSMap* m);
+  void handle_mds_map(MFSMap* m);
 
-  int init(int rank);
+  int init(mds_role_t role_);
   int recover_journal(Journaler *journaler);
   int dump(const char *dumpfile);
   int undump(const char *dumpfile);
index 4be47b2b239c92c45f871390272e60069938bb13..63e5ac11089553e8fdbe614ef3ec4f8c036d74ba 100644 (file)
@@ -60,7 +60,7 @@ void JournalTool::usage()
     << "    <output>: [summary|binary|json] [--path <path>]\n"
     << "\n"
     << "Options:\n"
-    << "  --rank=<int>  Journal rank (default 0)\n";
+    << "  --rank=<str>  Journal rank (default 0)\n";
 
   generic_client_usage();
 }
@@ -82,14 +82,17 @@ int JournalTool::main(std::vector<const char*> &argv)
   }
 
   std::vector<const char*>::iterator arg = argv.begin();
+
   std::string rank_str;
-  if(ceph_argparse_witharg(argv, arg, &rank_str, "--rank", (char*)NULL)) {
-    std::string rank_err;
-    rank = strict_strtol(rank_str.c_str(), 10, &rank_err);
-    if (!rank_err.empty()) {
-        derr << "Bad rank '" << rank_str << "'" << dendl;
-        usage();
-    }
+  if(!ceph_argparse_witharg(argv, arg, &rank_str, "--rank", (char*)NULL)) {
+    // Default: act on rank 0.  Will give the user an error if they
+    // try invoking this way when they have more than one filesystem.
+    rank_str = "0";
+  }
+
+  r = role_selector.parse(*fsmap, rank_str);
+  if (r != 0) {
+    return r;
   }
 
   std::string mode;
@@ -111,7 +114,9 @@ int JournalTool::main(std::vector<const char*> &argv)
   dout(4) << "JournalTool: connecting to RADOS..." << dendl;
   rados.connect();
  
-  int const pool_id = mdsmap->get_metadata_pool();
+  auto fs = fsmap->get_filesystem(role_selector.get_ns());
+  assert(fs != nullptr);
+  int const pool_id = fs->mds_map.get_metadata_pool();
   dout(4) << "JournalTool: resolving pool " << pool_id << dendl;
   std::string pool_name;
   r = rados.pool_reverse_lookup(pool_id, &pool_name);
@@ -126,18 +131,27 @@ int JournalTool::main(std::vector<const char*> &argv)
 
   // Execution
   // =========
-  dout(4) << "Executing for rank " << rank << dendl;
-  if (mode == std::string("journal")) {
-    return main_journal(argv);
-  } else if (mode == std::string("header")) {
-    return main_header(argv);
-  } else if (mode == std::string("event")) {
-    return main_event(argv);
-  } else {
-    derr << "Bad command '" << mode << "'" << dendl;
-    usage();
-    return -EINVAL;
+  for (auto role : role_selector.get_roles()) {
+    rank = role.rank;
+    dout(4) << "Executing for rank " << rank << dendl;
+    if (mode == std::string("journal")) {
+      r = main_journal(argv);
+    } else if (mode == std::string("header")) {
+      r = main_header(argv);
+    } else if (mode == std::string("event")) {
+      r = main_event(argv);
+    } else {
+      derr << "Bad command '" << mode << "'" << dendl;
+      usage();
+      return -EINVAL;
+    }
+
+    if (r != 0) {
+      return r;
+    }
   }
+
+  return r;
 }
 
 
@@ -528,7 +542,7 @@ int JournalTool::journal_export(std::string const &path, bool import)
    */
   {
     Dumper dumper;
-    r = dumper.init(rank);
+    r = dumper.init(mds_role_t(role_selector.get_ns(), rank));
     if (r < 0) {
       derr << "dumper::init failed: " << cpp_strerror(r) << dendl;
       return r;
@@ -558,15 +572,10 @@ int JournalTool::journal_reset(bool hard)
     return r;
   }
 
-  if (mdsmap->is_dne(mds_rank_t(rank))) {
-    std::cerr << "MDS rank " << rank << " does not exist" << std::endl;
-    return -ENOENT;
-  }
-
   if (hard) {
-    r = resetter.reset_hard(rank);
+    r = resetter.reset_hard(mds_role_t(role_selector.get_ns(), rank));
   } else {
-    r = resetter.reset(rank);
+    r = resetter.reset(mds_role_t(role_selector.get_ns(), rank));
   }
   resetter.shutdown();
 
@@ -1209,8 +1218,9 @@ int JournalTool::consume_inos(const std::set<inodeno_t> &inos)
   int r = 0;
 
   // InoTable is a per-MDS structure, so iterate over assigned ranks
+  auto fs = fsmap->get_filesystem(role_selector.get_ns());
   std::set<mds_rank_t> in_ranks;
-  mdsmap->get_mds_set(in_ranks);
+  fs->mds_map.get_mds_set(in_ranks);
 
   for (std::set<mds_rank_t>::iterator rank_i = in_ranks.begin();
       rank_i != in_ranks.end(); ++rank_i)
index f717859a6f14d3929305b444bf02d1fd7c90eb42..f8f90606fd099e81001d37db1f7283d4f7422dca 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "MDSUtility.h"
+#include "RoleSelector.h"
 #include <vector>
 
 #include "mds/mdstypes.h"
@@ -32,7 +33,10 @@ class JournalScanner;
 class JournalTool : public MDSUtility
 {
   private:
-    int rank;
+    MDSRoleSelector role_selector;
+    // Bit hacky, use this `rank` member to control behaviour of the
+    // various main_ functions.
+    mds_rank_t rank;
 
     // Entry points
     int main_journal(std::vector<const char*> &argv);
index d335d92fda0f4ed4d25e27475d48802abf5906d5..b6b9eab1441cba558013f2f2cb9b71df0a079040 100644 (file)
@@ -27,7 +27,7 @@ MDSUtility::MDSUtility() :
 {
   monc = new MonClient(g_ceph_context);
   messenger = Messenger::create_client_messenger(g_ceph_context, "mds");
-  mdsmap = new MDSMap();
+  fsmap = new FSMap();
   objecter = new Objecter(g_ceph_context, messenger, monc, NULL, 0, 0);
 }
 
@@ -37,7 +37,7 @@ MDSUtility::~MDSUtility()
   delete objecter;
   delete monc;
   delete messenger;
-  delete mdsmap;
+  delete fsmap;
   assert(waiting_for_mds_map == NULL);
 }
 
@@ -91,11 +91,11 @@ int MDSUtility::init()
   Mutex init_lock("MDSUtility:init");
   Cond cond;
   bool done = false;
-  assert(!mdsmap->get_epoch());
+  assert(!fsmap->get_epoch());
   lock.Lock();
   waiting_for_mds_map = new C_SafeCond(&init_lock, &cond, &done, NULL);
   lock.Unlock();
-  monc->sub_want("mdsmap", 0, CEPH_SUBSCRIBE_ONETIME);
+  monc->sub_want("fsmap", 0, CEPH_SUBSCRIBE_ONETIME);
   monc->renew_subs();
 
   // Wait for MDS map
@@ -104,7 +104,7 @@ int MDSUtility::init()
   while (!done)
     cond.Wait(init_lock);
   init_lock.Unlock();
-  dout(4) << "Got MDS map " << mdsmap->get_epoch() << dendl;
+  dout(4) << "Got MDS map " << fsmap->get_epoch() << dendl;
 
   finisher.start();
 
@@ -130,8 +130,8 @@ bool MDSUtility::ms_dispatch(Message *m)
 {
    Mutex::Locker locker(lock);
    switch (m->get_type()) {
-   case CEPH_MSG_MDS_MAP:
-     handle_mds_map((MMDSMap*)m);
+   case CEPH_MSG_FS_MAP:
+     handle_mds_map((MFSMap*)m);
      break;
    case CEPH_MSG_OSD_MAP:
      break;
@@ -142,9 +142,9 @@ bool MDSUtility::ms_dispatch(Message *m)
 }
 
 
-void MDSUtility::handle_mds_map(MMDSMap* m)
+void MDSUtility::handle_mds_map(MFSMap* m)
 {
-  mdsmap->decode(m->get_encoded());
+  fsmap->decode(m->get_encoded());
   if (waiting_for_mds_map) {
     waiting_for_mds_map->complete(0);
     waiting_for_mds_map = NULL;
index 4034043a78f13059255ebae634f9b01882fb6f69..4d233c9b730a9ebc4a2e7589b8adbee275f0027a 100644 (file)
@@ -15,8 +15,8 @@
 #define MDS_UTILITY_H_
 
 #include "osdc/Objecter.h"
-#include "mds/MDSMap.h"
-#include "messages/MMDSMap.h"
+#include "mds/FSMap.h"
+#include "messages/MFSMap.h"
 #include "msg/Dispatcher.h"
 #include "msg/Messenger.h"
 #include "auth/Auth.h"
@@ -32,7 +32,7 @@
 class MDSUtility : public Dispatcher {
 protected:
   Objecter *objecter;
-  MDSMap *mdsmap;
+  FSMap *fsmap;
   Messenger *messenger;
   MonClient *monc;
 
@@ -46,7 +46,7 @@ public:
   MDSUtility();
   ~MDSUtility();
 
-  void handle_mds_map(MMDSMap* m);
+  void handle_mds_map(MFSMap* m);
   bool ms_dispatch(Message *m);
   bool ms_handle_reset(Connection *con) { return false; }
   void ms_handle_remote_reset(Connection *con) {}
index b255f9ee7bb8385610bbfac8b60cd456f0d8b452..f1102f35a483b69e36524ae91fff9d0f8a07237e 100644 (file)
 
 #define dout_subsys ceph_subsys_mds
 
-int Resetter::reset(int rank)
+int Resetter::reset(mds_role_t role)
 {
   Mutex mylock("Resetter::reset::lock");
   Cond cond;
   bool done;
   int r;
 
-  JournalPointer jp(rank, mdsmap->get_metadata_pool());
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+  int const pool_id = fs->mds_map.get_metadata_pool();
+
+  JournalPointer jp(role.rank, pool_id);
   int jp_load_result = jp.load(objecter);
   if (jp_load_result != 0) {
     std::cerr << "Error loading journal: " << cpp_strerror(jp_load_result) <<
@@ -41,7 +45,7 @@ int Resetter::reset(int rank)
   }
 
   Journaler journaler(jp.front,
-      mdsmap->get_metadata_pool(),
+      pool_id,
       CEPH_FS_ONDISK_MAGIC,
       objecter, 0, 0, &timer, &finisher);
 
@@ -109,10 +113,14 @@ int Resetter::reset(int rank)
   return 0;
 }
 
-int Resetter::reset_hard(int rank)
+int Resetter::reset_hard(mds_role_t role)
 {
-  JournalPointer jp(rank, mdsmap->get_metadata_pool());
-  jp.front = rank + MDS_INO_LOG_OFFSET;
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+  int const pool_id = fs->mds_map.get_metadata_pool();
+
+  JournalPointer jp(role.rank, pool_id);
+  jp.front = role.rank + MDS_INO_LOG_OFFSET;
   jp.back = 0;
   int r = jp.save(objecter);
   if (r != 0) {
@@ -121,12 +129,13 @@ int Resetter::reset_hard(int rank)
   }
 
   Journaler journaler(jp.front,
-    mdsmap->get_metadata_pool(),
+    pool_id,
     CEPH_FS_ONDISK_MAGIC,
     objecter, 0, 0, &timer, &finisher);
   journaler.set_writeable();
 
-  file_layout_t default_log_layout = MDCache::gen_default_log_layout(*mdsmap);
+  file_layout_t default_log_layout = MDCache::gen_default_log_layout(
+      fsmap->get_filesystem(role.fscid)->mds_map);
   journaler.create(&default_log_layout, g_conf->mds_journal_format);
 
   C_SaferCond cond;
@@ -150,7 +159,7 @@ int Resetter::reset_hard(int rank)
   }
 
   dout(4) << "Successfully wrote new journal pointer and header for rank "
-    << rank << dendl;
+    << role << dendl;
   return 0;
 }
 
index 2baaf47f43a630e77a84f6045961ea93ef6750d3..115f6ffeecbcaee0126287c7686eb2200d3c76ff 100644 (file)
@@ -36,8 +36,8 @@ public:
    * For use when no journal header/pointer was present: write one
    * out from scratch.
    */
-  int reset_hard(int rank);
-  int reset(int rank);
+  int reset_hard(mds_role_t role);
+  int reset(mds_role_t role);
 };
 
 #endif /* JOURNAL_RESETTER_H_ */
diff --git a/src/tools/cephfs/RoleSelector.cc b/src/tools/cephfs/RoleSelector.cc
new file mode 100644 (file)
index 0000000..b352c4c
--- /dev/null
@@ -0,0 +1,58 @@
+
+#include "RoleSelector.h"
+
+int MDSRoleSelector::parse_rank(
+    const FSMap &fsmap,
+    std::string const &str)
+{
+  if (str == "all" || str == "*") {
+    std::set<mds_rank_t> in;
+    const MDSMap &mds_map = fsmap.get_filesystem(fscid)->mds_map;
+    mds_map.get_mds_set(in);
+
+    for (auto rank : in) {
+      roles.push_back(mds_role_t(fscid, rank));
+    }
+
+    return 0;
+  } else {
+    std::string rank_err;
+    mds_rank_t rank = strict_strtol(str.c_str(), 10, &rank_err);
+    if (!rank_err.empty()) {
+      return -EINVAL;
+    }
+    if (fsmap.get_filesystem(fscid)->mds_map.is_dne(rank)) {
+      return -ENOENT;
+    }
+    roles.push_back(mds_role_t(fscid, rank));
+    return 0;
+  }
+}
+
+int MDSRoleSelector::parse(const FSMap &fsmap, std::string const &str)
+{
+  auto colon_pos = str.find(":");
+  if (colon_pos == std::string::npos) {
+    // An unqualified rank.  Only valid if there is only one
+    // namespace.
+    if (fsmap.get_filesystems().size() == 1) {
+      fscid = fsmap.get_filesystems().begin()->first;
+      return parse_rank(fsmap, str);
+    } else {
+      return -EINVAL;
+    }
+  } else if (colon_pos == 0 || colon_pos == str.size() - 1) {
+    return -EINVAL;
+  } else {
+    const std::string ns_str = str.substr(0, colon_pos);
+    const std::string rank_str = str.substr(colon_pos + 1);
+    std::shared_ptr<Filesystem> fs_ptr;
+    int r = fsmap.parse_filesystem(ns_str, &fs_ptr);
+    if (r != 0) {
+      return r;
+    }
+    fscid = fs_ptr->fscid;
+    return parse_rank(fsmap, rank_str);
+  }
+}
+
diff --git a/src/tools/cephfs/RoleSelector.h b/src/tools/cephfs/RoleSelector.h
new file mode 100644 (file)
index 0000000..933c51d
--- /dev/null
@@ -0,0 +1,35 @@
+
+#ifndef ROLE_SELECTOR_H_
+#define ROLE_SELECTOR_H_
+
+#include <string>
+#include <vector>
+#include "mds/mdstypes.h"
+#include "mds/FSMap.h"
+
+/**
+ * When you want to let the user act on a single rank in a namespace,
+ * or all of them.
+ */
+class MDSRoleSelector
+{
+  public:
+    const std::vector<mds_role_t> &get_roles() const {return roles;}
+    int parse(const FSMap &fsmap, std::string const &str);
+    MDSRoleSelector()
+      : fscid(FS_CLUSTER_ID_NONE)
+    {}
+    fs_cluster_id_t get_ns() const
+    {
+      return fscid;
+    }
+  protected:
+    int parse_rank(
+        const FSMap &fsmap,
+        std::string const &str);
+    std::vector<mds_role_t> roles;
+    fs_cluster_id_t fscid;
+};
+
+#endif // ROLE_SELECTOR_H_
+
index 2d14a4f9286f901d7998a3068cc89e528feb58c3..2ff020a6de6712196169db85490ff568488c90bb 100644 (file)
@@ -38,38 +38,32 @@ void TableTool::usage()
 
 
 /**
- * For a function that takes an MDS rank as an argument and
- * returns an error code, execute it either on all ranks (if
- * this->rank is MDS_RANK_NONE), or on the rank specified
- * by this->rank.
+ * For a function that takes an MDS role as an argument and
+ * returns an error code, execute it on the roles specified
+ * by `role_selector`.
  */
-int TableTool::apply_rank_fn(std::function<int(mds_rank_t, Formatter *)> fptr, Formatter *f)
+int TableTool::apply_role_fn(std::function<int(mds_role_t, Formatter *)> fptr, Formatter *f)
 {
   assert(f != NULL);
 
   int r = 0;
-  std::set<mds_rank_t> apply_to_ranks;
-  if (rank == MDS_RANK_NONE) {
-    mdsmap->get_mds_set(apply_to_ranks);
-  } else {
-    apply_to_ranks.insert(rank);
-  }
 
   f->open_object_section("ranks");
 
-  for (std::set<mds_rank_t>::iterator rank_i = apply_to_ranks.begin();
-      rank_i != apply_to_ranks.end(); ++rank_i) {
+  for (auto role : role_selector.get_roles()) {
     std::ostringstream rank_str;
-    rank_str << *rank_i;
+    rank_str << role.rank;
     f->open_object_section(rank_str.str().c_str());
 
     f->open_object_section("data");
-    int rank_r = fptr(*rank_i, f);
+    int rank_r = fptr(role, f);
     f->close_section();
     r = r ? r : rank_r;
 
     f->dump_int("result", rank_r);
     f->close_section();
+
+    
   }
 
   f->close_section();
@@ -90,21 +84,21 @@ protected:
   // The RADOS object ID for the table
   std::string object_name;
 
-  // The rank in question (may be NONE)
-  mds_rank_t rank;
+  // The role in question (may be NONE)
+  mds_role_t role;
 
   // Whether this is an MDSTable subclass (i.e. has leading version field to decode)
   bool mds_table;
 
 public:
-  TableHandler(mds_rank_t r, std::string const &name, bool mds_table_)
-    : rank(r), mds_table(mds_table_)
+  TableHandler(mds_role_t r, std::string const &name, bool mds_table_)
+    : role(r), mds_table(mds_table_)
   {
     // Compose object name of the table we will dump
     std::ostringstream oss;
     oss << "mds";
-    if (rank != MDS_RANK_NONE) {
-      oss << rank;
+    if (!role.is_none()) {
+      oss << role.rank;
     }
     oss << "_" << name;
     object_name = oss.str();
@@ -127,7 +121,7 @@ public:
           f->dump_int("version", version);
         }
         A table_inst;
-        table_inst.set_rank(rank);
+        table_inst.set_rank(role.rank);
         table_inst.decode(q);
         table_inst.dump(f);
 
@@ -147,7 +141,7 @@ public:
   {
     A table_inst;
     // Compose new (blank) table
-    table_inst.set_rank(rank);
+    table_inst.set_rank(role.rank);
     table_inst.reset_state();
     // Write the table out
     return write(table_inst, io);
@@ -183,21 +177,21 @@ private:
   // The RADOS object ID for the table
   std::string object_name;
 
-  // The rank in question (may be NONE)
-  mds_rank_t rank;
+  // The role (rank may be NONE)
+  mds_role_t role;
 
   // Whether this is an MDSTable subclass (i.e. has leading version field to decode)
   bool mds_table;
 
 public:
-  TableHandlerOmap(mds_rank_t r, std::string const &name, bool mds_table_)
-    : rank(r), mds_table(mds_table_)
+  TableHandlerOmap(mds_role_t r, std::string const &name, bool mds_table_)
+    : role(r), mds_table(mds_table_)
   {
     // Compose object name of the table we will dump
     std::ostringstream oss;
     oss << "mds";
-    if (rank != MDS_RANK_NONE) {
-      oss << rank;
+    if (!role.is_none()) {
+      oss << role.rank;
     }
     oss << "_" << name;
     object_name = oss.str();
@@ -212,13 +206,14 @@ public:
     bufferlist header_bl;
     int r = io->omap_get_header(object_name, &header_bl);
     if (r != 0) {
-      derr << "error reading header: " << cpp_strerror(r) << dendl;
+      derr << "error reading header on '" << object_name << "': "
+           << cpp_strerror(r) << dendl;
       return r;
     }
 
     // Decode the header
     A table_inst;
-    table_inst.set_rank(rank);
+    table_inst.set_rank(role.rank);
     try {
       table_inst.decode_header(header_bl);
     } catch (buffer::error &e) {
@@ -259,7 +254,7 @@ public:
   int reset(librados::IoCtx *io)
   {
     A table_inst;
-    table_inst.set_rank(rank);
+    table_inst.set_rank(role.rank);
     table_inst.reset_state();
     bufferlist header_bl;
     table_inst.encode_header(&header_bl);
@@ -277,14 +272,14 @@ public:
 class InoTableHandler : public TableHandler<InoTable>
 {
   public:
-  explicit InoTableHandler(mds_rank_t r)
+  explicit InoTableHandler(mds_role_t r)
     : TableHandler(r, "inotable", true)
   {}
 
   int take_inos(librados::IoCtx *io, inodeno_t max, Formatter *f)
   {
     InoTable inst;
-    inst.set_rank(rank);
+    inst.set_rank(role.rank);
     inst.reset_state();
 
     int r = 0;
@@ -317,18 +312,7 @@ int TableTool::main(std::vector<const char*> &argv)
   dout(4) << "connecting to RADOS..." << dendl;
   rados.connect();
  
-  int const pool_id = mdsmap->get_metadata_pool();
-  dout(4) << "resolving pool " << pool_id << dendl;
-  std::string pool_name;
-  r = rados.pool_reverse_lookup(pool_id, &pool_name);
-  if (r < 0) {
-    derr << "Pool " << pool_id << " identified in MDS map not found in RADOS!" << dendl;
-    return r;
-  }
 
-  dout(4) << "creating IoCtx.." << dendl;
-  r = rados.ioctx_create(pool_name.c_str(), io);
-  assert(r == 0);
 
   // Require at least 3 args <rank> <mode> <arg> [args...]
   if (argv.size() < 3) {
@@ -336,33 +320,47 @@ int TableTool::main(std::vector<const char*> &argv)
     return -EINVAL;
   }
 
-  const std::string rank_str = std::string(argv[0]);
+  const std::string role_str = std::string(argv[0]);
   const std::string mode = std::string(argv[1]);
+  const std::string table = std::string(argv[2]);
 
-  if (rank_str == "all") {
-    rank = MDS_RANK_NONE;
-  } else {
-    std::string rank_err;
-    rank = strict_strtol(rank_str.c_str(), 10, &rank_err);
-    if (!rank_err.empty()) {
-      derr << "Bad rank '" << rank_str << "'" << dendl;
-      usage();
-    }
+  r = role_selector.parse(*fsmap, role_str);
+  if (r < 0) {
+    derr << "Bad rank selection: " << role_str << "'" << dendl;
+    return r;
+  }
+
+  auto fs =  fsmap->get_filesystem(role_selector.get_ns());
+  assert(fs != nullptr);
+  int const pool_id = fs->mds_map.get_metadata_pool();
+  dout(4) << "resolving pool " << pool_id << dendl;
+  std::string pool_name;
+  r = rados.pool_reverse_lookup(pool_id, &pool_name);
+  if (r < 0) {
+    derr << "Pool " << pool_id << " identified in MDS map not found in RADOS!"
+         << dendl;
+    return r;
+  }
+
+  dout(4) << "creating IoCtx.." << dendl;
+  r = rados.ioctx_create(pool_name.c_str(), io);
+  if (r != 0) {
+    return r;
   }
 
   JSONFormatter jf(true);
   if (mode == "reset") {
     const std::string table = std::string(argv[2]);
     if (table == "session") {
-      r = apply_rank_fn([this](mds_rank_t rank, Formatter *f) -> int {
+      r = apply_role_fn([this](mds_role_t rank, Formatter *f) -> int {
             return TableHandlerOmap<SessionMapStore>(rank, "sessionmap", false).reset(&io);
       }, &jf);
     } else if (table == "inode") {
-      r = apply_rank_fn([this](mds_rank_t rank, Formatter *f) -> int {
+      r = apply_role_fn([this](mds_role_t rank, Formatter *f) -> int {
             return TableHandler<InoTable>(rank, "inotable", true).reset(&io);
       }, &jf);
     } else if (table == "snap") {
-      r = TableHandler<SnapServer>(MDS_RANK_NONE, "snaptable", true).reset(&io);
+      r = TableHandler<SnapServer>(mds_role_t(), "snaptable", true).reset(&io);
       jf.open_object_section("reset_snap_status");
       jf.dump_int("result", r);
       jf.close_section();
@@ -375,18 +373,18 @@ int TableTool::main(std::vector<const char*> &argv)
   } else if (mode == "show") {
     const std::string table = std::string(argv[2]);
     if (table == "session") {
-      r = apply_rank_fn([this](mds_rank_t rank, Formatter *f) -> int {
+      r = apply_role_fn([this](mds_role_t rank, Formatter *f) -> int {
         return TableHandlerOmap<SessionMapStore>(rank, "sessionmap", false).load_and_dump(&io, f);
       }, &jf);
     } else if (table == "inode") {
-      r = apply_rank_fn([this](mds_rank_t rank, Formatter *f) -> int {
+      r = apply_role_fn([this](mds_role_t rank, Formatter *f) -> int {
         return TableHandler<InoTable>(rank, "inotable", true).load_and_dump(&io, f);;
       }, &jf);
     } else if (table == "snap") {
       jf.open_object_section("show_snap_table");
       {
         r = TableHandler<SnapServer>(
-            MDS_RANK_NONE, "snaptable", true).load_and_dump(&io, &jf);
+            mds_role_t(), "snaptable", true).load_and_dump(&io, &jf);
         jf.dump_int("result", r);
       }
       jf.close_section();
@@ -403,7 +401,7 @@ int TableTool::main(std::vector<const char*> &argv)
       derr << "Bad ino '" << ino_str << "'" << dendl;
       return -EINVAL;
     }
-    r = apply_rank_fn([this, ino](mds_rank_t rank, Formatter *f) -> int {
+    r = apply_role_fn([this, ino](mds_role_t rank, Formatter *f) -> int {
       return InoTableHandler(rank).take_inos(&io, ino, f);
     }, &jf);
   } else {
index 57705ef171153f9a1cc750c401ecbc9beac0673c..bcd3167b29e4fee4e917387c95272b896096c4eb 100644 (file)
 
 
 #include "MDSUtility.h"
+#include "RoleSelector.h"
 
 #include "include/rados/librados.hpp"
 
-
 /**
  * Command line tool for debugging the backing store of
  * MDSTable instances.
 class TableTool : public MDSUtility
 {
   private:
-    mds_rank_t rank;
+    MDSRoleSelector role_selector;
 
     // I/O handles
     librados::Rados rados;
     librados::IoCtx io;
 
-    int apply_rank_fn(std::function<int(mds_rank_t, Formatter *)> fptr, Formatter *f);
+    int apply_role_fn(std::function<int(mds_role_t, Formatter *)> fptr, Formatter *f);
 
   public:
     void usage();
-    TableTool() :
-      rank(MDS_RANK_NONE) {}
     int main(std::vector<const char*> &argv);
 
 };
+