X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Frgw%2Frgw_main.cc;fp=src%2Fceph%2Fsrc%2Frgw%2Frgw_main.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=85ec5fec0c0ecf0174841a2255b1598e9f0bcac2;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/rgw/rgw_main.cc b/src/ceph/src/rgw/rgw_main.cc deleted file mode 100644 index 85ec5fe..0000000 --- a/src/ceph/src/rgw/rgw_main.cc +++ /dev/null @@ -1,622 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "acconfig.h" - -#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/safe_io.h" -#include "include/compat.h" -#include "include/str_list.h" -#include "include/stringify.h" -#include "rgw_common.h" -#include "rgw_rados.h" -#include "rgw_user.h" -#include "rgw_period_pusher.h" -#include "rgw_realm_reloader.h" -#include "rgw_rest.h" -#include "rgw_rest_s3.h" -#include "rgw_rest_swift.h" -#include "rgw_rest_admin.h" -#include "rgw_rest_usage.h" -#include "rgw_rest_user.h" -#include "rgw_rest_bucket.h" -#include "rgw_rest_metadata.h" -#include "rgw_rest_log.h" -#include "rgw_rest_opstate.h" -#include "rgw_replica_log.h" -#include "rgw_rest_replica_log.h" -#include "rgw_rest_config.h" -#include "rgw_rest_realm.h" -#include "rgw_swift_auth.h" -#include "rgw_log.h" -#include "rgw_tools.h" -#include "rgw_resolve.h" - -#include "rgw_request.h" -#include "rgw_process.h" -#include "rgw_frontend.h" -#if defined(WITH_RADOSGW_BEAST_FRONTEND) -#include "rgw_asio_frontend.h" -#endif /* WITH_RADOSGW_BEAST_FRONTEND */ - -#include -#include -#include -#include - -#include "include/types.h" -#include "common/BackTrace.h" - -#ifdef HAVE_SYS_PRCTL_H -#include -#endif - -#define dout_subsys ceph_subsys_rgw - -using namespace std; - -static sig_t sighandler_alrm; - -class RGWProcess; - -static int signal_fd[2] = {0, 0}; -static std::atomic disable_signal_fd = { 0 }; - -void signal_shutdown() -{ - if (!disable_signal_fd) { - int val = 0; - int ret = write(signal_fd[0], (char *)&val, sizeof(val)); - if (ret < 0) { - derr << "ERROR: " << __func__ << ": write() returned " - << cpp_strerror(errno) << dendl; - } - } -} - -static void wait_shutdown() -{ - int val; - int r = safe_read_exact(signal_fd[1], &val, sizeof(val)); - if (r < 0) { - derr << "safe_read_exact returned with error" << dendl; - } -} - -static int signal_fd_init() -{ - return socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fd); -} - -static void signal_fd_finalize() -{ - close(signal_fd[0]); - close(signal_fd[1]); -} - -static void handle_sigterm(int signum) -{ - dout(1) << __func__ << dendl; -#if defined(WITH_RADOSGW_FCGI_FRONTEND) - FCGX_ShutdownPending(); -#endif - - // send a signal to make fcgi's accept(2) wake up. unfortunately the - // initial signal often isn't sufficient because we race with accept's - // check of the flag wet by ShutdownPending() above. - if (signum != SIGUSR1) { - signal_shutdown(); - - // safety net in case we get stuck doing an orderly shutdown. - uint64_t secs = g_ceph_context->_conf->rgw_exit_timeout_secs; - if (secs) - alarm(secs); - dout(1) << __func__ << " set alarm for " << secs << dendl; - } - -} - -static void godown_alarm(int signum) -{ - _exit(0); -} - -#ifdef HAVE_CURL_MULTI_WAIT -static void check_curl() -{ -} -#else -static void check_curl() -{ - derr << "WARNING: libcurl doesn't support curl_multi_wait()" << dendl; - derr << "WARNING: cross zone / region transfer performance may be affected" << dendl; -} -#endif - -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() -{ - cerr << "usage: radosgw [options...]" << std::endl; - cerr << "options:\n"; - cerr << " --rgw-region= region in which radosgw runs\n"; - cerr << " --rgw-zone= zone in which radosgw runs\n"; - cerr << " --rgw-socket-path= specify a unix domain socket path\n"; - cerr << " -m monaddress[:port] connect to specified monitor\n"; - cerr << " --keyring= path to radosgw keyring\n"; - cerr << " --logfile= file to log debug output\n"; - cerr << " --debug-rgw=/ set radosgw debug level\n"; - generic_server_usage(); - - return 0; -} - -static RGWRESTMgr *set_logging(RGWRESTMgr *mgr) -{ - mgr->set_logging(true); - return mgr; -} - -static RGWRESTMgr *rest_filter(RGWRados *store, int dialect, RGWRESTMgr *orig) -{ - RGWSyncModuleInstanceRef sync_module = store->get_sync_module(); - return sync_module->get_rest_filter(dialect, orig); -} - -RGWRealmReloader *preloader = NULL; - -static void reloader_handler(int signum) -{ - if (preloader) { - bufferlist bl; - bufferlist::iterator p = bl.begin(); - preloader->handle_notify(RGWRealmNotify::Reload, p); - } - sighup_handler(signum); -} - -/* - * start up the RADOS connection and then handle HTTP messages as they come in - */ -#ifdef BUILDING_FOR_EMBEDDED -extern "C" int cephd_rgw(int argc, const char **argv) -#else -int main(int argc, const char **argv) -#endif -{ - // 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 */ - vector def_args; - def_args.push_back("--debug-rgw=1/5"); - def_args.push_back("--keyring=$rgw_data/keyring"); - - vector args; - argv_to_vec(argc, argv, args); - env_to_vec(args); - - // First, let's determine which frontends are configured. - int flags = CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS; - global_pre_init(&def_args, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_DAEMON, - flags); - - list frontends; - get_str_list(g_conf->rgw_frontends, ",", frontends); - multimap fe_map; - list configs; - if (frontends.empty()) { - frontends.push_back("civetweb"); - } - for (list::iterator iter = frontends.begin(); iter != frontends.end(); ++iter) { - string& f = *iter; - - if (f.find("civetweb") != string::npos) { - // If civetweb is configured as a frontend, prevent global_init() from - // dropping permissions by setting the appropriate flag. - flags |= CINIT_FLAG_DEFER_DROP_PRIVILEGES; - if (f.find("port") != string::npos) { - // check for the most common ws problems - if ((f.find("port=") == string::npos) || - (f.find("port= ") != string::npos)) { - derr << "WARNING: civetweb frontend config found unexpected spacing around 'port' " - << "(ensure civetweb port parameter has the form 'port=80' with no spaces " - << "before or after '=')" << dendl; - } - } - } - - RGWFrontendConfig *config = new RGWFrontendConfig(f); - int r = config->init(); - if (r < 0) { - delete config; - cerr << "ERROR: failed to init config: " << f << std::endl; - return EINVAL; - } - - configs.push_back(config); - - string framework = config->get_framework(); - fe_map.insert(pair(framework, config)); - } - - // Now that we've determined which frontend(s) to use, continue with global - // initialization. Passing false as the final argument ensures that - // global_pre_init() is not invoked twice. - // claim the reference and release it after subsequent destructors have fired - auto cct = global_init(&def_args, args, CEPH_ENTITY_TYPE_CLIENT, - CODE_ENVIRONMENT_DAEMON, - flags, "rgw_data", false); - - for (std::vector::iterator i = args.begin(); i != args.end(); ++i) { - if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) { - usage(); - return 0; - } - } - - // maintain existing region root pool for new multisite objects - if (!g_conf->rgw_region_root_pool.empty()) { - const char *root_pool = g_conf->rgw_region_root_pool.c_str(); - if (g_conf->rgw_zonegroup_root_pool.empty()) { - g_conf->set_val_or_die("rgw_zonegroup_root_pool", root_pool); - } - if (g_conf->rgw_period_root_pool.empty()) { - g_conf->set_val_or_die("rgw_period_root_pool", root_pool); - } - if (g_conf->rgw_realm_root_pool.empty()) { - g_conf->set_val_or_die("rgw_realm_root_pool", root_pool); - } - } - - // for region -> zonegroup conversion (must happen before common_init_finish()) - if (!g_conf->rgw_region.empty() && g_conf->rgw_zonegroup.empty()) { - g_conf->set_val_or_die("rgw_zonegroup", g_conf->rgw_region.c_str()); - } - - check_curl(); - - if (g_conf->daemonize) { - global_init_daemonize(g_ceph_context); - } - Mutex 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(); - - // Enable the perf counter before starting the service thread - g_ceph_context->enable_perf_counter(); - - common_init_finish(g_ceph_context); - - int r = rgw_tools_init(g_ceph_context); - if (r < 0) { - derr << "ERROR: unable to initialize rgw tools" << dendl; - return -r; - } - - rgw_init_resolver(); - - curl_global_init(CURL_GLOBAL_ALL); - -#if defined(WITH_RADOSGW_FCGI_FRONTEND) - FCGX_Init(); -#endif - - RGWRados *store = RGWStoreManager::get_storage(g_ceph_context, - g_conf->rgw_enable_gc_threads, g_conf->rgw_enable_lc_threads, g_conf->rgw_enable_quota_threads, - g_conf->rgw_run_sync_thread, g_conf->rgw_dynamic_resharding); - if (!store) { - mutex.Lock(); - init_timer.cancel_all_events(); - init_timer.shutdown(); - mutex.Unlock(); - - derr << "Couldn't init storage provider (RADOS)" << dendl; - return EIO; - } - r = rgw_perf_start(g_ceph_context); - if (r < 0) { - derr << "ERROR: failed starting rgw perf" << dendl; - return -r; - } - - rgw_rest_init(g_ceph_context, store, store->get_zonegroup()); - - mutex.Lock(); - init_timer.cancel_all_events(); - init_timer.shutdown(); - mutex.Unlock(); - - rgw_user_init(store); - rgw_bucket_init(store->meta_mgr); - rgw_log_usage_init(g_ceph_context, store); - - RGWREST rest; - - list apis; - - get_str_list(g_conf->rgw_enable_apis, apis); - - map apis_map; - for (list::iterator li = apis.begin(); li != apis.end(); ++li) { - apis_map[*li] = true; - } - - // S3 website mode is a specialization of S3 - const bool s3website_enabled = apis_map.count("s3website") > 0; - // Swift API entrypoint could placed in the root instead of S3 - const bool swift_at_root = g_conf->rgw_swift_url_prefix == "/"; - if (apis_map.count("s3") > 0 || s3website_enabled) { - if (! swift_at_root) { - rest.register_default_mgr(set_logging(rest_filter(store, RGW_REST_S3, - new RGWRESTMgr_S3(s3website_enabled)))); - } else { - derr << "Cannot have the S3 or S3 Website enabled together with " - << "Swift API placed in the root of hierarchy" << dendl; - return EINVAL; - } - } - - if (apis_map.count("swift") > 0) { - RGWRESTMgr_SWIFT* const swift_resource = new RGWRESTMgr_SWIFT; - - if (! g_conf->rgw_cross_domain_policy.empty()) { - swift_resource->register_resource("crossdomain.xml", - set_logging(new RGWRESTMgr_SWIFT_CrossDomain)); - } - - swift_resource->register_resource("healthcheck", - set_logging(new RGWRESTMgr_SWIFT_HealthCheck)); - - swift_resource->register_resource("info", - set_logging(new RGWRESTMgr_SWIFT_Info)); - - if (! swift_at_root) { - rest.register_resource(g_conf->rgw_swift_url_prefix, - set_logging(rest_filter(store, RGW_REST_SWIFT, - swift_resource))); - } else { - if (store->get_zonegroup().zones.size() > 1) { - derr << "Placing Swift API in the root of URL hierarchy while running" - << " multi-site configuration requires another instance of RadosGW" - << " with S3 API enabled!" << dendl; - } - - rest.register_default_mgr(set_logging(swift_resource)); - } - } - - if (apis_map.count("swift_auth") > 0) { - rest.register_resource(g_conf->rgw_swift_auth_entry, - set_logging(new RGWRESTMgr_SWIFT_Auth)); - } - - if (apis_map.count("admin") > 0) { - RGWRESTMgr_Admin *admin_resource = new RGWRESTMgr_Admin; - admin_resource->register_resource("usage", new RGWRESTMgr_Usage); - admin_resource->register_resource("user", new RGWRESTMgr_User); - admin_resource->register_resource("bucket", new RGWRESTMgr_Bucket); - - /*Registering resource for /admin/metadata */ - admin_resource->register_resource("metadata", new RGWRESTMgr_Metadata); - admin_resource->register_resource("log", new RGWRESTMgr_Log); - admin_resource->register_resource("opstate", new RGWRESTMgr_Opstate); - admin_resource->register_resource("replica_log", new RGWRESTMgr_ReplicaLog); - admin_resource->register_resource("config", new RGWRESTMgr_Config); - admin_resource->register_resource("realm", new RGWRESTMgr_Realm); - rest.register_resource(g_conf->rgw_admin_entry, admin_resource); - } - - /* Initialize the registry of auth strategies which will coordinate - * the dynamic reconfiguration. */ - auto auth_registry = \ - rgw::auth::StrategyRegistry::create(g_ceph_context, store); - - /* Header custom behavior */ - rest.register_x_headers(g_conf->rgw_log_http_headers); - - OpsLogSocket *olog = NULL; - - if (!g_conf->rgw_ops_log_socket_path.empty()) { - olog = new OpsLogSocket(g_ceph_context, g_conf->rgw_ops_log_data_backlog); - olog->init(g_conf->rgw_ops_log_socket_path); - } - - r = signal_fd_init(); - if (r < 0) { - derr << "ERROR: unable to initialize signal fds" << dendl; - exit(1); - } - - init_async_signal_handler(); - register_async_signal_handler(SIGHUP, reloader_handler); - register_async_signal_handler(SIGTERM, handle_sigterm); - register_async_signal_handler(SIGINT, handle_sigterm); - register_async_signal_handler(SIGUSR1, handle_sigterm); - sighandler_alrm = signal(SIGALRM, godown_alarm); - - map service_map_meta; - service_map_meta["pid"] = stringify(getpid()); - - list fes; - - int fe_count = 0; - - for (multimap::iterator fiter = fe_map.begin(); - fiter != fe_map.end(); ++fiter, ++fe_count) { - RGWFrontendConfig *config = fiter->second; - string framework = config->get_framework(); - RGWFrontend *fe = NULL; - - if (framework == "civetweb" || framework == "mongoose") { - framework = "civetweb"; - std::string uri_prefix; - config->get_val("prefix", "", &uri_prefix); - - RGWProcessEnv env = { store, &rest, olog, 0, uri_prefix, auth_registry }; - - fe = new RGWCivetWebFrontend(env, config); - } - else if (framework == "loadgen") { - int port; - config->get_val("port", 80, &port); - std::string uri_prefix; - config->get_val("prefix", "", &uri_prefix); - - RGWProcessEnv env = { store, &rest, olog, port, uri_prefix, auth_registry }; - - fe = new RGWLoadGenFrontend(env, config); - } -#if defined(WITH_RADOSGW_BEAST_FRONTEND) - else if ((framework == "beast") && - cct->check_experimental_feature_enabled("rgw-beast-frontend")) { - int port; - config->get_val("port", 80, &port); - std::string uri_prefix; - config->get_val("prefix", "", &uri_prefix); - RGWProcessEnv env{ store, &rest, olog, port, uri_prefix, auth_registry }; - fe = new RGWAsioFrontend(env); - } -#endif /* WITH_RADOSGW_BEAST_FRONTEND */ -#if defined(WITH_RADOSGW_FCGI_FRONTEND) - else if (framework == "fastcgi" || framework == "fcgi") { - framework = "fastcgi"; - std::string uri_prefix; - config->get_val("prefix", "", &uri_prefix); - RGWProcessEnv fcgi_pe = { store, &rest, olog, 0, uri_prefix, auth_registry }; - - fe = new RGWFCGXFrontend(fcgi_pe, config); - } -#endif /* WITH_RADOSGW_FCGI_FRONTEND */ - - service_map_meta["frontend_type#" + stringify(fe_count)] = framework; - service_map_meta["frontend_config#" + stringify(fe_count)] = config->get_config(); - - if (fe == NULL) { - dout(0) << "WARNING: skipping unknown framework: " << framework << dendl; - continue; - } - - dout(0) << "starting handler: " << fiter->first << dendl; - int r = fe->init(); - if (r < 0) { - derr << "ERROR: failed initializing frontend" << dendl; - return -r; - } - r = fe->run(); - if (r < 0) { - derr << "ERROR: failed run" << dendl; - return -r; - } - - fes.push_back(fe); - } - - r = store->register_to_service_map("rgw", service_map_meta); - if (r < 0) { - derr << "ERROR: failed to register to service map: " << cpp_strerror(-r) << dendl; - - /* ignore error */ - } - - - // add a watcher to respond to realm configuration changes - RGWPeriodPusher pusher(store); - RGWFrontendPauser pauser(fes, &pusher); - RGWRealmReloader reloader(store, service_map_meta, &pauser); - - preloader = &reloader; - - RGWRealmWatcher realm_watcher(g_ceph_context, store->realm); - realm_watcher.add_watcher(RGWRealmNotify::Reload, reloader); - realm_watcher.add_watcher(RGWRealmNotify::ZonesNeedPeriod, pusher); - -#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 - - wait_shutdown(); - - derr << "shutting down" << dendl; - - for (list::iterator liter = fes.begin(); liter != fes.end(); - ++liter) { - RGWFrontend *fe = *liter; - fe->stop(); - } - - for (list::iterator liter = fes.begin(); liter != fes.end(); - ++liter) { - RGWFrontend *fe = *liter; - fe->join(); - delete fe; - } - - for (list::iterator liter = configs.begin(); - liter != configs.end(); ++liter) { - RGWFrontendConfig *fec = *liter; - delete fec; - } - - unregister_async_signal_handler(SIGHUP, reloader_handler); - unregister_async_signal_handler(SIGTERM, handle_sigterm); - unregister_async_signal_handler(SIGINT, handle_sigterm); - unregister_async_signal_handler(SIGUSR1, handle_sigterm); - shutdown_async_signal_handler(); - - rgw_log_usage_finalize(); - - delete olog; - - RGWStoreManager::close_storage(store); - - rgw_tools_cleanup(); - rgw_shutdown_resolver(); - curl_global_cleanup(); - - rgw_perf_stop(g_ceph_context); - - dout(1) << "final shutdown" << dendl; - - signal_fd_finalize(); - - return 0; -}