summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhaircommander <pehunt@redhat.com>2018-08-20 18:24:35 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2018-08-21 15:37:39 +0000
commit149481a57184becf3e9be329d253602654414118 (patch)
treedff153e67e834673756e2f10aed2c6bfb7494067
parent021027a24b7b6906a2d7ed86c67e34167bc26284 (diff)
downloadpodman-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.go28
-rw-r--r--libpod/stats.go10
-rw-r--r--test/e2e/stats_test.go23
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))
+ })
})