From 5f7cbbf0b3d7a08661b9c6f6f15fbc0accf37782 Mon Sep 17 00:00:00 2001 From: Anton Myagkov Date: Wed, 12 Feb 2025 19:00:15 +0100 Subject: [PATCH] issue-3017: restore endpoints despite of missing socket directory (#3011) --- .../libs/endpoints/endpoint_manager.cpp | 5 +- cloud/blockstore/tests/e2e-tests/test.py | 63 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/cloud/blockstore/libs/endpoints/endpoint_manager.cpp b/cloud/blockstore/libs/endpoints/endpoint_manager.cpp index d1f2199dfda..0eab2ac33f5 100644 --- a/cloud/blockstore/libs/endpoints/endpoint_manager.cpp +++ b/cloud/blockstore/libs/endpoints/endpoint_manager.cpp @@ -740,7 +740,10 @@ TFuture TEndpointManager::RestoreSingleEndpoint( return promise.ExtractValue(); } - auto socketPath = request->GetUnixSocketPath(); + auto socketPath = TFsPath(request->GetUnixSocketPath()); + if (!socketPath.Parent().Exists()) { + socketPath.Parent().MkDir(); + } auto response = self->StartEndpointImpl( std::move(ctx), diff --git a/cloud/blockstore/tests/e2e-tests/test.py b/cloud/blockstore/tests/e2e-tests/test.py index 508bade7d27..41cda702ef6 100644 --- a/cloud/blockstore/tests/e2e-tests/test.py +++ b/cloud/blockstore/tests/e2e-tests/test.py @@ -431,3 +431,66 @@ def test_do_not_restore_endpoint_with_missing_volume(): assert result.returncode == 0 assert 0 == len(os.listdir(endpoints_dir)) cleanup_after_test(env) + + +def test_restore_endpoint_when_socket_directory_does_not_exist(): + # Scenario: + # 1. run nbs + # 2. create volume and start endpoint + # 4. copy endpoint to backup directory + # 5. stop endpoint + # 6. stop nbs + # 7. copy endpoint from backup directory to endpoints directory + # 8. remove socket directory + # 8. run nbs + # 9. check that endpoint was restored + env, run = init() + + volume_name = "example-disk" + block_size = 4096 + blocks_count = 10000 + nbd_device = Path("/dev/nbd0") + socket_dir = Path("/tmp") / volume_name + socket_dir.mkdir() + socket_path = socket_dir / "nbd.sock" + try: + result = run( + "createvolume", + "--disk-id", + volume_name, + "--blocks-count", + str(blocks_count), + "--block-size", + str(block_size), + ) + assert result.returncode == 0 + + result = run( + "startendpoint", + "--disk-id", + volume_name, + "--socket", + socket_path, + "--ipc-type", + "nbd", + "--persistent", + "--nbd-device", + nbd_device + ) + + shutil.rmtree(socket_dir) + + env.nbs.restart() + + result = run( + "listendpoints", + "--wait-for-restoring", + ) + assert result.returncode == 0 + assert socket_path.exists() + + except subprocess.CalledProcessError as e: + log_called_process_error(e) + raise + + cleanup_after_test(env)