Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
shaohk opened this issue Sep 26, 2023 · 3 comments · Fixed by #631
Closed

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

shaohk opened this issue Sep 26, 2023 · 3 comments · Fixed by #631

Comments

@shaohk
Copy link

shaohk commented Sep 26, 2023

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?

@discordianfish
Copy link
Member

We essentially just parse net/tcp, can you provide the relevant /proc/net/tcp content in this situation?

@dswarbrick
Copy link
Contributor

@shaohk Are you implying that you suspect the contents of /proc/netstat are changing mid-flight when procfs reads that file? I would be skeptical of that, since it is read with io.ReadAll (limited to 1 MiB) via the internal/util.ReadFileNoStat function.

@rexagod
Copy link
Contributor

rexagod commented Mar 21, 2024

I couldn't reproduce this with the aforementioned snippet running for a thousand times. @shaohk Are you still able to reproduce this with the latest release?

SuperQ pushed a commit that referenced this issue Apr 15, 2024
```
TCP, TCP6, UDP, and UDP6 are dynamically changing,
and when we read these files, we should read them all at once.
there will be data consistency issues if using line by lin reading

fix: #576
```

Signed-off-by: weidongkl <weidong@uniontech.com>
jritter pushed a commit to jritter/procfs that referenced this issue Jul 15, 2024
```
TCP, TCP6, UDP, and UDP6 are dynamically changing,
and when we read these files, we should read them all at once.
there will be data consistency issues if using line by lin reading

fix: prometheus#576
```

Signed-off-by: weidongkl <weidong@uniontech.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants