server relax handling of op on non-existant IOID

PVA protocol has inherent races because server destroy
isn't ack'd by client.  So we must be tolerant of late
arriving messages for non-existant IOIDs.
This commit is contained in:
Michael Davidsaver
2020-01-31 14:28:30 -08:00
parent 1a286ede6e
commit 363761ab77
2 changed files with 25 additions and 9 deletions
+17 -5
View File
@@ -479,11 +479,20 @@ void ServerConn::handle_MONITOR()
std::shared_ptr<MonitorOp> op;
auto it = opByIOID.find(ioid);
if(it==opByIOID.end() || !(op=std::dynamic_pointer_cast<MonitorOp>(it->second))
|| op->state==ServerOp::Dead || op->state==ServerOp::Creating) {
log_printf(connio, Err, "Client %s MONITORs %s IOID %u state=%d\n", peerName.c_str(),
it==opByIOID.end() ? "non-existant" : "invalid", unsigned(ioid),
op ? op->state : ServerOp::Dead);
if(it==opByIOID.end() || it->second->state==ServerOp::Dead) {
// since server destroy commands aren't acknowledged, we can race
// with traffic sent by the client before processing our destroy.
// so we can't fault hard, so just ignore and hope for the best.
log_printf(connio, Debug, "Client %s MONITORs non-existant IOID %u\n",
peerName.c_str(), unsigned(ioid));
return;
} else if(!(op=std::dynamic_pointer_cast<MonitorOp>(it->second))
|| op->state==ServerOp::Creating) {
// mixing up operation types, or trying to exec before we complete creation,
// is a protocol error.
log_printf(connio, Err, "Client %s MONITORs invalid IOID %u state=%d\n",
peerName.c_str(), unsigned(ioid), op ? op->state : ServerOp::Dead);
bev.reset();
return;
}
@@ -516,6 +525,9 @@ void ServerConn::handle_MONITOR()
if(subcmd&0x04) {
bool start = subcmd&0x40;
log_printf(connio, Debug, "Client %s IOID %u MON %s\n",
peerName.c_str(), unsigned(ioid), start ? "START" : "STOP");
{
Guard G(op->lock);
op->state = start ? ServerOp::Executing : ServerOp::Idle;