Skip to content

procfs has data consistency issues when reading /proc/net/tcp #576

@shaohk

Description

@shaohk

func (fs FS) NetTCP() (NetTCP, error) {

I read tcp connections by procfs like this

package main

import (
	"fmt"

	"github.com/prometheus/procfs"
)

func main() {
	fs, _ := procfs.NewDefaultFS()

	tcps, _ := fs.NetTCP()
	for _, tcp := range tcps {
		fmt.Println(tcp.LocalAddr, tcp.LocalPort, tcp.RemAddr, tcp.RemPort, tcp.Inode)
	}
}

When I execute multiple times, I find that the same TCP connection appears twice. eg:

Tue Sep 26 18:48 [root@host ~]# ./nettcp | sort | uniq -c | grep '2 '
      ......
      1 192.168.0.2 22815 127.0.0.1 8181 4157386808
      2 192.168.0.2 24219 127.0.0.1 8300 4192187746
      1 192.168.0.2 29727 127.0.0.1 5002 4185948034
      ......

But, When I execute multiple netstat command, there won't be the phenomenon mentioned above. eg:

Tue Sep 26 18:50 [root@host ~]# netstat -npta | awk '{print $1, $4, $5, $7}' | sort | uniq -c
      ......
      1 tcp 192.168.0.2:11609 127.0.0.1:8300 138167/python
      1 tcp 192.168.0.2:12385 127.0.0.1:8300 138188/python
      1 tcp 192.168.0.2:12465 127.0.0.1:8035 266462/agent
      ......

And I find netstat source code, find the code that

FILE *proc_fopen(const char *name)
{
    static char *buffer;
    static size_t pagesz;
    FILE *fd = fopen(name, "r");

    if (fd == NULL)
      return NULL;

    if (!buffer) {
      pagesz = getpagesize();
      buffer = malloc(pagesz);
    }

    setvbuf(fd, buffer, _IOFBF, pagesz);

    return fd;
}

netstat sets the setvbuf to _IOFBF mode when opening the net/tcp file. But golang procfs doesn't set this.

How can we ensure consistency when reading net/tcp in Golang?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions