]> git.proxmox.com Git - ceph.git/blob - ceph/src/ceph_osd.cc
update sources to 12.2.8
[ceph.git] / ceph / src / ceph_osd.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) 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 <boost/scoped_ptr.hpp>
19
20 #include <iostream>
21 #include <string>
22 using namespace std;
23
24 #include "osd/OSD.h"
25 #include "os/ObjectStore.h"
26 #include "mon/MonClient.h"
27 #include "include/ceph_features.h"
28
29 #include "common/config.h"
30
31 #include "mon/MonMap.h"
32
33 #include "msg/Messenger.h"
34
35 #include "common/Timer.h"
36 #include "common/TracepointProvider.h"
37 #include "common/ceph_argparse.h"
38
39 #include "global/global_init.h"
40 #include "global/signal_handler.h"
41
42 #include "include/color.h"
43 #include "common/errno.h"
44 #include "common/pick_address.h"
45
46 #include "perfglue/heap_profiler.h"
47
48 #include "include/assert.h"
49
50 #define dout_context g_ceph_context
51 #define dout_subsys ceph_subsys_osd
52
53 namespace {
54
55 TracepointProvider::Traits osd_tracepoint_traits("libosd_tp.so",
56 "osd_tracing");
57 TracepointProvider::Traits os_tracepoint_traits("libos_tp.so",
58 "osd_objectstore_tracing");
59 #ifdef WITH_OSD_INSTRUMENT_FUNCTIONS
60 TracepointProvider::Traits cyg_profile_traits("libcyg_profile_tp.so",
61 "osd_function_tracing");
62 #endif
63
64 } // anonymous namespace
65
66 OSD *osd = NULL;
67
68 void handle_osd_signal(int signum)
69 {
70 if (osd)
71 osd->handle_signal(signum);
72 }
73
74 static void usage()
75 {
76 cout << "usage: ceph-osd -i <ID> [flags]\n"
77 << " --osd-data PATH data directory\n"
78 << " --osd-journal PATH\n"
79 << " journal file or block device\n"
80 << " --mkfs create a [new] data directory\n"
81 << " --mkkey generate a new secret key. This is normally used in combination with --mkfs\n"
82 << " --convert-filestore\n"
83 << " run any pending upgrade operations\n"
84 << " --flush-journal flush all data out of journal\n"
85 << " --mkjournal initialize a new journal\n"
86 << " --check-wants-journal\n"
87 << " check whether a journal is desired\n"
88 << " --check-allows-journal\n"
89 << " check whether a journal is allowed\n"
90 << " --check-needs-journal\n"
91 << " check whether a journal is required\n"
92 << " --debug_osd <N> set debug level (e.g. 10)\n"
93 << " --get-device-fsid PATH\n"
94 << " get OSD fsid for the given block device\n"
95 << std::endl;
96 generic_server_usage();
97 }
98
99 int main(int argc, const char **argv)
100 {
101 vector<const char*> args;
102 argv_to_vec(argc, argv, args);
103 env_to_vec(args);
104
105 vector<const char*> def_args;
106 // We want to enable leveldb's log, while allowing users to override this
107 // option, therefore we will pass it as a default argument to global_init().
108 def_args.push_back("--leveldb-log=");
109
110 auto cct = global_init(&def_args, args, CEPH_ENTITY_TYPE_OSD,
111 CODE_ENVIRONMENT_DAEMON,
112 0, "osd_data");
113 ceph_heap_profiler_init();
114
115 // osd specific args
116 bool mkfs = false;
117 bool mkjournal = false;
118 bool check_wants_journal = false;
119 bool check_allows_journal = false;
120 bool check_needs_journal = false;
121 bool mkkey = false;
122 bool flushjournal = false;
123 bool dump_journal = false;
124 bool convertfilestore = false;
125 bool get_osd_fsid = false;
126 bool get_cluster_fsid = false;
127 bool get_journal_fsid = false;
128 bool get_device_fsid = false;
129 string device_path;
130 std::string dump_pg_log;
131
132 std::string val;
133 for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
134 if (ceph_argparse_double_dash(args, i)) {
135 break;
136 } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
137 usage();
138 } else if (ceph_argparse_flag(args, i, "--mkfs", (char*)NULL)) {
139 mkfs = true;
140 } else if (ceph_argparse_flag(args, i, "--mkjournal", (char*)NULL)) {
141 mkjournal = true;
142 } else if (ceph_argparse_flag(args, i, "--check-allows-journal", (char*)NULL)) {
143 check_allows_journal = true;
144 } else if (ceph_argparse_flag(args, i, "--check-wants-journal", (char*)NULL)) {
145 check_wants_journal = true;
146 } else if (ceph_argparse_flag(args, i, "--check-needs-journal", (char*)NULL)) {
147 check_needs_journal = true;
148 } else if (ceph_argparse_flag(args, i, "--mkkey", (char*)NULL)) {
149 mkkey = true;
150 } else if (ceph_argparse_flag(args, i, "--flush-journal", (char*)NULL)) {
151 flushjournal = true;
152 } else if (ceph_argparse_flag(args, i, "--convert-filestore", (char*)NULL)) {
153 convertfilestore = true;
154 } else if (ceph_argparse_witharg(args, i, &val, "--dump-pg-log", (char*)NULL)) {
155 dump_pg_log = val;
156 } else if (ceph_argparse_flag(args, i, "--dump-journal", (char*)NULL)) {
157 dump_journal = true;
158 } else if (ceph_argparse_flag(args, i, "--get-cluster-fsid", (char*)NULL)) {
159 get_cluster_fsid = true;
160 } else if (ceph_argparse_flag(args, i, "--get-osd-fsid", "--get-osd-uuid", (char*)NULL)) {
161 get_osd_fsid = true;
162 } else if (ceph_argparse_flag(args, i, "--get-journal-fsid", "--get-journal-uuid", (char*)NULL)) {
163 get_journal_fsid = true;
164 } else if (ceph_argparse_witharg(args, i, &device_path,
165 "--get-device-fsid", (char*)NULL)) {
166 get_device_fsid = true;
167 } else {
168 ++i;
169 }
170 }
171 if (!args.empty()) {
172 derr << "unrecognized arg " << args[0] << dendl;
173 usage();
174 }
175
176 if (get_journal_fsid) {
177 device_path = g_conf->osd_journal;
178 get_device_fsid = true;
179 }
180 if (get_device_fsid) {
181 uuid_d uuid;
182 int r = ObjectStore::probe_block_device_fsid(g_ceph_context, device_path,
183 &uuid);
184 if (r < 0) {
185 cerr << "failed to get device fsid for " << device_path
186 << ": " << cpp_strerror(r) << std::endl;
187 exit(1);
188 }
189 cout << uuid << std::endl;
190 return 0;
191 }
192
193 if (!dump_pg_log.empty()) {
194 common_init_finish(g_ceph_context);
195 bufferlist bl;
196 std::string error;
197 int r = bl.read_file(dump_pg_log.c_str(), &error);
198 if (r >= 0) {
199 pg_log_entry_t e;
200 bufferlist::iterator p = bl.begin();
201 while (!p.end()) {
202 uint64_t pos = p.get_off();
203 try {
204 ::decode(e, p);
205 }
206 catch (const buffer::error &e) {
207 derr << "failed to decode LogEntry at offset " << pos << dendl;
208 return 1;
209 }
210 derr << pos << ":\t" << e << dendl;
211 }
212 } else {
213 derr << "unable to open " << dump_pg_log << ": " << error << dendl;
214 }
215 return 0;
216 }
217
218 // whoami
219 char *end;
220 const char *id = g_conf->name.get_id().c_str();
221 int whoami = strtol(id, &end, 10);
222 if (*end || end == id || whoami < 0) {
223 derr << "must specify '-i #' where # is the osd number" << dendl;
224 usage();
225 }
226
227 if (g_conf->osd_data.empty()) {
228 derr << "must specify '--osd-data=foo' data path" << dendl;
229 usage();
230 }
231
232 // the store
233 string store_type = g_conf->osd_objectstore;
234 {
235 char fn[PATH_MAX];
236 snprintf(fn, sizeof(fn), "%s/type", g_conf->osd_data.c_str());
237 int fd = ::open(fn, O_RDONLY);
238 if (fd >= 0) {
239 bufferlist bl;
240 bl.read_fd(fd, 64);
241 if (bl.length()) {
242 store_type = string(bl.c_str(), bl.length() - 1); // drop \n
243 g_conf->set_val("osd_objectstore", store_type);
244 dout(5) << "object store type is " << store_type << dendl;
245 }
246 ::close(fd);
247 }
248 }
249 ObjectStore *store = ObjectStore::create(g_ceph_context,
250 store_type,
251 g_conf->osd_data,
252 g_conf->osd_journal,
253 g_conf->osd_os_flags);
254 if (!store) {
255 derr << "unable to create object store" << dendl;
256 return -ENODEV;
257 }
258
259
260 if (mkkey) {
261 common_init_finish(g_ceph_context);
262 KeyRing *keyring = KeyRing::create_empty();
263 if (!keyring) {
264 derr << "Unable to get a Ceph keyring." << dendl;
265 return 1;
266 }
267
268 EntityName ename(g_conf->name);
269 EntityAuth eauth;
270
271 int ret = keyring->load(g_ceph_context, g_conf->keyring);
272 if (ret == 0 &&
273 keyring->get_auth(ename, eauth)) {
274 derr << "already have key in keyring " << g_conf->keyring << dendl;
275 } else {
276 eauth.key.create(g_ceph_context, CEPH_CRYPTO_AES);
277 keyring->add(ename, eauth);
278 bufferlist bl;
279 keyring->encode_plaintext(bl);
280 int r = bl.write_file(g_conf->keyring.c_str(), 0600);
281 if (r)
282 derr << TEXT_RED << " ** ERROR: writing new keyring to " << g_conf->keyring
283 << ": " << cpp_strerror(r) << TEXT_NORMAL << dendl;
284 else
285 derr << "created new key in keyring " << g_conf->keyring << dendl;
286 }
287 }
288 if (mkfs) {
289 common_init_finish(g_ceph_context);
290 MonClient mc(g_ceph_context);
291 if (mc.build_initial_monmap() < 0)
292 return -1;
293 if (mc.get_monmap_privately() < 0)
294 return -1;
295
296 if (mc.monmap.fsid.is_zero()) {
297 derr << "must specify cluster fsid" << dendl;
298 return -EINVAL;
299 }
300
301 int err = OSD::mkfs(g_ceph_context, store, g_conf->osd_data,
302 mc.monmap.fsid, whoami);
303 if (err < 0) {
304 derr << TEXT_RED << " ** ERROR: error creating empty object store in "
305 << g_conf->osd_data << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
306 exit(1);
307 }
308 derr << "created object store " << g_conf->osd_data
309 << " for osd." << whoami << " fsid " << mc.monmap.fsid << dendl;
310 }
311 if (mkfs || mkkey)
312 exit(0);
313 if (mkjournal) {
314 common_init_finish(g_ceph_context);
315 int err = store->mkjournal();
316 if (err < 0) {
317 derr << TEXT_RED << " ** ERROR: error creating fresh journal " << g_conf->osd_journal
318 << " for object store " << g_conf->osd_data
319 << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
320 exit(1);
321 }
322 derr << "created new journal " << g_conf->osd_journal
323 << " for object store " << g_conf->osd_data << dendl;
324 exit(0);
325 }
326 if (check_wants_journal) {
327 if (store->wants_journal()) {
328 cout << "wants journal: yes" << std::endl;
329 exit(0);
330 } else {
331 cout << "wants journal: no" << std::endl;
332 exit(1);
333 }
334 }
335 if (check_allows_journal) {
336 if (store->allows_journal()) {
337 cout << "allows journal: yes" << std::endl;
338 exit(0);
339 } else {
340 cout << "allows journal: no" << std::endl;
341 exit(1);
342 }
343 }
344 if (check_needs_journal) {
345 if (store->needs_journal()) {
346 cout << "needs journal: yes" << std::endl;
347 exit(0);
348 } else {
349 cout << "needs journal: no" << std::endl;
350 exit(1);
351 }
352 }
353 if (flushjournal) {
354 common_init_finish(g_ceph_context);
355 int err = store->mount();
356 if (err < 0) {
357 derr << TEXT_RED << " ** ERROR: error flushing journal " << g_conf->osd_journal
358 << " for object store " << g_conf->osd_data
359 << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
360 goto flushjournal_out;
361 }
362 store->umount();
363 derr << "flushed journal " << g_conf->osd_journal
364 << " for object store " << g_conf->osd_data
365 << dendl;
366 flushjournal_out:
367 delete store;
368 exit(err < 0 ? 1 : 0);
369 }
370 if (dump_journal) {
371 common_init_finish(g_ceph_context);
372 int err = store->dump_journal(cout);
373 if (err < 0) {
374 derr << TEXT_RED << " ** ERROR: error dumping journal " << g_conf->osd_journal
375 << " for object store " << g_conf->osd_data
376 << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
377 exit(1);
378 }
379 derr << "dumped journal " << g_conf->osd_journal
380 << " for object store " << g_conf->osd_data
381 << dendl;
382 exit(0);
383
384 }
385
386
387 if (convertfilestore) {
388 int err = store->mount();
389 if (err < 0) {
390 derr << TEXT_RED << " ** ERROR: error mounting store " << g_conf->osd_data
391 << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
392 exit(1);
393 }
394 err = store->upgrade();
395 store->umount();
396 if (err < 0) {
397 derr << TEXT_RED << " ** ERROR: error converting store " << g_conf->osd_data
398 << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
399 exit(1);
400 }
401 exit(0);
402 }
403
404 string magic;
405 uuid_d cluster_fsid, osd_fsid;
406 int w;
407 int r = OSD::peek_meta(store, magic, cluster_fsid, osd_fsid, w);
408 if (r < 0) {
409 derr << TEXT_RED << " ** ERROR: unable to open OSD superblock on "
410 << g_conf->osd_data << ": " << cpp_strerror(-r)
411 << TEXT_NORMAL << dendl;
412 if (r == -ENOTSUP) {
413 derr << TEXT_RED << " ** please verify that underlying storage "
414 << "supports xattrs" << TEXT_NORMAL << dendl;
415 }
416 exit(1);
417 }
418 if (w != whoami) {
419 derr << "OSD id " << w << " != my id " << whoami << dendl;
420 exit(1);
421 }
422 if (strcmp(magic.c_str(), CEPH_OSD_ONDISK_MAGIC)) {
423 derr << "OSD magic " << magic << " != my " << CEPH_OSD_ONDISK_MAGIC
424 << dendl;
425 exit(1);
426 }
427
428 if (get_cluster_fsid) {
429 cout << cluster_fsid << std::endl;
430 exit(0);
431 }
432 if (get_osd_fsid) {
433 cout << osd_fsid << std::endl;
434 exit(0);
435 }
436
437 pick_addresses(g_ceph_context, CEPH_PICK_ADDRESS_PUBLIC
438 |CEPH_PICK_ADDRESS_CLUSTER);
439
440 if (g_conf->public_addr.is_blank_ip() && !g_conf->cluster_addr.is_blank_ip()) {
441 derr << TEXT_YELLOW
442 << " ** WARNING: specified cluster addr but not public addr; we recommend **\n"
443 << " ** you specify neither or both. **"
444 << TEXT_NORMAL << dendl;
445 }
446
447 std::string public_msgr_type = g_conf->ms_public_type.empty() ? g_conf->get_val<std::string>("ms_type") : g_conf->ms_public_type;
448 std::string cluster_msgr_type = g_conf->ms_cluster_type.empty() ? g_conf->get_val<std::string>("ms_type") : g_conf->ms_cluster_type;
449 Messenger *ms_public = Messenger::create(g_ceph_context, public_msgr_type,
450 entity_name_t::OSD(whoami), "client",
451 getpid(),
452 Messenger::HAS_HEAVY_TRAFFIC |
453 Messenger::HAS_MANY_CONNECTIONS);
454 Messenger *ms_cluster = Messenger::create(g_ceph_context, cluster_msgr_type,
455 entity_name_t::OSD(whoami), "cluster",
456 getpid(),
457 Messenger::HAS_HEAVY_TRAFFIC |
458 Messenger::HAS_MANY_CONNECTIONS);
459 Messenger *ms_hb_back_client = Messenger::create(g_ceph_context, cluster_msgr_type,
460 entity_name_t::OSD(whoami), "hb_back_client",
461 getpid(), Messenger::HEARTBEAT);
462 Messenger *ms_hb_front_client = Messenger::create(g_ceph_context, public_msgr_type,
463 entity_name_t::OSD(whoami), "hb_front_client",
464 getpid(), Messenger::HEARTBEAT);
465 Messenger *ms_hb_back_server = Messenger::create(g_ceph_context, cluster_msgr_type,
466 entity_name_t::OSD(whoami), "hb_back_server",
467 getpid(), Messenger::HEARTBEAT);
468 Messenger *ms_hb_front_server = Messenger::create(g_ceph_context, public_msgr_type,
469 entity_name_t::OSD(whoami), "hb_front_server",
470 getpid(), Messenger::HEARTBEAT);
471 Messenger *ms_objecter = Messenger::create(g_ceph_context, public_msgr_type,
472 entity_name_t::OSD(whoami), "ms_objecter",
473 getpid(), 0);
474 if (!ms_public || !ms_cluster || !ms_hb_front_client || !ms_hb_back_client || !ms_hb_back_server || !ms_hb_front_server || !ms_objecter)
475 exit(1);
476 ms_cluster->set_cluster_protocol(CEPH_OSD_PROTOCOL);
477 ms_hb_front_client->set_cluster_protocol(CEPH_OSD_PROTOCOL);
478 ms_hb_back_client->set_cluster_protocol(CEPH_OSD_PROTOCOL);
479 ms_hb_back_server->set_cluster_protocol(CEPH_OSD_PROTOCOL);
480 ms_hb_front_server->set_cluster_protocol(CEPH_OSD_PROTOCOL);
481
482 cout << "starting osd." << whoami
483 << " at " << ms_public->get_myaddr()
484 << " osd_data " << g_conf->osd_data
485 << " " << ((g_conf->osd_journal.empty()) ?
486 "(no journal)" : g_conf->osd_journal)
487 << std::endl;
488
489 boost::scoped_ptr<Throttle> client_byte_throttler(
490 new Throttle(g_ceph_context, "osd_client_bytes",
491 g_conf->osd_client_message_size_cap));
492
493 // All feature bits 0 - 34 should be present from dumpling v0.67 forward
494 uint64_t osd_required =
495 CEPH_FEATURE_UID |
496 CEPH_FEATURE_PGID64 |
497 CEPH_FEATURE_OSDENC;
498
499 ms_public->set_default_policy(Messenger::Policy::stateless_server(0));
500 ms_public->set_policy_throttlers(entity_name_t::TYPE_CLIENT,
501 client_byte_throttler.get(),
502 nullptr);
503 ms_public->set_policy(entity_name_t::TYPE_MON,
504 Messenger::Policy::lossy_client(CEPH_FEATURE_UID |
505 CEPH_FEATURE_PGID64 |
506 CEPH_FEATURE_OSDENC));
507 ms_public->set_policy(entity_name_t::TYPE_MGR,
508 Messenger::Policy::lossy_client(CEPH_FEATURE_UID |
509 CEPH_FEATURE_PGID64 |
510 CEPH_FEATURE_OSDENC));
511
512 //try to poison pill any OSD connections on the wrong address
513 ms_public->set_policy(entity_name_t::TYPE_OSD,
514 Messenger::Policy::stateless_server(0));
515
516 ms_cluster->set_default_policy(Messenger::Policy::stateless_server(0));
517 ms_cluster->set_policy(entity_name_t::TYPE_MON, Messenger::Policy::lossy_client(0));
518 ms_cluster->set_policy(entity_name_t::TYPE_OSD,
519 Messenger::Policy::lossless_peer(osd_required));
520 ms_cluster->set_policy(entity_name_t::TYPE_CLIENT,
521 Messenger::Policy::stateless_server(0));
522
523 ms_hb_front_client->set_policy(entity_name_t::TYPE_OSD,
524 Messenger::Policy::lossy_client(0));
525 ms_hb_back_client->set_policy(entity_name_t::TYPE_OSD,
526 Messenger::Policy::lossy_client(0));
527 ms_hb_back_server->set_policy(entity_name_t::TYPE_OSD,
528 Messenger::Policy::stateless_server(0));
529 ms_hb_front_server->set_policy(entity_name_t::TYPE_OSD,
530 Messenger::Policy::stateless_server(0));
531
532 ms_objecter->set_default_policy(Messenger::Policy::lossy_client(CEPH_FEATURE_OSDREPLYMUX));
533
534 r = ms_public->bind(g_conf->public_addr);
535 if (r < 0)
536 exit(1);
537 r = ms_cluster->bind(g_conf->cluster_addr);
538 if (r < 0)
539 exit(1);
540
541 if (g_conf->osd_heartbeat_use_min_delay_socket) {
542 ms_hb_front_client->set_socket_priority(SOCKET_PRIORITY_MIN_DELAY);
543 ms_hb_back_client->set_socket_priority(SOCKET_PRIORITY_MIN_DELAY);
544 ms_hb_back_server->set_socket_priority(SOCKET_PRIORITY_MIN_DELAY);
545 ms_hb_front_server->set_socket_priority(SOCKET_PRIORITY_MIN_DELAY);
546 }
547
548 // hb back should bind to same ip as cluster_addr (if specified)
549 entity_addr_t hb_back_addr = g_conf->osd_heartbeat_addr;
550 if (hb_back_addr.is_blank_ip()) {
551 hb_back_addr = g_conf->cluster_addr;
552 if (hb_back_addr.is_ip())
553 hb_back_addr.set_port(0);
554 }
555 r = ms_hb_back_server->bind(hb_back_addr);
556 if (r < 0)
557 exit(1);
558 r = ms_hb_back_client->client_bind(hb_back_addr);
559 if (r < 0)
560 exit(1);
561
562 // hb front should bind to same ip as public_addr
563 entity_addr_t hb_front_addr = g_conf->public_addr;
564 if (hb_front_addr.is_ip())
565 hb_front_addr.set_port(0);
566 r = ms_hb_front_server->bind(hb_front_addr);
567 if (r < 0)
568 exit(1);
569 r = ms_hb_front_client->client_bind(hb_front_addr);
570 if (r < 0)
571 exit(1);
572
573 // Set up crypto, daemonize, etc.
574 global_init_daemonize(g_ceph_context);
575 common_init_finish(g_ceph_context);
576
577 TracepointProvider::initialize<osd_tracepoint_traits>(g_ceph_context);
578 TracepointProvider::initialize<os_tracepoint_traits>(g_ceph_context);
579 #ifdef WITH_OSD_INSTRUMENT_FUNCTIONS
580 TracepointProvider::initialize<cyg_profile_traits>(g_ceph_context);
581 #endif
582
583 MonClient mc(g_ceph_context);
584 if (mc.build_initial_monmap() < 0)
585 return -1;
586 global_init_chdir(g_ceph_context);
587
588 if (global_init_preload_erasure_code(g_ceph_context) < 0)
589 return -1;
590
591 srand(time(NULL) + getpid());
592
593 osd = new OSD(g_ceph_context,
594 store,
595 whoami,
596 ms_cluster,
597 ms_public,
598 ms_hb_front_client,
599 ms_hb_back_client,
600 ms_hb_front_server,
601 ms_hb_back_server,
602 ms_objecter,
603 &mc,
604 g_conf->osd_data,
605 g_conf->osd_journal);
606
607 int err = osd->pre_init();
608 if (err < 0) {
609 derr << TEXT_RED << " ** ERROR: osd pre_init failed: " << cpp_strerror(-err)
610 << TEXT_NORMAL << dendl;
611 return 1;
612 }
613
614 ms_public->start();
615 ms_hb_front_client->start();
616 ms_hb_back_client->start();
617 ms_hb_front_server->start();
618 ms_hb_back_server->start();
619 ms_cluster->start();
620 ms_objecter->start();
621
622 // start osd
623 err = osd->init();
624 if (err < 0) {
625 derr << TEXT_RED << " ** ERROR: osd init failed: " << cpp_strerror(-err)
626 << TEXT_NORMAL << dendl;
627 return 1;
628 }
629
630 // install signal handlers
631 init_async_signal_handler();
632 register_async_signal_handler(SIGHUP, sighup_handler);
633 register_async_signal_handler_oneshot(SIGINT, handle_osd_signal);
634 register_async_signal_handler_oneshot(SIGTERM, handle_osd_signal);
635
636 osd->final_init();
637
638 if (g_conf->inject_early_sigterm)
639 kill(getpid(), SIGTERM);
640
641 ms_public->wait();
642 ms_hb_front_client->wait();
643 ms_hb_back_client->wait();
644 ms_hb_front_server->wait();
645 ms_hb_back_server->wait();
646 ms_cluster->wait();
647 ms_objecter->wait();
648
649 unregister_async_signal_handler(SIGHUP, sighup_handler);
650 unregister_async_signal_handler(SIGINT, handle_osd_signal);
651 unregister_async_signal_handler(SIGTERM, handle_osd_signal);
652 shutdown_async_signal_handler();
653
654 // done
655 delete osd;
656 delete ms_public;
657 delete ms_hb_front_client;
658 delete ms_hb_back_client;
659 delete ms_hb_front_server;
660 delete ms_hb_back_server;
661 delete ms_cluster;
662 delete ms_objecter;
663
664 client_byte_throttler.reset();
665
666 // cd on exit, so that gmon.out (if any) goes into a separate directory for each node.
667 char s[20];
668 snprintf(s, sizeof(s), "gmon/%d", getpid());
669 if ((mkdir(s, 0755) == 0) && (chdir(s) == 0)) {
670 dout(0) << "ceph-osd: gmon.out should be in " << s << dendl;
671 }
672
673 return 0;
674 }