Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C] I/O-Puffer abschalten



roadracer
26-08-2011, 15:29
Hallo,
schon wieder ein Thread von mir hier. :D

Also, zum Thema:
Ich habe ein Programm in Arbeit. Dieses soll die Anzahl der gesendeten Bytes in /sys/class/net/eth0/statistics/rx_bytes (oder so) lesen und auswerten. Später soll die ganze Geschichte (auch) auf meinem Homeserver (TrekStor/Linux/ARM) laufen. Programmieren tue ich aber an meinem normalen PC (OpenSUSE/x86).

Zum Problem:
Da /sys/class/net/eth0/statistics/rx_bytes alle paar Sekunden ausgelesen werden soll, muss ich die Pufferung dieser Datei unterbinden, da sonst immer der selbe Wert eingelesen wird. Eigentlich mit einer FILE-Struktur und setbuf()/setvbuf() kein Problem. Nachdem das aber auf meinem Server nicht ging, habe ich noch einen Filedescriptor und 0_SYNC/O_DIRECT probiert. Bringt aber auch nix.
PC(x86):


file = fopen("/sys/class/net/eth0/statistics/rx_bytes", "r");
geht nicht!

file = fopen("/sys/class/net/eth0/statistics/rx_bytes", "r");
setbuf(file, NULL);
-oder-
setvbuf(file, NULL, _IONBF, 0);
geht!
fd = open("/sys/class/net/eth0/statistics/rx_bytes", O_RDONLY);
geht!
fd = open("/sys/class/net/eth0/statistics/rx_bytes", O_RDONLY | O_SYNC);
geht!
fd = open("/sys/class/net/eth0/statistics/rx_bytes", O_RDONLY | O_DIRECT);
geht!
fd = open("/sys/class/net/eth0/statistics/rx_bytes", O_RDONLY | O_SYNC | O_DIRECT);
geht!

Server(ARM):


file = fopen("/sys/class/net/eth0/statistics/rx_bytes", "r");
geht nicht!

file = fopen("/sys/class/net/eth0/statistics/rx_bytes", "r");
setbuf(file, NULL);
-oder-
setvbuf(file, NULL, _IONBF, 0);
geht nicht!

fd = open("/sys/class/net/eth0/statistics/rx_bytes", O_RDONLY);
geht nicht!

fd = open("/sys/class/net/eth0/statistics/rx_bytes", O_RDONLY | O_SYNC);
geht nicht!

fd = open("/sys/class/net/eth0/statistics/rx_bytes", O_RDONLY | O_DIRECT);
geht nicht!

fd = open("/sys/class/net/eth0/statistics/rx_bytes", O_RDONLY | O_SYNC | O_DIRECT);
geht nicht!

Das einzige was hilft, ist die Datei vor jedem Auslesen zu schließen und neu zu öffnen. Das ist aber ziemliche Pfuscherei.

Für mich sieht es so aus, als habe Trekstor in seiner Firmware den Linux-Kernel gepached, dass er die Unterbindung der Pufferung nicht mehr zulässt.
Kennt jemand eine Lösung?

VG

sommerfee
26-08-2011, 16:56
Dieses soll die Anzahl der gesendeten Bytes in /sys/class/net/eth0/statistics/rx_bytes (oder so) lesen und auswerten.

Habe ich das richtig verstanden? Es geht nur darum, wie groß diese Datei ist? Dann würde ich stat() nehmen.

roadracer
26-08-2011, 18:26
Was, Größe der Datei? Die kann ich dir jetzt schon sagen: In jedem Fall 4096 Byte egal was drinsteht.
Ich möchte im Sekundentakt diese Datei immer wieder auslesen und auswerten. Nur muss ich dafür die Pufferung abstellen und das will mir auf meinem Homeserver nicht gelingen.

msi
26-08-2011, 22:08
ein paar ideen:

- datei immer neu auf/zumachen
- mmap verwenden?

roadracer
27-08-2011, 12:50
mmap hört sich recht interessant an, mir ist nur noch nicht ganz klar wie ich es bei meinem Problem einsetzten soll.
Ich würde es einfach so versuchen:

file = open(...);
mapped_m = mmap(..., file, ...);
while(...) {
read(mapped_m, ...);
msync(file, ...);
}
munmap(file, ...);
Kommt das hin?

undefined
28-08-2011, 17:17
In anbetracht dessen das ohnehin immer nur eine Zeile drinne steht ;)


/**
* gcc -W -Wextra -pedantic -o example open.c
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
int c;
size_t *t = malloc(0);
char **gptr = (char **)malloc(sizeof(char *));

FILE *fp = fopen("/sys/class/net/eth0/statistics/rx_bytes","r");
if(NULL == fp)
{
fprintf(stderr, "Öffnen von %s fehlgeschlagen!\n", "rx_bytes");
return EXIT_FAILURE;
}

while((c = getline(gptr, t, fp)) > 0)
{
fputs(*gptr, stdout);
}
fclose(fp);

return EXIT_SUCCESS;
}

roadracer
28-08-2011, 17:24
@undefined:
Das geht zwar auf meinem x86 PC, jedoch nicht auf meinem ARM Homeserver, wo ich die Datei im Sekundentakt immer wieder auslesen muss.