@@ -6,13 +6,16 @@ import (
66 "fmt"
77 "os"
88 "runtime"
9+ "strconv"
910
1011 "github.com/Sirupsen/logrus"
1112 "github.com/codegangsta/cli"
1213 "github.com/opencontainers/runc/libcontainer"
1314 "github.com/opencontainers/specs"
1415)
1516
17+ const SD_LISTEN_FDS_START = 3
18+
1619var startCommand = cli.Command {
1720 Name : "start" ,
1821 Usage : "create and run a container" ,
@@ -27,6 +30,13 @@ var startCommand = cli.Command{
2730 setupSdNotify (spec , notifySocket )
2831 }
2932
33+ listenFds := os .Getenv ("LISTEN_FDS" )
34+ listenPid := os .Getenv ("LISTEN_PID" )
35+
36+ if listenFds != "" && listenPid == strconv .Itoa (os .Getpid ()) {
37+ setupSocketActivation (spec , listenFds )
38+ }
39+
3040 if os .Geteuid () != 0 {
3141 logrus .Fatal ("runc should be run as root" )
3242 }
@@ -79,6 +89,19 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec) (int, error) {
7989 // that created it.
8090 defer destroy (container )
8191 process := newProcess (spec .Process )
92+
93+ //support for on-demand socket activation: pass file descriptors into the container.
94+ if os .Getenv ("LISTEN_FDS" ) != "" {
95+ listenFdsInt , err := strconv .Atoi (os .Getenv ("LISTEN_FDS" ))
96+ if err != nil {
97+ return - 1 , err
98+ }
99+
100+ for i := SD_LISTEN_FDS_START ; i < (listenFdsInt + SD_LISTEN_FDS_START ); i ++ {
101+ process .ExtraFiles = append (process .ExtraFiles , os .NewFile (uintptr (i ), "" ))
102+ }
103+ }
104+
82105 tty , err := newTty (spec .Process .Terminal , process , rootuid )
83106 if err != nil {
84107 return - 1 , err
@@ -100,6 +123,13 @@ func setupSdNotify(spec *specs.LinuxSpec, notifySocket string) {
100123 spec .Process .Env = append (spec .Process .Env , fmt .Sprintf ("NOTIFY_SOCKET=%s" , notifySocket ))
101124}
102125
126+ // If systemd is supporting on-demand socket activation, this function will add support
127+ // for on-demand socket activation for the containerized service.
128+ func setupSocketActivation (spec * specs.LinuxSpec , listenFds string ) {
129+ spec .Process .Env = append (spec .Process .Env , fmt .Sprintf ("LISTEN_FDS=%s" , listenFds ))
130+ spec .Process .Env = append (spec .Process .Env , "LISTEN_PID=1" )
131+ }
132+
103133func destroy (container libcontainer.Container ) {
104134 status , err := container .Status ()
105135 if err != nil {
0 commit comments