class MPGStatsAck : public Message {
public:
- map<pg_t,eversion_t> pg_stat;
+ map<pg_t,pair<version_t,epoch_t> > pg_stat;
MPGStatsAck() : Message(MSG_PGSTATSACK) {}
<< "\t" << pg_state_string(st.state)
<< "\t" << st.last_change
<< "\t" << st.version
- << "\t" << st.reported
+ << "\t" << st.reported_epoch << ":" << st.reported_seq
<< "\t" << st.up
<< "\t" << st.acting
<< "\t" << st.last_scrub << "\t" << st.last_scrub_stamp
hash_map<pg_t,pg_stat_t>::const_iterator t = pg_map.pg_stat.find(p->first);
if (t == pg_map.pg_stat.end())
return true;
- if (t->second.reported != p->second.reported)
+ if (t->second.reported_epoch != p->second.reported_epoch ||
+ t->second.reported_seq != p->second.reported_seq)
return true;
}
for (map<pg_t,pg_stat_t>::const_iterator p = stats->pg_stat.begin();
p != stats->pg_stat.end();
++p) {
- ack->pg_stat[p->first] = p->second.reported;
+ ack->pg_stat[p->first] = make_pair(p->second.reported_seq, p->second.reported_epoch);
}
mon->send_reply(stats, ack);
stats->put();
p != stats->pg_stat.end();
++p) {
pg_t pgid = p->first;
- ack->pg_stat[pgid] = p->second.reported;
+ ack->pg_stat[pgid] = make_pair(p->second.reported_seq, p->second.reported_epoch);
- if ((pg_map.pg_stat.count(pgid) &&
- pg_map.pg_stat[pgid].reported > p->second.reported)) {
- dout(15) << " had " << pgid << " from " << pg_map.pg_stat[pgid].reported << dendl;
+ if (pg_map.pg_stat.count(pgid) &&
+ (pg_map.pg_stat[pgid].reported_seq > p->second.reported_seq ||
+ pg_map.pg_stat[pgid].reported_epoch > p->second.reported_epoch)) {
+ dout(15) << " had " << pgid << " from " << pg_map.pg_stat[pgid].reported_epoch << ":"
+ << pg_map.pg_stat[pgid].reported_seq << dendl;
continue;
}
if (pending_inc.pg_stat_updates.count(pgid) &&
- pending_inc.pg_stat_updates[pgid].reported > p->second.reported) {
- dout(15) << " had " << pgid << " from " << pending_inc.pg_stat_updates[pgid].reported
- << " (pending)" << dendl;
+ (pending_inc.pg_stat_updates[pgid].reported_seq > p->second.reported_seq ||
+ pending_inc.pg_stat_updates[pgid].reported_epoch > p->second.reported_epoch)) {
+ dout(15) << " had " << pgid << " from " << pending_inc.pg_stat_updates[pgid].reported_epoch << ":"
+ << pending_inc.pg_stat_updates[pgid].reported_seq << " (pending)" << dendl;
continue;
}
if (pg_map.pg_stat.count(pgid) == 0) {
- dout(15) << " got " << pgid << " reported at " << p->second.reported
+ dout(15) << " got " << pgid << " reported at " << p->second.reported_epoch << ":"
+ << p->second.reported_seq
<< " state " << pg_state_string(p->second.state)
<< " but DNE in pg_map; pool was probably deleted."
<< dendl;
}
dout(15) << " got " << pgid
- << " reported at " << p->second.reported
+ << " reported at " << p->second.reported_epoch << ":" << p->second.reported_seq
<< " state " << pg_state_string(pg_map.pg_stat[pgid].state)
<< " -> " << pg_state_string(p->second.state)
<< dendl;
pg->pg_stats_publish_lock.Lock();
if (pg->pg_stats_publish_valid) {
m->pg_stat[pg->info.pgid] = pg->pg_stats_publish;
- dout(25) << " sending " << pg->info.pgid << " " << pg->pg_stats_publish.reported << dendl;
+ dout(25) << " sending " << pg->info.pgid << " " << pg->pg_stats_publish.reported_epoch << ":"
+ << pg->pg_stats_publish.reported_seq << dendl;
} else {
- dout(25) << " NOT sending " << pg->info.pgid << " " << pg->pg_stats_publish.reported << ", not valid" << dendl;
+ dout(25) << " NOT sending " << pg->info.pgid << " " << pg->pg_stats_publish.reported_epoch << ":"
+ << pg->pg_stats_publish.reported_seq << ", not valid" << dendl;
}
pg->pg_stats_publish_lock.Unlock();
}
++p;
if (ack->pg_stat.count(pg->info.pgid)) {
- eversion_t acked = ack->pg_stat[pg->info.pgid];
+ pair<version_t,epoch_t> acked = ack->pg_stat[pg->info.pgid];
pg->pg_stats_publish_lock.Lock();
- if (acked == pg->pg_stats_publish.reported) {
- dout(25) << " ack on " << pg->info.pgid << " " << pg->pg_stats_publish.reported << dendl;
+ if (acked.first == pg->pg_stats_publish.reported_seq &&
+ acked.second == pg->pg_stats_publish.reported_epoch) {
+ dout(25) << " ack on " << pg->info.pgid << " " << pg->pg_stats_publish.reported_epoch
+ << ":" << pg->pg_stats_publish.reported_seq << dendl;
pg->stat_queue_item.remove_myself();
pg->put("pg_stat_queue");
} else {
- dout(25) << " still pending " << pg->info.pgid << " " << pg->pg_stats_publish.reported
- << " > acked " << acked << dendl;
+ dout(25) << " still pending " << pg->info.pgid << " " << pg->pg_stats_publish.reported_epoch
+ << ":" << pg->pg_stats_publish.reported_seq << " > acked " << acked << dendl;
}
pg->pg_stats_publish_lock.Unlock();
} else {
- dout(30) << " still pending " << pg->info.pgid << " " << pg->pg_stats_publish.reported << dendl;
+ dout(30) << " still pending " << pg->info.pgid << " " << pg->pg_stats_publish.reported_epoch
+ << ":" << pg->pg_stats_publish.reported_seq << dendl;
}
}
pg_stats_publish_lock.Lock();
if (is_primary()) {
// update our stat summary
- info.stats.reported.inc(get_osdmap()->get_epoch());
+ info.stats.reported_epoch = get_osdmap()->get_epoch();
+ ++info.stats.reported_seq;
info.stats.version = info.last_update;
info.stats.created = info.history.epoch_created;
info.stats.last_scrub = info.history.last_scrub;
pg_stats_publish.stats.sum.num_objects_unfound = get_num_unfound();
}
- dout(15) << "publish_stats_to_osd " << pg_stats_publish.reported << dendl;
+ dout(15) << "publish_stats_to_osd " << pg_stats_publish.reported_epoch
+ << ":" << pg_stats_publish.reported_seq << dendl;
} else {
pg_stats_publish_valid = false;
dout(15) << "publish_stats_to_osd -- not primary" << dendl;
}
// if we haven't reported our PG stats in a long time, do so now.
- if (pg->info.stats.reported.epoch + g_conf->osd_pg_stat_report_interval_max < advmap.osdmap->get_epoch()) {
- dout(20) << "reporting stats to osd after " << (advmap.osdmap->get_epoch() - pg->info.stats.reported.epoch)
+ if (pg->info.stats.reported_epoch + g_conf->osd_pg_stat_report_interval_max < advmap.osdmap->get_epoch()) {
+ dout(20) << "reporting stats to osd after " << (advmap.osdmap->get_epoch() - pg->info.stats.reported_epoch)
<< " epochs" << dendl;
pg->publish_stats_to_osd();
}
changed = true;
}
- if (oinfo.stats.reported < info.stats.reported) // make sure reported always increases
- oinfo.stats.reported = info.stats.reported;
+ if (oinfo.stats.reported_seq < info.stats.reported_seq || // make sure reported always increases
+ oinfo.stats.reported_epoch < info.stats.reported_epoch) {
+ oinfo.stats.reported_seq = info.stats.reported_seq;
+ oinfo.stats.reported_epoch = info.stats.reported_epoch;
+ }
if (info.last_backfill.is_max())
info.stats = oinfo.stats;
void pg_stat_t::dump(Formatter *f) const
{
f->dump_stream("version") << version;
- f->dump_stream("reported") << reported;
+ f->dump_stream("reported_seq") << reported_seq;
+ f->dump_stream("reported_epoch") << reported_epoch;
f->dump_string("state", pg_state_string(state));
f->dump_stream("last_fresh") << last_fresh;
f->dump_stream("last_change") << last_change;
{
ENCODE_START(13, 8, bl);
::encode(version, bl);
- ::encode(reported, bl);
+ ::encode(reported_seq, bl);
+ ::encode(reported_epoch, bl);
::encode(state, bl);
::encode(log_start, bl);
::encode(ondisk_log_start, bl);
{
DECODE_START_LEGACY_COMPAT_LEN(13, 8, 8, bl);
::decode(version, bl);
- ::decode(reported, bl);
+ ::decode(reported_seq, bl);
+ ::decode(reported_epoch, bl);
::decode(state, bl);
::decode(log_start, bl);
::decode(ondisk_log_start, bl);
o.push_back(new pg_stat_t(a));
a.version = eversion_t(1, 3);
- a.reported = eversion_t(1, 2);
+ a.reported_epoch = 1;
+ a.reported_seq = 2;
a.state = 123;
a.mapping_epoch = 998;
a.last_fresh = utime_t(1002, 1);
return c;
}
- void inc(epoch_t e) {
- if (epoch < e)
- epoch = e;
- version++;
- }
-
string get_key_name() const;
void encode(bufferlist &bl) const {
*/
struct pg_stat_t {
eversion_t version;
- eversion_t reported;
+ version_t reported_seq; // sequence number
+ epoch_t reported_epoch; // epoch of this report
__u32 state;
utime_t last_fresh; // last reported
utime_t last_change; // new state != previous state
utime_t last_became_active;
pg_stat_t()
- : state(0),
+ : reported_seq(0),
+ reported_epoch(0),
+ state(0),
created(0), last_epoch_clean(0),
parent_split_bits(0),
stats_invalid(false),
if (state & PG_STATE_CLEAN) {
// we are clean as of this report, and should thus take the
// reported epoch
- return reported.epoch;
+ return reported_epoch;
} else {
return last_epoch_clean;
}
if (s.state & PG_STATE_CLEAN)
s.last_clean = now;
s.last_change = now;
- s.reported.inc(1);
+ s.reported_seq++;
pgs_changes.insert(pgid);
}