]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: add `ceph fs [new|rm|ls]`
authorJohn Spray <john.spray@inktank.com>
Tue, 29 Apr 2014 19:05:11 +0000 (20:05 +0100)
committerJohn Spray <jspray@redhat.com>
Mon, 30 Jun 2014 09:36:39 +0000 (10:36 +0100)
Signed-off-by: John Spray <john.spray@inktank.com>
src/mds/MDSMap.cc
src/mds/MDSMap.h
src/mon/MDSMonitor.cc
src/mon/MDSMonitor.h
src/mon/MonCommands.h
src/mon/Monitor.cc

index 199e080271007baead710e6efe64845934583f64..f681c89c1fb87049e14e69b14c4e26d425b5967b 100644 (file)
@@ -144,6 +144,8 @@ void MDSMap::dump(Formatter *f) const
     f->dump_int("pool", *p);
   f->close_section();
   f->dump_int("metadata_pool", metadata_pool);
+  f->dump_bool("enabled", enabled);
+  f->dump_string("fs_name", fs_name);
 }
 
 void MDSMap::generate_test_instances(list<MDSMap*>& ls)
@@ -489,6 +491,7 @@ void MDSMap::encode(bufferlist& bl, uint64_t features) const
     ::encode(data_pools, bl);
     ::encode(cas_pool, bl);
     ::encode(enabled, bl);
+    ::encode(fs_name, bl);
 
     // kclient ignores everything from here
     __u16 ev = 7;
@@ -540,6 +543,7 @@ void MDSMap::decode(bufferlist::iterator& p)
   }
   if (struct_v >= 5) {
     ::decode(enabled, p);
+    ::decode(fs_name, p);
   }
 
   // kclient ignores everything from here
index 913814ef9428f0e0fb4a1c9231118f1a69f9b5d0..1693e3aa8182531c40d1034878da59af75d5ea64 100644 (file)
@@ -145,6 +145,7 @@ protected:
   // base map
   epoch_t epoch;
   bool enabled;
+  std::string fs_name;
   uint32_t flags;        // flags
   epoch_t last_failure;  // mds epoch of last failure
   epoch_t last_failure_osd_epoch; // osd epoch of last failure; any mds entering replay needs
@@ -192,7 +193,10 @@ public:
 
 public:
   MDSMap() 
-    : epoch(0), enabled(false), flags(0), last_failure(0), last_failure_osd_epoch(0), tableserver(0), root(0),
+    : epoch(0), enabled(false), fs_name("default"),
+      flags(0), last_failure(0),
+      last_failure_osd_epoch(0),
+      tableserver(0), root(0),
       session_timeout(0),
       session_autoclose(0),
       max_file_size(0),
index bfcc134831ea6952d772e1df7a4ee3fe7425ccf5..f17cce5ecc76b24c2ebd7eb093c9fc32ff2a4b95 100644 (file)
@@ -57,9 +57,10 @@ void MDSMonitor::print_map(MDSMap &m, int dbl)
   *_dout << dendl;
 }
 
-void MDSMonitor::create_new_fs(MDSMap &m, int metadata_pool, int data_pool)
+void MDSMonitor::create_new_fs(MDSMap &m, const std::string &name, int metadata_pool, int data_pool)
 {
   m.enabled = true;
+  m.fs_name = name;
   m.max_mds = g_conf->max_mds;
   m.created = ceph_clock_now(g_ceph_context);
   m.data_pools.insert(data_pool);
@@ -701,6 +702,63 @@ bool MDSMonitor::preprocess_command(MMonCommand *m)
        ds << mdsmap.compat;
       }
       r = 0;
+  } else if (prefix == "fs ls") {
+    if (f) {
+      f->open_array_section("filesystems");
+      {
+        if (pending_mdsmap.enabled) {
+          f->open_object_section("filesystem");
+          {
+            f->dump_string("name", pending_mdsmap.fs_name);
+            const char *md_pool_name = mon->osdmon()->osdmap.get_pool_name(pending_mdsmap.metadata_pool);
+            /* Output both the names and IDs of pools, for use by
+             * humans and machines respectively */
+            assert(md_pool_name != NULL);
+            f->dump_string("metadata_pool", md_pool_name);
+            f->dump_int("metadata_pool_id", pending_mdsmap.metadata_pool);
+            f->open_array_section("data_pool_ids");
+            {
+              for (std::set<int64_t>::iterator dpi = pending_mdsmap.data_pools.begin();
+                   dpi != pending_mdsmap.data_pools.end(); ++dpi) {
+                f->dump_int("data_pool_id", *dpi);
+              }
+            }
+
+            f->open_array_section("data_pools");
+            {
+                for (std::set<int64_t>::iterator dpi = pending_mdsmap.data_pools.begin();
+                   dpi != pending_mdsmap.data_pools.end(); ++dpi) {
+                  const char *pool_name = mon->osdmon()->osdmap.get_pool_name(*dpi);
+                  assert(pool_name != NULL);
+                  f->dump_string("data_pool", pool_name);
+                }
+            }
+
+            f->close_section();
+          }
+          f->close_section();
+        }
+      }
+      f->close_section();
+      f->flush(ds);
+    } else {
+      if (pending_mdsmap.enabled) {
+        const char *md_pool_name = mon->osdmon()->osdmap.get_pool_name(pending_mdsmap.metadata_pool);
+        assert(md_pool_name != NULL);
+        
+        ds << "name: " << pending_mdsmap.fs_name << ", metadata pool: " << md_pool_name << ", data pools: [";
+        for (std::set<int64_t>::iterator dpi = pending_mdsmap.data_pools.begin();
+           dpi != pending_mdsmap.data_pools.end(); ++dpi) {
+          const char *pool_name = mon->osdmon()->osdmap.get_pool_name(*dpi);
+          assert(pool_name != NULL);
+          ds << pool_name << " ";
+        }
+        ds << "]" << std::endl;
+      } else {
+        ds << "No filesystems enabled" << std::endl;
+      }
+    }
+    r = 0;
   }
 
   if (r != -1) {
@@ -794,22 +852,253 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
   }
 
   string prefix;
-
   cmd_getval(g_ceph_context, cmdmap, "prefix", prefix);
 
+  /* Refuse to execute if mon cluster unavailable */
   MonSession *session = m->get_session();
   if (!session) {
     mon->reply_command(m, -EACCES, "access denied", rdata, get_last_committed());
     return true;
   }
 
+  /* Execute filesystem add/remove, or pass through to filesystem_command */
+  bool const handled = management_command(prefix, cmdmap, ss, r);
+  if (!handled) {
+    if (!pending_mdsmap.enabled) {
+      ss << "No filesystem configured: use `ceph fs new` to create a filesystem";
+      r = -ENOENT;
+    } else {
+      bool const completed = filesystem_command(m, prefix, cmdmap, ss, r);
+      if (!completed) {
+        // Do not reply, the message has been enqueued for retry
+        return false;
+      }
+    }
+  }
+
+  /* Compose response */
+  string rs;
+  getline(ss, rs);
+
+  if (r >= 0) {
+    // success.. delay reply
+    wait_for_finished_proposal(new Monitor::C_Command(mon, m, r, rs,
+                                             get_last_committed() + 1));
+    return true;
+  } else {
+    // reply immediately
+    mon->reply_command(m, r, rs, rdata, get_last_committed());
+    return false;
+  }
+}
+
+
+/**
+ * Handle a command for creating or removing a filesystem.
+ *
+ * @return true if such a command was found, else false to
+ *         fall through and look for other types of command.
+ */
+bool MDSMonitor::management_command(
+    std::string const &prefix,
+    map<string, cmd_vartype> &cmdmap,
+    std::stringstream &ss,
+    int &r)
+{
+  if (prefix == "mds newfs") {
+    /* Legacy `newfs` command, takes pool numbers instead of
+     * names, assumes fs name to be 'default', and can
+     * overwrite existing filesystem settings */
+    MDSMap newmap;
+    int64_t metadata, data;
+
+    if (!cmd_getval(g_ceph_context, cmdmap, "metadata", metadata)) {
+      ss << "error parsing 'metadata' value '"
+         << cmd_vartype_stringify(cmdmap["metadata"]) << "'";
+      r = -EINVAL;
+      return true;
+    }
+    if (!cmd_getval(g_ceph_context, cmdmap, "data", data)) {
+      ss << "error parsing 'data' value '"
+         << cmd_vartype_stringify(cmdmap["data"]) << "'";
+      r = -EINVAL;
+      return true;
+    }
+    // Check that the requested pools exist
+    const pg_pool_t *p = mon->osdmon()->osdmap.get_pg_pool(data);
+    if (!p) {
+      ss << "pool id '" << data << "' does not exist";
+      r = -ENOENT;
+      return true;
+    } else if (p->is_erasure()) {
+      const char *pn = mon->osdmon()->osdmap.get_pool_name(data);
+      assert(pn != NULL);
+      ss << "pool '" << pn << "' (id '" << data << "')"
+         << " is an erasure-code pool";
+      r = -EINVAL;
+      return true;
+    }
+
+    p = mon->osdmon()->osdmap.get_pg_pool(metadata);
+    if (!p) {
+      ss << "pool id '" << metadata << "' does not exist";
+      r = -ENOENT;
+      return true;
+    } else if (p->is_erasure()) {
+      const char *pn = mon->osdmon()->osdmap.get_pool_name(metadata);
+      assert(pn != NULL);
+      ss << "pool '" << pn << "' (id '" << metadata << "')"
+         << " is an erasure-code pool";
+      r = -EINVAL;
+      return true;
+    }
+
+    string sure;
+    cmd_getval(g_ceph_context, cmdmap, "sure", sure);
+    if (pending_mdsmap.enabled && sure != "--yes-i-really-mean-it") {
+      ss << "this is DANGEROUS and will wipe out the mdsmap's fs, and may clobber data in the new pools you specify.  add --yes-i-really-mean-it if you do.";
+      r = -EPERM;
+
+      return true;
+    } else {
+      newmap.inc = pending_mdsmap.inc;
+      pending_mdsmap = newmap;
+      pending_mdsmap.epoch = mdsmap.epoch + 1;
+      create_new_fs(pending_mdsmap, "default", metadata, data);
+      ss << "new fs with metadata pool " << metadata << " and data pool " << data;
+      r = 0;
+      return true;
+    }
+  } else if (prefix == "fs new") {
+    string metadata_name;
+    cmd_getval(g_ceph_context, cmdmap, "metadata", metadata_name);
+    int64_t metadata = mon->osdmon()->osdmap.lookup_pg_pool_name(metadata_name);
+    if (metadata < 0) {
+      r = -ENOENT;
+      ss << "pool '" << metadata_name << "' does not exist";
+      return true;
+    }
+
+    string data_name;
+    cmd_getval(g_ceph_context, cmdmap, "data", data_name);
+    int64_t data = mon->osdmon()->osdmap.lookup_pg_pool_name(data_name);
+    if (data < 0) {
+      r = -ENOENT;
+      ss << "pool '" << data_name << "' does not exist";
+      return true;
+    }
+
+    // Warn if crash_replay_interval is not set on the data pool
+    //  (on creation should have done pools[pool].crash_replay_interval =
+    //  cct->_conf->osd_default_data_pool_replay_window;)
+    pg_pool_t const *data_pool = mon->osdmon()->osdmap.get_pg_pool(data);
+    if (data_pool->get_crash_replay_interval() == 0) {
+      ss << "warning: crash_replay_interval not set on data pool '" << data << "', ";
+    }
+    
+    string fs_name;
+    cmd_getval(g_ceph_context, cmdmap, "fs_name", fs_name);
+    if (fs_name.empty()) {
+        // Ensure fs name is not empty so that we can implement
+        // commmands that refer to FS by name in future.
+        ss << "Filesystem name may not be empty";
+        return -EINVAL;
+    }
+
+    if (pending_mdsmap.enabled == true
+        && pending_mdsmap.fs_name == fs_name
+        && *(pending_mdsmap.data_pools.begin()) == data
+        && pending_mdsmap.metadata_pool == metadata) {
+      // Identical FS created already, this is a no-op
+      r = 0;
+      ss << "filesystem '" << fs_name << "' already exists";
+      return true;
+    }
+
+    if (pending_mdsmap.enabled) {
+      /* We currently only support one filesystem, so cannot create a second */
+      ss << "A filesystem already exists, use `ceph fs rm` if you wish to delete it";
+      r = -EINVAL;
+    }
+
+    // All checks passed, go ahead and create.
+    MDSMap newmap;
+    newmap.inc = pending_mdsmap.inc;
+    pending_mdsmap = newmap;
+    pending_mdsmap.epoch = mdsmap.epoch + 1;
+    create_new_fs(pending_mdsmap, fs_name, metadata, data);
+    ss << "new fs with metadata pool " << metadata << " and data pool " << data;
+    r = 0;
+    return true;
+  } else if (prefix == "fs rm") {
+    // Check caller has correctly named the FS to delete
+    // (redundant while there is only one FS, but command
+    //  syntax should apply to multi-FS future)
+    string fs_name;
+    cmd_getval(g_ceph_context, cmdmap, "fs_name", fs_name);
+    if (!pending_mdsmap.enabled || fs_name != pending_mdsmap.fs_name) {
+        // Consider absence success to make deletes idempotent
+        ss << "filesystem '" << fs_name << "' does not exist";
+        return 0;
+    }
+
+    // Check that no MDS daemons are active
+    if (!pending_mdsmap.up.empty()) {
+      ss << "all MDS daemons must be inactive before removing filesystem";
+      r = -EINVAL;
+      return true;
+    }
+
+    // Check for confirmation flag
+    string sure;
+    cmd_getval(g_ceph_context, cmdmap, "sure", sure);
+    if (sure != "--yes-i-really-mean-it") {
+      ss << "this is a DESTRUCTIVE operation and will make data in your filesystem permanently" \
+            "inaccessible.  Add --yes-i-really-mean-it if you are sure you wish to continue.";
+      r = -EPERM;
+      return true;
+    }
+
+    MDSMap newmap;
+    newmap.inc = pending_mdsmap.inc;
+    pending_mdsmap = newmap;
+    pending_mdsmap.epoch = mdsmap.epoch + 1;
+    assert(pending_mdsmap.enabled == false);
+    pending_mdsmap.metadata_pool = -1;
+    pending_mdsmap.cas_pool = -1;
+    pending_mdsmap.created = ceph_clock_now(g_ceph_context);
+
+    r = 0;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+
+/**
+ * Handle a command that affects the filesystem (i.e. a filesystem
+ * must exist for the command to act upon).
+ *
+ * @return true if the message is done with,
+ *         else false (if it was enqueued for retry)
+ */
+bool MDSMonitor::filesystem_command(
+    MMonCommand *m,
+    std::string const &prefix,
+    map<string, cmd_vartype> &cmdmap,
+    std::stringstream &ss,
+    int &r)
+{
   string whostr;
   cmd_getval(g_ceph_context, cmdmap, "who", whostr);
   if (prefix == "mds stop" ||
       prefix == "mds deactivate") {
     int who = parse_pos_long(whostr.c_str(), &ss);
-    if (who < 0)
-      goto out;
+    if (who < 0) {
+      return true;
+    }
     if (!pending_mdsmap.is_active(who)) {
       r = -EEXIST;
       ss << "mds." << who << " not active (" 
@@ -834,8 +1123,9 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
   } else if (prefix == "mds set_max_mds") {
     // NOTE: see also "mds set max_mds", which can modify the same field.
     int64_t maxmds;
-    if (!cmd_getval(g_ceph_context, cmdmap, "maxmds", maxmds) || maxmds < 0)
-      goto out;
+    if (!cmd_getval(g_ceph_context, cmdmap, "maxmds", maxmds) || maxmds < 0) {
+      return true;
+    }
     pending_mdsmap.max_mds = maxmds;
     r = 0;
     ss << "max_mds = " << pending_mdsmap.max_mds;
@@ -843,19 +1133,21 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
     string var;
     if (!cmd_getval(g_ceph_context, cmdmap, "var", var) || var.empty()) {
       ss << "Invalid variable";
-      goto out;
+      return true;
     }
     string val;
     string interr;
     int64_t n = 0;
-    if (!cmd_getval(g_ceph_context, cmdmap, "val", val))
-      goto out;
+    if (!cmd_getval(g_ceph_context, cmdmap, "val", val)) {
+      return true;
+    }
     // we got a string.  see if it contains an int.
     n = strict_strtoll(val.c_str(), 10, &interr);
     if (var == "max_mds") {
       // NOTE: see also "mds set_max_mds", which can modify the same field.
-      if (interr.length())
-       goto out;
+      if (interr.length()) {
+       return true;
+      }
       pending_mdsmap.max_mds = n;
     } else if (var == "inline_data") {
       if (val == "true" || val == "yes" || (!interr.length() && n == 1)) {
@@ -864,7 +1156,7 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
            confirm != "--yes-i-really-mean-it") {
          ss << "inline data is new and experimental; you must specify --yes-i-really-mean-it";
          r = -EPERM;
-         goto out;
+         return true;
        }
        ss << "inline data enabled";
        pending_mdsmap.set_inline_data_enabled(true);
@@ -876,17 +1168,17 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
       } else {
        ss << "value must be false|no|0 or true|yes|1";
        r = -EINVAL;
-       goto out;
+       return true;
       }
     } else if (var == "max_file_size") {
       if (interr.length()) {
        ss << var << " requires an integer value";
-       goto out;
+       return true;
       }
       if (n < CEPH_MIN_STRIPE_UNIT) {
        r = -ERANGE;
        ss << var << " must at least " << CEPH_MIN_STRIPE_UNIT;
-       goto out;
+       return true;
       }
       pending_mdsmap.max_file_size = n;
     } else if (var == "allow_new_snaps") {
@@ -899,18 +1191,18 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
            confirm != "--yes-i-really-mean-it") {
          ss << "Snapshots are unstable and will probably break your FS! Set to --yes-i-really-mean-it if you are sure you want to enable them";
          r = -EPERM;
-         goto out;
+         return true;
        }
        pending_mdsmap.set_snaps_allowed();
        ss << "enabled new snapshots";
       } else {
        ss << "value must be true|yes|1 or false|no|0";
        r = -EINVAL;
-       goto out;
+       return true;
       }
     } else {
       ss << "unknown variable " << var;
-      goto out;
+      return true;
     }
     r = 0;
   } else if (prefix == "mds setmap") {
@@ -924,9 +1216,8 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
     if (pending_mdsmap.epoch == e) {
       map.epoch = pending_mdsmap.epoch;  // make sure epoch is correct
       pending_mdsmap = map;
-      string rs = "set mds map";
-      wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs,
-                                               get_last_committed() + 1));
+      ss << "set mds map";
+      r = 0;
       return true;
     } else {
       ss << "next mdsmap epoch " << pending_mdsmap.epoch << " != " << e;
@@ -938,24 +1229,21 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
       ss << "error parsing 'gid' value '"
          << cmd_vartype_stringify(cmdmap["gid"]) << "'";
       r = -EINVAL;
-      goto out;
+      return true;
     }
     int64_t state;
     if (!cmd_getval(g_ceph_context, cmdmap, "state", state)) {
       ss << "error parsing 'state' string value '"
          << cmd_vartype_stringify(cmdmap["state"]) << "'";
       r = -EINVAL;
-      goto out;
+      return true;
     }
     if (!pending_mdsmap.is_dne_gid(gid)) {
       MDSMap::mds_info_t& info = pending_mdsmap.get_info_gid(gid);
       info.state = state;
       stringstream ss;
       ss << "set mds gid " << gid << " to state " << state << " " << ceph_mds_state_name(state);
-      string rs;
-      getline(ss, rs);
-      wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs,
-                                               get_last_committed() + 1));
+      r = 0;
       return true;
     }
 
@@ -974,7 +1262,7 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
       ss << "error parsing 'gid' value '"
          << cmd_vartype_stringify(cmdmap["gid"]) << "'";
       r = -EINVAL;
-      goto out;
+      return true;
     }
     int state = pending_mdsmap.get_state_gid(gid);
     if (state == 0) {
@@ -988,10 +1276,7 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
       pending_mdsmap.mds_info.erase(gid);
       stringstream ss;
       ss << "removed mds gid " << gid;
-      string rs;
-      getline(ss, rs);
-      wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs,
-                                               get_last_committed() + 1));
+      r = 0;
       return true;
     }
   } else if (prefix == "mds rmfailed") {
@@ -1000,15 +1285,12 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
       ss << "error parsing 'who' value '"
          << cmd_vartype_stringify(cmdmap["who"]) << "'";
       r = -EINVAL;
-      goto out;
+      return true;
     }
     pending_mdsmap.failed.erase(w);
     stringstream ss;
     ss << "removed failed mds." << w;
-    string rs;
-    getline(ss, rs);
-    wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs,
-                                             get_last_committed() + 1));
+    r = 0;
     return true;
   } else if (prefix == "mds cluster_down") {
     if (pending_mdsmap.test_flag(CEPH_MDSMAP_DOWN)) {
@@ -1032,7 +1314,7 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
       ss << "error parsing feature value '"
          << cmd_vartype_stringify(cmdmap["feature"]) << "'";
       r = -EINVAL;
-      goto out;
+      return true;
     }
     if (pending_mdsmap.compat.compat.contains(f)) {
       ss << "removing compat feature " << f;
@@ -1048,7 +1330,7 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
       ss << "error parsing feature value '"
          << cmd_vartype_stringify(cmdmap["feature"]) << "'";
       r = -EINVAL;
-      goto out;
+      return true;
     }
     if (pending_mdsmap.compat.incompat.contains(f)) {
       ss << "removing incompat feature " << f;
@@ -1113,92 +1395,11 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
       if (r == 0)
        ss << "removed data pool " << poolid << " from mdsmap";
     }
-  } else if (prefix == "mds newfs") {
-    MDSMap newmap;
-    int64_t metadata, data;
-    if (!cmd_getval(g_ceph_context, cmdmap, "metadata", metadata)) {
-      ss << "error parsing 'metadata' value '"
-         << cmd_vartype_stringify(cmdmap["metadata"]) << "'";
-      r = -EINVAL;
-      goto out;
-    }
-    if (!cmd_getval(g_ceph_context, cmdmap, "data", data)) {
-      ss << "error parsing 'data' value '"
-         << cmd_vartype_stringify(cmdmap["data"]) << "'";
-      r = -EINVAL;
-      goto out;
-    }
-
-    const pg_pool_t *p = mon->osdmon()->osdmap.get_pg_pool(data);
-    if (!p) {
-      ss << "pool id '" << data << "' does not exist";
-      r = -ENOENT;
-      goto out;
-    } else if (p->is_erasure()) {
-      const char *pn = mon->osdmon()->osdmap.get_pool_name(data);
-      assert(pn != NULL);
-      ss << "pool '" << pn << "' (id '" << data << "')"
-         << " is an erasure-code pool";
-      r = -EINVAL;
-      goto out;
-    }
-
-    p = mon->osdmon()->osdmap.get_pg_pool(metadata);
-    if (!p) {
-      ss << "pool id '" << metadata << "' does not exist";
-      r = -ENOENT;
-      goto out;
-    } else if (p->is_erasure()) {
-      const char *pn = mon->osdmon()->osdmap.get_pool_name(metadata);
-      assert(pn != NULL);
-      ss << "pool '" << pn << "' (id '" << metadata << "')"
-         << " is an erasure-code pool";
-      r = -EINVAL;
-      goto out;
-    }
-
-    // Warn if crash_replay_interval is not set on the data pool
-    //  (on creation should have done pools[pool].crash_replay_interval =
-    //  cct->_conf->osd_default_data_pool_replay_window;)
-    pg_pool_t const *data_pool = osdmon->osdmap.get_pg_pool(data);
-    if (data_pool->get_crash_replay_interval() == 0) {
-      ss << "warning: crash_replay_interval not set on data pool '" << data << "', ";
-    }
-    
-    string sure;
-    cmd_getval(g_ceph_context, cmdmap, "sure", sure);
-    if (pending_mdsmap.enabled && sure != "--yes-i-really-mean-it") {
-      ss << "this is DANGEROUS and will wipe out the mdsmap's fs, and may clobber data in the new pools you specify.  add --yes-i-really-mean-it if you do.";
-      r = -EPERM;
-    } else {
-      newmap.inc = pending_mdsmap.inc;
-      pending_mdsmap = newmap;
-      pending_mdsmap.epoch = mdsmap.epoch + 1;
-      create_new_fs(pending_mdsmap, metadata, data);
-      ss << "new fs with metadata pool " << metadata << " and data pool " << data;
-      string rs;
-      getline(ss, rs);
-      wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs,
-                                               get_last_committed() + 1));
-      return true;
-    }
   } else {
     ss << "unrecognized command";
   }
- out:
-  string rs;
-  getline(ss, rs);
 
-  if (r >= 0) {
-    // success.. delay reply
-    wait_for_finished_proposal(new Monitor::C_Command(mon, m, r, rs,
-                                             get_last_committed() + 1));
-    return true;
-  } else {
-    // reply immediately
-    mon->reply_command(m, r, rs, rdata, get_last_committed());
-    return false;
-  }
+  return true;
 }
 
 
index 901e93e379b7fe1c6dde618c0b5fd2bb1450fc31..fda64e1484cd8b4e44bc0fbf89980690e300cdfb 100644 (file)
@@ -63,7 +63,7 @@ class MDSMonitor : public PaxosService {
     }
   };
 
-  void create_new_fs(MDSMap &m, int metadata_pool, int data_pool);
+  void create_new_fs(MDSMap &m, const std::string &name, int metadata_pool, int data_pool);
 
   version_t get_trim_to();
 
@@ -99,6 +99,17 @@ class MDSMonitor : public PaxosService {
 
   bool preprocess_command(MMonCommand *m);
   bool prepare_command(MMonCommand *m);
+  bool management_command(
+      std::string const &prefix,
+      map<string, cmd_vartype> &cmdmap,
+      std::stringstream &ss,
+      int &r);
+  bool filesystem_command(
+      MMonCommand *m,
+      std::string const &prefix,
+      map<string, cmd_vartype> &cmdmap,
+      std::stringstream &ss,
+      int &r);
 
   // beacons
   struct beacon_info_t {
index 993589360ebd2de4884468c16b54e213cb3c04cc..67007692d051fb976cdaa7b057a5f694b751d2b9 100644 (file)
@@ -292,8 +292,22 @@ COMMAND("mds newfs " \
        "name=metadata,type=CephInt,range=0 " \
        "name=data,type=CephInt,range=0 " \
        "name=sure,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
-       "make new filesystom using pools <metadata> and <data>", \
+       "make new filesystem using pools <metadata> and <data>", \
        "mds", "rw", "cli,rest")
+COMMAND("fs new " \
+       "name=fs_name,type=CephString " \
+       "name=metadata,type=CephString " \
+       "name=data,type=CephString ", \
+       "make new filesystem using named pools <metadata> and <data>", \
+       "fs", "rw", "cli,rest")
+COMMAND("fs rm " \
+       "name=fs_name,type=CephString " \
+       "name=sure,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
+       "disable the named filesystem", \
+       "fs", "rw", "cli,rest")
+COMMAND("fs ls ", \
+       "list filesystems", \
+       "fs", "r", "cli,rest")
 /*
  * Monmap commands
  */
index 7767542218a63f9fe22abdc3391128599f6bf0a0..f983284eb8d232670acbd05bdd3cc9bac7b82fc7 100644 (file)
@@ -2316,7 +2316,7 @@ void Monitor::handle_command(MMonCommand *m)
     return;
   }
 
-  if (module == "mds") {
+  if (module == "mds" || module == "fs") {
     mdsmon()->dispatch(m);
     return;
   }