*
*/
+#include <filesystem>
+#include "common/async/context_pool.h"
#include "common/ceph_argparse.h"
#include "common/code_environment.h"
#include "common/config.h"
#include "common/signal.h"
#include "common/version.h"
#include "erasure-code/ErasureCodePlugin.h"
+#include "extblkdev/ExtBlkDevPlugin.h"
#include "global/global_context.h"
#include "global/global_init.h"
#include "global/pidfile.h"
#include "include/str_list.h"
#include "mon/MonClient.h"
+#ifndef _WIN32
#include <pwd.h>
#include <grp.h>
+#endif
#include <errno.h>
#ifdef HAVE_SYS_PRCTL_H
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_
+
+namespace fs = std::filesystem;
+
+using std::cerr;
+using std::string;
+
static void global_init_set_globals(CephContext *cct)
{
g_ceph_context = cct;
static int chown_path(const std::string &pathname, const uid_t owner, const gid_t group,
const std::string &uid_str, const std::string &gid_str)
{
+ #ifdef _WIN32
+ return 0;
+ #else
+
const char *pathname_cstr = c_str_or_null(pathname);
if (!pathname_cstr) {
}
return r;
+ #endif
}
void global_pre_init(
}
else if (ret) {
cct->_log->flush();
- cerr << "global_init: error reading config file." << std::endl;
+ cerr << "global_init: error reading config file. "
+ << conf.get_parse_error() << std::endl;
_exit(1);
}
// command line (as passed by caller)
conf.parse_argv(args);
- if (conf->log_early &&
- !cct->_log->is_started()) {
- cct->_log->start();
- }
-
if (!cct->_log->is_started()) {
cct->_log->start();
}
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,
- const char *data_dir_option, bool run_pre_init)
+ int flags, bool run_pre_init)
{
// Ensure we're not calling the global init functions multiple times.
static bool first_run = true;
// manually. If they have, update them.
if (g_ceph_context->get_init_flags() != flags) {
g_ceph_context->set_init_flags(flags);
+ if (flags & (CINIT_FLAG_NO_DEFAULT_CONFIG_FILE|
+ CINIT_FLAG_NO_MON_CONFIG)) {
+ g_conf()->no_mon_config = true;
+ }
}
+ #ifndef _WIN32
// signal stuff
int siglist[] = { SIGPIPE, 0 };
block_signals(siglist, NULL);
+ #endif
if (g_conf()->fatal_signal_handlers) {
install_standard_sighandlers();
}
- register_assert_context(g_ceph_context);
+ ceph::register_assert_context(g_ceph_context);
if (g_conf()->log_flush_on_exit)
g_ceph_context->_log->set_flush_on_exit();
// drop privileges?
- ostringstream priv_ss;
-
+ std::ostringstream priv_ss;
+
+ #ifndef _WIN32
// consider --setuser root a no-op, even if we're not root
if (getuid() != 0) {
if (g_conf()->setuser.length()) {
<< std::endl;
exit(1);
}
+#if defined(HAVE_SYS_PRCTL_H)
+ if (g_conf().get_val<bool>("set_keepcaps")) {
+ if (prctl(PR_SET_KEEPCAPS, 1) == -1) {
+ cerr << "warning: unable to set keepcaps flag: " << cpp_strerror(errno) << std::endl;
+ }
+ }
+#endif
if (setuid(uid) != 0) {
cerr << "unable to setuid " << uid << ": " << cpp_strerror(errno)
<< std::endl;
priv_ss << "deferred set uid:gid to " << uid << ":" << gid << " (" << uid_string << ":" << gid_string << ")";
}
}
+ #endif /* _WIN32 */
#if defined(HAVE_SYS_PRCTL_H)
if (prctl(PR_SET_DUMPABLE, 1) == -1) {
// make sure our mini-session gets legacy values
g_conf().apply_changes(nullptr);
- MonClient mc_bootstrap(g_ceph_context);
+ ceph::async::io_context_pool cp(1);
+ MonClient mc_bootstrap(g_ceph_context, cp);
if (mc_bootstrap.get_monmap_and_config() < 0) {
+ cp.stop();
g_ceph_context->_log->flush();
cerr << "failed to fetch mon config (--no-mon-config to skip)"
<< std::endl;
_exit(1);
}
+ cp.stop();
}
// Expand metavariables. Invoke configuration observers. Open log file.
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);
- if (r < 0 && errno != EEXIST) {
- cerr << "warning: unable to create " << g_conf()->run_dir << ": " << cpp_strerror(errno) << std::endl;
+
+ if (!fs::exists(g_conf()->run_dir.c_str())) {
+ std::error_code ec;
+ if (!fs::create_directory(g_conf()->run_dir, ec)) {
+ cerr << "warning: unable to create " << g_conf()->run_dir
+ << ec.message() << std::endl;
+ }
+ fs::permissions(
+ g_conf()->run_dir.c_str(),
+ fs::perms::owner_all |
+ fs::perms::group_read | fs::perms::group_exec |
+ fs::perms::others_read | fs::perms::others_exec);
}
}
return boost::intrusive_ptr<CephContext>{g_ceph_context, false};
}
-namespace TOPNSPC::common {
-void intrusive_ptr_add_ref(CephContext* cct)
-{
- cct->get();
-}
-void intrusive_ptr_release(CephContext* cct)
-{
- cct->put();
-}
-}
void global_print_banner(void)
{
output_ceph_version();
if (global_init_prefork(cct) < 0)
return;
-#if !defined(_AIX)
+#if !defined(_AIX) && !defined(_WIN32)
int ret = daemon(1, 1);
if (ret) {
ret = errno;
#endif
}
+/* Make file descriptors 0, 1, and possibly 2 point to /dev/null.
+ *
+ * Instead of just closing fd, we redirect it to /dev/null with dup2().
+ * We have to do this because otherwise some arbitrary call to open() later
+ * in the program might get back one of these file descriptors. It's hard to
+ * guarantee that nobody ever writes to stdout, even though they're not
+ * supposed to.
+ */
int reopen_as_null(CephContext *cct, int fd)
{
- int newfd = open("/dev/null", O_RDONLY|O_CLOEXEC);
+ int newfd = open(DEV_NULL, O_RDWR | O_CLOEXEC);
if (newfd < 0) {
int err = errno;
lderr(cct) << __func__ << " failed to open /dev/null: " << cpp_strerror(err)
void global_init_postfork_start(CephContext *cct)
{
+ // reexpand the meta in child process
+ cct->_conf.finalize_reexpand_meta();
+
// restart log thread
cct->_log->start();
cct->notify_post_fork();
- /* This is the old trick where we make file descriptors 0, 1, and possibly 2
- * point to /dev/null.
- *
- * We have to do this because otherwise some arbitrary call to open() later
- * in the program might get back one of these file descriptors. It's hard to
- * guarantee that nobody ever writes to stdout, even though they're not
- * supposed to.
- */
reopen_as_null(cct, STDIN_FILENO);
const auto& conf = cct->_conf;
}
}
-/* Map stderr to /dev/null. This isn't really re-entrant; we rely on the old unix
- * behavior that the file descriptor that gets assigned is the lowest
- * available one.
- */
int global_init_shutdown_stderr(CephContext *cct)
{
reopen_as_null(cct, STDERR_FILENO);
- int l = cct->_conf->err_to_stderr ? -1 : -2;
- cct->_log->set_stderr_level(l, l);
+ cct->_log->set_stderr_level(-2, -2);
return 0;
}
string plugins = conf->osd_erasure_code_plugins;
// validate that this is a not a legacy plugin
- list<string> plugins_list;
+ std::list<string> plugins_list;
get_str_list(plugins, plugins_list);
- for (list<string>::iterator i = plugins_list.begin();
- i != plugins_list.end();
- ++i) {
+ for (auto i = plugins_list.begin(); i != plugins_list.end(); ++i) {
string plugin_name = *i;
string replacement = "";
}
}
- stringstream ss;
- int r = ErasureCodePluginRegistry::instance().preload(
+ std::stringstream ss;
+ int r = ceph::ErasureCodePluginRegistry::instance().preload(
plugins,
conf.get_val<std::string>("erasure_code_dir"),
&ss);