Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 36 additions & 6 deletions Sources/Containerization/LinuxContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -712,8 +712,11 @@ extension LinuxContainer {
fileMountContextHolder.withLock { $0 = ctx }
}

// Start up our friendly unix socket relays.
for socket in self.config.sockets {
// Sockets relayed into the container must be staged before the
// container process starts so their bind mounts can be added to
// the runtime spec. Outbound relays are started after the process
// exists, when its mount namespace is available.
for socket in self.config.sockets where socket.direction == .into {
try await self.relayUnixSocket(
socket: socket,
relayManager: relayManager,
Expand Down Expand Up @@ -834,8 +837,21 @@ extension LinuxContainer {
)
try await process.start()

// Resolve outbound sockets through the running container's mount
// namespace. Looking beneath the static rootfs cannot see tmpfs or
// other mounts created by the OCI runtime.
for socket in self.config.sockets where socket.direction == .outOf {
try await self.relayUnixSocket(
socket: socket,
relayManager: createdState.relayManager,
agent: agent,
containerPID: process.pid
)
}

state = .started(.init(createdState, process: process))
} catch {
try? await createdState.relayManager.stopAll()
try? await agent.close()
try? await createdState.vm.stop()
state.setErrored(error: error)
Expand Down Expand Up @@ -1143,7 +1159,8 @@ extension LinuxContainer {
private func relayUnixSocket(
socket: UnixSocketConfiguration,
relayManager: UnixSocketRelayManager,
agent: any VirtualMachineAgent
agent: any VirtualMachineAgent,
containerPID: Int32? = nil
) async throws {
guard let relayAgent = agent as? SocketRelayAgent else {
throw ContainerizationError(
Expand All @@ -1153,19 +1170,32 @@ extension LinuxContainer {
}

var socket = socket
let rootInGuest = URL(filePath: self.root)

let port: UInt32
if socket.direction == .into {
port = self.hostVsockPorts.wrappingAdd(1, ordering: .relaxed).oldValue
socket.destination = URL(filePath: Self.guestSocketStagingPath(socket.id))
} else {
guard let containerPID, containerPID > 0 else {
throw ContainerizationError(
.invalidState,
message: "cannot start outbound socket relay before the container process"
)
}
port = self.guestVsockPorts.wrappingAdd(1, ordering: .relaxed).oldValue
socket.source = rootInGuest.appending(path: socket.source.path)
}

try await relayManager.start(port: port, socket: socket)
try await relayAgent.relaySocket(port: port, configuration: socket)
do {
try await relayAgent.relaySocket(
port: port,
configuration: socket,
containerPID: containerPID
)
} catch {
try? await relayManager.stop(socket: socket)
throw error
}
}

/// Default chunk size for file transfers (1MiB).
Expand Down
Loading