env_to_vec(args);
std::map<std::string,std::string> defaults = {
- { "pid_file", "" }
+ { "pid_file", "" },
+ { "chdir", "/" } // FUSE will chdir("/"); be ready.
};
auto cct = global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT,
int newargc;
vec_to_argv(argv[0], args, &newargc, &newargv);
- // FUSE will chdir("/"); be ready.
- g_ceph_context->_conf->set_val("chdir", "/");
- g_ceph_context->_conf->apply_changes(nullptr);
-
// check for 32-bit arch
#ifndef __LP64__
cerr << std::endl;
argv_to_vec(argc, argv, args);
env_to_vec(args);
- auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_MGR,
+ map<string,string> defaults = {
+ { "keyring", "$mgr_data/keyring" }
+ };
+ auto cct = global_init(&defaults, args, CEPH_ENTITY_TYPE_MGR,
CODE_ENVIRONMENT_DAEMON, 0,
"mgr_data");
- // For consumption by KeyRing::from_ceph_context in MonClient
- g_conf->set_val_or_die("keyring", "$mgr_data/keyring");
// Handle --help
- if ((args.size() == 1 && (std::string(args[0]) == "--help" || std::string(args[0]) == "-h"))) {
+ if ((args.size() == 1 && (std::string(args[0]) == "--help" ||
+ std::string(args[0]) == "-h"))) {
usage();
}
}
}
+ // don't try to get config from mon cluster during startup
+ flags |= CINIT_FLAG_NO_MON_CONFIG;
+
auto cct = global_init(&defaults, args,
CEPH_ENTITY_TYPE_MON, CODE_ENVIRONMENT_DAEMON,
flags, "mon_data");
}
if (mkfs) {
common_init_finish(g_ceph_context);
- MonClient mc(g_ceph_context);
- if (mc.build_initial_monmap() < 0)
- return -1;
- if (mc.get_monmap_privately() < 0)
- return -1;
- if (mc.monmap.fsid.is_zero()) {
+ if (g_conf->get_val<uuid_d>("fsid").is_zero()) {
derr << "must specify cluster fsid" << dendl;
forker.exit(-EINVAL);
}
- int err = OSD::mkfs(g_ceph_context, store, data_path, mc.monmap.fsid,
+ int err = OSD::mkfs(g_ceph_context, store, data_path,
+ g_conf->get_val<uuid_d>("fsid"),
whoami);
if (err < 0) {
derr << TEXT_RED << " ** ERROR: error creating empty object store in "
forker.exit(1);
}
dout(0) << "created object store " << data_path
- << " for osd." << whoami << " fsid " << mc.monmap.fsid << dendl;
+ << " for osd." << whoami
+ << " fsid " << g_conf->get_val<uuid_d>("fsid")
+ << dendl;
}
if (mkfs || mkkey) {
forker.exit(0);
else if (ceph_argparse_witharg(args, i, &val, "--conf", "-c", (char*)NULL)) {
*conf_file_list = val;
}
+ else if (ceph_argparse_flag(args, i, "--no-mon-config", (char*)NULL)) {
+ iparams.no_mon_config = true;
+ }
else if (ceph_argparse_witharg(args, i, &val, "--cluster", (char*)NULL)) {
*cluster = val;
}
uint32_t module_type;
EntityName name;
+
+ bool no_mon_config = false;
};
/////////////////////// Functions ///////////////////////
// Set up defaults that make sense for an unprivileged daemon
CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS = 0x1,
- // By default, don't read a configuration file
+ // By default, don't read a configuration file OR contact mons
CINIT_FLAG_NO_DEFAULT_CONFIG_FILE = 0x2,
// Don't close stderr (in daemonize)
// don't drop privileges
CINIT_FLAG_DEFER_DROP_PRIVILEGES = 0x10,
+
+ // do'nt contact mons for config
+ CINIT_FLAG_NO_MON_CONFIG = 0x20,
};
/*
#include "global/signal_handler.h"
#include "include/compat.h"
#include "include/str_list.h"
+#include "mon/MonClient.h"
#include <pwd.h>
#include <grp.h>
{
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);
+ if (flags & (CINIT_FLAG_NO_DEFAULT_CONFIG_FILE|
+ CINIT_FLAG_NO_MON_CONFIG)) {
+ iparams.no_mon_config = true;
+ }
+
CephContext *cct = common_preinit(iparams, code_env, flags);
cct->_conf->cluster = cluster;
global_init_set_globals(cct);
conf->parse_argv(args); // argv override
+ if (!iparams.no_mon_config) {
+ MonClient mc_bootstrap(g_ceph_context);
+ if (mc_bootstrap.get_monmap_and_config() < 0) {
+ derr << "failed to fetch mon config (--no-mon-config to skip)" << dendl;
+ cct->_log->flush();
+ _exit(1);
+ }
+ }
+
// Now we're ready to complain about config file parse errors
g_conf->complain_about_parse_errors(g_ceph_context);
}
int ret;
+ {
+ MonClient mc_bootstrap(cct);
+ ret = mc_bootstrap.get_monmap_and_config();
+ if (ret < 0)
+ return ret;
+ }
+
//monmap
monclient = new MonClient(cct);
ret = -CEPHFS_ERROR_MON_MAP_BUILD; //defined in libcephfs.h;
return -EISCONN;
state = CONNECTING;
+ {
+ MonClient mc_bootstrap(cct);
+ err = mc_bootstrap.get_monmap_and_config();
+ if (err < 0)
+ return err;
+ }
+
// get monmap
err = monclient.build_initial_monmap();
if (err < 0)
#include "messages/MMonGetVersionReply.h"
#include "messages/MMonMap.h"
#include "messages/MConfig.h"
+#include "messages/MGetConfig.h"
#include "messages/MAuth.h"
#include "messages/MLogAck.h"
#include "messages/MAuthReply.h"
return 0;
}
-int MonClient::get_monmap_privately()
+int MonClient::get_monmap_and_config()
{
ldout(cct, 10) << __func__ << dendl;
- Mutex::Locker l(monc_lock);
+ assert(!messenger);
- bool temp_msgr = false;
- Messenger* smessenger = NULL;
- if (!messenger) {
- messenger = smessenger = Messenger::create_client_messenger(cct, "temp_mon_client");
- if (NULL == messenger) {
- return -1;
- }
- messenger->add_dispatcher_head(this);
- smessenger->start();
- temp_msgr = true;
- }
+ utime_t interval;
+ interval.set_from_double(cct->_conf->mon_client_hunt_interval * 10);
- int attempt = 10;
+ cct->init_crypto();
- ldout(cct, 10) << "have " << monmap.epoch << " fsid " << monmap.fsid << dendl;
+ int r = build_initial_monmap();
+ if (r < 0) {
+ lderr(cct) << __func__ << " cannot identify monitors to contact" << dendl;
+ goto out;
+ }
- std::random_device rd;
- std::mt19937 rng(rd());
- assert(monmap.size() > 0);
- std::uniform_int_distribution<unsigned> ranks(0, monmap.size() - 1);
- while (monmap.fsid.is_zero()) {
- auto rank = ranks(rng);
- auto& pending_con = _add_conn(rank, 0);
- auto con = pending_con.get_con();
- ldout(cct, 10) << "querying mon." << monmap.get_name(rank) << " "
- << con->get_peer_addr() << dendl;
- con->send_message(new MMonGetMap);
-
- if (--attempt == 0)
- break;
-
- utime_t interval;
- interval.set_from_double(cct->_conf->mon_client_hunt_interval);
- map_cond.WaitInterval(monc_lock, interval);
-
- if (monmap.fsid.is_zero() && con) {
- con->mark_down(); // nope, clean that connection up
+ messenger = Messenger::create_client_messenger(
+ cct, "temp_mon_client");
+ assert(messenger);
+ messenger->add_dispatcher_head(this);
+ messenger->start();
+
+ r = init();
+ if (r < 0) {
+ goto out_msgr;
+ }
+ r = authenticate(cct->_conf->client_mount_timeout);
+ if (r < 0) {
+ goto out_shutdown;
+ }
+ if (!monmap.persistent_features.contains_all(
+ ceph::features::mon::FEATURE_MIMIC)) {
+ ldout(cct,10) << __func__ << " pre-mimic monitor, no config to fetch"
+ << dendl;
+ } else {
+ Mutex::Locker l(monc_lock);
+ while (!got_config) {
+ ldout(cct,20) << __func__ << " waiting for config" << dendl;
+ map_cond.WaitInterval(monc_lock, interval);
}
}
-
- if (temp_msgr) {
- pending_cons.clear();
- monc_lock.Unlock();
- messenger->shutdown();
- if (smessenger)
- smessenger->wait();
- delete messenger;
- messenger = 0;
- monc_lock.Lock();
+ if (got_config) {
+ ldout(cct,10) << __func__ << " success" << dendl;
+ r = 0;
+ } else {
+ lderr(cct) << __func__ << " failed to get config" << dendl;
+ r = -EIO;
}
- pending_cons.clear();
+out_shutdown:
+ shutdown();
- if (!monmap.fsid.is_zero())
- return 0;
- return -1;
+out_msgr:
+ messenger->shutdown();
+ messenger->wait();
+ delete messenger;
+ messenger = nullptr;
+
+ if (!monmap.fsid.is_zero()) {
+ cct->_conf->set_val("fsid", stringify(monmap.fsid));
+ }
+
+out:
+ cct->shutdown_crypto();
+ return r;
}
ldout(cct,10) << __func__ << " " << *m << dendl;
cct->_conf->set_mon_vals(cct, m->config);
m->put();
+ got_config = true;
+ map_cond.Signal();
}
// ----------------------
if (initialized) {
finisher.wait_for_empty();
finisher.stop();
+ initialized = false;
}
monc_lock.Lock();
timer.shutdown();
bool want_monmap;
Cond map_cond;
bool passthrough_monmap = false;
+ bool got_config = false;
// authenticate
std::unique_ptr<AuthClientHandler> auth;
int build_initial_monmap();
int get_monmap();
- int get_monmap_privately();
+ int get_monmap_and_config();
/**
* If you want to see MonMap messages, set this and
* the MonClient will tell the Messenger it hasn't
vector<const char*> orig_args = args;
global_pre_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_DAEMON,
- CINIT_FLAG_NO_DAEMON_ACTIONS);
+ CINIT_FLAG_NO_DAEMON_ACTIONS |
+ CINIT_FLAG_NO_MON_CONFIG);
std::unique_ptr<CephContext,
std::function<void(CephContext*)> > cct_deleter{
g_ceph_context,