argv[argc++] = args[i];
}
-bool parse_ip_port(const char *s, entity_addr_t& a)
+bool parse_ip_port(const char *s, entity_addr_t& a, const char **end)
{
int count = 0; // digit count
int off = 0;
return false; // no digits
}
if (count < 3 && *s != '.') {
- cerr << "should period at " << off << std::endl;
+ cerr << "should be period at " << off << std::endl;
return false; // should have 3 periods
}
s++; off++;
if (count == 4 && *(s-1) != ':') break;
if (count == 5) break;
}
+ if (end)
+ *end = s;
return true;
}
OPTION(global, num_mds, 0, INT, 1),
OPTION(global, num_osd, 0, INT, 4),
OPTION(global, num_client, 0, INT, 1),
- OPTION(mon, monmap_file, 0, STR, ".ceph_monmap"),
+ OPTION(mon, monmap_file, 'M', STR, 0),
OPTION(mon, mon_host, 'm', STR, 0),
OPTION(global, daemonize, 'd', BOOL, false),
OPTION(global, logger, 0, BOOL, true),
OPTION(global, log_sym_dir, 0, STR, INSTALL_PREFIX "/var/log/ceph"), // if daemonize == true
OPTION(global, log_to_stdout, 0, BOOL, true),
OPTION(global, pid_file, 'p', STR, 0),
- OPTION(global, conf_file, 'c', STR, INSTALL_PREFIX "etc/ceph/ceph.conf"),
+ OPTION(global, conf_file, 'c', STR, INSTALL_PREFIX "/etc/ceph/ceph.conf"),
+ OPTION(global, cluster_conf_file, 'C', STR, INSTALL_PREFIX "/etc/ceph/cluster.conf"),
OPTION(global, dump_conf, 0, BOOL, false),
OPTION(global, chdir_root, 0, BOOL, true), // chdir("/") after daemonizing. if true, we generate absolute paths as needed.
OPTION(global, fake_clock, 0, BOOL, false),
if (CMD_EQ("conf_file", 'c')) {
SAFE_SET_ARG_VAL(&g_conf.conf_file, STR);
+ } else if (CMD_EQ("cluster_conf_file", 'C')) {
+ SAFE_SET_ARG_VAL(&g_conf.cluster_conf_file, STR);
+ } else if (CMD_EQ("monmap_file", 'M')) {
+ SAFE_SET_ARG_VAL(&g_conf.monmap_file, STR);
} else if (CMD_EQ("dump_conf", 0)) {
SET_BOOL_ARG_VAL(&g_conf.dump_conf);
} else if (CMD_EQ("bind", 0)) {
#include "msg/SimpleMessenger.h"
#include "messages/MMonGetMap.h"
#include "messages/MMonMap.h"
+#include "common/ConfUtils.h"
#include "MonClient.h"
#include "MonMap.h"
int MonClient::probe_mon(MonMap *pmonmap)
{
- entity_addr_t monaddr;
- parse_ip_port(g_conf.mon_host, monaddr);
+ vector<entity_addr_t> monaddrs;
+
+ const char *p = g_conf.mon_host;
+ const char *end = p + strlen(p);
+ while (p < end) {
+ entity_addr_t a;
+ if (parse_ip_port(p, a, &p)) {
+ monaddrs.push_back(a);
+ } else {
+ break;
+ }
+ }
+ if (monaddrs.empty()) {
+ cerr << "couldn't parse ip:port(s) from '" << g_conf.mon_host << "'" << std::endl;
+ return -1;
+ }
rank.bind();
- dout(1) << " connecting to monitor at " << monaddr << " ..." << dendl;
+ dout(1) << " connecting to monitor(s) at " << monaddrs << " ..." << dendl;
Messenger *msgr = rank.register_entity(entity_name_t::CLIENT(-1));
msgr->set_dispatcher(this);
rank.start(true); // do not daemonize!
int attempt = 10;
+ int i = 0;
monmap_lock.Lock();
+ srand(getpid());
while (monmap_bl.length() == 0) {
- dout(10) << "querying " << monaddr << dendl;
+ i = rand() % monaddrs.size();
+ dout(10) << "querying " << monaddrs[i] << dendl;
entity_inst_t mi;
- mi.addr = monaddr;
+ mi.addr = monaddrs[i];
mi.name = entity_name_t::MON(0); // FIXME HRM!
msgr->send_message(new MMonGetMap, mi);
if (monmap_bl.length()) {
pmonmap->decode(monmap_bl);
- dout(2) << "get_monmap got monmap from " << monaddr << " fsid " << pmonmap->fsid << dendl;
- cout << "[got monmap from " << monaddr << " fsid " << pmonmap->fsid << "]" << std::endl;
+ dout(2) << "get_monmap got monmap from " << monaddrs[i] << " fsid " << pmonmap->fsid << dendl;
+ cout << "[got monmap from " << monaddrs[i] << " fsid " << pmonmap->fsid << "]" << std::endl;
}
msgr->shutdown();
msgr->destroy();
if (monmap_bl.length())
return 0;
- cerr << "unable to fetch monmap from " << monaddr
+ cerr << "unable to fetch monmap from " << monaddrs
<< ": " << strerror(errno) << std::endl;
return -1; // failed
}
int MonClient::get_monmap(MonMap *pmonmap)
{
+ static string monstr;
+
+ if (!g_conf.mon_host) {
+ // cluster conf?
+ ConfFile a(g_conf.cluster_conf_file);
+ ConfFile b("cluster.conf");
+ ConfFile *c = 0;
+
+ if (a.parse())
+ c = &a;
+ else if (b.parse())
+ c = &b;
+ if (c) {
+ for (int i=0; i<15; i++) {
+ char *val = 0;
+ char monname[10];
+ sprintf(monname, "mon%d", i);
+ c->read(monname, "mon addr", &val, 0);
+ if (!val || !val[0])
+ break;
+
+ if (monstr.length())
+ monstr += ",";
+ monstr += val;
+ }
+ g_conf.mon_host = monstr.c_str();
+ }
+ }
+
// probe?
if (g_conf.mon_host &&
probe_mon(pmonmap) == 0)
return 0;
- // file?
- const char *monmap_fn = g_conf.monmap_file;
- int r = pmonmap->read(monmap_fn);
- if (r >= 0) {
- cout << "[opened monmap at " << monmap_fn << " fsid " << pmonmap->fsid << "]" << std::endl;
- return 0;
+ if (g_conf.monmap_file) {
+ // file?
+ const char *monmap_fn = g_conf.monmap_file;
+ int r = pmonmap->read(monmap_fn);
+ if (r >= 0) {
+ cout << "[opened monmap at " << monmap_fn << " fsid " << pmonmap->fsid << "]" << std::endl;
+ return 0;
+ }
+
+ cerr << "unable to read monmap from " << monmap_fn << ": " << strerror(errno) << std::endl;
}
- cerr << "unable to read monmap from " << monmap_fn
- << ": " << strerror(errno) << std::endl;
+ cerr << "must specify monitor address (-m monaddr) or cluster conf (-C cluster.conf) or monmap file (-M monmap)" << std::endl;
return -1;
}