server_linux.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // +build linux
  2. package server
  3. import (
  4. "fmt"
  5. "net"
  6. "net/http"
  7. "github.com/docker/docker/daemon"
  8. "github.com/docker/docker/pkg/sockets"
  9. "github.com/docker/docker/pkg/systemd"
  10. )
  11. // newServer sets up the required serverCloser and does protocol specific checking.
  12. func (s *Server) newServer(proto, addr string) (serverCloser, error) {
  13. var (
  14. err error
  15. l net.Listener
  16. )
  17. switch proto {
  18. case "fd":
  19. ls, err := systemd.ListenFD(addr)
  20. if err != nil {
  21. return nil, err
  22. }
  23. chErrors := make(chan error, len(ls))
  24. // We don't want to start serving on these sockets until the
  25. // daemon is initialized and installed. Otherwise required handlers
  26. // won't be ready.
  27. <-s.start
  28. // Since ListenFD will return one or more sockets we have
  29. // to create a go func to spawn off multiple serves
  30. for i := range ls {
  31. listener := ls[i]
  32. go func() {
  33. httpSrv := http.Server{Handler: s.router}
  34. chErrors <- httpSrv.Serve(listener)
  35. }()
  36. }
  37. for i := 0; i < len(ls); i++ {
  38. if err := <-chErrors; err != nil {
  39. return nil, err
  40. }
  41. }
  42. return nil, nil
  43. case "tcp":
  44. l, err = s.initTcpSocket(addr)
  45. if err != nil {
  46. return nil, err
  47. }
  48. case "unix":
  49. if l, err = sockets.NewUnixSocket(addr, s.cfg.SocketGroup, s.start); err != nil {
  50. return nil, err
  51. }
  52. default:
  53. return nil, fmt.Errorf("Invalid protocol format: %q", proto)
  54. }
  55. return &HttpServer{
  56. &http.Server{
  57. Addr: addr,
  58. Handler: s.router,
  59. },
  60. l,
  61. }, nil
  62. }
  63. func (s *Server) AcceptConnections(d *daemon.Daemon) {
  64. // Tell the init daemon we are accepting requests
  65. s.daemon = d
  66. go systemd.SdNotify("READY=1")
  67. // close the lock so the listeners start accepting connections
  68. select {
  69. case <-s.start:
  70. default:
  71. close(s.start)
  72. }
  73. }