Skip to content

Commit

Permalink
STAT code, fixes & review comments by Serge.
Browse files Browse the repository at this point in the history
Signed-off-by: Anjali Kulkarni <[email protected]>
  • Loading branch information
anjalidk authored and hallyn committed Jan 17, 2024
1 parent 0d2c90f commit 18ad4c3
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 3 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CC = gcc
CFLAGS = -g -Wall -Werror -fPIC -std=gnu99
DEPS = resource.h resource_impl.h resmem.h resnet.h resproc.h resvm.h rescpu.h resfs.h
OBJ = resource.o resmem.o resnet.o resproc.o reskern.o resvm.o rescpu.o resfs.o net_if.o net_route.o net_arp.o
DEPS = resource.h resource_impl.h resmem.h resnet.h resproc.h resvm.h rescpu.h resfs.h stat.h
OBJ = resource.o resmem.o resnet.o resproc.o reskern.o resvm.o rescpu.o resfs.o net_if.o net_route.o net_arp.o stat.o
TEST = test
RM = rm -rf
CP = cp
Expand Down
4 changes: 4 additions & 0 deletions resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "resnet.h"
#include "resproc.h"
#include "resvm.h"
#include "stat.h"
#include "rescpu.h"
#include "resfs.h"

Expand Down Expand Up @@ -212,6 +213,9 @@ int res_read(int res_id, void *out, size_t out_sz, void **hint, int pid, int fla
if (res_id >= DEV_MIN && res_id < DEV_MAX)
return getdevinfo(res_id, out, out_sz, hint, flags);

if (res_id >= STAT_MIN && res_id < STAT_MAX)
return getstatinfo(res_id, out, out_sz, hint, flags);

if (res_id >= FS_MIN && res_id < FS_MAX)
return getfsinfo(res_id, out, out_sz, hint, flags);

Expand Down
30 changes: 30 additions & 0 deletions resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ typedef struct res_blk {
#define RES_CPU_CORECOUNT 6002
#define CPU_MAX 6010

#define STAT_MIN 7000
#define RES_STAT_INFO 7001
#define STAT_MAX 7002

#define FS_MIN 8000
#define FS_AIONR 8001
#define FS_AIOMAXNR 8002
Expand Down Expand Up @@ -549,6 +553,32 @@ struct vmstat {
unsigned long nr_unstable;
};

struct cpu_stat {
unsigned long long user;
unsigned long long nice;
unsigned long long system;
unsigned long long idle;
unsigned long long iowait;
unsigned long long irq;
unsigned long long softirq;
unsigned long long steal;
unsigned long long guest;
unsigned long long guest_nice;
};

struct stat_info {
struct cpu_stat cpu;
struct cpu_stat *all_cpu; /* Array of len cpu_num */
int cpu_num;
char intr[9000]; // total of all interrupts serviced(since boot)
unsigned long long ctxt;
unsigned long long btime;
unsigned long long processes;
unsigned long long procs_running;
unsigned long long procs_blocked;
char softirq[9000]; /* Number of softirq for all CPUs. */
};

/* Allocating memory and building a res_blk structure to return bulk
* resource information.
*/
Expand Down
164 changes: 164 additions & 0 deletions stat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/* Copyright (C) 2023, Oracle and/or its affiliates. All rights reserved
*
* This file is part of libresource.
*
* libresource is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* libresource is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libresource. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _RESOURCE_H
#include "resource.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "resvm.h"
#include "resource_impl.h"
#include <errno.h>
#include <libgen.h>
#include "stat.h"

static char buffer[20000];

static int populate_statcpu(struct cpu_stat *all_cpu, int cpu_num)
{
char buf[36];
const char *cstr;

if (!all_cpu) {
return -1;
}
for (int i = 0; i < cpu_num; i++) {
snprintf(buf, 36, "cpu%d", i);
cstr = strstr(buffer, buf);
if (cstr) {
cstr += strlen(buf)+1;
sscanf(cstr, "%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
&all_cpu->user,
&all_cpu->nice,
&all_cpu->system,
&all_cpu->idle,
&all_cpu->iowait,
&all_cpu->irq,
&all_cpu->softirq,
&all_cpu->steal,
&all_cpu->guest,
&all_cpu->guest_nice);
}
all_cpu++;
}
return 0;
}

static int populate_statinfo(void *out, int test)
{
char *cstr;
struct stat_info *st;
int cpu_num;

st = (struct stat_info *) out;
cstr = strstr(buffer, "cpu ");
if (cstr) {
sscanf(cstr, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
&st->cpu.user,
&st->cpu.nice,
&st->cpu.system,
&st->cpu.idle,
&st->cpu.iowait,
&st->cpu.irq,
&st->cpu.softirq,
&st->cpu.steal,
&st->cpu.guest,
&st->cpu.guest_nice);
}
cstr = strstr(buffer, "intr ");
memset(&st->intr, '\0', sizeof(st->intr));
if (cstr) {
unsigned int bytes = 0;
char *cstr1 = cstr + 5;
while (*cstr1 != '\n' && bytes < 8999) {
cstr1++;
bytes++;
}
strncpy(st->intr, cstr+5, bytes);
}
cstr = strstr(buffer, "ctxt ");
if (cstr)
sscanf(cstr, "ctxt %Lu", &st->ctxt);
cstr = strstr(buffer, "btime ");
if (cstr)
sscanf(cstr, "btime %Lu", &st->btime);
cstr = strstr(buffer, "processes ");
if (cstr)
sscanf(cstr, "processes %Lu", &st->processes);
cstr = strstr(buffer, "procs_running ");
if (cstr)
sscanf(cstr, "procs_running %Lu", &st->procs_running);
cstr = strstr(buffer, "procs_blocked ");
if (cstr)
sscanf(cstr, "procs_blocked %Lu", &st->procs_blocked);
cstr = strstr(buffer, "softirq ");
memset(&st->softirq, '\0', sizeof(st->softirq));
if (cstr) {
unsigned int bytes = 0;
char *cstr1 = cstr + 8;
while (*cstr1 != '\n' && bytes < 8999) {
cstr1++;
bytes++;
}
strncpy(st->softirq, cstr+8, bytes);
}

cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
populate_statcpu(st->all_cpu, cpu_num);
return 0;
}

int getstatexist(int res_id, void *exist, size_t sz, void *hint, int flags)
{
int ret;
ret = file_to_buf("./stat_info.orig", buffer, sizeof(buffer));
if (ret == -1)
return -1;
ret = populate_statinfo(exist, 1);
return ret;
}

int getstatinfo(int res_id, void *out, size_t sz, void **hint, int flags)
{
int ret, cpu_num, cpu_size;

#ifdef TESTING
ret = file_to_buf("./stat_info.orig", buffer, sizeof(buffer));
#else
ret = file_to_buf(STAT_FILE, buffer, sizeof(buffer));
#endif
if (ret == -1)
return -1;

switch (res_id) {
case RES_STAT_INFO:
cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
cpu_size = sizeof(struct cpu_stat) * cpu_num;
CHECK_SIZE(sz, (sizeof(struct stat_info) + cpu_size));
ret = populate_statinfo(out, 0);
break;
default:
eprintf("Resource Id is invalid");
errno = EINVAL;
return -1;

}
return ret;
}
26 changes: 26 additions & 0 deletions stat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* Copyright (C) 2023, Oracle and/or its affiliates. All rights reserved
*
* This file is part of libresource.
*
* libresource is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* libresource is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libresource. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _STAT_H
#define _STAT_H

#define STAT_FILE "/proc/stat"

extern int getstatinfo(int res_id, void *out, size_t sz, void **hint,
int flags);
#endif /* _STAT_H */
5 changes: 4 additions & 1 deletion tests/MEM/mem_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ int main(int argc, char **argv)
exit(1);
}
fp = fopen ("./mem_info.txt", "w");

if (fp == NULL) {
printf("mem_info.txt does not exist!\n");
exit(1);
}
if (exist.memtotal)
fprintf(fp, "MemTotal: %lu kB\n", mem.memtotal);
if (exist.memfree)
Expand Down
10 changes: 10 additions & 0 deletions tests/STAT/stat.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export LD_LIBRARY_PATH=`git rev-parse --show-toplevel`
cd $LD_LIBRARY_PATH
cd tests/STAT
rm -f stat_info.orig
rm -f stat_info.txt
cc -I $LD_LIBRARY_PATH -std=gnu99 -o stat_test stat_test.c -L $LD_LIBRARY_PATH -lresource
cat /proc/stat > stat_info.orig
./stat_test
diff stat_info.orig stat_info.txt

81 changes: 81 additions & 0 deletions tests/STAT/stat_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* Copyright (C) 2023, Oracle and/or its affiliates. All rights reserved
*
* This file is part of libresource.
*
* libresource is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* libresource is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libresource. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <resource.h>

int main(int argc, char **argv)
{
struct stat_info stats, *st;
int cpu_num, size, err = 0;
FILE *fp;
char buf[36];
struct cpu_stat *all_cpu;

cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
size = sizeof(struct cpu_stat) * cpu_num;
stats.all_cpu = (struct cpu_stat *) malloc(size);
err = res_read(RES_STAT_INFO, &stats, sizeof(stats)+size, NULL, 0, 0);
if (err != 0)
printf("err is %d\n",err);
st = &stats;
fp = fopen ("./stat_info.txt", "w");
if (fp == NULL) {
printf("stat_info.txt does not exist!\n");
exit(1);
}
fprintf(fp, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\n",
st->cpu.user,
st->cpu.nice,
st->cpu.system,
st->cpu.idle,
st->cpu.iowait,
st->cpu.irq,
st->cpu.softirq,
st->cpu.steal,
st->cpu.guest,
st->cpu.guest_nice);
all_cpu = st->all_cpu;
for (int i = 0; i < cpu_num; i++) {
sprintf(buf, "cpu%d", i);
fprintf(fp, "%s %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\n",
buf,
all_cpu->user,
all_cpu->nice,
all_cpu->system,
all_cpu->idle,
all_cpu->iowait,
all_cpu->irq,
all_cpu->softirq,
all_cpu->steal,
all_cpu->guest,
all_cpu->guest_nice);
all_cpu++;
}
fprintf(fp, "intr %s\n", st->intr);
fprintf(fp, "ctxt %Lu\n",st->ctxt);
fprintf(fp, "btime %Lu\n", st->btime);
fprintf(fp, "processes %Lu\n", st->processes);
fprintf(fp, "procs_running %Lu\n", st->procs_running);
fprintf(fp, "procs_blocked %Lu\n", st->procs_blocked);
fprintf(fp, "softirq %s\n", st->softirq);
fclose(fp);
}

0 comments on commit 18ad4c3

Please sign in to comment.