summaryrefslogtreecommitdiff
path: root/src/ceph_osd.cc
diff options
context:
space:
mode:
authorSage Weil <sage.weil@dreamhost.com>2011-09-23 09:57:45 -0700
committerSage Weil <sage.weil@dreamhost.com>2011-09-23 10:04:52 -0700
commit0fdc86389a80fcb1031e411592aefb9d43a931b1 (patch)
treec9c65af4d34a61b8c9c1789719c631cb066933ad /src/ceph_osd.cc
parent5369c776d0d5a665bbde2a643e49dea4b384c473 (diff)
downloadceph-0fdc86389a80fcb1031e411592aefb9d43a931b1.tar.gz
rename source files c* -> ceph-*
Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
Diffstat (limited to 'src/ceph_osd.cc')
-rw-r--r--src/ceph_osd.cc363
1 files changed, 363 insertions, 0 deletions
diff --git a/src/ceph_osd.cc b/src/ceph_osd.cc
new file mode 100644
index 00000000000..5d50349afe0
--- /dev/null
+++ b/src/ceph_osd.cc
@@ -0,0 +1,363 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <sys/stat.h>
+#include <iostream>
+#include <string>
+using namespace std;
+
+#include "osd/OSD.h"
+
+#include "common/config.h"
+
+#include "mon/MonMap.h"
+#include "mon/MonClient.h"
+
+
+#include "msg/SimpleMessenger.h"
+
+#include "common/Timer.h"
+#include "global/global_init.h"
+#include "common/ceph_argparse.h"
+
+#include "include/color.h"
+#include "common/errno.h"
+
+#include "perfglue/heap_profiler.h"
+
+void usage()
+{
+ derr << "usage: ceph-osd -i osdid [--osd-data=path] [--osd-journal=path] "
+ << "[--mkfs] [--mkjournal] [--convert-filestore]" << dendl;
+ derr << " --debug_osd N set debug level (e.g. 10)" << dendl;
+ generic_server_usage();
+}
+
+int main(int argc, const char **argv)
+{
+ vector<const char*> args;
+ argv_to_vec(argc, argv, args);
+ env_to_vec(args);
+ vector<const char *>::iterator args_iter;
+
+ global_init(args, CEPH_ENTITY_TYPE_OSD, CODE_ENVIRONMENT_DAEMON, 0);
+ ceph_heap_profiler_init();
+
+ // osd specific args
+ bool mkfs = false;
+ bool mkjournal = false;
+ bool mkkey = false;
+ bool flushjournal = false;
+ bool convertfilestore = false;
+ std::string dump_pg_log;
+
+ std::string val;
+ for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
+ if (ceph_argparse_double_dash(args, i)) {
+ break;
+ } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
+ usage();
+ exit(0);
+ } else if (ceph_argparse_flag(args, i, "--mkfs", (char*)NULL)) {
+ mkfs = true;
+ } else if (ceph_argparse_flag(args, i, "--mkjournal", (char*)NULL)) {
+ mkjournal = true;
+ } else if (ceph_argparse_flag(args, i, "--mkkey", (char*)NULL)) {
+ mkkey = true;
+ } else if (ceph_argparse_flag(args, i, "--flush-journal", (char*)NULL)) {
+ flushjournal = true;
+ } else if (ceph_argparse_flag(args, i, "--convert-filestore", (char*)NULL)) {
+ convertfilestore = true;
+ } else if (ceph_argparse_witharg(args, i, &val, "--dump-pg-log", (char*)NULL)) {
+ dump_pg_log = val;
+ } else {
+ ++i;
+ }
+ }
+ if (!args.empty()) {
+ derr << "unrecognized arg " << args[0] << dendl;
+ usage();
+ }
+
+ if (!dump_pg_log.empty()) {
+ common_init_finish(g_ceph_context);
+ bufferlist bl;
+ std::string error;
+ int r = bl.read_file(dump_pg_log.c_str(), &error);
+ if (r >= 0) {
+ PG::Log::Entry e;
+ bufferlist::iterator p = bl.begin();
+ while (!p.end()) {
+ uint64_t pos = p.get_off();
+ try {
+ ::decode(e, p);
+ }
+ catch (const buffer::error &e) {
+ derr << "failed to decode LogEntry at offset " << pos << dendl;
+ return 1;
+ }
+ derr << pos << ":\t" << e << dendl;
+ }
+ } else {
+ derr << "unable to open " << dump_pg_log << ": " << error << dendl;
+ }
+ return 0;
+ }
+
+ // whoami
+ char *end;
+ const char *id = g_conf->name.get_id().c_str();
+ int whoami = strtol(id, &end, 10);
+ if (*end || end == id || whoami < 0) {
+ derr << "must specify '-i #' where # is the osd number" << dendl;
+ usage();
+ }
+
+ if (g_conf->osd_data.empty()) {
+ derr << "must specify '--osd-data=foo' data path" << dendl;
+ usage();
+ }
+
+ if (mkfs) {
+ common_init_finish(g_ceph_context);
+ MonClient mc(g_ceph_context);
+ if (mc.build_initial_monmap() < 0)
+ return -1;
+ if (mc.get_monmap_privately() < 0)
+ return -1;
+
+ int err = OSD::mkfs(g_conf->osd_data, g_conf->osd_journal, mc.monmap.fsid, whoami);
+ if (err < 0) {
+ derr << TEXT_RED << " ** ERROR: error creating empty object store in "
+ << g_conf->osd_data << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
+ exit(1);
+ }
+ derr << "created object store " << g_conf->osd_data;
+ if (!g_conf->osd_journal.empty())
+ *_dout << " journal " << g_conf->osd_journal;
+ *_dout << " for osd" << whoami << " fsid " << mc.monmap.fsid << dendl;
+ }
+ if (mkkey) {
+ common_init_finish(g_ceph_context);
+ KeyRing *keyring = KeyRing::create_empty();
+ if (!keyring) {
+ derr << "Unable to get a Ceph keyring." << dendl;
+ return 1;
+ }
+ EntityName ename(g_conf->name);
+ EntityAuth eauth;
+ eauth.key.create(g_ceph_context, CEPH_CRYPTO_AES);
+ keyring->add(ename, eauth);
+ bufferlist bl;
+ keyring->encode_plaintext(bl);
+ int r = bl.write_file(g_conf->keyring.c_str(), 0600);
+ if (r)
+ derr << TEXT_RED << " ** ERROR: writing new keyring to " << g_conf->keyring
+ << ": " << cpp_strerror(r) << TEXT_NORMAL << dendl;
+ else
+ derr << "created new key in keyring " << g_conf->keyring << dendl;
+ }
+ if (mkfs || mkkey)
+ exit(0);
+ if (mkjournal) {
+ common_init_finish(g_ceph_context);
+ int err = OSD::mkjournal(g_conf->osd_data, g_conf->osd_journal);
+ if (err < 0) {
+ derr << TEXT_RED << " ** ERROR: error creating fresh journal " << g_conf->osd_journal
+ << " for object store " << g_conf->osd_data
+ << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
+ exit(1);
+ }
+ derr << "created new journal " << g_conf->osd_journal
+ << " for object store " << g_conf->osd_data << dendl;
+ exit(0);
+ }
+ if (flushjournal) {
+ common_init_finish(g_ceph_context);
+ int err = OSD::flushjournal(g_conf->osd_data, g_conf->osd_journal);
+ if (err < 0) {
+ derr << TEXT_RED << " ** ERROR: error flushing journal " << g_conf->osd_journal
+ << " for object store " << g_conf->osd_data
+ << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
+ exit(1);
+ }
+ derr << "flushed journal " << g_conf->osd_journal
+ << " for object store " << g_conf->osd_data
+ << dendl;
+ exit(0);
+ }
+
+ if (convertfilestore) {
+ int err = OSD::convertfs(g_conf->osd_data, g_conf->osd_journal);
+ if (err < 0) {
+ derr << TEXT_RED << " ** ERROR: error converting store " << g_conf->osd_data
+ << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
+ exit(1);
+ }
+ }
+
+ string magic;
+ ceph_fsid_t fsid;
+ int w;
+ int r = OSD::peek_meta(g_conf->osd_data, magic, fsid, w);
+ if (r < 0) {
+ derr << TEXT_RED << " ** ERROR: unable to open OSD superblock on "
+ << g_conf->osd_data << ": " << cpp_strerror(-r)
+ << TEXT_NORMAL << dendl;
+ if (r == -ENOTSUP) {
+ derr << TEXT_RED << " ** please verify that underlying storage "
+ << "supports xattrs" << TEXT_NORMAL << dendl;
+ }
+ exit(1);
+ }
+ if (w != whoami) {
+ derr << "OSD id " << w << " != my id " << whoami << dendl;
+ exit(1);
+ }
+ if (strcmp(magic.c_str(), CEPH_OSD_ONDISK_MAGIC)) {
+ derr << "OSD magic " << magic << " != my " << CEPH_OSD_ONDISK_MAGIC
+ << dendl;
+ exit(1);
+ }
+
+ if (g_conf->public_addr.is_blank_ip() && !g_conf->cluster_addr.is_blank_ip()) {
+ derr << TEXT_YELLOW
+ << " ** WARNING: specified cluster addr but not public addr; we recommend **\n"
+ << " ** you specify neither or both. **"
+ << TEXT_NORMAL << dendl;
+ }
+
+ SimpleMessenger *client_messenger = new SimpleMessenger(g_ceph_context);
+ SimpleMessenger *cluster_messenger = new SimpleMessenger(g_ceph_context);
+ SimpleMessenger *messenger_hbin = new SimpleMessenger(g_ceph_context);
+ SimpleMessenger *messenger_hbout = new SimpleMessenger(g_ceph_context);
+
+ client_messenger->bind(g_conf->public_addr, getpid());
+ cluster_messenger->bind(g_conf->cluster_addr, getpid());
+
+ // hb should bind to same ip as cluster_addr (if specified)
+ entity_addr_t hb_addr = g_conf->cluster_addr;
+ if (!hb_addr.is_blank_ip())
+ hb_addr.set_port(0);
+ messenger_hbout->bind(hb_addr, getpid());
+
+ cout << "starting osd" << whoami
+ << " at " << client_messenger->get_ms_addr()
+ << " osd_data " << g_conf->osd_data
+ << " " << ((g_conf->osd_journal.empty()) ?
+ "(no journal)" : g_conf->osd_journal)
+ << std::endl;
+
+ client_messenger->register_entity(entity_name_t::OSD(whoami));
+ cluster_messenger->register_entity(entity_name_t::OSD(whoami));
+ messenger_hbin->register_entity(entity_name_t::OSD(whoami));
+ messenger_hbout->register_entity(entity_name_t::OSD(whoami));
+
+ Throttle client_throttler(g_conf->osd_client_message_size_cap);
+
+ uint64_t supported =
+ CEPH_FEATURE_UID |
+ CEPH_FEATURE_NOSRCADDR |
+ CEPH_FEATURE_PGID64;
+
+ client_messenger->set_default_policy(SimpleMessenger::Policy::stateless_server(supported, 0));
+ client_messenger->set_policy(entity_name_t::TYPE_CLIENT,
+ SimpleMessenger::Policy::stateless_server(supported, 0));
+ client_messenger->set_policy_throttler(entity_name_t::TYPE_CLIENT, &client_throttler);
+ client_messenger->set_policy(entity_name_t::TYPE_MON,
+ SimpleMessenger::Policy::client(supported,
+ CEPH_FEATURE_UID |
+ CEPH_FEATURE_PGID64));
+ //try to poison pill any OSD connections on the wrong address
+ client_messenger->set_policy(entity_name_t::TYPE_OSD,
+ SimpleMessenger::Policy::stateless_server(0,0));
+
+ cluster_messenger->set_default_policy(SimpleMessenger::Policy::stateless_server(0, 0));
+ cluster_messenger->set_policy(entity_name_t::TYPE_MON, SimpleMessenger::Policy::client(0,0));
+ cluster_messenger->set_policy(entity_name_t::TYPE_OSD,
+ SimpleMessenger::Policy::lossless_peer(supported,
+ CEPH_FEATURE_UID |
+ CEPH_FEATURE_PGID64));
+ cluster_messenger->set_policy(entity_name_t::TYPE_CLIENT,
+ SimpleMessenger::Policy::stateless_server(0, 0));
+
+ // Set up crypto, daemonize, etc.
+ // Leave stderr open in case we need to report errors.
+ global_init_daemonize(g_ceph_context, CINIT_FLAG_NO_CLOSE_STDERR);
+ common_init_finish(g_ceph_context);
+
+ int err = OSD::convertfs(g_conf->osd_data, g_conf->osd_journal);
+ if (err < 0) {
+ derr << TEXT_RED << " ** ERROR: error converting store " << g_conf->osd_data
+ << ": " << cpp_strerror(-err) << TEXT_NORMAL << dendl;
+ exit(1);
+ }
+
+ MonClient mc(g_ceph_context);
+ if (mc.build_initial_monmap() < 0)
+ return -1;
+ global_init_chdir(g_ceph_context);
+
+ OSD *osd = new OSD(whoami, cluster_messenger, client_messenger,
+ messenger_hbin, messenger_hbout,
+ &mc,
+ g_conf->osd_data, g_conf->osd_journal);
+ err = osd->pre_init();
+ if (err < 0) {
+ derr << TEXT_RED << " ** ERROR: initializing osd failed: " << cpp_strerror(-err)
+ << TEXT_NORMAL << dendl;
+ return 1;
+ }
+
+ // Now close the standard file descriptors
+ global_init_shutdown_stderr(g_ceph_context);
+
+ client_messenger->start();
+ messenger_hbin->start_with_nonce(getpid());
+ messenger_hbout->start();
+ cluster_messenger->start();
+
+ // start osd
+ err = osd->init();
+ if (err < 0) {
+ derr << TEXT_RED << " ** ERROR: initializing osd failed: " << cpp_strerror(-err)
+ << TEXT_NORMAL << dendl;
+ return 1;
+ }
+
+ client_messenger->wait();
+ messenger_hbin->wait();
+ messenger_hbout->wait();
+ cluster_messenger->wait();
+
+ // done
+ delete osd;
+ client_messenger->destroy();
+ messenger_hbin->destroy();
+ messenger_hbout->destroy();
+ cluster_messenger->destroy();
+
+ // cd on exit, so that gmon.out (if any) goes into a separate directory for each node.
+ char s[20];
+ snprintf(s, sizeof(s), "gmon/%d", getpid());
+ if ((mkdir(s, 0755) == 0) && (chdir(s) == 0)) {
+ dout(0) << "ceph-osd: gmon.out should be in " << s << dendl;
+ }
+
+ return 0;
+}