github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/container_daemon/initd/start.go (about)

     1  package initd
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  	"syscall"
     9  
    10  	"github.com/cloudfoundry-incubator/garden-linux/container_daemon"
    11  	"github.com/cloudfoundry-incubator/garden-linux/container_daemon/unix_socket"
    12  	"github.com/cloudfoundry-incubator/garden-linux/containerizer"
    13  	"github.com/cloudfoundry-incubator/garden-linux/containerizer/system"
    14  	"github.com/docker/docker/pkg/reexec"
    15  	"github.com/pivotal-golang/lager"
    16  
    17  	// for rexec.Register("proc_starter")
    18  	_ "github.com/cloudfoundry-incubator/garden-linux/container_daemon/proc_starter"
    19  )
    20  
    21  func init() {
    22  	reexec.Register("initd", start)
    23  }
    24  
    25  // initd listens on a socket, spawns requested processes and reaps their
    26  // exit statuses.
    27  func start() {
    28  	defer func() {
    29  		if r := recover(); r != nil {
    30  			fmt.Fprintf(os.Stderr, "initd: panicked: %s\n", r)
    31  			os.Exit(4)
    32  		}
    33  	}()
    34  
    35  	flag.String("title", "", "")
    36  	dropCaps := flag.Bool("dropCapabilities", false, "drop capabilities before running processes")
    37  	flag.Parse()
    38  
    39  	container_daemon.Detach("/dev/null", "/dev/null")
    40  	logger := lager.NewLogger("initd")
    41  
    42  	syncWriter := os.NewFile(uintptr(4), "/dev/sync_writer")
    43  	syscall.RawSyscall(syscall.SYS_FCNTL, uintptr(4), syscall.F_SETFD, syscall.FD_CLOEXEC)
    44  	defer syncWriter.Close()
    45  
    46  	sync := &containerizer.PipeSynchronizer{
    47  		Writer: syncWriter,
    48  	}
    49  
    50  	reaper := system.StartReaper(logger, syscall.Wait4)
    51  	defer reaper.Stop()
    52  
    53  	daemon := &container_daemon.ContainerDaemon{
    54  		CmdPreparer: &container_daemon.ProcessSpecPreparer{
    55  			Users:   container_daemon.LibContainerUser{},
    56  			Rlimits: &container_daemon.RlimitsManager{},
    57  			Reexec: container_daemon.CommandFunc(func(args ...string) *exec.Cmd {
    58  				return &exec.Cmd{
    59  					Path: "/proc/self/exe",
    60  					Args: args,
    61  				}
    62  			}),
    63  			AlwaysDropCapabilities: *dropCaps,
    64  		},
    65  		Spawner: &container_daemon.Spawn{
    66  			Runner: reaper,
    67  			PTY:    system.KrPty,
    68  		},
    69  		Signaller: &container_daemon.ProcessSignaller{
    70  			Logger: logger,
    71  		},
    72  	}
    73  
    74  	socketFile := os.NewFile(uintptr(5), "/dev/host.sock")
    75  	listener, err := unix_socket.NewListenerFromFile(socketFile)
    76  	if err != nil {
    77  		fail(fmt.Sprintf("initd: failed to create listener: %s\n", err), 5)
    78  	}
    79  
    80  	socketFile.Close()
    81  
    82  	if err := sync.SignalSuccess(); err != nil {
    83  		fail(fmt.Sprintf("signal host: %s", err), 6)
    84  	}
    85  
    86  	if err := daemon.Run(listener); err != nil {
    87  		fail(fmt.Sprintf("run daemon: %s", err), 7)
    88  	}
    89  }
    90  
    91  func fail(err string, code int) {
    92  	fmt.Fprintf(os.Stderr, "initd: %s\n", err)
    93  	os.Exit(code)
    94  }