Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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   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 }