diff --git a/internal/daemon/daemon.go b/internal/daemon/daemon.go index 017ea2b..4cfe4e1 100644 --- a/internal/daemon/daemon.go +++ b/internal/daemon/daemon.go @@ -168,7 +168,7 @@ func (d *Daemon) Serve(ctx context.Context) error { return nil default: } - if ne, ok := err.(net.Error); ok && ne.Temporary() { + if _, ok := err.(net.Error); ok { if d.logger != nil { d.logger.Warn("daemon accept temporary failure", "error", err.Error()) } diff --git a/internal/daemon/vm.go b/internal/daemon/vm.go index 8190163..21e3836 100644 --- a/internal/daemon/vm.go +++ b/internal/daemon/vm.go @@ -326,10 +326,13 @@ func (d *Daemon) startVMLocked(ctx context.Context, vm model.VMRecord, image mod return cleanupOnErr(err) } if err := machine.Start(ctx); err != nil { - vm.Runtime.PID = d.resolveFirecrackerPID(ctx, machine, apiSock) + // Use a fresh context: the request ctx may already be cancelled (client + // disconnect), but we still need the PID so cleanupRuntime can kill the + // Firecracker process that was spawned before the failure. + vm.Runtime.PID = d.resolveFirecrackerPID(context.Background(), machine, apiSock) return cleanupOnErr(err) } - vm.Runtime.PID = d.resolveFirecrackerPID(ctx, machine, apiSock) + vm.Runtime.PID = d.resolveFirecrackerPID(context.Background(), machine, apiSock) op.debugStage("firecracker_started", "pid", vm.Runtime.PID) op.stage("socket_access", "api_socket", apiSock) if err := d.ensureSocketAccess(ctx, apiSock, "firecracker api socket"); err != nil {