]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/cephfs/MDSUtility.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / tools / cephfs / MDSUtility.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2014 John Spray <john.spray@inktank.com>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 */
13
14 #include "MDSUtility.h"
15 #include "mon/MonClient.h"
16
17 #define dout_context g_ceph_context
18 #define dout_subsys ceph_subsys_mds
19
20
21 MDSUtility::MDSUtility() :
22 Dispatcher(g_ceph_context),
23 objecter(NULL),
24 finisher(g_ceph_context, "MDSUtility", "fn_mds_utility"),
25 waiting_for_mds_map(NULL),
26 inited(false)
27 {
28 monc = new MonClient(g_ceph_context, poolctx);
29 messenger = Messenger::create_client_messenger(g_ceph_context, "mds");
30 fsmap = new FSMap();
31 objecter = new Objecter(g_ceph_context, messenger, monc, poolctx);
32 }
33
34
35 MDSUtility::~MDSUtility()
36 {
37 if (inited) {
38 shutdown();
39 }
40 delete objecter;
41 delete monc;
42 delete messenger;
43 delete fsmap;
44 ceph_assert(waiting_for_mds_map == NULL);
45 }
46
47
48 int MDSUtility::init()
49 {
50 // Initialize Messenger
51 poolctx.start(1);
52 messenger->start();
53
54 objecter->set_client_incarnation(0);
55 objecter->init();
56
57 // Connect dispatchers before starting objecter
58 messenger->add_dispatcher_tail(objecter);
59 messenger->add_dispatcher_tail(this);
60
61 // Initialize MonClient
62 if (monc->build_initial_monmap() < 0) {
63 objecter->shutdown();
64 messenger->shutdown();
65 messenger->wait();
66 return -1;
67 }
68
69 monc->set_want_keys(CEPH_ENTITY_TYPE_MON|CEPH_ENTITY_TYPE_OSD|CEPH_ENTITY_TYPE_MDS);
70 monc->set_messenger(messenger);
71 monc->init();
72 int r = monc->authenticate();
73 if (r < 0) {
74 derr << "Authentication failed, did you specify an MDS ID with a valid keyring?" << dendl;
75 monc->shutdown();
76 objecter->shutdown();
77 messenger->shutdown();
78 messenger->wait();
79 return r;
80 }
81
82 client_t whoami = monc->get_global_id();
83 messenger->set_myname(entity_name_t::CLIENT(whoami.v));
84
85 // Start Objecter and wait for OSD map
86 objecter->start();
87 objecter->wait_for_osd_map();
88
89 // Prepare to receive MDS map and request it
90 ceph::mutex init_lock = ceph::make_mutex("MDSUtility:init");
91 ceph::condition_variable cond;
92 bool done = false;
93 ceph_assert(!fsmap->get_epoch());
94 lock.lock();
95 waiting_for_mds_map = new C_SafeCond(init_lock, cond, &done, NULL);
96 lock.unlock();
97 monc->sub_want("fsmap", 0, CEPH_SUBSCRIBE_ONETIME);
98 monc->renew_subs();
99
100 // Wait for MDS map
101 dout(4) << "waiting for MDS map..." << dendl;
102 {
103 std::unique_lock locker{init_lock};
104 cond.wait(locker, [&done] { return done; });
105 }
106 dout(4) << "Got MDS map " << fsmap->get_epoch() << dendl;
107
108 finisher.start();
109
110 inited = true;
111 return 0;
112 }
113
114
115 void MDSUtility::shutdown()
116 {
117 finisher.stop();
118
119 lock.lock();
120 objecter->shutdown();
121 lock.unlock();
122 monc->shutdown();
123 messenger->shutdown();
124 messenger->wait();
125 poolctx.finish();
126 }
127
128
129 bool MDSUtility::ms_dispatch(Message *m)
130 {
131 std::lock_guard locker{lock};
132 switch (m->get_type()) {
133 case CEPH_MSG_FS_MAP:
134 handle_fs_map((MFSMap*)m);
135 break;
136 case CEPH_MSG_OSD_MAP:
137 break;
138 default:
139 return false;
140 }
141 m->put();
142 return true;
143 }
144
145
146 void MDSUtility::handle_fs_map(MFSMap* m)
147 {
148 *fsmap = m->get_fsmap();
149 if (waiting_for_mds_map) {
150 waiting_for_mds_map->complete(0);
151 waiting_for_mds_map = NULL;
152 }
153 }
154
155