forked from wrenn/wrenn
fix: assorted bug fixes for CH migration
Fix resource leaks, race conditions, and error handling across host agent and control plane: proper sparse file cleanup on close error, connect error wrapping for MakeDir, CoW file cleanup on pause failure, per-sandbox VM directories, deferred map deletion to avoid race in VM destroy, and goroutine launch for extension background workers.
This commit is contained in:
@ -379,5 +379,9 @@ func createSparseFile(path string, sizeBytes int64) error {
|
|||||||
os.Remove(path)
|
os.Remove(path)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return f.Close()
|
if err := f.Close(); err != nil {
|
||||||
|
os.Remove(path)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -301,7 +301,7 @@ func (s *Server) MakeDir(
|
|||||||
|
|
||||||
resp, err := client.MakeDir(ctx, msg.Path)
|
resp, err := client.MakeDir(ctx, msg.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("make dir: %w", err)
|
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("make dir: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return connect.NewResponse(&pb.MakeDirResponse{
|
return connect.NewResponse(&pb.MakeDirResponse{
|
||||||
@ -373,6 +373,8 @@ func (s *Server) ExecStream(
|
|||||||
Error: ev.Error,
|
Error: ev.Error,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if err := stream.Send(&resp); err != nil {
|
if err := stream.Send(&resp); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -889,6 +891,8 @@ func (s *Server) ConnectProcess(
|
|||||||
Error: ev.Error,
|
Error: ev.Error,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if err := stream.Send(&resp); err != nil {
|
if err := stream.Send(&resp); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -541,6 +541,7 @@ func (m *Manager) Pause(ctx context.Context, sandboxID string) error {
|
|||||||
warnErr("snapshot dir cleanup error", sandboxID, os.RemoveAll(pauseDir))
|
warnErr("snapshot dir cleanup error", sandboxID, os.RemoveAll(pauseDir))
|
||||||
warnErr("network cleanup error during pause", sandboxID, network.RemoveNetwork(sb.slot))
|
warnErr("network cleanup error during pause", sandboxID, network.RemoveNetwork(sb.slot))
|
||||||
m.slots.Release(sb.SlotIndex)
|
m.slots.Release(sb.SlotIndex)
|
||||||
|
os.Remove(sb.dmDevice.CowPath)
|
||||||
if sb.baseImagePath != "" {
|
if sb.baseImagePath != "" {
|
||||||
m.loops.Release(sb.baseImagePath)
|
m.loops.Release(sb.baseImagePath)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,7 +77,7 @@ func (c *VMConfig) applyDefaults() {
|
|||||||
c.SocketPath = fmt.Sprintf("/tmp/ch-%s.sock", c.SandboxID)
|
c.SocketPath = fmt.Sprintf("/tmp/ch-%s.sock", c.SandboxID)
|
||||||
}
|
}
|
||||||
if c.SandboxDir == "" {
|
if c.SandboxDir == "" {
|
||||||
c.SandboxDir = "/tmp/ch-vm"
|
c.SandboxDir = fmt.Sprintf("/tmp/ch-vm-%s", c.SandboxID)
|
||||||
}
|
}
|
||||||
if c.TapDevice == "" {
|
if c.TapDevice == "" {
|
||||||
c.TapDevice = "tap0"
|
c.TapDevice = "tap0"
|
||||||
|
|||||||
@ -143,7 +143,6 @@ func (m *Manager) Destroy(ctx context.Context, sandboxID string) error {
|
|||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
return fmt.Errorf("VM not found: %s", sandboxID)
|
return fmt.Errorf("VM not found: %s", sandboxID)
|
||||||
}
|
}
|
||||||
delete(m.vms, sandboxID)
|
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
|
|
||||||
slog.Info("destroying VM", "sandbox", sandboxID)
|
slog.Info("destroying VM", "sandbox", sandboxID)
|
||||||
@ -161,6 +160,10 @@ func (m *Manager) Destroy(ctx context.Context, sandboxID string) error {
|
|||||||
|
|
||||||
os.Remove(vm.Config.SocketPath)
|
os.Remove(vm.Config.SocketPath)
|
||||||
|
|
||||||
|
m.mu.Lock()
|
||||||
|
delete(m.vms, sandboxID)
|
||||||
|
m.mu.Unlock()
|
||||||
|
|
||||||
slog.Info("VM destroyed", "sandbox", sandboxID)
|
slog.Info("VM destroyed", "sandbox", sandboxID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -255,7 +255,7 @@ func Run(opts ...Option) {
|
|||||||
// Start extension background workers.
|
// Start extension background workers.
|
||||||
for _, ext := range o.extensions {
|
for _, ext := range o.extensions {
|
||||||
for _, worker := range ext.BackgroundWorkers(sctx) {
|
for _, worker := range ext.BackgroundWorkers(sctx) {
|
||||||
worker(ctx)
|
go worker(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user