-
Notifications
You must be signed in to change notification settings - Fork 85
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
vsock: TCP test + fix a bug leading to an error in TCP connect call in guest #267
Open
mtjhrc
wants to merge
7
commits into
containers:main
Choose a base branch
from
mtjhrc:tsi-tests-and-fixes
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
07ef524
to
a5b8eed
Compare
Add a tests directory containing an E2E testing framework. The tests are E2E in the sense that they use the public API of libkrun to start a VM and run a test program in the guest. Note that currently this is very limited, because there are no other userspace executables or libraries (not even libc) in the guest apart from `guest-agent`. `guest-agent` is a statically linked Rust executable, that executes the guest part of each test. In the future this can be extended to run tests with specific images which would allow the use of system libraries by the test program. This also introduces 2 tests: test_vm_config - asserts the VM is constructed with the correct number of CPUs and amount of memory. This also serves as an example how the tests can be parameterized. test_vsock_guest_connect - This tests the guest connecting to a vsock port created by the `krun_add_vsock_port` API. Signed-off-by: Matej Hrica <mhrica@redhat.com>
The install target should depend on generation of the libkrun.pc file, because it installs it. The libkrun.pc target should be .PHONY because libkrun.pc file might already exists and be generated, but it could be made using a different PREFIX, which would lead to the installed libkrun.pc pointing to the wrong prefix. Signed-off-by: Matej Hrica <mhrica@redhat.com>
Intruduce a test target in Makefile, that runs the e2e tests agains the built binary. Signed-off-by: Matej Hrica <mhrica@redhat.com>
a5b8eed
to
78b3f5a
Compare
Attempt to run the tests in a new network namespace to allow the tests to use fixed TCP ports. Signed-off-by: Matej Hrica <mhrica@redhat.com>
Signed-off-by: Matej Hrica <mhrica@redhat.com>
Add another state to the Proxy trait called ConnectedUnconfirmed. This is used when when the socket is connected (on the host), but confirm_connect hasn't been called yet. Make the TCP implementation use this new transitional state fixing the described bug: `libkrun` connects to the TCP socket on the host (this action is done upon the TSI_CONNECT request), but the guest is not yet connected to stream vsock socket corresponding to the actual transport for that connection. (We have not called `confirm_connect`). The problem is that since we assume the guest is already connected we attempt to recv in process_event. Which can cause the VSOCK_OP_CREDIT_REQUEST to be sent the guest, but the guest is expecting a VSOCK_OP_RESPONSE as a response to a connection request. This makes the guest kernel return EPROTO from the connect syscall. (specifically EPROTO is returned from the `virtio_transport_recv_connecting` in `net/vmw_vsock/virtio_transport_common.c`) Signed-off-by: Matej Hrica <mhrica@redhat.com>
…(vsock) Signed-off-by: Matej Hrica <mhrica@redhat.com>
78b3f5a
to
5988a3d
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds a simple tests that attempts to connect to a TCP socket on host from the guest. However this would often fail, due to a race condition:
As far as I understand, this is what happens:
libkrun
connects to the TCP socket on the host (this action is done upon the TSI_CONNECT request), but the guest is not connected to stream vsock socket corresponding to the actual transport for that connection. (We have not calledconfirm_connect
). The problem is that since we assume the guest is already connected we attempt to recv here:libkrun/src/devices/src/virtio/vsock/tcp.rs
Lines 700 to 714 in a84dc1a
This returns
wait_credit = true
, which causes us to sendVSOCK_OP_CREDIT_REQUEST
before sending theVSOCK_OP_RESPONSE
to theVSOCK_OP_REQUEST
which the guest kernel sends.The kernel is not expecting this and returns EPROTO from
connect
call in the guest userspace. (specifically EPROTO is returned from thevirtio_transport_recv_connecting
innet/vmw_vsock/virtio_transport_common.c
)The fix here introduces a new state ConnectedUnconfirmed which it uses for TCP Proxy code in vsock. This state is used as a transitional state between the host socket being connected to libkrun and the
confirm_connect
being called, meaning the connection is actually established to the guest and we can actually send/recv.A similar issue cannot happen with UDP sockets, because
VSOCK_OP_REQUEST
/VSOCK_OP_RESPONSE
is only used for stream sockets. This also cannot currently happen with UNIX stream sockets, because currently these are only ever connected on the host andconfirm_connect
-ed at the same time here:libkrun/src/devices/src/virtio/vsock/muxer.rs
Lines 533 to 534 in a84dc1a
Though, should the unix stream sockets also use the
ConnectedUnconfirmed
state too? For consistency of the semantics of theProxy
trait methods it would make sense...Depends on: #258