1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
4 #include <boost/intrusive/list.hpp>
5 #include "common/ceph_argparse.h"
6 #include "global/global_init.h"
7 #include "global/signal_handler.h"
8 #include "common/config.h"
9 #include "common/errno.h"
10 #include "common/Timer.h"
11 #include "common/TracepointProvider.h"
13 #include "rgw_signal.h"
14 #include "rgw_common.h"
18 #ifdef HAVE_SYS_PRCTL_H
19 #include <sys/prctl.h>
24 static constexpr auto dout_subsys
= ceph_subsys_rgw
;
26 static sig_t sighandler_alrm
;
28 static void godown_alarm(int signum
)
33 class C_InitTimeout
: public Context
{
36 void finish(int r
) override
{
37 derr
<< "Initialization timeout, failed to initialize" << dendl
;
44 cout
<< "usage: radosgw [options...]" << std::endl
;
46 cout
<< " --rgw-region=<region> region in which radosgw runs\n";
47 cout
<< " --rgw-zone=<zone> zone in which radosgw runs\n";
48 cout
<< " --rgw-socket-path=<path> specify a unix domain socket path\n";
49 cout
<< " -m monaddress[:port] connect to specified monitor\n";
50 cout
<< " --keyring=<path> path to radosgw keyring\n";
51 cout
<< " --logfile=<logfile> file to log debug output\n";
52 cout
<< " --debug-rgw=<log-level>/<memory-level> set radosgw debug level\n";
53 generic_server_usage();
59 * start up the RADOS connection and then handle HTTP messages as they come in
61 int main(int argc
, char *argv
[])
65 // dout() messages will be sent to stderr, but FCGX wants messages on stdout
66 // Redirect stderr to stdout.
67 TEMP_FAILURE_RETRY(close(STDERR_FILENO
));
68 if (TEMP_FAILURE_RETRY(dup2(STDOUT_FILENO
, STDERR_FILENO
)) < 0) {
70 cout
<< "failed to redirect stderr to stdout: " << cpp_strerror(err
)
75 /* alternative default for module */
76 map
<std::string
,std::string
> defaults
= {
77 { "debug_rgw", "1/5" },
78 { "keyring", "$rgw_data/keyring" },
79 { "objecter_inflight_ops", "24576" },
80 // require a secure mon connection by default
81 { "ms_mon_client_mode", "secure" },
82 { "auth_client_required", "cephx" }
85 auto args
= argv_to_vec(argc
, argv
);
87 cerr
<< argv
[0] << ": -h or --help for usage" << std::endl
;
90 if (ceph_argparse_need_usage(args
)) {
95 int flags
= CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS
;
96 // Prevent global_init() from dropping permissions until frontends can bind
98 flags
|= CINIT_FLAG_DEFER_DROP_PRIVILEGES
;
100 auto cct
= rgw_global_init(&defaults
, args
, CEPH_ENTITY_TYPE_CLIENT
,
101 CODE_ENVIRONMENT_DAEMON
, flags
);
103 DoutPrefix
dp(cct
.get(), dout_subsys
, "rgw main: ");
104 rgw::AppMain
main(&dp
);
106 main
.init_frontends1(false /* nfs */);
109 if (g_conf()->daemonize
) {
110 global_init_daemonize(g_ceph_context
);
112 ceph::mutex mutex
= ceph::make_mutex("main");
113 SafeTimer
init_timer(g_ceph_context
, mutex
);
116 init_timer
.add_event_after(g_conf()->rgw_init_timeout
, new C_InitTimeout
);
119 common_init_finish(g_ceph_context
);
120 init_async_signal_handler();
122 /* XXXX check locations thru sighandler_alrm */
123 register_async_signal_handler(SIGHUP
, rgw::signal::sighup_handler
);
124 r
= rgw::signal::signal_fd_init();
126 derr
<< "ERROR: unable to initialize signal fds" << dendl
;
130 register_async_signal_handler(SIGTERM
, rgw::signal::handle_sigterm
);
131 register_async_signal_handler(SIGINT
, rgw::signal::handle_sigterm
);
132 register_async_signal_handler(SIGUSR1
, rgw::signal::handle_sigterm
);
133 sighandler_alrm
= signal(SIGALRM
, godown_alarm
);
135 main
.init_perfcounters();
136 main
.init_http_clients();
139 if (! main
.get_driver()) {
141 init_timer
.cancel_all_events();
142 init_timer
.shutdown();
145 derr
<< "Couldn't init storage provider (RADOS)" << dendl
;
149 main
.cond_init_apis();
152 init_timer
.cancel_all_events();
153 init_timer
.shutdown();
158 main
.init_tracepoints();
160 main
.init_frontends2(nullptr /* RGWLib */);
161 main
.init_notification_endpoints();
163 #if defined(HAVE_SYS_PRCTL_H)
164 if (prctl(PR_SET_DUMPABLE
, 1) == -1) {
165 cerr
<< "warning: unable to set dumpable flag: " << cpp_strerror(errno
) << std::endl
;
169 rgw::signal::wait_shutdown();
171 derr
<< "shutting down" << dendl
;
173 const auto finalize_async_signals
= []() {
174 unregister_async_signal_handler(SIGHUP
, rgw::signal::sighup_handler
);
175 unregister_async_signal_handler(SIGTERM
, rgw::signal::handle_sigterm
);
176 unregister_async_signal_handler(SIGINT
, rgw::signal::handle_sigterm
);
177 unregister_async_signal_handler(SIGUSR1
, rgw::signal::handle_sigterm
);
178 shutdown_async_signal_handler();
181 main
.shutdown(finalize_async_signals
);
183 dout(1) << "final shutdown" << dendl
;
185 rgw::signal::signal_fd_finalize();
188 } /* main(int argc, char* argv[]) */