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