diff --git a/scripts/vm/hypervisor/kvm/imageserver/backends/nbd.py b/scripts/vm/hypervisor/kvm/imageserver/backends/nbd.py index ed6d3ac6ed7..48ba1d9fe90 100644 --- a/scripts/vm/hypervisor/kvm/imageserver/backends/nbd.py +++ b/scripts/vm/hypervisor/kvm/imageserver/backends/nbd.py @@ -21,7 +21,13 @@ from typing import Any, Dict, List, Optional, Tuple import nbd -from ..constants import CHUNK_SIZE, NBD_STATE_DIRTY, NBD_STATE_HOLE, NBD_STATE_ZERO +from ..constants import ( + CHUNK_SIZE, + NBD_BLOCK_STATUS_CHUNK, + NBD_STATE_DIRTY, + NBD_STATE_HOLE, + NBD_STATE_ZERO, +) from ..util import merge_dirty_zero_extents from .base import BackendSession, ImageBackend @@ -175,7 +181,7 @@ class NbdConnection: return [{"start": 0, "length": size, "zero": False}] allocation_extents: List[Dict[str, Any]] = [] - chunk = min(size, 64 * 1024 * 1024) + chunk = min(size, NBD_BLOCK_STATUS_CHUNK) offset = 0 def extent_cb(*args: Any, **kwargs: Any) -> int: @@ -246,7 +252,7 @@ class NbdConnection: allocation_extents: List[Tuple[int, int, bool]] = [] dirty_extents: List[Tuple[int, int, bool]] = [] - chunk = min(size, 64 * 1024 * 1024) + chunk = min(size, NBD_BLOCK_STATUS_CHUNK) offset = 0 def extent_cb(*args: Any, **kwargs: Any) -> int: diff --git a/scripts/vm/hypervisor/kvm/imageserver/constants.py b/scripts/vm/hypervisor/kvm/imageserver/constants.py index 4e8d5c86da5..6e0ae03a0b5 100644 --- a/scripts/vm/hypervisor/kvm/imageserver/constants.py +++ b/scripts/vm/hypervisor/kvm/imageserver/constants.py @@ -26,5 +26,20 @@ NBD_STATE_DIRTY = 1 MAX_PARALLEL_READS = 8 MAX_PARALLEL_WRITES = 1 -CFG_DIR = "/tmp/imagetransfer" +# HTTP server defaults +DEFAULT_LISTEN_ADDRESS = "127.0.0.1" +DEFAULT_HTTP_PORT = 54323 + +# Control socket CONTROL_SOCKET = "/var/run/cloudstack/image-server.sock" +CONTROL_SOCKET_BACKLOG = 32 +CONTROL_SOCKET_PERMISSIONS = 0o660 +CONTROL_RECV_BUFFER = 4096 + +# Maximum size of a JSON body in a PATCH request (zero / flush ops) +MAX_PATCH_JSON_SIZE = 64 * 1024 # 64 KiB + +# Byte range requested per block_status call for NBD extent queries +NBD_BLOCK_STATUS_CHUNK = 64 * 1024 * 1024 # 64 MiB + +CFG_DIR = "/tmp/imagetransfer" diff --git a/scripts/vm/hypervisor/kvm/imageserver/handler.py b/scripts/vm/hypervisor/kvm/imageserver/handler.py index a689467238b..9bfed8d52f9 100644 --- a/scripts/vm/hypervisor/kvm/imageserver/handler.py +++ b/scripts/vm/hypervisor/kvm/imageserver/handler.py @@ -26,7 +26,7 @@ from urllib.parse import parse_qs from .backends import NbdBackend, create_backend from .concurrency import ConcurrencyManager from .config import TransferRegistry -from .constants import CHUNK_SIZE, MAX_PARALLEL_READS, MAX_PARALLEL_WRITES +from .constants import CHUNK_SIZE, MAX_PARALLEL_READS, MAX_PARALLEL_WRITES, MAX_PATCH_JSON_SIZE from .util import is_fallback_dirty_response, json_bytes, now_s @@ -422,7 +422,7 @@ class Handler(BaseHTTPRequestHandler): except ValueError: self._send_error_json(HTTPStatus.BAD_REQUEST, "Invalid Content-Length") return - if content_length <= 0 or content_length > 64 * 1024: + if content_length <= 0 or content_length > MAX_PATCH_JSON_SIZE: self._send_error_json(HTTPStatus.BAD_REQUEST, "Invalid Content-Length") return diff --git a/scripts/vm/hypervisor/kvm/imageserver/server.py b/scripts/vm/hypervisor/kvm/imageserver/server.py index d348bf4950d..53d4383b96f 100644 --- a/scripts/vm/hypervisor/kvm/imageserver/server.py +++ b/scripts/vm/hypervisor/kvm/imageserver/server.py @@ -33,7 +33,16 @@ except ImportError: from .concurrency import ConcurrencyManager from .config import TransferRegistry -from .constants import CONTROL_SOCKET, MAX_PARALLEL_READS, MAX_PARALLEL_WRITES +from .constants import ( + CONTROL_RECV_BUFFER, + CONTROL_SOCKET, + CONTROL_SOCKET_BACKLOG, + CONTROL_SOCKET_PERMISSIONS, + DEFAULT_HTTP_PORT, + DEFAULT_LISTEN_ADDRESS, + MAX_PARALLEL_READS, + MAX_PARALLEL_WRITES, +) from .handler import Handler @@ -95,7 +104,7 @@ def _handle_control_conn(conn: socket.socket, registry: TransferRegistry) -> Non try: data = b"" while True: - chunk = conn.recv(4096) + chunk = conn.recv(CONTROL_RECV_BUFFER) if not chunk: break data += chunk @@ -151,8 +160,8 @@ def _control_listener(registry: TransferRegistry, sock_path: str) -> None: srv = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) srv.bind(sock_path) - os.chmod(sock_path, 0o660) - srv.listen(5) + os.chmod(sock_path, CONTROL_SOCKET_PERMISSIONS) + srv.listen(CONTROL_SOCKET_BACKLOG) logging.info("control socket listening on %s", sock_path) while True: @@ -168,8 +177,8 @@ def main() -> None: parser = argparse.ArgumentParser( description="CloudStack image server backed by NBD / local file" ) - parser.add_argument("--listen", default="127.0.0.1", help="Address to bind") - parser.add_argument("--port", type=int, default=54323, help="Port to listen on") + parser.add_argument("--listen", default=DEFAULT_LISTEN_ADDRESS, help="Address to bind") + parser.add_argument("--port", type=int, default=DEFAULT_HTTP_PORT, help="Port to listen on") parser.add_argument( "--control-socket", default=CONTROL_SOCKET,