]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/osd/main.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / crimson / osd / main.cc
CommitLineData
11fdf7f2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
2// vim: ts=8 sw=2 smarttab
3
4#include <sys/types.h>
5#include <unistd.h>
6
7#include <iostream>
9f95a23c 8#include <random>
11fdf7f2
TL
9
10#include <seastar/core/app-template.hh>
9f95a23c 11#include <seastar/core/print.hh>
11fdf7f2 12#include <seastar/core/thread.hh>
9f95a23c 13#include <seastar/util/std-compat.hh>
11fdf7f2 14
9f95a23c 15#include "auth/KeyRing.h"
11fdf7f2 16#include "common/ceph_argparse.h"
9f95a23c 17#include "crimson/common/buffer_io.h"
11fdf7f2 18#include "crimson/common/config_proxy.h"
9f95a23c
TL
19#include "crimson/net/Messenger.h"
20#include "global/pidfile.h"
11fdf7f2
TL
21
22#include "osd.h"
23
9f95a23c
TL
24using config_t = crimson::common::ConfigProxy;
25namespace fs = seastar::compat::filesystem;
11fdf7f2
TL
26
27void usage(const char* prog) {
9f95a23c
TL
28 std::cout << "usage: " << prog << " -i <ID>\n"
29 << " --help-seastar show Seastar help messages\n";
11fdf7f2
TL
30 generic_server_usage();
31}
32
9f95a23c
TL
33auto partition_args(seastar::app_template& app, char** argv_begin, char** argv_end)
34{
35 namespace bpo = boost::program_options;
36 // collect all options consumed by seastar::app_template
37 auto parsed = bpo::command_line_parser(std::distance(argv_begin, argv_end),
38 argv_begin)
39 .options(app.get_options_description()).allow_unregistered().run();
40 auto unknown_args = bpo::collect_unrecognized(parsed.options,
41 bpo::include_positional);
42 std::vector<const char*> ceph_args, app_args;
43 // ceph_argparse_early_args() and
44 // seastar::smp::get_options_description() use "-c" for different
45 // options. and ceph wins
46 auto consume_conf_arg = [&](char** argv) {
47 if (std::strcmp(*argv, "-c") == 0) {
48 ceph_args.push_back(*argv++);
49 if (argv != argv_end) {
50 ceph_args.push_back(*argv++);
51 }
52 }
53 return argv;
54 };
55 auto unknown = unknown_args.begin();
56 auto consume_unknown_arg = [&](char** argv) {
57 for (; unknown != unknown_args.end() &&
58 argv != argv_end &&
59 *unknown == *argv; ++argv, ++unknown) {
60 if (std::strcmp(*argv, "--help-seastar") == 0) {
61 app_args.push_back("--help");
62 } else {
63 ceph_args.push_back(*argv);
64 }
65 }
66 return argv;
67 };
68 for (auto argv = argv_begin; argv != argv_end;) {
69 if (auto next_arg = consume_conf_arg(argv); next_arg != argv) {
70 argv = next_arg;
71 } else if (auto next_arg = consume_unknown_arg(argv); next_arg != argv) {
72 argv = next_arg;
73 } else {
74 app_args.push_back(*argv++);
75 }
76 }
77 return make_pair(std::move(ceph_args), std::move(app_args));
78}
79
80using crimson::common::local_conf;
81
82seastar::future<> make_keyring()
83{
84 const auto path = local_conf().get_val<string>("keyring");
85 return seastar::file_exists(path).then([path](bool exists) {
86 KeyRing keyring;
87 EntityName name{local_conf()->name};
88 EntityAuth auth;
89 if (exists &&
90 keyring.load(nullptr, path) == 0 &&
91 keyring.get_auth(name, auth)) {
92 seastar::fprint(std::cerr, "already have key in keyring: %s\n", path);
93 return seastar::now();
94 } else {
95 auth.key.create(std::make_unique<CephContext>().get(), CEPH_CRYPTO_AES);
96 keyring.add(name, auth);
97 bufferlist bl;
98 keyring.encode_plaintext(bl);
99 const auto permissions = (seastar::file_permissions::user_read |
100 seastar::file_permissions::user_write);
101 return ceph::buffer::write_file(std::move(bl), path, permissions);
102 }
103 }).handle_exception_type([path](const fs::filesystem_error& e) {
104 seastar::fprint(std::cerr, "FATAL: writing new keyring to %s: %s\n", path, e.what());
105 throw e;
106 });
107}
108
109uint64_t get_nonce()
110{
111 if (auto pid = getpid(); pid != 1) {
112 return pid;
113 } else {
114 // we're running in a container; use a random number instead!
115 std::random_device rd;
116 std::default_random_engine rng{rd()};
117 return std::uniform_int_distribution<uint64_t>{}(rng);
118 }
119}
120
11fdf7f2
TL
121int main(int argc, char* argv[])
122{
9f95a23c
TL
123 seastar::app_template app;
124 app.add_options()
125 ("mkkey", "generate a new secret key. "
126 "This is normally used in combination with --mkfs")
127 ("mkfs", "create a [new] data directory")
128 ("debug", "enable debug output on all loggers");
129
130 auto [ceph_args, app_args] = partition_args(app, argv, argv + argc);
131 if (ceph_argparse_need_usage(ceph_args) &&
132 std::find(app_args.begin(), app_args.end(), "--help") == app_args.end()) {
11fdf7f2
TL
133 usage(argv[0]);
134 return EXIT_SUCCESS;
135 }
9f95a23c 136 std::string cluster_name;
11fdf7f2
TL
137 std::string conf_file_list;
138 // ceph_argparse_early_args() could _exit(), while local_conf() won't ready
139 // until it's started. so do the boilerplate-settings parsing here.
9f95a23c 140 auto init_params = ceph_argparse_early_args(ceph_args,
11fdf7f2 141 CEPH_ENTITY_TYPE_OSD,
9f95a23c 142 &cluster_name,
11fdf7f2 143 &conf_file_list);
9f95a23c
TL
144 seastar::sharded<crimson::osd::OSD> osd;
145 using crimson::common::sharded_conf;
146 using crimson::common::sharded_perf_coll;
11fdf7f2 147 try {
9f95a23c
TL
148 return app.run_deprecated(app_args.size(), const_cast<char**>(app_args.data()),
149 [&, &ceph_args=ceph_args] {
11fdf7f2 150 auto& config = app.configuration();
9f95a23c
TL
151 return seastar::async([&] {
152 if (config.count("debug")) {
153 seastar::global_logger_registry().set_all_loggers_level(
154 seastar::log_level::debug
155 );
156 }
157 sharded_conf().start(init_params.name, cluster_name).get();
158 seastar::engine().at_exit([] {
159 return sharded_conf().stop();
160 });
161 sharded_perf_coll().start().get();
162 seastar::engine().at_exit([] {
163 return sharded_perf_coll().stop();
164 });
165 local_conf().parse_config_files(conf_file_list).get();
166 local_conf().parse_argv(ceph_args).get();
167 pidfile_write(local_conf()->pid_file);
168 const int whoami = std::stoi(local_conf()->name.get_id());
169 const auto nonce = get_nonce();
170 crimson::net::MessengerRef cluster_msgr, client_msgr;
171 crimson::net::MessengerRef hb_front_msgr, hb_back_msgr;
172 for (auto [msgr, name] : {make_pair(std::ref(cluster_msgr), "cluster"s),
173 make_pair(std::ref(client_msgr), "client"s),
174 make_pair(std::ref(hb_front_msgr), "hb_front"s),
175 make_pair(std::ref(hb_back_msgr), "hb_back"s)}) {
176 msgr = crimson::net::Messenger::create(entity_name_t::OSD(whoami), name,
177 nonce);
178 if (local_conf()->ms_crc_data) {
179 msgr->set_crc_data();
180 }
181 if (local_conf()->ms_crc_header) {
182 msgr->set_crc_header();
183 }
184 }
185 osd.start_single(whoami, nonce,
186 cluster_msgr, client_msgr,
187 hb_front_msgr, hb_back_msgr).get();
188 if (config.count("mkkey")) {
189 make_keyring().handle_exception([](std::exception_ptr) {
190 seastar::engine().exit(1);
191 }).get();
192 }
193 if (config.count("mkfs")) {
194 osd.invoke_on(
195 0,
196 &crimson::osd::OSD::mkfs,
197 local_conf().get_val<uuid_d>("osd_uuid"),
198 local_conf().get_val<uuid_d>("fsid")).get();
199 }
200 seastar::engine().at_exit([&] {
201 return osd.stop();
202 });
203 if (config.count("mkkey") || config.count("mkfs")) {
204 seastar::engine().exit(0);
11fdf7f2 205 } else {
9f95a23c 206 osd.invoke_on(0, &crimson::osd::OSD::start).get();
11fdf7f2
TL
207 }
208 });
209 });
210 } catch (...) {
211 seastar::fprint(std::cerr, "FATAL: Exception during startup, aborting: %s\n", std::current_exception());
212 return EXIT_FAILURE;
213 }
214}
215
216/*
217 * Local Variables:
218 * compile-command: "make -j4 \
219 * -C ../../../build \
220 * crimson-osd"
221 * End:
222 */