35
35
#include "osd/osd_types.h"
36
36
#include "osd/PG.h" // yuck
38
#include "common/config.h"
41
41
#define DOUT_SUBSYS mon
43
43
#define dout_prefix _prefix(mon, pg_map)
44
44
static ostream& _prefix(Monitor *mon, PGMap& pg_map) {
45
return *_dout << dbeginl
46
<< "mon." << mon->name << "@" << mon->rank
45
return *_dout << "mon." << mon->name << "@" << mon->rank
47
46
<< (mon->is_starting() ? (const char*)"(starting)":(mon->is_leader() ? (const char*)"(leader)":(mon->is_peon() ? (const char*)"(peon)":(const char*)"(?\?)")))
48
47
<< ".pg v" << pg_map.version << " ";
53
51
Tick function to update the map based on performance every N seconds
54
void PGMonitor::on_election_start()
57
last_sent_pg_create.clear();
58
last_osd_report.clear();
56
61
void PGMonitor::tick()
58
63
if (!paxos->is_active()) return;
60
65
update_from_paxos();
66
handle_osd_timeouts();
61
67
dout(10) << pg_map << dendl;
154
void PGMonitor::handle_osd_timeouts()
156
if (!mon->is_leader())
158
utime_t now(g_clock.now());
159
utime_t timeo(g_conf.mon_osd_report_timeout, 0);
160
if (now - mon->get_leader_since() < timeo) {
161
// We haven't been the leader for long enough to consider OSD timeouts
165
mon->osdmon()->handle_osd_timeouts(now, last_osd_report);
147
168
void PGMonitor::create_pending()
149
170
pending_inc = PGMap::Incremental();
281
302
bool PGMonitor::preprocess_pg_stats(MPGStats *stats)
283
int from = stats->get_orig_source().num();
287
305
MonSession *session = stats->get_session();
307
derr << "PGMonitor::preprocess_pg_stats: no monitor session!" << dendl;
290
311
if (!session->caps.check_privileges(PAXOS_PGMAP, MON_CAP_R)) {
291
dout(0) << "MPGStats received from entity with insufficient privileges "
292
<< session->caps << dendl;
312
derr << "PGMonitor::preprocess_pg_stats: MPGStats received from entity "
313
<< "with insufficient privileges " << session->caps << dendl;
296
// first, just see if they need a new osdmap. but
318
// First, just see if they need a new osdmap. But
297
319
// only if they've had the map for a while.
298
320
if (stats->had_map_for > 30.0 &&
299
321
mon->osdmon()->paxos->is_readable() &&
300
322
stats->epoch < mon->osdmon()->osdmap.get_epoch())
301
323
mon->osdmon()->send_latest_now_nodelete(stats, stats->epoch+1);
303
// any new osd or pg info?
304
if (!pg_map.osd_stat.count(from) ||
305
pg_map.osd_stat[from] != stats->osd_stat)
306
return false; // new osd stat
308
for (map<pg_t,pg_stat_t>::iterator p = stats->pg_stat.begin();
309
p != stats->pg_stat.end();
311
if (pg_map.pg_stat.count(p->first) == 0 ||
312
pg_map.pg_stat[p->first].reported != p->second.reported)
313
return false; // new pg stat(s)
325
// Always forward the PGStats to the leader, even if they are the same as
326
// the old PGStats. The leader will mark as down osds that haven't sent
327
// PGStats for a few minutes.
331
bool PGMonitor::pg_stats_have_changed(int from, const MPGStats *stats) const
334
hash_map<int,osd_stat_t>::const_iterator s = pg_map.osd_stat.find(from);
335
if (s == pg_map.osd_stat.end())
337
if (s->second != stats->osd_stat)
341
for (map<pg_t,pg_stat_t>::const_iterator p = stats->pg_stat.begin();
342
p != stats->pg_stat.end(); ++p) {
343
hash_map<pg_t,pg_stat_t>::const_iterator t = pg_map.pg_stat.find(p->first);
344
if (t == pg_map.pg_stat.end())
346
if (t->second.reported != p->second.reported)
316
dout(10) << " message contains no new osd|pg stats" << dendl;
317
ack = new MPGStatsAck;
318
for (map<pg_t,pg_stat_t>::iterator p = stats->pg_stat.begin();
319
p != stats->pg_stat.end();
321
ack->pg_stat[p->first] = p->second.reported;
322
mon->send_reply(stats, ack);
328
353
bool PGMonitor::prepare_pg_stats(MPGStats *stats)
374
if (!pg_stats_have_changed(from, stats)) {
375
dout(10) << " message contains no new osd|pg stats" << dendl;
376
MPGStatsAck *ack = new MPGStatsAck;
377
for (map<pg_t,pg_stat_t>::const_iterator p = stats->pg_stat.begin();
378
p != stats->pg_stat.end();
380
ack->pg_stat[p->first] = p->second.reported;
382
mon->send_reply(stats, ack);
347
388
pending_inc.osd_stat_updates[from] = stats->osd_stat;
602
642
// deleted pools?
603
for (set<pg_t>::iterator p = pg_map.pg_set.begin();
604
p != pg_map.pg_set.end();
606
if (!osdmap->have_pg_pool(p->pool())) {
607
dout(20) << " removing creating_pg " << *p << " because containing pool deleted" << dendl;
608
pending_inc.pg_remove.insert(*p);
643
for (hash_map<pg_t,pg_stat_t>::const_iterator p = pg_map.pg_stat.begin();
644
p != pg_map.pg_stat.end(); ++p) {
645
if (!osdmap->have_pg_pool(p->first.pool())) {
646
dout(20) << " removing creating_pg " << p->first << " because "
647
<< "containing pool deleted" << dendl;
648
pending_inc.pg_remove.insert(p->first);
706
746
if (pgid.parse(m->cmd[2].c_str())) {
707
747
vector<int> up, acting;
748
pg_t mpgid = mon->osdmon()->osdmap.raw_pg_to_pg(pgid);
708
749
mon->osdmon()->osdmap.pg_to_up_acting_osds(pgid, up, acting);
709
ss << "osdmap e" << mon->osdmon()->osdmap.get_epoch() << " pg " << pgid
750
ss << "osdmap e" << mon->osdmon()->osdmap.get_epoch()
751
<< " pg " << pgid << " (" << mpgid << ")"
710
752
<< " -> up " << up << " acting " << acting;
799
841
mon->reply_command(m, err, rs, paxos->get_version());
845
enum health_status_t PGMonitor::get_health(std::ostream &ss) const
847
enum health_status_t ret(HEALTH_OK);
849
const hash_map<pg_t,pg_stat_t> &pg_stat = pg_map.pg_stat;
851
hash_map<pg_t,pg_stat_t>::const_iterator p = pg_stat.begin();
852
hash_map<pg_t,pg_stat_t>::const_iterator p_end = pg_stat.end();
854
for (; p != p_end; ++p) {
855
seen |= p->second.state;
858
string prequel(" Some PGs are: ");
859
if (seen & PG_STATE_CRASHED) {
860
ss << prequel << "crashed";
863
if (seen & PG_STATE_DOWN) {
864
ss << prequel << "down";
867
if (seen & PG_STATE_REPLAY) {
868
ss << prequel << "replaying";
871
if (seen & PG_STATE_SPLITTING) {
872
ss << prequel << "splitting";
875
if (seen & PG_STATE_DEGRADED) {
876
ss << prequel << "degraded";
879
if (seen & PG_STATE_INCONSISTENT) {
880
ss << prequel << "inconsistent";
883
if (seen & PG_STATE_PEERING) {
884
ss << prequel << "peering";
887
if (seen & PG_STATE_REPAIR) {
888
ss << prequel << "repairing";
891
if (prequel == ",") {
892
if (ret > HEALTH_WARN)