mirror of
https://github.com/ceph/ceph
synced 2025-02-22 10:37:15 +00:00
msg/Pipe: prepare Message data for wire under pipe_lock
We cannot trust the Message bufferlists or other structures to be stable without pipe_lock, as another Pipe may claim and modify the sent list items while we are writing to the socket. Related to #3678. Signed-off-by: Sage Weil <sage@inktank.com>
This commit is contained in:
parent
40706afc66
commit
d16ad9263d
@ -1475,10 +1475,35 @@ void Pipe::writer()
|
||||
// encode and copy out of *m
|
||||
m->encode(connection_state->get_features(), !msgr->cct->_conf->ms_nocrc);
|
||||
|
||||
// prepare everything
|
||||
ceph_msg_header& header = m->get_header();
|
||||
ceph_msg_footer& footer = m->get_footer();
|
||||
|
||||
// Now that we have all the crcs calculated, handle the
|
||||
// digital signature for the message, if the pipe has session
|
||||
// security set up. Some session security options do not
|
||||
// actually calculate and check the signature, but they should
|
||||
// handle the calls to sign_message and check_signature. PLR
|
||||
if (session_security == NULL) {
|
||||
ldout(msgr->cct, 20) << "writer no session security" << dendl;
|
||||
} else {
|
||||
if (session_security->sign_message(m)) {
|
||||
ldout(msgr->cct, 20) << "writer failed to sign seq # " << header.seq
|
||||
<< "): sig = " << footer.sig << dendl;
|
||||
} else {
|
||||
ldout(msgr->cct, 20) << "writer signed seq # " << header.seq
|
||||
<< "): sig = " << footer.sig << dendl;
|
||||
}
|
||||
}
|
||||
|
||||
bufferlist blist = m->get_payload();
|
||||
blist.append(m->get_middle());
|
||||
blist.append(m->get_data());
|
||||
|
||||
pipe_lock.Unlock();
|
||||
|
||||
ldout(msgr->cct,20) << "writer sending " << m->get_seq() << " " << m << dendl;
|
||||
int rc = write_message(m);
|
||||
int rc = write_message(header, footer, blist);
|
||||
|
||||
pipe_lock.Lock();
|
||||
if (rc < 0) {
|
||||
@ -1858,32 +1883,10 @@ int Pipe::write_keepalive()
|
||||
}
|
||||
|
||||
|
||||
int Pipe::write_message(Message *m)
|
||||
int Pipe::write_message(ceph_msg_header& header, ceph_msg_footer& footer, bufferlist& blist)
|
||||
{
|
||||
const ceph_msg_header& header = m->get_header();
|
||||
const ceph_msg_footer& footer = m->get_footer();
|
||||
int ret;
|
||||
|
||||
// Now that we have all the crcs calculated, handle the digital signature for the message, if the
|
||||
// pipe has session security set up. Some session security options do not actually calculate and
|
||||
// check the signature, but they should handle the calls to sign_message and check_signature. PLR
|
||||
|
||||
if (session_security == NULL) {
|
||||
ldout(msgr->cct, 20) << "Pipe: write_message: session security NULL for this pipe." << dendl;
|
||||
} else {
|
||||
if (session_security->sign_message(m)) {
|
||||
ldout(msgr->cct, 20) << "Failed to put signature in client message (seq # " << header.seq << "): sig = " << footer.sig << dendl;
|
||||
} else {
|
||||
ldout(msgr->cct, 20) << "Put signature in client message (seq # " << header.seq << "): sig = " << footer.sig << dendl;
|
||||
}
|
||||
}
|
||||
|
||||
bufferlist blist = m->get_payload();
|
||||
blist.append(m->get_middle());
|
||||
blist.append(m->get_data());
|
||||
|
||||
ldout(msgr->cct,20) << "write_message " << m << dendl;
|
||||
|
||||
// set up msghdr and iovecs
|
||||
struct msghdr msg;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
@ -178,7 +178,7 @@ class DispatchQueue;
|
||||
int randomize_out_seq();
|
||||
|
||||
int read_message(Message **pm);
|
||||
int write_message(Message *m);
|
||||
int write_message(ceph_msg_header& h, ceph_msg_footer& f, bufferlist& body);
|
||||
/**
|
||||
* Write the given data (of length len) to the Pipe's socket. This function
|
||||
* will loop until all passed data has been written out.
|
||||
|
Loading…
Reference in New Issue
Block a user