|
14 | 14 | """
|
15 | 15 |
|
16 | 16 | import os.path
|
| 17 | +import subprocess |
| 18 | +import time |
| 19 | +from pathlib import Path |
17 | 20 | from socket import timeout as SocketTimeout
|
18 | 21 |
|
19 | 22 | from framework.utils_vsock import (
|
@@ -126,7 +129,7 @@ def test_vsock_epipe(uvm_plain, bin_vsock_path, test_fc_session_root_path):
|
126 | 129 | validate_fc_metrics(metrics)
|
127 | 130 |
|
128 | 131 |
|
129 |
| -def test_vsock_transport_reset( |
| 132 | +def test_vsock_transport_reset_h2g( |
130 | 133 | uvm_nano, microvm_factory, bin_vsock_path, test_fc_session_root_path
|
131 | 134 | ):
|
132 | 135 | """
|
@@ -215,3 +218,93 @@ def test_vsock_transport_reset(
|
215 | 218 | check_host_connections(path, blob_path, blob_hash)
|
216 | 219 | metrics = vm2.flush_metrics()
|
217 | 220 | validate_fc_metrics(metrics)
|
| 221 | + |
| 222 | + |
| 223 | +def test_vsock_transport_reset_g2h( |
| 224 | + uvm_nano, microvm_factory, bin_vsock_path, test_fc_session_root_path |
| 225 | +): |
| 226 | + """ |
| 227 | + Vsock transport reset test. |
| 228 | + """ |
| 229 | + test_vm = uvm_nano |
| 230 | + test_vm.add_net_iface() |
| 231 | + test_vm.api.vsock.put(vsock_id="vsock0", guest_cid=3, uds_path=f"/{VSOCK_UDS_PATH}") |
| 232 | + test_vm.start() |
| 233 | + test_vm.wait_for_up() |
| 234 | + |
| 235 | + # Generate the random data blob file. |
| 236 | + blob_path, blob_hash = make_blob(test_fc_session_root_path) |
| 237 | + vm_blob_path = "/tmp/vsock/test.blob" |
| 238 | + |
| 239 | + # Set up a tmpfs drive on the guest, so we can copy the blob there. |
| 240 | + # Guest-initiated connections (echo workers) will use this blob. |
| 241 | + _copy_vsock_data_to_guest(test_vm.ssh, blob_path, vm_blob_path, bin_vsock_path) |
| 242 | + |
| 243 | + host_socket_path = os.path.join( |
| 244 | + test_vm.path, f"{VSOCK_UDS_PATH}_{ECHO_SERVER_PORT}" |
| 245 | + ) |
| 246 | + host_socat_commmand = [ |
| 247 | + "socat", |
| 248 | + "-dddd", |
| 249 | + f"UNIX-LISTEN:{host_socket_path},fork", |
| 250 | + "STDOUT", |
| 251 | + ] |
| 252 | + host_socat = subprocess.Popen( |
| 253 | + host_socat_commmand, stdout=subprocess.PIPE, stderr=subprocess.PIPE |
| 254 | + ) |
| 255 | + |
| 256 | + # Give some time for host socat to create socket |
| 257 | + time.sleep(0.5) |
| 258 | + assert Path(host_socket_path).exists() |
| 259 | + test_vm.create_jailed_resource(host_socket_path) |
| 260 | + |
| 261 | + # Create a socat process in the guest which will connect to the host socat |
| 262 | + guest_socat_commmand = f"tmux new -d 'socat - vsock-connect:2:{ECHO_SERVER_PORT}'" |
| 263 | + test_vm.ssh.run(guest_socat_commmand) |
| 264 | + |
| 265 | + # socat should be running in the guest now |
| 266 | + code, _, _ = test_vm.ssh.run("pidof socat") |
| 267 | + assert code == 0 |
| 268 | + |
| 269 | + # Create snapshot. |
| 270 | + snapshot = test_vm.snapshot_full() |
| 271 | + test_vm.resume() |
| 272 | + |
| 273 | + # After `create_snapshot` + 'restore' calls, connection should be dropped |
| 274 | + code, _, _ = test_vm.ssh.run("pidof socat") |
| 275 | + assert code == 1 |
| 276 | + |
| 277 | + # Kill host socat as it is not useful anymore |
| 278 | + host_socat.kill() |
| 279 | + host_socat.communicate() |
| 280 | + |
| 281 | + # Terminate VM. |
| 282 | + metrics = test_vm.flush_metrics() |
| 283 | + validate_fc_metrics(metrics) |
| 284 | + test_vm.kill() |
| 285 | + |
| 286 | + # Load snapshot. |
| 287 | + vm2 = microvm_factory.build() |
| 288 | + vm2.spawn() |
| 289 | + vm2.restore_from_snapshot(snapshot, resume=True) |
| 290 | + vm2.wait_for_up() |
| 291 | + |
| 292 | + # After snap restore all vsock connections should be |
| 293 | + # dropped. This means guest socat should exit same way |
| 294 | + # as it did after snapshot was taken. |
| 295 | + code, _, _ = vm2.ssh.run("pidof socat") |
| 296 | + assert code == 1 |
| 297 | + |
| 298 | + # Start guest echo server. |
| 299 | + path = start_guest_echo_server(vm2) |
| 300 | + |
| 301 | + # Check that vsock device still works. |
| 302 | + # Test guest-initiated connections. |
| 303 | + path = os.path.join(vm2.path, make_host_port_path(VSOCK_UDS_PATH, ECHO_SERVER_PORT)) |
| 304 | + check_guest_connections(vm2, path, vm_blob_path, blob_hash) |
| 305 | + |
| 306 | + # Test host-initiated connections. |
| 307 | + path = os.path.join(vm2.jailer.chroot_path(), VSOCK_UDS_PATH) |
| 308 | + check_host_connections(path, blob_path, blob_hash) |
| 309 | + metrics = vm2.flush_metrics() |
| 310 | + validate_fc_metrics(metrics) |
0 commit comments