github.com/containers/podman/v4@v4.9.4/pkg/machine/sockets.go (about) 1 package machine 2 3 import ( 4 "bufio" 5 "bytes" 6 "fmt" 7 "net" 8 "path/filepath" 9 "time" 10 11 "github.com/containers/podman/v4/pkg/machine/define" 12 ) 13 14 // SetSocket creates a new machine file for the socket and assigns it to 15 // `socketLoc` 16 func SetSocket(socketLoc *define.VMFile, path string, symlink *string) error { 17 socket, err := define.NewMachineFile(path, symlink) 18 if err != nil { 19 return err 20 } 21 *socketLoc = *socket 22 return nil 23 } 24 25 // ReadySocketPath returns the filepath for the ready socket 26 func ReadySocketPath(runtimeDir, machineName string) string { 27 return filepath.Join(runtimeDir, fmt.Sprintf("%s_ready.sock", machineName)) 28 } 29 30 // ListenAndWaitOnSocket waits for a new connection to the listener and sends 31 // any error back through the channel. ListenAndWaitOnSocket is intended to be 32 // used as a goroutine 33 func ListenAndWaitOnSocket(errChan chan<- error, listener net.Listener) { 34 conn, err := listener.Accept() 35 if err != nil { 36 errChan <- err 37 return 38 } 39 _, err = bufio.NewReader(conn).ReadString('\n') 40 41 if closeErr := conn.Close(); closeErr != nil { 42 errChan <- closeErr 43 return 44 } 45 46 errChan <- err 47 } 48 49 // DialSocketWithBackoffs attempts to connect to the socket in maxBackoffs attempts 50 func DialSocketWithBackoffs(maxBackoffs int, backoff time.Duration, socketPath string) (conn net.Conn, err error) { 51 for i := 0; i < maxBackoffs; i++ { 52 if i > 0 { 53 time.Sleep(backoff) 54 backoff *= 2 55 } 56 conn, err = net.Dial("unix", socketPath) 57 if err == nil { 58 return conn, nil 59 } 60 } 61 return nil, err 62 } 63 64 // DialSocketWithBackoffsAndProcCheck attempts to connect to the socket in 65 // maxBackoffs attempts. After every failure to connect, it makes sure the 66 // specified process is alive 67 func DialSocketWithBackoffsAndProcCheck( 68 maxBackoffs int, 69 backoff time.Duration, 70 socketPath string, 71 checkProccessStatus func(string, int, *bytes.Buffer) error, 72 procHint string, 73 procPid int, 74 errBuf *bytes.Buffer, 75 ) (conn net.Conn, err error) { 76 for i := 0; i < maxBackoffs; i++ { 77 if i > 0 { 78 time.Sleep(backoff) 79 backoff *= 2 80 } 81 conn, err = net.Dial("unix", socketPath) 82 if err == nil { 83 return conn, nil 84 } 85 86 // check to make sure process denoted by procHint is alive 87 err = checkProccessStatus(procHint, procPid, errBuf) 88 if err != nil { 89 return nil, err 90 } 91 } 92 return nil, err 93 }