(pid1 int)
| 105 | } |
| 106 | |
| 107 | func (s *notifySocket) run(pid1 int) error { |
| 108 | if s.socket == nil { |
| 109 | return nil |
| 110 | } |
| 111 | notifySocketHostAddr := net.UnixAddr{Name: s.host, Net: "unixgram"} |
| 112 | client, err := net.DialUnix("unixgram", nil, ¬ifySocketHostAddr) |
| 113 | if err != nil { |
| 114 | return err |
| 115 | } |
| 116 | |
| 117 | ticker := time.NewTicker(time.Millisecond * 100) |
| 118 | defer ticker.Stop() |
| 119 | |
| 120 | fileChan := make(chan []byte) |
| 121 | go func() { |
| 122 | for { |
| 123 | buf := make([]byte, 4096) |
| 124 | r, err := s.socket.Read(buf) |
| 125 | if err != nil { |
| 126 | return |
| 127 | } |
| 128 | got := buf[0:r] |
| 129 | // systemd-ready sends a single datagram with the state string as payload, |
| 130 | // so we don't need to worry about partial messages. |
| 131 | for line := range bytes.SplitSeq(got, []byte{'\n'}) { |
| 132 | if bytes.HasPrefix(got, []byte("READY=")) { |
| 133 | fileChan <- line |
| 134 | return |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | } |
| 139 | }() |
| 140 | |
| 141 | for { |
| 142 | select { |
| 143 | case <-ticker.C: |
| 144 | _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid1))) |
| 145 | if err != nil { |
| 146 | return nil |
| 147 | } |
| 148 | case b := <-fileChan: |
| 149 | return notifyHost(client, b, pid1) |
| 150 | } |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | // notifyHost tells the host (usually systemd) that the container reported READY. |
| 155 | // Also sends MAINPID and BARRIER. |
no test coverage detected