~mathiaz/+junk/ceph-new-pkg-review

« back to all changes in this revision

Viewing changes to src/cmon.cc

  • Committer: Mathias Gug
  • Date: 2010-07-29 03:10:42 UTC
  • Revision ID: mathias.gug@canonical.com-20100729031042-n9n8kky962qb4onb
Import ceph_0.21-0ubuntu1 from https://launchpad.net/~clint-fewbar/+archive/ceph/+packages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
 
2
// vim: ts=8 sw=2 smarttab
 
3
/*
 
4
 * Ceph - scalable distributed file system
 
5
 *
 
6
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 
7
 *
 
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.
 
12
 * 
 
13
 */
 
14
 
 
15
#include <sys/types.h>
 
16
#include <sys/stat.h>
 
17
#include <fcntl.h>
 
18
 
 
19
#include <sys/stat.h>
 
20
#include <iostream>
 
21
#include <string>
 
22
using namespace std;
 
23
 
 
24
#include "config.h"
 
25
 
 
26
#include "mon/MonMap.h"
 
27
#include "mon/Monitor.h"
 
28
#include "mon/MonitorStore.h"
 
29
 
 
30
#include "msg/SimpleMessenger.h"
 
31
 
 
32
#include "include/CompatSet.h"
 
33
 
 
34
#include "common/Timer.h"
 
35
#include "common/common_init.h"
 
36
 
 
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[];
 
40
 
 
41
void usage()
 
42
{
 
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";
 
46
  cerr << "  --mkfs\n";
 
47
  cerr << "        build fresh monitor fs\n";
 
48
  generic_server_usage();
 
49
}
 
50
 
 
51
int main(int argc, const char **argv) 
 
52
{
 
53
  int err;
 
54
  DEFINE_CONF_VARS(usage);
 
55
 
 
56
  bool mkfs = false;
 
57
  const char *osdmapfn = 0;
 
58
 
 
59
  vector<const char*> args;
 
60
  argv_to_vec(argc, argv, args);
 
61
  env_to_vec(args);
 
62
 
 
63
  common_set_defaults(true);
 
64
  common_init(args, "mon", true);
 
65
 
 
66
  FOR_EACH_ARG(args) {
 
67
    if (CONF_ARG_EQ("mkfs", '\0')) {
 
68
      mkfs = true;
 
69
    } else if (CONF_ARG_EQ("osdmap", '\0')) {
 
70
      CONF_SAFE_SET_ARG_VAL(&osdmapfn, OPT_STR);
 
71
    } else
 
72
      usage();
 
73
  }
 
74
 
 
75
  // whoami
 
76
  char *end;
 
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;
 
80
    usage();
 
81
  }
 
82
 
 
83
  if (!g_conf.mon_data) {
 
84
    cerr << "must specify '--mon-data=foo' data path" << std::endl;
 
85
    usage();
 
86
  }
 
87
 
 
88
  // -- mkfs --
 
89
  if (mkfs) {
 
90
    if (!g_conf.monmap || !osdmapfn)
 
91
      usage();
 
92
 
 
93
    // make sure it doesn't already exist
 
94
        /*
 
95
    struct stat st;
 
96
    if (::lstat(g_conf.mon_data, &st) == 0) {
 
97
      cerr << "monfs dir " << g_conf.mon_data << " already exists; remove it first" << std::endl;
 
98
      usage();
 
99
    }
 
100
        */
 
101
 
 
102
    // load monmap
 
103
    bufferlist monmapbl, osdmapbl;
 
104
    int err = monmapbl.read_file(g_conf.monmap);
 
105
    if (err < 0)
 
106
      exit(1);
 
107
    MonMap monmap;
 
108
    monmap.decode(monmapbl);
 
109
    
 
110
    err = osdmapbl.read_file(osdmapfn);
 
111
    if (err < 0)
 
112
      exit(1);
 
113
 
 
114
    // go
 
115
    MonitorStore store(g_conf.mon_data);
 
116
    Monitor mon(whoami, &store, 0, &monmap);
 
117
    mon.mkfs(osdmapbl);
 
118
    cout << argv[0] << ": created monfs at " << g_conf.mon_data 
 
119
         << " for mon" << whoami
 
120
         << std::endl;
 
121
    return 0;
 
122
  }
 
123
 
 
124
  if (g_conf.clock_tare) g_clock.tare();
 
125
 
 
126
  CompatSet mon_features(ceph_mon_feature_compat,
 
127
                         ceph_mon_feature_ro_compat,
 
128
                         ceph_mon_feature_incompat);
 
129
  CompatSet ondisk_features;
 
130
 
 
131
  MonitorStore store(g_conf.mon_data);
 
132
  err = store.mount();
 
133
  if (err < 0) {
 
134
    char buf[80];
 
135
    cerr << "problem opening monitor store in " << g_conf.mon_data << ": " << strerror_r(-err, buf, sizeof(buf)) << std::endl;
 
136
    exit(1);
 
137
  }
 
138
 
 
139
  bufferlist magicbl;
 
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;
 
144
    exit(1);
 
145
  }
 
146
 
 
147
  bufferlist features;
 
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
 
154
    //be made smarter.
 
155
    ondisk_features = CompatSet(ceph_mon_feature_compat,
 
156
                                ceph_mon_feature_ro_compat,
 
157
                                ceph_mon_feature_incompat);
 
158
  } else {
 
159
    bufferlist::iterator it = features.begin();
 
160
    ondisk_features.decode(it);
 
161
  }
 
162
  
 
163
  if (!mon_features.writeable(ondisk_features)) {
 
164
    cerr << "monitor executable cannot read disk! Missing features: "
 
165
         << std::endl;
 
166
    CompatSet diff = mon_features.unsupported(ondisk_features);
 
167
    //NEEDS_COMPATSET_ITER
 
168
    exit(1);
 
169
  }
 
170
 
 
171
 
 
172
  // monmap?
 
173
  MonMap monmap;
 
174
  {
 
175
    bufferlist latest;
 
176
    store.get_bl_ss(latest, "monmap/latest", 0);
 
177
    if (latest.length() == 0) {
 
178
      cerr << "mon fs missing 'monmap'" << std::endl;
 
179
      exit(1);
 
180
    }
 
181
    bufferlist::iterator p = latest.begin();
 
182
    version_t v;
 
183
    ::decode(v, p);
 
184
    bufferlist mapbl;
 
185
    ::decode(mapbl, p);
 
186
    monmap.decode(mapbl);
 
187
    assert(v == monmap.get_epoch());
 
188
  }
 
189
 
 
190
  if ((unsigned)whoami >= monmap.size() || whoami < 0) {
 
191
    cerr << "mon" << whoami << " does not exist in monmap" << std::endl;
 
192
    exit(1);
 
193
  }
 
194
 
 
195
  entity_addr_t ipaddr = monmap.get_inst(whoami).addr;
 
196
  entity_addr_t conf_addr;
 
197
  char *mon_addr_str;
 
198
 
 
199
  if (conf_read_key(NULL, "mon addr", OPT_STR, &mon_addr_str, NULL) &&
 
200
      conf_addr.parse(mon_addr_str) &&
 
201
      ipaddr != conf_addr)
 
202
    cerr << "WARNING: 'mon addr' config option does not match monmap file" << std::endl
 
203
         << "         continuing with monmap configuration" << std::endl;
 
204
 
 
205
  // bind
 
206
  SimpleMessenger *messenger = new SimpleMessenger();
 
207
 
 
208
  cout << "starting mon" << whoami 
 
209
       << " at " << monmap.get_inst(whoami).addr
 
210
       << " mon_data " << g_conf.mon_data
 
211
       << " fsid " << monmap.get_fsid()
 
212
       << std::endl;
 
213
  g_my_addr = monmap.get_inst(whoami).addr;
 
214
  err = messenger->bind();
 
215
  if (err < 0)
 
216
    return 1;
 
217
 
 
218
  // start monitor
 
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);
 
222
 
 
223
  messenger->start();  // may daemonize
 
224
 
 
225
  uint64_t supported =
 
226
    CEPH_FEATURE_UID |
 
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,
 
232
                                                               CEPH_FEATURE_UID));
 
233
  mon->init();
 
234
  messenger->wait();
 
235
 
 
236
  store.umount();
 
237
  delete mon;
 
238
  messenger->destroy();
 
239
 
 
240
  // cd on exit, so that gmon.out (if any) goes into a separate directory for each node.
 
241
  char s[20];
 
242
  snprintf(s, sizeof(s), "gmon/%d", getpid());
 
243
  if (mkdir(s, 0755) == 0)
 
244
    chdir(s);
 
245
 
 
246
  return 0;
 
247
}
 
248