]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | lock("MDSUtility::lock"), | |
25 | finisher(g_ceph_context, "MDSUtility", "fn_mds_utility"), | |
26 | waiting_for_mds_map(NULL) | |
27 | { | |
28 | monc = new MonClient(g_ceph_context); | |
29 | messenger = Messenger::create_client_messenger(g_ceph_context, "mds"); | |
30 | fsmap = new FSMap(); | |
31 | objecter = new Objecter(g_ceph_context, messenger, monc, NULL, 0, 0); | |
32 | } | |
33 | ||
34 | ||
35 | MDSUtility::~MDSUtility() | |
36 | { | |
37 | delete objecter; | |
38 | delete monc; | |
39 | delete messenger; | |
40 | delete fsmap; | |
41 | assert(waiting_for_mds_map == NULL); | |
42 | } | |
43 | ||
44 | ||
45 | int MDSUtility::init() | |
46 | { | |
47 | // Initialize Messenger | |
48 | int r = messenger->bind(g_conf->public_addr); | |
49 | if (r < 0) | |
50 | return r; | |
51 | ||
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 | 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 | Mutex init_lock("MDSUtility:init"); | |
91 | Cond cond; | |
92 | bool done = false; | |
93 | 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 | init_lock.Lock(); | |
103 | while (!done) | |
104 | cond.Wait(init_lock); | |
105 | init_lock.Unlock(); | |
106 | dout(4) << "Got MDS map " << fsmap->get_epoch() << dendl; | |
107 | ||
108 | finisher.start(); | |
109 | ||
110 | return 0; | |
111 | } | |
112 | ||
113 | ||
114 | void MDSUtility::shutdown() | |
115 | { | |
116 | finisher.stop(); | |
117 | ||
118 | lock.Lock(); | |
119 | objecter->shutdown(); | |
120 | lock.Unlock(); | |
121 | monc->shutdown(); | |
122 | messenger->shutdown(); | |
123 | messenger->wait(); | |
124 | } | |
125 | ||
126 | ||
127 | bool MDSUtility::ms_dispatch(Message *m) | |
128 | { | |
129 | Mutex::Locker locker(lock); | |
130 | switch (m->get_type()) { | |
131 | case CEPH_MSG_FS_MAP: | |
132 | handle_fs_map((MFSMap*)m); | |
133 | break; | |
134 | case CEPH_MSG_OSD_MAP: | |
135 | break; | |
136 | default: | |
137 | return false; | |
138 | } | |
139 | m->put(); | |
140 | return true; | |
141 | } | |
142 | ||
143 | ||
144 | void MDSUtility::handle_fs_map(MFSMap* m) | |
145 | { | |
146 | *fsmap = m->get_fsmap(); | |
147 | if (waiting_for_mds_map) { | |
148 | waiting_for_mds_map->complete(0); | |
149 | waiting_for_mds_map = NULL; | |
150 | } | |
151 | } | |
152 | ||
153 | ||
154 | bool MDSUtility::ms_get_authorizer(int dest_type, AuthAuthorizer **authorizer, | |
155 | bool force_new) | |
156 | { | |
157 | if (dest_type == CEPH_ENTITY_TYPE_MON) | |
158 | return true; | |
159 | ||
160 | if (force_new) { | |
161 | if (monc->wait_auth_rotating(10) < 0) | |
162 | return false; | |
163 | } | |
164 | ||
165 | *authorizer = monc->build_authorizer(dest_type); | |
166 | return *authorizer != NULL; | |
167 | } |