summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rgw/rgw_main.cc')
-rw-r--r--src/rgw/rgw_main.cc188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc
new file mode 100644
index 000000000..6d2630251
--- /dev/null
+++ b/src/rgw/rgw_main.cc
@@ -0,0 +1,188 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#include <boost/intrusive/list.hpp>
+#include "common/ceph_argparse.h"
+#include "global/global_init.h"
+#include "global/signal_handler.h"
+#include "common/config.h"
+#include "common/errno.h"
+#include "common/Timer.h"
+#include "common/TracepointProvider.h"
+#include "rgw_main.h"
+#include "rgw_signal.h"
+#include "rgw_common.h"
+#include "rgw_lib.h"
+#include "rgw_log.h"
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
+using namespace std;
+
+static constexpr auto dout_subsys = ceph_subsys_rgw;
+
+static sig_t sighandler_alrm;
+
+static void godown_alarm(int signum)
+{
+ _exit(0);
+}
+
+class C_InitTimeout : public Context {
+public:
+ C_InitTimeout() {}
+ void finish(int r) override {
+ derr << "Initialization timeout, failed to initialize" << dendl;
+ exit(1);
+ }
+};
+
+static int usage()
+{
+ cout << "usage: radosgw [options...]" << std::endl;
+ cout << "options:\n";
+ cout << " --rgw-region=<region> region in which radosgw runs\n";
+ cout << " --rgw-zone=<zone> zone in which radosgw runs\n";
+ cout << " --rgw-socket-path=<path> specify a unix domain socket path\n";
+ cout << " -m monaddress[:port] connect to specified monitor\n";
+ cout << " --keyring=<path> path to radosgw keyring\n";
+ cout << " --logfile=<logfile> file to log debug output\n";
+ cout << " --debug-rgw=<log-level>/<memory-level> set radosgw debug level\n";
+ generic_server_usage();
+
+ return 0;
+}
+
+/*
+ * start up the RADOS connection and then handle HTTP messages as they come in
+ */
+int main(int argc, char *argv[])
+{
+ int r{0};
+
+ // dout() messages will be sent to stderr, but FCGX wants messages on stdout
+ // Redirect stderr to stdout.
+ TEMP_FAILURE_RETRY(close(STDERR_FILENO));
+ if (TEMP_FAILURE_RETRY(dup2(STDOUT_FILENO, STDERR_FILENO)) < 0) {
+ int err = errno;
+ cout << "failed to redirect stderr to stdout: " << cpp_strerror(err)
+ << std::endl;
+ return ENOSYS;
+ }
+
+ /* alternative default for module */
+ map<std::string,std::string> defaults = {
+ { "debug_rgw", "1/5" },
+ { "keyring", "$rgw_data/keyring" },
+ { "objecter_inflight_ops", "24576" },
+ // require a secure mon connection by default
+ { "ms_mon_client_mode", "secure" },
+ { "auth_client_required", "cephx" }
+ };
+
+ auto args = argv_to_vec(argc, argv);
+ if (args.empty()) {
+ cerr << argv[0] << ": -h or --help for usage" << std::endl;
+ exit(1);
+ }
+ if (ceph_argparse_need_usage(args)) {
+ usage();
+ exit(0);
+ }
+
+ int flags = CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS;
+ // Prevent global_init() from dropping permissions until frontends can bind
+ // privileged ports
+ flags |= CINIT_FLAG_DEFER_DROP_PRIVILEGES;
+
+ auto cct = rgw_global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT,
+ CODE_ENVIRONMENT_DAEMON, flags);
+
+ DoutPrefix dp(cct.get(), dout_subsys, "rgw main: ");
+ rgw::AppMain main(&dp);
+
+ main.init_frontends1(false /* nfs */);
+ main.init_numa();
+
+ if (g_conf()->daemonize) {
+ global_init_daemonize(g_ceph_context);
+ }
+ ceph::mutex mutex = ceph::make_mutex("main");
+ SafeTimer init_timer(g_ceph_context, mutex);
+ init_timer.init();
+ mutex.lock();
+ init_timer.add_event_after(g_conf()->rgw_init_timeout, new C_InitTimeout);
+ mutex.unlock();
+
+ common_init_finish(g_ceph_context);
+ init_async_signal_handler();
+
+ /* XXXX check locations thru sighandler_alrm */
+ register_async_signal_handler(SIGHUP, rgw::signal::sighup_handler);
+ r = rgw::signal::signal_fd_init();
+ if (r < 0) {
+ derr << "ERROR: unable to initialize signal fds" << dendl;
+ exit(1);
+ }
+
+ register_async_signal_handler(SIGTERM, rgw::signal::handle_sigterm);
+ register_async_signal_handler(SIGINT, rgw::signal::handle_sigterm);
+ register_async_signal_handler(SIGUSR1, rgw::signal::handle_sigterm);
+ sighandler_alrm = signal(SIGALRM, godown_alarm);
+
+ main.init_perfcounters();
+ main.init_http_clients();
+
+ main.init_storage();
+ if (! main.get_driver()) {
+ mutex.lock();
+ init_timer.cancel_all_events();
+ init_timer.shutdown();
+ mutex.unlock();
+
+ derr << "Couldn't init storage provider (RADOS)" << dendl;
+ return EIO;
+ }
+
+ main.cond_init_apis();
+
+ mutex.lock();
+ init_timer.cancel_all_events();
+ init_timer.shutdown();
+ mutex.unlock();
+
+ main.init_ldap();
+ main.init_opslog();
+ main.init_tracepoints();
+ main.init_lua();
+ main.init_frontends2(nullptr /* RGWLib */);
+ main.init_notification_endpoints();
+
+#if defined(HAVE_SYS_PRCTL_H)
+ if (prctl(PR_SET_DUMPABLE, 1) == -1) {
+ cerr << "warning: unable to set dumpable flag: " << cpp_strerror(errno) << std::endl;
+ }
+#endif
+
+ rgw::signal::wait_shutdown();
+
+ derr << "shutting down" << dendl;
+
+ const auto finalize_async_signals = []() {
+ unregister_async_signal_handler(SIGHUP, rgw::signal::sighup_handler);
+ unregister_async_signal_handler(SIGTERM, rgw::signal::handle_sigterm);
+ unregister_async_signal_handler(SIGINT, rgw::signal::handle_sigterm);
+ unregister_async_signal_handler(SIGUSR1, rgw::signal::handle_sigterm);
+ shutdown_async_signal_handler();
+ };
+
+ main.shutdown(finalize_async_signals);
+
+ dout(1) << "final shutdown" << dendl;
+
+ rgw::signal::signal_fd_finalize();
+
+ return 0;
+} /* main(int argc, char* argv[]) */