]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: mount non-default filesystem by name
authorYan, Zheng <zyan@redhat.com>
Wed, 6 Apr 2016 13:11:46 +0000 (21:11 +0800)
committerYan, Zheng <zyan@redhat.com>
Fri, 10 Jun 2016 01:30:20 +0000 (09:30 +0800)
To mount non-default filesytem, user needs to provide mds namespace ID.
This is inconvenience.

This patch makes user be able to mount filesystem by name. To do this,
client first subscribes to FSMapUser. Subscribe to mdsmap.<ID> after
knowning ID of the filesystem.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/client/Client.cc
src/client/Client.h
src/common/config_opts.h

index c632f12683c061f832d586ee6f8fc8eb3b2b49a5..66794b70270117af22b0f28f53103f624dc2a07e 100644 (file)
@@ -59,6 +59,7 @@
 #include "messages/MClientCapRelease.h"
 #include "messages/MMDSMap.h"
 #include "messages/MFSMap.h"
+#include "messages/MFSMapUser.h"
 
 #include "mon/MonClient.h"
 
@@ -244,7 +245,7 @@ Client::Client(Messenger *m, MonClient *mc)
     objecter_finisher(m->cct),
     tick_event(NULL),
     monclient(mc), messenger(m), whoami(m->get_myname().num()),
-    cap_epoch_barrier(0), fsmap(nullptr),
+    cap_epoch_barrier(0), fsmap(nullptr), fsmap_user(nullptr),
     last_tid(0), oldest_tid(0), last_flush_tid(1),
     initialized(false), authenticated(false),
     mounted(false), unmounting(false),
@@ -489,18 +490,6 @@ int Client::init()
 
   monclient->set_want_keys(CEPH_ENTITY_TYPE_MDS | CEPH_ENTITY_TYPE_OSD);
 
-  std::string want = "mdsmap";
-  const auto &want_ns = cct->_conf->client_mds_namespace;
-  if (want_ns != FS_CLUSTER_ID_NONE) {
-    std::ostringstream oss;
-    oss << want << "." << want_ns;
-    want = oss.str();
-  }
-  ldout(cct, 10) << "Subscribing to map '" << want << "'" << dendl;
-
-  monclient->sub_want(want, 0, 0);
-  monclient->renew_subs();
-
   // logger
   PerfCountersBuilder plb(cct, "client", l_c_first, l_c_last);
   plb.add_time_avg(l_c_reply, "reply", "Latency of receiving a reply on metadata request");
@@ -2378,6 +2367,9 @@ bool Client::ms_dispatch(Message *m)
   case CEPH_MSG_FS_MAP:
     handle_fs_map(static_cast<MFSMap*>(m));
     break;
+  case CEPH_MSG_FS_MAP_USER:
+    handle_fs_map_user(static_cast<MFSMapUser*>(m));
+    break;
   case CEPH_MSG_CLIENT_SESSION:
     handle_client_session(static_cast<MClientSession*>(m));
     break;
@@ -2448,6 +2440,17 @@ void Client::handle_fs_map(MFSMap *m)
   monclient->sub_got("fsmap", fsmap->get_epoch());
 }
 
+void Client::handle_fs_map_user(MFSMapUser *m)
+{
+  delete fsmap_user;
+  fsmap_user = new FSMapUser;
+  *fsmap_user = m->get_fsmap();
+  m->put();
+
+  monclient->sub_got("fsmap.user", fsmap_user->get_epoch());
+  signal_cond_list(waiting_for_fsmap);
+}
+
 void Client::handle_mds_map(MMDSMap* m)
 {
   if (m->get_epoch() < mdsmap->get_epoch()) {
@@ -5292,6 +5295,49 @@ int Client::authenticate()
   return 0;
 }
 
+int Client::fetch_fsmap(bool user)
+{
+  int r;
+  // Retrieve FSMap to enable looking up daemon addresses.  We need FSMap
+  // rather than MDSMap because no one MDSMap contains all the daemons, and
+  // a `tell` can address any daemon.
+  version_t fsmap_latest;
+  do {
+    C_SaferCond cond;
+    monclient->get_version("fsmap", &fsmap_latest, NULL, &cond);
+    client_lock.Unlock();
+    r = cond.wait();
+    client_lock.Lock();
+  } while (r == -EAGAIN);
+
+  if (r < 0) {
+    lderr(cct) << "Failed to learn FSMap version: " << cpp_strerror(r) << dendl;
+    return r;
+  }
+
+  ldout(cct, 10) << __func__ << " learned FSMap version " << fsmap_latest << dendl;
+
+  if (user) {
+    if (fsmap_user == nullptr || fsmap_user->get_epoch() < fsmap_latest) {
+      monclient->sub_want("fsmap.user", fsmap_latest, CEPH_SUBSCRIBE_ONETIME);
+      monclient->renew_subs();
+      wait_on_list(waiting_for_fsmap);
+    }
+    assert(fsmap_user != nullptr);
+    assert(fsmap_user->get_epoch() >= fsmap_latest);
+  } else {
+    if (fsmap == nullptr || fsmap->get_epoch() < fsmap_latest) {
+      monclient->sub_want("fsmap", fsmap_latest, CEPH_SUBSCRIBE_ONETIME);
+      monclient->renew_subs();
+      wait_on_list(waiting_for_fsmap);
+    }
+    assert(fsmap != nullptr);
+    assert(fsmap->get_epoch() >= fsmap_latest);
+  }
+  ldout(cct, 10) << __func__ << " finished waiting for FSMap version "
+                << fsmap_latest << dendl;
+  return 0;
+}
 
 /**
  *
@@ -5316,34 +5362,11 @@ int Client::mds_command(
     return r;
   }
 
-  // Retrieve FSMap to enable looking up daemon addresses.  We need FSMap
-  // rather than MDSMap because no one MDSMap contains all the daemons, and
-  // a `tell` can address any daemon.
-  version_t fsmap_latest;
-  do {
-    C_SaferCond cond;
-    monclient->get_version("fsmap", &fsmap_latest, NULL, &cond);
-    client_lock.Unlock();
-    r = cond.wait();
-    client_lock.Lock();
-  } while (r == -EAGAIN);
-  ldout(cct, 20) << "Learned FSMap version " << fsmap_latest << dendl;
-
+  r = fetch_fsmap(false);
   if (r < 0) {
-    lderr(cct) << "Failed to learn FSMap version: " << cpp_strerror(r) << dendl;
     return r;
   }
 
-  if (fsmap == nullptr || fsmap->get_epoch() < fsmap_latest) {
-    monclient->sub_want("fsmap", fsmap_latest, CEPH_SUBSCRIBE_ONETIME);
-    monclient->renew_subs();
-    wait_on_list(waiting_for_fsmap);
-  }
-  assert(fsmap != nullptr);
-  assert(fsmap->get_epoch() >= fsmap_latest);
-  ldout(cct, 20) << "Finished waiting for FSMap version " << fsmap_latest
-    << dendl;
-
   // Look up MDS target(s) of the command
   std::vector<mds_gid_t> targets;
   r = resolve_mds(mds_spec, &targets);
@@ -5445,9 +5468,27 @@ int Client::mount(const std::string &mount_root, bool require_mds)
     return r;
   }
 
+  std::string want = "mdsmap";
+  const auto &mds_ns = cct->_conf->client_mds_namespace;
+  if (!mds_ns.empty()) {
+    r = fetch_fsmap(true);
+    if (r < 0)
+      return r;
+    fs_cluster_id_t cid = fsmap_user->get_fs_cid(mds_ns);
+    if (cid == FS_CLUSTER_ID_NONE)
+      return -ENOENT;
+
+    std::ostringstream oss;
+    oss << want << "." << cid;
+    want = oss.str();
+  }
+  ldout(cct, 10) << "Subscribing to map '" << want << "'" << dendl;
+
+  monclient->sub_want(want, 0, 0);
+  monclient->renew_subs();
+
   tick(); // start tick
   
-  ldout(cct, 2) << "mounted: have mdsmap " << mdsmap->get_epoch() << dendl;
   if (require_mds) {
     while (1) {
       auto availability = mdsmap->is_cluster_available();
index da604f546e89467d682a87ead2c0a5446cd1cc82..9a41b909e16eff4b8a0b28b06ef1e85359b3e2ee 100644 (file)
@@ -49,6 +49,7 @@ using std::fstream;
 #include "UserGroups.h"
 
 class FSMap;
+class FSMapUser;
 class MonClient;
 
 class CephContext;
@@ -289,10 +290,12 @@ protected:
   // FSMap, for when using mds_command
   list<Cond*> waiting_for_fsmap;
   FSMap *fsmap;
+  FSMapUser *fsmap_user;
 
   // MDS command state
   std::map<ceph_tid_t, CommandOp> commands;
   void handle_command_reply(MCommandReply *m);
+  int fetch_fsmap(bool user);
   int resolve_mds(
       const std::string &mds_spec,
       std::vector<mds_gid_t> *targets);
@@ -569,6 +572,7 @@ protected:
   // messaging
   void handle_mds_map(class MMDSMap *m);
   void handle_fs_map(class MFSMap *m);
+  void handle_fs_map_user(class MFSMapUser *m);
   void handle_osd_map(class MOSDMap *m);
 
   void handle_lease(MClientLease *m);
index fe8353d84665060144288f04ef5f0c418e46ea97..6c1d86d25462e0f112c46ef5682c539608c5c91a 100644 (file)
@@ -416,7 +416,7 @@ OPTION(client_try_dentry_invalidate, OPT_BOOL, true) // the client should try to
 OPTION(client_die_on_failed_remount, OPT_BOOL, true)
 OPTION(client_check_pool_perm, OPT_BOOL, true)
 OPTION(client_use_faked_inos, OPT_BOOL, false)
-OPTION(client_mds_namespace, OPT_INT, -1)
+OPTION(client_mds_namespace, OPT_STR, "")
 
 OPTION(crush_location, OPT_STR, "")       // whitespace-separated list of key=value pairs describing crush location
 OPTION(crush_location_hook, OPT_STR, "")