]> git.proxmox.com Git - ceph.git/blame - ceph/src/ceph_mds.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / ceph_mds.cc
CommitLineData
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) 2004-2006 Sage Weil <sage@newdream.net>
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
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <fcntl.h>
18#include <pthread.h>
19
20#include <iostream>
21#include <string>
7c673cae 22
f67539c2 23#include "common/async/context_pool.h"
7c673cae
FG
24#include "include/ceph_features.h"
25#include "include/compat.h"
11fdf7f2 26#include "include/random.h"
7c673cae
FG
27
28#include "common/config.h"
29#include "common/strtol.h"
9f95a23c 30#include "common/numa.h"
7c673cae
FG
31
32#include "mon/MonMap.h"
33#include "mds/MDSDaemon.h"
34
35#include "msg/Messenger.h"
36
37#include "common/Timer.h"
38#include "common/ceph_argparse.h"
39#include "common/pick_address.h"
11fdf7f2 40#include "common/Preforker.h"
7c673cae
FG
41
42#include "global/global_init.h"
43#include "global/signal_handler.h"
44#include "global/pidfile.h"
45
46#include "mon/MonClient.h"
47
48#include "auth/KeyRing.h"
49
50#include "perfglue/heap_profiler.h"
51
11fdf7f2 52#include "include/ceph_assert.h"
7c673cae
FG
53
54#define dout_context g_ceph_context
55#define dout_subsys ceph_subsys_mds
56
20effc67
TL
57using std::cerr;
58using std::cout;
59using std::vector;
60
7c673cae
FG
61static void usage()
62{
11fdf7f2 63 cout << "usage: ceph-mds -i <ID> [flags]\n"
7c673cae
FG
64 << " -m monitorip:port\n"
65 << " connect to monitor at given address\n"
66 << " --debug_mds n\n"
67 << " debug MDS level (e.g. 10)\n"
7c673cae
FG
68 << std::endl;
69 generic_server_usage();
70}
71
72
7c673cae
FG
73MDSDaemon *mds = NULL;
74
75
76static void handle_mds_signal(int signum)
77{
78 if (mds)
79 mds->handle_signal(signum);
80}
81
7c673cae 82int main(int argc, const char **argv)
7c673cae
FG
83{
84 ceph_pthread_setname(pthread_self(), "ceph-mds");
85
20effc67 86 auto args = argv_to_vec(argc, argv);
11fdf7f2
TL
87 if (args.empty()) {
88 cerr << argv[0] << ": -h or --help for usage" << std::endl;
89 exit(1);
90 }
91 if (ceph_argparse_need_usage(args)) {
92 usage();
93 exit(0);
94 }
7c673cae
FG
95
96 auto cct = global_init(NULL, args,
f67539c2 97 CEPH_ENTITY_TYPE_MDS, CODE_ENVIRONMENT_DAEMON, 0);
7c673cae
FG
98 ceph_heap_profiler_init();
99
9f95a23c
TL
100 int numa_node = g_conf().get_val<int64_t>("mds_numa_node");
101 size_t numa_cpu_set_size = 0;
102 cpu_set_t numa_cpu_set;
103 if (numa_node >= 0) {
104 int r = get_numa_node_cpu_set(numa_node, &numa_cpu_set_size, &numa_cpu_set);
105 if (r < 0) {
106 dout(1) << __func__ << " unable to determine mds numa node " << numa_node
107 << " CPUs" << dendl;
108 numa_node = -1;
109 } else {
110 r = set_cpu_affinity_all_threads(numa_cpu_set_size, &numa_cpu_set);
111 if (r < 0) {
112 derr << __func__ << " failed to set numa affinity: " << cpp_strerror(r)
113 << dendl;
114 }
115 }
116 } else {
117 dout(1) << __func__ << " not setting numa affinity" << dendl;
118 }
7c673cae
FG
119 std::string val, action;
120 for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
121 if (ceph_argparse_double_dash(args, i)) {
122 break;
123 }
7c673cae 124 else if (ceph_argparse_witharg(args, i, &val, "--hot-standby", (char*)NULL)) {
11fdf7f2 125 dout(0) << "--hot-standby is obsolete and has no effect" << dendl;
7c673cae
FG
126 }
127 else {
128 derr << "Error: can't understand argument: " << *i << "\n" << dendl;
11fdf7f2 129 exit(1);
7c673cae
FG
130 }
131 }
132
11fdf7f2
TL
133 Preforker forker;
134
135 entity_addrvec_t addrs;
136 pick_addresses(g_ceph_context, CEPH_PICK_ADDRESS_PUBLIC, &addrs);
7c673cae
FG
137
138 // Normal startup
11fdf7f2 139 if (g_conf()->name.has_default_id()) {
7c673cae 140 derr << "must specify '-i name' with the ceph-mds instance name" << dendl;
11fdf7f2 141 exit(1);
7c673cae
FG
142 }
143
11fdf7f2
TL
144 if (g_conf()->name.get_id().empty() ||
145 (g_conf()->name.get_id()[0] >= '0' && g_conf()->name.get_id()[0] <= '9')) {
146 derr << "MDS id '" << g_conf()->name << "' is invalid. "
7c673cae 147 "MDS names may not start with a numeric digit." << dendl;
11fdf7f2
TL
148 exit(1);
149 }
150
151 if (global_init_prefork(g_ceph_context) >= 0) {
152 std::string err;
153 int r = forker.prefork(err);
154 if (r < 0) {
155 cerr << err << std::endl;
156 return r;
157 }
158 if (forker.is_parent()) {
159 if (forker.parent_wait(err) != 0) {
160 return -ENXIO;
161 }
162 return 0;
163 }
164 global_init_postfork_start(g_ceph_context);
7c673cae 165 }
11fdf7f2
TL
166 common_init_finish(g_ceph_context);
167 global_init_chdir(g_ceph_context);
7c673cae 168
11fdf7f2 169 std::string public_msgr_type = g_conf()->ms_public_type.empty() ? g_conf().get_val<std::string>("ms_type") : g_conf()->ms_public_type;
7c673cae
FG
170 Messenger *msgr = Messenger::create(g_ceph_context, public_msgr_type,
171 entity_name_t::MDS(-1), "mds",
f67539c2 172 Messenger::get_random_nonce());
7c673cae 173 if (!msgr)
11fdf7f2 174 forker.exit(1);
7c673cae
FG
175 msgr->set_cluster_protocol(CEPH_MDS_PROTOCOL);
176
11fdf7f2 177 cout << "starting " << g_conf()->name << " at " << msgr->get_myaddrs()
7c673cae
FG
178 << std::endl;
179 uint64_t required =
180 CEPH_FEATURE_OSDREPLYMUX;
181
182 msgr->set_default_policy(Messenger::Policy::lossy_client(required));
183 msgr->set_policy(entity_name_t::TYPE_MON,
184 Messenger::Policy::lossy_client(CEPH_FEATURE_UID |
185 CEPH_FEATURE_PGID64));
186 msgr->set_policy(entity_name_t::TYPE_MDS,
187 Messenger::Policy::lossless_peer(CEPH_FEATURE_UID));
188 msgr->set_policy(entity_name_t::TYPE_CLIENT,
189 Messenger::Policy::stateful_server(0));
190
11fdf7f2 191 int r = msgr->bindv(addrs);
7c673cae 192 if (r < 0)
11fdf7f2 193 forker.exit(1);
7c673cae 194
11fdf7f2
TL
195 // set up signal handlers, now that we've daemonized/forked.
196 init_async_signal_handler();
197 register_async_signal_handler(SIGHUP, sighup_handler);
198
7c673cae 199 // get monmap
f67539c2
TL
200 ceph::async::io_context_pool ctxpool(2);
201 MonClient mc(g_ceph_context, ctxpool);
7c673cae 202 if (mc.build_initial_monmap() < 0)
11fdf7f2 203 forker.exit(1);
7c673cae
FG
204 global_init_chdir(g_ceph_context);
205
206 msgr->start();
207
208 // start mds
f67539c2 209 mds = new MDSDaemon(g_conf()->name.get_id().c_str(), msgr, &mc, ctxpool);
7c673cae
FG
210
211 // in case we have to respawn...
212 mds->orig_argc = argc;
213 mds->orig_argv = argv;
214
11fdf7f2
TL
215 if (g_conf()->daemonize) {
216 global_init_postfork_finish(g_ceph_context);
217 forker.daemonize();
218 }
219
7c673cae
FG
220 r = mds->init();
221 if (r < 0) {
222 msgr->wait();
223 goto shutdown;
224 }
225
7c673cae
FG
226 register_async_signal_handler_oneshot(SIGINT, handle_mds_signal);
227 register_async_signal_handler_oneshot(SIGTERM, handle_mds_signal);
228
11fdf7f2 229 if (g_conf()->inject_early_sigterm)
7c673cae
FG
230 kill(getpid(), SIGTERM);
231
232 msgr->wait();
233
234 unregister_async_signal_handler(SIGHUP, sighup_handler);
235 unregister_async_signal_handler(SIGINT, handle_mds_signal);
236 unregister_async_signal_handler(SIGTERM, handle_mds_signal);
237 shutdown_async_signal_handler();
238
239 shutdown:
f67539c2 240 ctxpool.stop();
7c673cae
FG
241 // yuck: grab the mds lock, so we can be sure that whoever in *mds
242 // called shutdown finishes what they were doing.
9f95a23c
TL
243 mds->mds_lock.lock();
244 mds->mds_lock.unlock();
7c673cae
FG
245
246 pidfile_remove();
247
248 // only delete if it was a clean shutdown (to aid memory leak
249 // detection, etc.). don't bother if it was a suicide.
250 if (mds->is_clean_shutdown()) {
251 delete mds;
252 delete msgr;
253 }
254
255 // cd on exit, so that gmon.out (if any) goes into a separate directory for each node.
256 char s[20];
257 snprintf(s, sizeof(s), "gmon/%d", getpid());
258 if ((mkdir(s, 0755) == 0) && (chdir(s) == 0)) {
259 cerr << "ceph-mds: gmon.out should be in " << s << std::endl;
260 }
261
262 return 0;
263}