github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/daemon/listeners/listeners_linux.go (about) 1 package listeners // import "github.com/docker/docker/daemon/listeners" 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "net" 7 "os" 8 "strconv" 9 10 "github.com/coreos/go-systemd/activation" 11 "github.com/docker/go-connections/sockets" 12 "github.com/sirupsen/logrus" 13 ) 14 15 // Init creates new listeners for the server. 16 // TODO: Clean up the fact that socketGroup and tlsConfig aren't always used. 17 func Init(proto, addr, socketGroup string, tlsConfig *tls.Config) ([]net.Listener, error) { 18 ls := []net.Listener{} 19 20 switch proto { 21 case "fd": 22 fds, err := listenFD(addr, tlsConfig) 23 if err != nil { 24 return nil, err 25 } 26 ls = append(ls, fds...) 27 case "tcp": 28 l, err := sockets.NewTCPSocket(addr, tlsConfig) 29 if err != nil { 30 return nil, err 31 } 32 ls = append(ls, l) 33 case "unix": 34 // 查找group的gid从/etc/group中,默认是docker用户的gid 35 gid, err := lookupGID(socketGroup) 36 if err != nil { 37 if socketGroup != "" { 38 if socketGroup != defaultSocketGroup { 39 return nil, err 40 } 41 logrus.Warnf("could not change group %s to %s: %v", addr, defaultSocketGroup, err) 42 } 43 gid = os.Getgid() 44 } 45 // 创建unix socket对象 46 l, err := sockets.NewUnixSocket(addr, gid) 47 if err != nil { 48 return nil, fmt.Errorf("can't create unix socket %s: %v", addr, err) 49 } 50 ls = append(ls, l) 51 default: 52 return nil, fmt.Errorf("invalid protocol format: %q", proto) 53 } 54 55 return ls, nil 56 } 57 58 // listenFD returns the specified socket activated files as a slice of 59 // net.Listeners or all of the activated files if "*" is given. 60 func listenFD(addr string, tlsConfig *tls.Config) ([]net.Listener, error) { 61 var ( 62 err error 63 listeners []net.Listener 64 ) 65 // socket activation 66 if tlsConfig != nil { 67 listeners, err = activation.TLSListeners(tlsConfig) 68 } else { 69 listeners, err = activation.Listeners() 70 } 71 if err != nil { 72 return nil, err 73 } 74 75 if len(listeners) == 0 { 76 return nil, fmt.Errorf("no sockets found via socket activation: make sure the service was started by systemd") 77 } 78 79 // default to all fds just like unix:// and tcp:// 80 if addr == "" || addr == "*" { 81 return listeners, nil 82 } 83 84 fdNum, err := strconv.Atoi(addr) 85 if err != nil { 86 return nil, fmt.Errorf("failed to parse systemd fd address: should be a number: %v", addr) 87 } 88 fdOffset := fdNum - 3 89 if len(listeners) < fdOffset+1 { 90 return nil, fmt.Errorf("too few socket activated files passed in by systemd") 91 } 92 if listeners[fdOffset] == nil { 93 return nil, fmt.Errorf("failed to listen on systemd activated file: fd %d", fdOffset+3) 94 } 95 for i, ls := range listeners { 96 if i == fdOffset || ls == nil { 97 continue 98 } 99 if err := ls.Close(); err != nil { 100 return nil, fmt.Errorf("failed to close systemd activated file: fd %d: %v", fdOffset+3, err) 101 } 102 } 103 return []net.Listener{listeners[fdOffset]}, nil 104 }