#include "global/signal_handler.h"
#include "include/compat.h"
#include "include/str_list.h"
-#include "common/admin_socket.h"
+#include "mon/MonClient.h"
#include <pwd.h>
#include <grp.h>
static void global_init_set_globals(CephContext *cct)
{
g_ceph_context = cct;
- g_conf = cct->_conf;
+ get_process_name(g_process_name, sizeof(g_process_name));
}
static void output_ceph_version()
return r;
}
-void global_pre_init(std::vector < const char * > *alt_def_args,
- std::vector < const char* >& args,
- uint32_t module_type, code_environment_t code_env,
- int flags)
+void global_pre_init(
+ const std::map<std::string,std::string> *defaults,
+ std::vector < const char* >& args,
+ uint32_t module_type, code_environment_t code_env,
+ int flags)
{
std::string conf_file_list;
std::string cluster = "";
- CephInitParameters iparams = ceph_argparse_early_args(args, module_type,
- &cluster, &conf_file_list);
+
+ CephInitParameters iparams = ceph_argparse_early_args(
+ args, module_type,
+ &cluster, &conf_file_list);
+
CephContext *cct = common_preinit(iparams, code_env, flags);
cct->_conf->cluster = cluster;
global_init_set_globals(cct);
- md_config_t *conf = cct->_conf;
+ auto& conf = cct->_conf;
- if (alt_def_args)
- conf->parse_argv(*alt_def_args); // alternative default args
+ if (flags & (CINIT_FLAG_NO_DEFAULT_CONFIG_FILE|
+ CINIT_FLAG_NO_MON_CONFIG)) {
+ conf->no_mon_config = true;
+ }
- int ret = conf->parse_config_files(c_str_or_null(conf_file_list),
- &cerr, flags);
+ // alternate defaults
+ if (defaults) {
+ for (auto& i : *defaults) {
+ conf.set_val_default(i.first, i.second);
+ }
+ }
+
+ int ret = conf.parse_config_files(c_str_or_null(conf_file_list),
+ &cerr, flags);
if (ret == -EDOM) {
- dout_emergency("global_init: error parsing config file.\n");
+ cct->_log->flush();
+ cerr << "global_init: error parsing config file." << std::endl;
_exit(1);
}
else if (ret == -ENOENT) {
if (!(flags & CINIT_FLAG_NO_DEFAULT_CONFIG_FILE)) {
if (conf_file_list.length()) {
- ostringstream oss;
- oss << "global_init: unable to open config file from search list "
- << conf_file_list << "\n";
- dout_emergency(oss.str());
+ cct->_log->flush();
+ cerr << "global_init: unable to open config file from search list "
+ << conf_file_list << std::endl;
_exit(1);
} else {
- derr << "did not load config file, using default settings." << dendl;
+ cerr << "did not load config file, using default settings." << std::endl;
}
}
}
else if (ret) {
- dout_emergency("global_init: error reading config file.\n");
+ cct->_log->flush();
+ cerr << "global_init: error reading config file." << std::endl;
_exit(1);
}
- conf->parse_env(); // environment variables override
+ // environment variables override (CEPH_ARGS, CEPH_KEYRING)
+ conf.parse_env(cct->get_module_type());
+
+ // command line (as passed by caller)
+ conf.parse_argv(args);
+
+ if (conf->log_early &&
+ !cct->_log->is_started()) {
+ cct->_log->start();
+ }
+
+ if (!conf->no_mon_config) {
+ // make sure our mini-session gets legacy values
+ conf.apply_changes(nullptr);
- conf->parse_argv(args); // argv override
+ MonClient mc_bootstrap(g_ceph_context);
+ if (mc_bootstrap.get_monmap_and_config() < 0) {
+ cct->_log->flush();
+ cerr << "failed to fetch mon config (--no-mon-config to skip)"
+ << std::endl;
+ _exit(1);
+ }
+ }
+ if (!cct->_log->is_started()) {
+ cct->_log->start();
+ }
+
+ // do the --show-config[-val], if present in argv
+ conf.do_argv_commands();
// Now we're ready to complain about config file parse errors
- g_conf->complain_about_parse_errors(g_ceph_context);
+ g_conf().complain_about_parse_errors(g_ceph_context);
}
boost::intrusive_ptr<CephContext>
-global_init(std::vector < const char * > *alt_def_args,
+global_init(const std::map<std::string,std::string> *defaults,
std::vector < const char* >& args,
uint32_t module_type, code_environment_t code_env,
int flags,
static bool first_run = true;
if (run_pre_init) {
// We will run pre_init from here (default).
- assert(!g_ceph_context && first_run);
- global_pre_init(alt_def_args, args, module_type, code_env, flags);
+ ceph_assert(!g_ceph_context && first_run);
+ global_pre_init(defaults, args, module_type, code_env, flags);
} else {
// Caller should have invoked pre_init manually.
- assert(g_ceph_context && first_run);
+ ceph_assert(g_ceph_context && first_run);
}
first_run = false;
int siglist[] = { SIGPIPE, 0 };
block_signals(siglist, NULL);
- if (g_conf->fatal_signal_handlers)
+ if (g_conf()->fatal_signal_handlers) {
install_standard_sighandlers();
+ }
+ register_assert_context(g_ceph_context);
- if (g_conf->log_flush_on_exit)
+ if (g_conf()->log_flush_on_exit)
g_ceph_context->_log->set_flush_on_exit();
// drop privileges?
// consider --setuser root a no-op, even if we're not root
if (getuid() != 0) {
- if (g_conf->setuser.length()) {
- cerr << "ignoring --setuser " << g_conf->setuser << " since I am not root"
+ if (g_conf()->setuser.length()) {
+ cerr << "ignoring --setuser " << g_conf()->setuser << " since I am not root"
<< std::endl;
}
- if (g_conf->setgroup.length()) {
- cerr << "ignoring --setgroup " << g_conf->setgroup
+ if (g_conf()->setgroup.length()) {
+ cerr << "ignoring --setgroup " << g_conf()->setgroup
<< " since I am not root" << std::endl;
}
- } else if (g_conf->setgroup.length() ||
- g_conf->setuser.length()) {
+ } else if (g_conf()->setgroup.length() ||
+ g_conf()->setuser.length()) {
uid_t uid = 0; // zero means no change; we can only drop privs here.
gid_t gid = 0;
std::string uid_string;
std::string gid_string;
- if (g_conf->setuser.length()) {
- uid = atoi(g_conf->setuser.c_str());
- if (!uid) {
- char buf[4096];
- struct passwd pa;
- struct passwd *p = 0;
- getpwnam_r(g_conf->setuser.c_str(), &pa, buf, sizeof(buf), &p);
- if (!p) {
- cerr << "unable to look up user '" << g_conf->setuser << "'"
+ std::string home_directory;
+ if (g_conf()->setuser.length()) {
+ char buf[4096];
+ struct passwd pa;
+ struct passwd *p = 0;
+
+ uid = atoi(g_conf()->setuser.c_str());
+ if (uid) {
+ getpwuid_r(uid, &pa, buf, sizeof(buf), &p);
+ } else {
+ getpwnam_r(g_conf()->setuser.c_str(), &pa, buf, sizeof(buf), &p);
+ if (!p) {
+ cerr << "unable to look up user '" << g_conf()->setuser << "'"
<< std::endl;
exit(1);
- }
- uid = p->pw_uid;
- gid = p->pw_gid;
- uid_string = g_conf->setuser;
+ }
+
+ uid = p->pw_uid;
+ gid = p->pw_gid;
+ uid_string = g_conf()->setuser;
+ }
+
+ if (p && p->pw_dir != nullptr) {
+ home_directory = std::string(p->pw_dir);
}
}
- if (g_conf->setgroup.length() > 0) {
- gid = atoi(g_conf->setgroup.c_str());
+ if (g_conf()->setgroup.length() > 0) {
+ gid = atoi(g_conf()->setgroup.c_str());
if (!gid) {
char buf[4096];
struct group gr;
struct group *g = 0;
- getgrnam_r(g_conf->setgroup.c_str(), &gr, buf, sizeof(buf), &g);
+ getgrnam_r(g_conf()->setgroup.c_str(), &gr, buf, sizeof(buf), &g);
if (!g) {
- cerr << "unable to look up group '" << g_conf->setgroup << "'"
+ cerr << "unable to look up group '" << g_conf()->setgroup << "'"
<< ": " << cpp_strerror(errno) << std::endl;
exit(1);
}
gid = g->gr_gid;
- gid_string = g_conf->setgroup;
+ gid_string = g_conf()->setgroup;
}
}
if ((uid || gid) &&
- g_conf->setuser_match_path.length()) {
+ g_conf()->setuser_match_path.length()) {
// induce early expansion of setuser_match_path config option
- string match_path = g_conf->setuser_match_path;
- g_conf->early_expand_meta(match_path, &cerr);
+ string match_path = g_conf()->setuser_match_path;
+ g_conf().early_expand_meta(match_path, &cerr);
struct stat st;
int r = ::stat(match_path.c_str(), &st);
if (r < 0) {
cerr << "unable to stat setuser_match_path "
- << g_conf->setuser_match_path
+ << g_conf()->setuser_match_path
<< ": " << cpp_strerror(errno) << std::endl;
exit(1);
}
<< std::endl;
exit(1);
}
+ if (setenv("HOME", home_directory.c_str(), 1) != 0) {
+ cerr << "warning: unable to set HOME to " << home_directory << ": "
+ << cpp_strerror(errno) << std::endl;
+ }
priv_ss << "set uid:gid to " << uid << ":" << gid << " (" << uid_string << ":" << gid_string << ")";
} else {
priv_ss << "deferred set uid:gid to " << uid << ":" << gid << " (" << uid_string << ":" << gid_string << ")";
if (prctl(PR_SET_DUMPABLE, 1) == -1) {
cerr << "warning: unable to set dumpable flag: " << cpp_strerror(errno) << std::endl;
}
+# if defined(PR_SET_THP_DISABLE)
+ if (!g_conf().get_val<bool>("thp") && prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0) == -1) {
+ cerr << "warning: unable to disable THP: " << cpp_strerror(errno) << std::endl;
+ }
+# endif
#endif
// Expand metavariables. Invoke configuration observers. Open log file.
- g_conf->apply_changes(NULL);
+ g_conf().apply_changes(nullptr);
- if (g_conf->run_dir.length() &&
+ if (g_conf()->run_dir.length() &&
code_env == CODE_ENVIRONMENT_DAEMON &&
!(flags & CINIT_FLAG_NO_DAEMON_ACTIONS)) {
- int r = ::mkdir(g_conf->run_dir.c_str(), 0755);
+ int r = ::mkdir(g_conf()->run_dir.c_str(), 0755);
if (r < 0 && errno != EEXIST) {
- cerr << "warning: unable to create " << g_conf->run_dir << ": " << cpp_strerror(errno) << std::endl;
+ cerr << "warning: unable to create " << g_conf()->run_dir << ": " << cpp_strerror(errno) << std::endl;
}
}
- register_assert_context(g_ceph_context);
-
// call all observers now. this has the side-effect of configuring
// and opening the log file immediately.
- g_conf->call_all_observers();
+ g_conf().call_all_observers();
if (priv_ss.str().length()) {
dout(0) << priv_ss.str() << dendl;
// Fix ownership on log files and run directories if needed.
// Admin socket files are chown()'d during the common init path _after_
// the service thread has been started. This is sadly a bit of a hack :(
- chown_path(g_conf->run_dir,
+ chown_path(g_conf()->run_dir,
g_ceph_context->get_set_uid(),
g_ceph_context->get_set_gid(),
g_ceph_context->get_set_uid_string(),
}
// Now we're ready to complain about config file parse errors
- g_conf->complain_about_parse_errors(g_ceph_context);
+ g_conf().complain_about_parse_errors(g_ceph_context);
// test leak checking
- if (g_conf->debug_deliberately_leak_memory) {
+ if (g_conf()->debug_deliberately_leak_memory) {
derr << "deliberately leaking some memory" << dendl;
char *s = new char[1234567];
(void)s;
if (g_code_env != CODE_ENVIRONMENT_DAEMON)
return -1;
- const md_config_t *conf = cct->_conf;
+ const auto& conf = cct->_conf;
if (!conf->daemonize) {
if (pidfile_write(conf) < 0)
*/
reopen_as_null(cct, STDIN_FILENO);
- const md_config_t *conf = cct->_conf;
+ const auto& conf = cct->_conf;
if (pidfile_write(conf) < 0)
exit(1);
void global_init_chdir(const CephContext *cct)
{
- const md_config_t *conf = cct->_conf;
+ const auto& conf = cct->_conf;
if (conf->chdir.empty())
return;
if (::chdir(conf->chdir.c_str())) {
int global_init_shutdown_stderr(CephContext *cct)
{
reopen_as_null(cct, STDERR_FILENO);
- cct->_log->set_stderr_level(-1, -1);
+ int l = cct->_conf->err_to_stderr ? -1 : -2;
+ cct->_log->set_stderr_level(l, l);
return 0;
}
int global_init_preload_erasure_code(const CephContext *cct)
{
- const md_config_t *conf = cct->_conf;
+ const auto& conf = cct->_conf;
string plugins = conf->osd_erasure_code_plugins;
// validate that this is a not a legacy plugin
stringstream ss;
int r = ErasureCodePluginRegistry::instance().preload(
plugins,
- conf->get_val<std::string>("erasure_code_dir"),
+ conf.get_val<std::string>("erasure_code_dir"),
&ss);
if (r)
derr << ss.str() << dendl;