1
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2
// vim: ts=8 sw=2 smarttab
4
* Ceph - scalable distributed file system
6
* Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
8
* This is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License version 2.1, as published by the Free Software
11
* Foundation. See file COPYING.
15
#include <sys/types.h>
26
#include "mon/MonMap.h"
27
#include "mon/Monitor.h"
28
#include "mon/MonitorStore.h"
30
#include "msg/SimpleMessenger.h"
32
#include "include/CompatSet.h"
34
#include "common/Timer.h"
35
#include "common/common_init.h"
37
extern const CompatSet::Feature ceph_mon_feature_compat[];
38
extern const CompatSet::Feature ceph_mon_feature_ro_compat[];
39
extern const CompatSet::Feature ceph_mon_feature_incompat[];
43
cerr << "usage: cmon -i monid [--mon-data=pathtodata] [flags]" << std::endl;
44
cerr << " --debug_mon n\n";
45
cerr << " debug monitor level (e.g. 10)\n";
47
cerr << " build fresh monitor fs\n";
48
generic_server_usage();
51
int main(int argc, const char **argv)
54
DEFINE_CONF_VARS(usage);
57
const char *osdmapfn = 0;
59
vector<const char*> args;
60
argv_to_vec(argc, argv, args);
63
common_set_defaults(true);
64
common_init(args, "mon", true);
67
if (CONF_ARG_EQ("mkfs", '\0')) {
69
} else if (CONF_ARG_EQ("osdmap", '\0')) {
70
CONF_SAFE_SET_ARG_VAL(&osdmapfn, OPT_STR);
77
int whoami = strtol(g_conf.id, &end, 10);
78
if (*end || end == g_conf.id || whoami < 0) {
79
cerr << "must specify '-i #' where # is the mon number" << std::endl;
83
if (!g_conf.mon_data) {
84
cerr << "must specify '--mon-data=foo' data path" << std::endl;
90
if (!g_conf.monmap || !osdmapfn)
93
// make sure it doesn't already exist
96
if (::lstat(g_conf.mon_data, &st) == 0) {
97
cerr << "monfs dir " << g_conf.mon_data << " already exists; remove it first" << std::endl;
103
bufferlist monmapbl, osdmapbl;
104
int err = monmapbl.read_file(g_conf.monmap);
108
monmap.decode(monmapbl);
110
err = osdmapbl.read_file(osdmapfn);
115
MonitorStore store(g_conf.mon_data);
116
Monitor mon(whoami, &store, 0, &monmap);
118
cout << argv[0] << ": created monfs at " << g_conf.mon_data
119
<< " for mon" << whoami
124
if (g_conf.clock_tare) g_clock.tare();
126
CompatSet mon_features(ceph_mon_feature_compat,
127
ceph_mon_feature_ro_compat,
128
ceph_mon_feature_incompat);
129
CompatSet ondisk_features;
131
MonitorStore store(g_conf.mon_data);
135
cerr << "problem opening monitor store in " << g_conf.mon_data << ": " << strerror_r(-err, buf, sizeof(buf)) << std::endl;
140
store.get_bl_ss(magicbl, "magic", 0);
141
string magic(magicbl.c_str(), magicbl.length()-1); // ignore trailing \n
142
if (strcmp(magic.c_str(), CEPH_MON_ONDISK_MAGIC)) {
143
cerr << "mon fs magic '" << magic << "' != current '" << CEPH_MON_ONDISK_MAGIC << "'" << std::endl;
148
store.get_bl_ss(features, COMPAT_SET_LOC, 0);
149
if (features.length() == 0) {
150
cerr << "WARNING: mon fs missing feature list.\n"
151
<< "Assuming it is old-style and introducing one." << std::endl;
152
//we only want the baseline ~v.18 features assumed to be on disk.
153
//If new features are introduced this code needs to disappear or
155
ondisk_features = CompatSet(ceph_mon_feature_compat,
156
ceph_mon_feature_ro_compat,
157
ceph_mon_feature_incompat);
159
bufferlist::iterator it = features.begin();
160
ondisk_features.decode(it);
163
if (!mon_features.writeable(ondisk_features)) {
164
cerr << "monitor executable cannot read disk! Missing features: "
166
CompatSet diff = mon_features.unsupported(ondisk_features);
167
//NEEDS_COMPATSET_ITER
176
store.get_bl_ss(latest, "monmap/latest", 0);
177
if (latest.length() == 0) {
178
cerr << "mon fs missing 'monmap'" << std::endl;
181
bufferlist::iterator p = latest.begin();
186
monmap.decode(mapbl);
187
assert(v == monmap.get_epoch());
190
if ((unsigned)whoami >= monmap.size() || whoami < 0) {
191
cerr << "mon" << whoami << " does not exist in monmap" << std::endl;
195
entity_addr_t ipaddr = monmap.get_inst(whoami).addr;
196
entity_addr_t conf_addr;
199
if (conf_read_key(NULL, "mon addr", OPT_STR, &mon_addr_str, NULL) &&
200
conf_addr.parse(mon_addr_str) &&
202
cerr << "WARNING: 'mon addr' config option does not match monmap file" << std::endl
203
<< " continuing with monmap configuration" << std::endl;
206
SimpleMessenger *messenger = new SimpleMessenger();
208
cout << "starting mon" << whoami
209
<< " at " << monmap.get_inst(whoami).addr
210
<< " mon_data " << g_conf.mon_data
211
<< " fsid " << monmap.get_fsid()
213
g_my_addr = monmap.get_inst(whoami).addr;
214
err = messenger->bind();
219
messenger->register_entity(entity_name_t::MON(whoami));
220
messenger->set_default_send_priority(CEPH_MSG_PRIO_HIGH);
221
Monitor *mon = new Monitor(whoami, &store, messenger, &monmap);
223
messenger->start(); // may daemonize
227
CEPH_FEATURE_NOSRCADDR |
228
CEPH_FEATURE_MONCLOCKCHECK;
229
messenger->set_default_policy(SimpleMessenger::Policy::stateless_server(supported, 0));
230
messenger->set_policy(entity_name_t::TYPE_MON,
231
SimpleMessenger::Policy::lossless_peer(supported,
238
messenger->destroy();
240
// cd on exit, so that gmon.out (if any) goes into a separate directory for each node.
242
snprintf(s, sizeof(s), "gmon/%d", getpid());
243
if (mkdir(s, 0755) == 0)