libpod: Filter out ENOTCONN errors when trying to close unix domain sockets
On FreeBSD, ENOTCONN can be reported if shutdown is called on a unix domain socket where the remote end is already closed. This change ignores those errors instead of printing an error message on container exit. [NO NEW TESTS NEEDED] Signed-off-by: Doug Rabson <dfr@rabson.org>
This commit is contained in:
		
							parent
							
								
									6668ac93bb
								
							
						
					
					
						commit
						f85fa9806a
					
				|  | @ -280,20 +280,20 @@ func readStdio(conn *net.UnixConn, streams *define.AttachStreams, receiveStdoutE | ||||||
| 	var err error | 	var err error | ||||||
| 	select { | 	select { | ||||||
| 	case err = <-receiveStdoutError: | 	case err = <-receiveStdoutError: | ||||||
| 		if err := conn.CloseWrite(); err != nil { | 		if err := socketCloseWrite(conn); err != nil { | ||||||
| 			logrus.Errorf("Failed to close stdin: %v", err) | 			logrus.Errorf("Failed to close stdin: %v", err) | ||||||
| 		} | 		} | ||||||
| 		return err | 		return err | ||||||
| 	case err = <-stdinDone: | 	case err = <-stdinDone: | ||||||
| 		if err == define.ErrDetach { | 		if err == define.ErrDetach { | ||||||
| 			if err := conn.CloseWrite(); err != nil { | 			if err := socketCloseWrite(conn); err != nil { | ||||||
| 				logrus.Errorf("Failed to close stdin: %v", err) | 				logrus.Errorf("Failed to close stdin: %v", err) | ||||||
| 			} | 			} | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		if err == nil { | 		if err == nil { | ||||||
| 			// copy stdin is done, close it
 | 			// copy stdin is done, close it
 | ||||||
| 			if connErr := conn.CloseWrite(); connErr != nil { | 			if connErr := socketCloseWrite(conn); connErr != nil { | ||||||
| 				logrus.Errorf("Unable to close conn: %v", connErr) | 				logrus.Errorf("Unable to close conn: %v", connErr) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -477,6 +477,16 @@ func (r *ConmonOCIRuntime) UnpauseContainer(ctr *Container) error { | ||||||
| 	return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, append(r.runtimeFlags, "resume", ctr.ID())...) | 	return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, append(r.runtimeFlags, "resume", ctr.ID())...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // This filters out ENOTCONN errors which can happen on FreeBSD if the
 | ||||||
|  | // other side of the connection is already closed.
 | ||||||
|  | func socketCloseWrite(conn *net.UnixConn) error { | ||||||
|  | 	err := conn.CloseWrite() | ||||||
|  | 	if err != nil && errors.Is(err, syscall.ENOTCONN) { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // HTTPAttach performs an attach for the HTTP API.
 | // HTTPAttach performs an attach for the HTTP API.
 | ||||||
| // The caller must handle closing the HTTP connection after this returns.
 | // The caller must handle closing the HTTP connection after this returns.
 | ||||||
| // The cancel channel is not closed; it is up to the caller to do so after
 | // The cancel channel is not closed; it is up to the caller to do so after
 | ||||||
|  | @ -689,7 +699,7 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http. | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 			// copy stdin is done, close it
 | 			// copy stdin is done, close it
 | ||||||
| 			if connErr := conn.CloseWrite(); connErr != nil { | 			if connErr := socketCloseWrite(conn); connErr != nil { | ||||||
| 				logrus.Errorf("Unable to close conn: %v", connErr) | 				logrus.Errorf("Unable to close conn: %v", connErr) | ||||||
| 			} | 			} | ||||||
| 		case <-cancel: | 		case <-cancel: | ||||||
|  |  | ||||||
|  | @ -653,7 +653,7 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 			// copy stdin is done, close it
 | 			// copy stdin is done, close it
 | ||||||
| 			if connErr := conn.CloseWrite(); connErr != nil { | 			if connErr := socketCloseWrite(conn); connErr != nil { | ||||||
| 				logrus.Errorf("Unable to close conn: %v", connErr) | 				logrus.Errorf("Unable to close conn: %v", connErr) | ||||||
| 			} | 			} | ||||||
| 		case <-cancel: | 		case <-cancel: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue