From b1f78e61a13328317eb661af5e73dbabac30fa88 Mon Sep 17 00:00:00 2001 From: Lokesh Mandvekar Date: Mon, 24 Sep 2018 09:31:35 -0400 Subject: [PATCH] runc-2:1.0.0-54.dev.git00dc700 - built commit 00dc700 - rebase 1807.patch - enable debuginfo for all versions Signed-off-by: Lokesh Mandvekar --- .gitignore | 1 + 1807.patch | 298 +++++++++++++++++++++++++++++++++-------------------- runc.spec | 14 +-- sources | 2 +- 4 files changed, 198 insertions(+), 117 deletions(-) diff --git a/.gitignore b/.gitignore index 6f98444..947cd0c 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ /runc-20aff4f.tar.gz /runc-fdd8055.tar.gz /runc-70ca035.tar.gz +/runc-00dc700.tar.gz diff --git a/1807.patch b/1807.patch index 4f46e89..8dab9a9 100644 --- a/1807.patch +++ b/1807.patch @@ -1,168 +1,179 @@ -From ecf53c23545092019602578583031c28fde4d2a1 Mon Sep 17 00:00:00 2001 +From cd9b959b34c183cf6cd031af678c4ec66b765080 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 25 May 2018 18:04:06 +0200 Subject: [PATCH] sd-notify: do not hang when NOTIFY_SOCKET is used with create if NOTIFY_SOCKET is used, do not block the main runc process waiting -for events on the notify socket. Change the logic to create a new -process that monitors exclusively the notify socket until an event is -received. +for events on the notify socket. Bind mount the parent directory of +the notify socket, so that "start" can create the socket and it is +still accessible from the container. Signed-off-by: Giuseppe Scrivano --- - init.go | 12 +++++++ - notify_socket.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++--------- + notify_socket.go | 113 ++++++++++++++++++++++++++++++++++------------- signals.go | 5 +-- - 3 files changed, 99 insertions(+), 19 deletions(-) + start.go | 13 +++++- + utils_linux.go | 12 ++++- + 4 files changed, 106 insertions(+), 37 deletions(-) -diff --git a/init.go b/init.go -index c8f453192..6a3d9e91c 100644 ---- a/init.go -+++ b/init.go -@@ -20,6 +20,18 @@ var initCommand = cli.Command{ - Name: "init", - Usage: `initialize the namespaces and launch the process (do not call it outside of runc)`, - Action: func(context *cli.Context) error { -+ // If NOTIFY_SOCKET is used create a new process that stays around -+ // so to not block "runc start". It will automatically exits when the -+ // container notifies that it is ready, or when the container is deleted -+ if os.Getenv("_NOTIFY_SOCKET_FD") != "" { -+ fd := os.Getenv("_NOTIFY_SOCKET_FD") -+ pid := os.Getenv("_NOTIFY_SOCKET_PID") -+ hostNotifySocket := os.Getenv("_NOTIFY_SOCKET_HOST") -+ notifySocketPath := os.Getenv("_NOTIFY_SOCKET_PATH") -+ notifySocketInit(fd, pid, hostNotifySocket, notifySocketPath) -+ os.Exit(0) -+ } -+ - factory, _ := libcontainer.New("") - if err := factory.StartInitialization(); err != nil { - // as the error is sent back to the parent there is no need to log diff --git a/notify_socket.go b/notify_socket.go -index cd6c0a989..e04e9d660 100644 +index cd6c0a98..7fbd2e73 100644 --- a/notify_socket.go +++ b/notify_socket.go -@@ -6,10 +6,13 @@ import ( +@@ -6,11 +6,14 @@ import ( "bytes" "fmt" "net" + "os" -+ "os/exec" ++ "path" "path/filepath" + "strconv" + "time" ++ "github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runtime-spec/specs-go" - - "github.com/sirupsen/logrus" +- "github.com/sirupsen/logrus" "github.com/urfave/cli" ) -@@ -64,24 +67,94 @@ func (s *notifySocket) setupSocket() error { + +@@ -26,12 +29,12 @@ func newNotifySocket(context *cli.Context, notifySocketHost string, id string) * + } + + root := filepath.Join(context.GlobalString("root"), id) +- path := filepath.Join(root, "notify.sock") ++ socketPath := filepath.Join(root, "notify", "notify.sock") + + notifySocket := ¬ifySocket{ + socket: nil, + host: notifySocketHost, +- socketPath: path, ++ socketPath: socketPath, + } + + return notifySocket +@@ -43,13 +46,19 @@ func (ns *notifySocket) Close() error { + + // If systemd is supporting sd_notify protocol, this function will add support + // for sd_notify protocol from within the container. +-func (s *notifySocket) setupSpec(context *cli.Context, spec *specs.Spec) { +- mount := specs.Mount{Destination: s.host, Source: s.socketPath, Options: []string{"bind"}} ++func (s *notifySocket) setupSpec(context *cli.Context, spec *specs.Spec) error { ++ pathInContainer := filepath.Join("/run/notify", path.Base(s.socketPath)) ++ mount := specs.Mount{ ++ Destination: path.Dir(pathInContainer), ++ Source: path.Dir(s.socketPath), ++ Options: []string{"bind", "nosuid", "noexec", "nodev", "ro"}, ++ } + spec.Mounts = append(spec.Mounts, mount) +- spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", s.host)) ++ spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", pathInContainer)) ++ return nil + } + +-func (s *notifySocket) setupSocket() error { ++func (s *notifySocket) bindSocket() error { + addr := net.UnixAddr{ + Name: s.socketPath, + Net: "unixgram", +@@ -64,45 +73,89 @@ func (s *notifySocket) setupSocket() error { return nil } -+func (notifySocket *notifySocket) notifyNewPid(pid int) { -+ notifySocketHostAddr := net.UnixAddr{Name: notifySocket.host, Net: "unixgram"} -+ client, err := net.DialUnix("unixgram", nil, ¬ifySocketHostAddr) -+ if err != nil { -+ return -+ } -+ newPid := fmt.Sprintf("MAINPID=%d\n", pid) -+ client.Write([]byte(newPid)) -+} -+ - // pid1 must be set only with -d, as it is used to set the new process as the main process - // for the service in systemd - func (notifySocket *notifySocket) run(pid1 int) { +-// pid1 must be set only with -d, as it is used to set the new process as the main process +-// for the service in systemd +-func (notifySocket *notifySocket) run(pid1 int) { - buf := make([]byte, 512) - notifySocketHostAddr := net.UnixAddr{Name: notifySocket.host, Net: "unixgram"} -- client, err := net.DialUnix("unixgram", nil, ¬ifySocketHostAddr) -+ file, err := notifySocket.socket.File() ++func (s *notifySocket) setupSocketDirectory() error { ++ return os.Mkdir(path.Dir(s.socketPath), 0755) ++} ++ ++func notifySocketStart(context *cli.Context, notifySocketHost, id string) (*notifySocket, error) { ++ notifySocket := newNotifySocket(context, notifySocketHost, id) ++ if notifySocket == nil { ++ return nil, nil ++ } ++ ++ if err := notifySocket.bindSocket(); err != nil { ++ return nil, err ++ } ++ return notifySocket, nil ++} ++ ++func (n *notifySocket) waitForContainer(container libcontainer.Container) error { ++ s, err := container.State() ++ if err != nil { ++ return err ++ } ++ return n.run(s.InitProcessPid) ++} ++ ++func (n *notifySocket) run(pid1 int) error { ++ if n.socket == nil { ++ return nil ++ } ++ notifySocketHostAddr := net.UnixAddr{Name: n.host, Net: "unixgram"} + client, err := net.DialUnix("unixgram", nil, ¬ifySocketHostAddr) if err != nil { - logrus.Error(err) - return +- logrus.Error(err) +- return ++ return err } - for { - r, err := notifySocket.socket.Read(buf) - if err != nil { - break -+ defer file.Close() -+ defer notifySocket.socket.Close() + -+ cmd := exec.Command("/proc/self/exe", "init") -+ cmd.ExtraFiles = []*os.File{file} -+ cmd.Env = append(cmd.Env, "_NOTIFY_SOCKET_FD=3", -+ fmt.Sprintf("_NOTIFY_SOCKET_PID=%d", pid1), -+ fmt.Sprintf("_NOTIFY_SOCKET_HOST=%s", notifySocket.host), -+ fmt.Sprintf("_NOTIFY_SOCKET_PATH=%s", notifySocket.socketPath)) -+ -+ if err := cmd.Start(); err != nil { -+ logrus.Fatal(err) -+ } -+ notifySocket.notifyNewPid(cmd.Process.Pid) -+ cmd.Process.Release() -+} -+ -+func notifySocketInit(envFd string, envPid string, notifySocketHost string, notifySocketPath string) { -+ intFd, err := strconv.Atoi(envFd) -+ if err != nil { -+ return -+ } -+ pid1, err := strconv.Atoi(envPid) -+ if err != nil { -+ return -+ } -+ -+ file := os.NewFile(uintptr(intFd), "unixgram") -+ defer file.Close() ++ ticker := time.NewTicker(time.Millisecond * 100) ++ defer ticker.Stop() + + fileChan := make(chan []byte) -+ exitChan := make(chan bool) -+ + go func() { + for { + buf := make([]byte, 512) -+ r, err := file.Read(buf) ++ r, err := n.socket.Read(buf) + if err != nil { + return + } -+ fileChan <- buf[0:r] ++ got := buf[0:r] ++ if !bytes.HasPrefix(got, []byte("READY=")) { ++ continue ++ } ++ fileChan <- got ++ return } - var out bytes.Buffer - for _, line := range bytes.Split(buf[0:r], []byte{'\n'}) { - if bytes.HasPrefix(line, []byte("READY=")) { + }() -+ go func() { -+ for { -+ if _, err := os.Stat(notifySocketPath); os.IsNotExist(err) { -+ exitChan <- true -+ return -+ } -+ time.Sleep(time.Second) -+ } -+ }() -+ -+ notifySocketHostAddr := net.UnixAddr{Name: notifySocketHost, Net: "unixgram"} -+ client, err := net.DialUnix("unixgram", nil, ¬ifySocketHostAddr) -+ if err != nil { -+ return -+ } + + for { + select { -+ case <-exitChan: -+ return ++ case <-ticker.C: ++ _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid1))) ++ if err != nil { ++ return nil ++ } + case b := <-fileChan: + for _, line := range bytes.Split(b, []byte{'\n'}) { -+ if !bytes.HasPrefix(line, []byte("READY=")) { -+ continue -+ } -+ + var out bytes.Buffer _, err = out.Write(line) if err != nil { - return -@@ -98,10 +171,8 @@ func (notifySocket *notifySocket) run(pid1 int) { +- return ++ return err + } + + _, err = out.Write([]byte{'\n'}) + if err != nil { +- return ++ return err + } + + _, err = client.Write(out.Bytes()) + if err != nil { +- return ++ return err } // now we can inform systemd to use pid1 as the pid to monitor @@ -170,13 +181,15 @@ index cd6c0a989..e04e9d660 100644 - newPid := fmt.Sprintf("MAINPID=%d\n", pid1) - client.Write([]byte(newPid)) - } +- return + newPid := fmt.Sprintf("MAINPID=%d\n", pid1) + client.Write([]byte(newPid)) - return ++ return nil } } + } diff --git a/signals.go b/signals.go -index 1811de837..d0988cb39 100644 +index 1811de83..d0988cb3 100644 --- a/signals.go +++ b/signals.go @@ -70,7 +70,7 @@ func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach @@ -198,3 +211,70 @@ index 1811de837..d0988cb39 100644 return e.status, nil } } +diff --git a/start.go b/start.go +index 2bb698b2..3a1769a4 100644 +--- a/start.go ++++ b/start.go +@@ -3,6 +3,7 @@ package main + import ( + "errors" + "fmt" ++ "os" + + "github.com/opencontainers/runc/libcontainer" + "github.com/urfave/cli" +@@ -31,7 +32,17 @@ your host.`, + } + switch status { + case libcontainer.Created: +- return container.Exec() ++ notifySocket, err := notifySocketStart(context, os.Getenv("NOTIFY_SOCKET"), container.ID()) ++ if err != nil { ++ return err ++ } ++ if err := container.Exec(); err != nil { ++ return err ++ } ++ if notifySocket != nil { ++ return notifySocket.waitForContainer(container) ++ } ++ return nil + case libcontainer.Stopped: + return errors.New("cannot start a container that has stopped") + case libcontainer.Running: +diff --git a/utils_linux.go b/utils_linux.go +index c6a34897..77423f67 100644 +--- a/utils_linux.go ++++ b/utils_linux.go +@@ -420,7 +420,9 @@ func startContainer(context *cli.Context, spec *specs.Spec, action CtAct, criuOp + + notifySocket := newNotifySocket(context, os.Getenv("NOTIFY_SOCKET"), id) + if notifySocket != nil { +- notifySocket.setupSpec(context, spec) ++ if err := notifySocket.setupSpec(context, spec); err != nil { ++ return -1, err ++ } + } + + container, err := createContainer(context, id, spec) +@@ -429,10 +431,16 @@ func startContainer(context *cli.Context, spec *specs.Spec, action CtAct, criuOp + } + + if notifySocket != nil { +- err := notifySocket.setupSocket() ++ err := notifySocket.setupSocketDirectory() + if err != nil { + return -1, err + } ++ if action == CT_ACT_RUN { ++ err := notifySocket.bindSocket() ++ if err != nil { ++ return -1, err ++ } ++ } + } + + // Support on-demand socket activation by passing file descriptors into the container init process. +-- +2.17.1 + diff --git a/runc.spec b/runc.spec index b544440..380f366 100644 --- a/runc.spec +++ b/runc.spec @@ -2,12 +2,7 @@ %global with_bundled 1 %global with_check 0 %global with_unit_test 0 - -%if 0%{?fedora} > 28 -%global with_debug 0 -%else %global with_debug 1 -%endif %if 0%{?with_debug} %global _find_debuginfo_dwz_opts %{nil} @@ -24,13 +19,13 @@ %global provider_prefix %{provider}.%{provider_tld}/%{project}/%{repo} %global import_path %{provider_prefix} %global git0 https://github.com/opencontainers/runc -%global commit0 70ca035aa6ecfc496e13365fdef20383408501ba +%global commit0 00dc70017d222b178a002ed30e9321b12647af2d %global shortcommit0 %(c=%{commit0}; echo ${c:0:7}) Name: %{repo} Epoch: 2 Version: 1.0.0 -Release: 53.dev.git%{shortcommit0}%{?dist} +Release: 54.dev.git%{shortcommit0}%{?dist} Summary: CLI for running Open Containers License: ASL 2.0 URL: %{git0} @@ -289,6 +284,11 @@ export GOPATH=%{buildroot}/%{gopath}:$(pwd)/Godeps/_workspace:%{gopath} %endif %changelog +* Mon Sep 24 2018 Lokesh Mandvekar - 2:1.0.0-54.dev.git00dc700 +- built commit 00dc700 +- rebase 1807.patch +- enable debuginfo for all versions + * Fri Sep 07 2018 baude - 2:1.0.0-53.dev.git70ca035 - Add BuildRequires git diff --git a/sources b/sources index b32ea6f..2961269 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (runc-70ca035.tar.gz) = 3373395f6e3cf2b379f803ec57e4005e00daab518e5d88b40f637620d77134445331525a058ffe672dc65bc409a10703409315f0d5fc649d889619ab7a1521e0 +SHA512 (runc-00dc700.tar.gz) = c50d7f865a0c4d9a97dc429e91d7c552e6f01543418a751eb778415bb563ae41457a161af5c8e0a62a14b9419b3730bb0a235c500478f6937eeacaf77b220887