@@ -36,6 +36,9 @@ type virtualMachineWrapper struct {
3636 stopped bool
3737}
3838
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+
3942func startVM (ctx context.Context , driver * driver.BaseDriver ) (* virtualMachineWrapper , chan error , error ) {
4043 usernetClient , err := startUsernet (ctx , driver )
4144 if err != nil {
@@ -57,7 +60,11 @@ func startVM(ctx context.Context, driver *driver.BaseDriver) (*virtualMachineWra
5760 errCh := make (chan error )
5861 go func () {
5962 //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+ }()
6168 for {
6269 select {
6370 case <- ctx .Done ():
@@ -700,5 +707,14 @@ func createSockPair() (*os.File, *os.File, error) {
700707 if err = syscall .SetsockoptInt (clientFD , syscall .SOL_SOCKET , syscall .SO_RCVBUF , 4 * 1024 * 1024 ); err != nil {
701708 return nil , nil , err
702709 }
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
704720}
0 commit comments