]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/cephfs_mirror/main.cc
efaa89c35931e6cd72b1869c16d13fa548523160
[ceph.git] / ceph / src / tools / cephfs_mirror / main.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "common/ceph_argparse.h"
5 #include "common/config.h"
6 #include "common/debug.h"
7 #include "common/errno.h"
8 #include "common/async/context_pool.h"
9 #include "common/Preforker.h"
10 #include "global/global_init.h"
11 #include "global/signal_handler.h"
12 #include "mon/MonClient.h"
13 #include "msg/Messenger.h"
14 #include "Mirror.h"
15
16 #include <vector>
17
18 void usage() {
19 std::cout << "usage: cephfs-mirror [options...]" << std::endl;
20 std::cout << "options:\n";
21 std::cout << " --mon-host monaddress[:port] connect to specified monitor\n";
22 std::cout << " --keyring=<path> path to keyring for local cluster\n";
23 std::cout << " --log-file=<logfile> file to log debug output\n";
24 std::cout << " --debug-cephfs-mirror=<log-level>/<memory-level> set cephfs-mirror debug level\n";
25 generic_server_usage();
26 }
27
28 cephfs::mirror::Mirror *mirror = nullptr;
29
30 static void handle_signal(int signum) {
31 if (mirror) {
32 mirror->handle_signal(signum);
33 }
34 }
35
36 int main(int argc, const char **argv) {
37 std::vector<const char*> args;
38 argv_to_vec(argc, argv, args);
39 if (args.empty()) {
40 cerr << argv[0] << ": -h or --help for usage" << std::endl;
41 ::exit(1);
42 }
43
44 if (ceph_argparse_need_usage(args)) {
45 usage();
46 ::exit(0);
47 }
48
49 auto cct = global_init(nullptr, args, CEPH_ENTITY_TYPE_CLIENT,
50 CODE_ENVIRONMENT_DAEMON,
51 CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS);
52
53 Preforker forker;
54 if (global_init_prefork(g_ceph_context) >= 0) {
55 std::string err;
56 int r = forker.prefork(err);
57 if (r < 0) {
58 cerr << err << std::endl;
59 return r;
60 }
61 if (forker.is_parent()) {
62 g_ceph_context->_log->start();
63 if (forker.parent_wait(err) != 0) {
64 return -ENXIO;
65 }
66 return 0;
67 }
68 global_init_postfork_start(g_ceph_context);
69 }
70
71 common_init_finish(g_ceph_context);
72
73 bool daemonize = g_conf().get_val<bool>("daemonize");
74 if (daemonize) {
75 global_init_postfork_finish(g_ceph_context);
76 forker.daemonize();
77 }
78
79 init_async_signal_handler();
80 register_async_signal_handler(SIGHUP, handle_signal);
81 register_async_signal_handler_oneshot(SIGINT, handle_signal);
82 register_async_signal_handler_oneshot(SIGTERM, handle_signal);
83
84 std::vector<const char*> cmd_args;
85 argv_to_vec(argc, argv, cmd_args);
86
87 Messenger *msgr = Messenger::create_client_messenger(g_ceph_context, "client");
88 msgr->set_default_policy(Messenger::Policy::lossy_client(0));
89
90 std::string reason;
91 ceph::async::io_context_pool ctxpool(1);
92 MonClient monc(MonClient(g_ceph_context, ctxpool));
93 int r = monc.build_initial_monmap();
94 if (r < 0) {
95 cerr << "failed to generate initial monmap" << std::endl;
96 goto cleanup_messenger;
97 }
98
99 msgr->start();
100
101 mirror = new cephfs::mirror::Mirror(g_ceph_context, cmd_args, &monc, msgr);
102 r = mirror->init(reason);
103 if (r < 0) {
104 std::cerr << "failed to initialize cephfs-mirror: " << reason << std::endl;
105 goto cleanup;
106 }
107
108 mirror->run();
109 delete mirror;
110
111 cleanup:
112 monc.shutdown();
113 cleanup_messenger:
114 msgr->shutdown();
115 msgr->wait();
116 delete msgr;
117
118 unregister_async_signal_handler(SIGHUP, handle_signal);
119 unregister_async_signal_handler(SIGINT, handle_signal);
120 unregister_async_signal_handler(SIGTERM, handle_signal);
121 shutdown_async_signal_handler();
122
123 return forker.signal_exit(r);
124 }