Skip to content
Snippets Groups Projects
Commit 945d4174 authored by ghuter's avatar ghuter
Browse files

Merge branch 'alexis_fix_net' into dev

parents ddbe21e6 6ac89356
No related branches found
No related tags found
2 merge requests!9fix sensor example (doc),!5Add dev name to labels
/*
* Example of a basic counter: an accumulator
**/
unsigned int init_acc(char *, void **);
unsigned int get_acc(uint64_t *results, void *);
void clean_acc(void *);
void label_acc(char **labels, void *);
Sensor rapl = {
.init = init_acc,
.get = get_acc,
.clean = clean_acc,
.label = label_acc,
.nb_opt = 1,
};
Optparse rapl_opt[1] = {
{
.longname = "accumulator",
.shortname = 'a',
.argtype = OPTPARSE_NONE, /* OPTPARSE_NONE / OPTPARSE_OPTIONAL / OPTPARSE_REQUIRED */
.usage_arg = NULL,
.usage_msg = "dumb accumulator",
},
};
This sensor can autodetect interfaces in use by giving the special
interface name "X". But the total number of interfaces it can autodetect
is currently under a hard-limit. This hard-limit can be changed by
modifying this line in `src/network.c`:
```c
#define NB_MAX_DEV 8
```
......@@ -17,28 +17,40 @@
along with MojitO/S. If not, see <https://www.gnu.org/licenses/>.
*******************************************************/
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include "util.h"
#define NB_MAX_DEV 8
#define NB_SENSOR 4
static char *route = "/proc/net/route";
char *_labels_network[NB_SENSOR] = {
"%s:rxp",
"%s:rxb",
"%s:txp",
"%s:txb",
};
struct Network {
uint64_t values[NB_SENSOR];
uint64_t tmp_values[NB_SENSOR];
int sources[NB_SENSOR];
uint64_t values[NB_MAX_DEV][NB_SENSOR];
uint64_t tmp_values[NB_MAX_DEV][NB_SENSOR];
int sources[NB_MAX_DEV][NB_SENSOR];
char labels[NB_MAX_DEV][NB_SENSOR][128];
char devs[NB_MAX_DEV][128];
int ndev;
};
typedef struct Network Network;
unsigned int _get_network(uint64_t *results, int *sources)
static void _get_network(uint64_t *results, int *sources)
{
if (sources == NULL) {
return 0;
return;
}
char buffer[128];
......@@ -51,18 +63,51 @@ unsigned int _get_network(uint64_t *results, int *sources)
results[i] = strtoull(buffer, NULL, 10);
}
return NB_SENSOR;
}
/*
* read from fd len chars and store them into buf
* make *s points to the first occurence of c into buf
*/
static int strchr_refill(int fd, char *buf, int len, char **s, char c)
{
*s = strchr(*s, c);
if (*s == NULL) {
int nbytes = read(fd, buf, len - 1);
if (nbytes < 0) {
perror("read");
return -1;
}
buf[len - 1] = '\0';
/* whole file read */
if (nbytes == 0) {
return 0;
}
*s = strchr(buf, c);
}
return 1;
}
unsigned int init_network(char *dev, void **ptr)
{
if (dev == NULL) {
return 0;
exit(1);
}
char *filenames[] = {
"/sys/class/net/%s/statistics/rx_packets",
"/sys/class/net/%s/statistics/rx_bytes",
"/sys/class/net/%s/statistics/tx_packets",
"/sys/class/net/%s/statistics/tx_bytes",
};
struct Network *state = malloc(sizeof(struct Network));
memset(state, '\0', sizeof(*state));
if (strcmp(dev, "X") == 0) {
int fd = open(route, O_RDONLY);
......@@ -74,50 +119,110 @@ unsigned int init_network(char *dev, void **ptr)
char buffer[1000];
if (read(fd, buffer, 999) < 0 ) {
perror("read");
/* skip first line */
char *s = buffer;
int ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\n');
if (ret != 1) {
close(fd);
free(state);
exit(1);
}
s++;
char *start_of_dev = index(buffer, '\n') + 1;
char *end_of_dev = index(start_of_dev, '\t');
*end_of_dev = '\0';
dev = start_of_dev;
close(fd);
}
char *start_of_dev = s;
/* jump to the end of the device name */
ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\t');
if (ret != 1) {
close(fd);
free(state);
exit(1);
}
char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
"/sys/class/net/%s/statistics/rx_bytes",
"/sys/class/net/%s/statistics/tx_packets",
"/sys/class/net/%s/statistics/tx_bytes"
};
state->ndev++; // ndev should be equal to 1 at this point
memcpy(&(state->devs[state->ndev - 1]), start_of_dev,
MIN((size_t)(sizeof(state->devs[0]) - 1), (size_t)(s - start_of_dev)));
for (;;) {
/* jump to the next line */
ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\n');
if (ret != 1) {
break;
}
s++;
start_of_dev = s;
ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\t');
if (ret != 1) {
break;
}
/* compare dev name to the previously saved one */
int newdev = 1;
for (int i = 0; i < state->ndev && newdev; i++) {
if (strncmp(start_of_dev, state->devs[i], s - start_of_dev) == 0) {
newdev = 0;
}
}
if (newdev) {
if (state->ndev >= NB_MAX_DEV) {
fprintf(stderr, "Maximum amount of network devices exceeded (%d).\n", NB_MAX_DEV);
break;
}
state->ndev++;
memcpy(&(state->devs[state->ndev - 1]), start_of_dev,
MIN((size_t)(sizeof(state->devs[0]) - 1), (size_t)(s - start_of_dev)));
}
}
Network *state = malloc(sizeof(Network));
close(fd);
} else {
state->ndev = 1;
memcpy(&(state->devs[0]), dev, strlen(dev) + 1);
}
char buffer2[256];
for (int i = 0; i < NB_SENSOR; i++) {
snprintf(buffer2, 256, filenames[i], dev);
state->sources[i] = open(buffer2, O_RDONLY);
for (int i = 0; i < state->ndev; i++) {
for (int j = 0; j < NB_SENSOR; j++) {
snprintf(buffer2, sizeof(buffer2), filenames[j], state->devs[i]);
errno = 0;
int fd = open(buffer2, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "init_network: open: %s: %.*s\n", strerror(errno),
(int)sizeof(buffer2), buffer2);
free(state);
exit(1);
}
state->sources[i][j] = fd;
snprintf(state->labels[i][j], sizeof(state->labels[i][j]), _labels_network[j],
state->devs[i]);
}
}
*ptr = (void *) state;
_get_network(state->values, state->sources);
return NB_SENSOR;
for (int i = 0; i < state->ndev; i++) {
_get_network(state->values[i], state->sources[i]);
}
return state->ndev * NB_SENSOR;
}
unsigned int get_network(uint64_t *results, void *ptr)
{
Network *state = (Network *) ptr;
_get_network(state->tmp_values, state->sources);
struct Network *state = (struct Network *) ptr;
for (int i = 0; i < NB_SENSOR; i++) {
results[i] = modulo_substraction(state->tmp_values[i], state->values[i]);
for (int i = 0; i < state->ndev; i++) {
_get_network(state->tmp_values[i], state->sources[i]);
for (int j = 0; j < NB_SENSOR; j++) {
results[i*NB_SENSOR + j] = modulo_substraction(state->tmp_values[i][j], state->values[i][j]);
}
memcpy(&(state->values[i]), &(state->tmp_values[i]),
NB_SENSOR * sizeof(state->values[i][0]));
}
memcpy(state->values, state->tmp_values, NB_SENSOR * sizeof(uint64_t));
return NB_SENSOR;
return state->ndev * NB_SENSOR;
}
void clean_network(void *ptr)
......@@ -128,19 +233,22 @@ void clean_network(void *ptr)
return;
}
for (int i = 0; i < NB_SENSOR; i++) {
close(state->sources[i]);
for (int i = 0; i < state->ndev; i++) {
for (int j = 0; j < NB_SENSOR; j++) {
close(state->sources[i][j]);
}
}
free(state);
}
char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
void label_network(char **labels, void *none)
void label_network(char **labels, void *ptr)
{
UNUSED(none);
struct Network *state = (struct Network *) ptr;
for (int i = 0; i < NB_SENSOR; i++) {
labels[i] = _labels_network[i];
for (int i = 0; i < state->ndev; i++) {
for (int j = 0; j < NB_SENSOR; j++) {
labels[i*NB_SENSOR + j] = state->labels[i][j];
}
}
}
......@@ -38,6 +38,8 @@
exit(code); \
} while (0)
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
/**
* @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment