From: Sage Weil Date: Sun, 13 Apr 2014 05:23:26 +0000 (-0700) Subject: osd/ReplicatedPG: handle misdirected do_command X-Git-Tag: v0.80-rc1~43^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F1664%2Fhead;p=ceph.git osd/ReplicatedPG: handle misdirected do_command We can get a query on a pg we still have but are no longer primary for. If that happens, do not reply. The client will resend to the correct OSD assuming it has the map. Send them the latest incremental so that we know they know there is something new. We don't know the exact epoch they have, unfortunately, because MCommand doesn't include it, but a newer inc is enough to make them request the right incrementals from a mon. Eventually they will figure it out and Objecter will resend the request to the correct target. It is possible we should include epoch in the MCommand message so that we can do this mapping "correctly" (as in, the same way MOSDOp does). That makes MCommand less general, though... a PG-specific command message might be the most precise thing. Another day... Fixes: #8085 Signed-off-by: Sage Weil --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index cde9baab686a..986eef51b6e1 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -4279,10 +4279,23 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector& cmd, buffe _have_pg(pcand)) { PG *pg = _lookup_lock_pg(pcand); assert(pg); - // simulate pg cmd= for pg->do-command - if (prefix != "pg") - cmd_putval(cct, cmdmap, "cmd", prefix); - r = pg->do_command(cmdmap, ss, data, odata); + if (pg->is_primary()) { + // simulate pg cmd= for pg->do-command + if (prefix != "pg") + cmd_putval(cct, cmdmap, "cmd", prefix); + r = pg->do_command(cmdmap, ss, data, odata); + } else { + ss << "not primary for pgid " << pgid; + + // send them the latest diff to ensure they realize the mapping + // has changed. + send_incremental_map(osdmap->get_epoch() - 1, con); + + // do not reply; they will get newer maps and realize they + // need to resend. + pg->unlock(); + return; + } pg->unlock(); } else { ss << "i don't have pgid " << pgid;