@@ -36,6 +36,9 @@ type virtualMachineWrapper struct {
36
36
stopped bool
37
37
}
38
38
39
+ // Hold all *os.File created via socketpair() so that they won't get garbage collected. f.FD() gets invalid if f gets garbage collected.
40
+ var vmNetworkFiles = make ([]* os.File , 1 )
41
+
39
42
func startVM (ctx context.Context , driver * driver.BaseDriver ) (* virtualMachineWrapper , chan error , error ) {
40
43
usernetClient , err := startUsernet (ctx , driver )
41
44
if err != nil {
@@ -57,7 +60,11 @@ func startVM(ctx context.Context, driver *driver.BaseDriver) (*virtualMachineWra
57
60
errCh := make (chan error )
58
61
go func () {
59
62
//Handle errors via errCh and handle stop vm during context close
60
-
63
+ defer func () {
64
+ for i := range vmNetworkFiles {
65
+ vmNetworkFiles [i ].Close ()
66
+ }
67
+ }()
61
68
for {
62
69
select {
63
70
case <- ctx .Done ():
@@ -700,5 +707,14 @@ func createSockPair() (*os.File, *os.File, error) {
700
707
if err = syscall .SetsockoptInt (clientFD , syscall .SOL_SOCKET , syscall .SO_RCVBUF , 4 * 1024 * 1024 ); err != nil {
701
708
return nil , nil , err
702
709
}
703
- return os .NewFile (uintptr (serverFD ), "server" ), os .NewFile (uintptr (clientFD ), "client" ), nil
710
+ server := os .NewFile (uintptr (serverFD ), "server" )
711
+ client := os .NewFile (uintptr (clientFD ), "client" )
712
+ runtime .SetFinalizer (server , func (file * os.File ) {
713
+ logrus .Debugf ("Server network file GC'ed" )
714
+ })
715
+ runtime .SetFinalizer (client , func (file * os.File ) {
716
+ logrus .Debugf ("Client network file GC'ed" )
717
+ })
718
+ vmNetworkFiles = append (vmNetworkFiles , server , client )
719
+ return server , client , nil
704
720
}
0 commit comments