diff options
author | haircommander <pehunt@redhat.com> | 2018-08-20 18:24:35 -0400 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-08-21 15:37:39 +0000 |
commit | 149481a57184becf3e9be329d253602654414118 (patch) | |
tree | dff153e67e834673756e2f10aed2c6bfb7494067 | |
parent | 021027a24b7b6906a2d7ed86c67e34167bc26284 (diff) | |
download | podman-149481a57184becf3e9be329d253602654414118.tar.gz podman-149481a57184becf3e9be329d253602654414118.tar.bz2 podman-149481a57184becf3e9be329d253602654414118.zip |
Fixed segfault in stats where container had netNS none or from container
Signed-off-by: haircommander <pehunt@redhat.com>
Closes: #1306
Approved by: rhatdan
-rw-r--r-- | libpod/networking_linux.go | 28 | ||||
-rw-r--r-- | libpod/stats.go | 10 | ||||
-rw-r--r-- | test/e2e/stats_test.go | 23 |
3 files changed, 58 insertions, 3 deletions
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index e5f935e30..77ab97910 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -249,9 +249,35 @@ func (r *Runtime) teardownNetNS(ctr *Container) error { return nil } +func getContainerNetNS(ctr *Container) (string, error) { + if ctr.state.NetNS != nil { + return ctr.state.NetNS.Path(), nil + } + if ctr.config.NetNsCtr != "" { + c, err := ctr.runtime.GetContainer(ctr.config.NetNsCtr) + if err != nil { + return "", err + } + if err = c.syncContainer(); err != nil { + return "", err + } + return c.state.NetNS.Path(), nil + } + return "", nil +} + func getContainerNetIO(ctr *Container) (*netlink.LinkStatistics, error) { var netStats *netlink.LinkStatistics - err := ns.WithNetNSPath(ctr.state.NetNS.Path(), func(_ ns.NetNS) error { + netNSPath, netPathErr := getContainerNetNS(ctr) + if netPathErr != nil { + return nil, netPathErr + } + if netNSPath == "" { + // If netNSPath is empty, it was set as none, and no netNS was set up + // this is a valid state and thus return no error, nor any statistics + return nil, nil + } + err := ns.WithNetNSPath(netNSPath, func(_ ns.NetNS) error { link, err := netlink.LinkByName(ocicni.DefaultInterfaceName) if err != nil { return err diff --git a/libpod/stats.go b/libpod/stats.go index 7830919ba..61e85ed5e 100644 --- a/libpod/stats.go +++ b/libpod/stats.go @@ -66,8 +66,14 @@ func (c *Container) GetContainerStats(previousStats *ContainerStats) (*Container stats.BlockInput, stats.BlockOutput = calculateBlockIO(cgroupStats) stats.CPUNano = cgroupStats.CPU.Usage.Total stats.SystemNano = cgroupStats.CPU.Usage.Kernel - stats.NetInput = netStats.TxBytes - stats.NetOutput = netStats.RxBytes + // Handle case where the container is not in a network namespace + if netStats != nil { + stats.NetInput = netStats.TxBytes + stats.NetOutput = netStats.RxBytes + } else { + stats.NetInput = 0 + stats.NetOutput = 0 + } return stats, nil } diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go index ad40cbe5a..8096f58b2 100644 --- a/test/e2e/stats_test.go +++ b/test/e2e/stats_test.go @@ -90,4 +90,27 @@ var _ = Describe("Podman stats", func() { Expect(session.IsJSONOutputValid()).To(BeTrue()) }) + It("podman stats on a container with no net ns", func() { + session := podmanTest.Podman([]string{"run", "-d", "--net", "none", ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session = podmanTest.Podman([]string{"stats", "--no-stream", "-a"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) + + It("podman stats on a container that joined another's net ns", func() { + session := podmanTest.RunTopContainer("") + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + cid := session.OutputToString() + + session = podmanTest.Podman([]string{"run", "-d", "--net", fmt.Sprintf("container:%s", cid), ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"stats", "--no-stream", "-a"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) }) |