-
Notifications
You must be signed in to change notification settings - Fork 347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix/dbus call issue #2838
Fix/dbus call issue #2838
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ use std::os::fd::AsRawFd; | |
use std::path::PathBuf; | ||
use std::sync::atomic::{AtomicU32, Ordering}; | ||
|
||
use nix::errno::Errno; | ||
use nix::sys::socket; | ||
|
||
use super::client::SystemdClient; | ||
|
@@ -228,9 +229,10 @@ impl DbusConnection { | |
.filter(|m| m.preamble.mtype == MessageType::MethodReturn) | ||
.collect(); | ||
|
||
let res = res.first().ok_or(DbusError::MethodCallErr( | ||
"expected method call to have reply, found no reply message".into(), | ||
))?; | ||
let res = res.first().ok_or(DbusError::AuthenticationErr(format!( | ||
"expected Hello call to have reply, found no reply message, got {:?} instead", | ||
res | ||
)))?; | ||
let mut ctr = 0; | ||
let id = String::deserialize(&res.body, &mut ctr)?; | ||
self.id = Some(id); | ||
|
@@ -247,13 +249,18 @@ impl DbusConnection { | |
let mut reply: [u8; REPLY_BUF_SIZE] = [0_u8; REPLY_BUF_SIZE]; | ||
let mut reply_buffer = [IoSliceMut::new(&mut reply[0..])]; | ||
|
||
let reply_rcvd = socket::recvmsg::<()>( | ||
let reply_res = socket::recvmsg::<()>( | ||
self.socket, | ||
&mut reply_buffer, | ||
None, | ||
socket::MsgFlags::empty(), | ||
)?; | ||
); | ||
|
||
let reply_rcvd = match reply_res { | ||
Ok(msg) => msg, | ||
Err(Errno::EAGAIN) => continue, | ||
Err(e) => return Err(e.into()), | ||
}; | ||
let received_byte_count = reply_rcvd.bytes; | ||
|
||
ret.extend_from_slice(&reply[0..received_byte_count]); | ||
|
@@ -296,20 +303,47 @@ impl DbusConnection { | |
None, | ||
)?; | ||
|
||
let reply = self.receive_complete_response()?; | ||
|
||
// note that a single received response can contain multiple | ||
// messages, so we must deserialize it piece by piece | ||
let mut ret = Vec::new(); | ||
let mut buf = &reply[..]; | ||
|
||
while !buf.is_empty() { | ||
let mut ctr = 0; | ||
let msg = Message::deserialize(&buf[ctr..], &mut ctr)?; | ||
// we reset the buf, because I couldn't figure out how the adjust_counter function | ||
// should should be changed to work correctly with non-zero start counter, and this solved that issue | ||
buf = &buf[ctr..]; | ||
ret.push(msg); | ||
|
||
// it is possible that while receiving messages, we get some extra/previous message | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we know why we get these extra messages? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As of now the only extra messages that are observed are of type signal, which basically broadcast some event to all connected clients. The thing is we used to get these before as well, but usually these would get consumed in buffers of some other method calls or such, and get ignored. In few cases that would not happen, which lead to the dbus error in question. To solve this, now we keep consuming all messages until we get method return or error message (in case of method call message). |
||
// for method calls, we need to have an error or method return type message, so | ||
// we keep looping until we get either of these. see https://github.com/containers/youki/issues/2826 | ||
// for more detailed analysis. | ||
loop { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure I understand why this loop is necessary. Shouldn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way |
||
let reply = self.receive_complete_response()?; | ||
|
||
// note that a single received response can contain multiple | ||
// messages, so we must deserialize it piece by piece | ||
let mut buf = &reply[..]; | ||
|
||
while !buf.is_empty() { | ||
let mut ctr = 0; | ||
let msg = Message::deserialize(&buf[ctr..], &mut ctr)?; | ||
// we reset the buf, because I couldn't figure out how the adjust_counter function | ||
// should should be changed to work correctly with non-zero start counter, and this solved that issue | ||
buf = &buf[ctr..]; | ||
ret.push(msg); | ||
} | ||
|
||
// in Youki, we only ever do method call apart from initial auth | ||
// in case it is, we don't really have a specific message to look | ||
// out of, so we take the buffer and break | ||
if mtype != MessageType::MethodCall { | ||
break; | ||
} | ||
|
||
// check if any of the received message is method return or error type | ||
let return_message_count = ret | ||
.iter() | ||
.filter(|m| { | ||
m.preamble.mtype == MessageType::MethodReturn | ||
|| m.preamble.mtype == MessageType::Error | ||
}) | ||
.count(); | ||
|
||
if return_message_count > 0 { | ||
break; | ||
} | ||
Comment on lines
+328
to
+346
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like suggestion for other ways to implement this. Ideally I feel that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I do not think it is. The complexity of should be contained in |
||
} | ||
Ok(ret) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍