summaryrefslogtreecommitdiff
path: root/agent/mibgroup/hardware/cpu/cpu_sysinfo.c
blob: ed1f3579fc5850a640d9b03570b657dfcc8f5138 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 *   sysinfo (sysget/sysmp) interface
 *     e.g. IRIX 6.x
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/hardware/cpu.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/sysmp.h>
#include <sys/sysinfo.h>
#include <sys/sysget.h>

int cpu_count;
int sinfo_ksize;
struct sysinfo* sinfo_cpus;   /* individual cpu stats */
struct sysinfo* sinfo_gen;    /* global stats */

/*
* Initialise the list of CPUs on the system
*   (including descriptions)
*/
void init_cpu_sysinfo( void )
{
    int i;
    netsnmp_cpu_info *cpu;
    char tstr[1024];

    cpu_count = sysmp(MP_NPROCS);

    /* fetch struct sysinfo size in kernel */

    if ((sinfo_ksize = sysmp(MP_SASZ, MPSA_SINFO)) < 0) {
        snmp_log_perror("init_cpu_sysinfo: sysinfo scall interface not supported");
        exit(1);
    }

    if (sizeof(struct sysinfo) != sinfo_ksize)
    {
        snmp_log_perror("init_cpu_sysinfo: size mismatch between userland and kernel sysinfo struct");
	exit(1);
    }

    /* allocate sysinfo for all cpus + global stats */

    sinfo_cpus = (struct sysinfo *) calloc(cpu_count, sinfo_ksize);
    if (!sinfo_cpus) {
        snmp_log_perror("init_cpu_sysinfo: Couldn't allocate memory bytes for sinfo_cpus");
        exit(1);
    }

    sinfo_gen = (struct sysinfo *) calloc(1, sinfo_ksize);
    if (!sinfo_gen) {
        snmp_log_perror("init_cpu_sysinfo: Couldn't allocate memory bytes for sinfo_gen");
        exit(1);
    }

    /* register cpus */

    cpu = netsnmp_cpu_get_byIdx(-1, 1);
    strcpy(cpu->name, "Overall CPU statistics");

    for (i = 0; i < cpu_count ; ++i)
    {
       cpu = netsnmp_cpu_get_byIdx(i, 1);
       sprintf(tstr, "cpu%d",i);
       strcpy(cpu->name,  tstr);
       strcpy(cpu->descr, "Central Processing Unit");
    }
}

/*
* Load the latest CPU usage statistics
*/
int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic )
{
    int i;
    netsnmp_cpu_info* cpu;
    sgt_cookie_t ck;

    /* fetch global stats */

    cpu = netsnmp_cpu_get_byIdx(-1, 0);

    if (sysmp(MP_SAGET, MPSA_SINFO, (char *) sinfo_gen, sinfo_ksize) < 0)
    {
        snmp_log_perror("netsnmp_cpu_arch_load: sysmp() failed");
	exit(1);
    }

    DEBUGMSGTL(("cpu_sysinfo", "total cpu kernel: %lu\n", sinfo_gen->cpu[CPU_KERNEL]));
    cpu->sys2_ticks  = (unsigned long long) sinfo_gen->cpu[CPU_KERNEL] + (unsigned long long) sinfo_gen->cpu[CPU_SXBRK] + (unsigned long long) sinfo_gen->cpu[CPU_INTR];
    cpu->kern_ticks  = (unsigned long long) sinfo_gen->cpu[CPU_KERNEL];
    cpu->intrpt_ticks = (unsigned long long) sinfo_gen->cpu[CPU_INTR];
    cpu->user_ticks = (unsigned long long) sinfo_gen->cpu[CPU_USER];
    cpu->wait_ticks   = (unsigned long long) sinfo_gen->cpu[CPU_WAIT];
    cpu->idle_ticks = (unsigned long long) sinfo_gen->cpu[CPU_IDLE];

    /* XXX - Do these really belong here ? */
    cpu->pageIn  = (unsigned long long)0;
    cpu->pageOut = (unsigned long long)0;
    cpu->swapIn  = (unsigned long long)sinfo_gen->swapin;
    cpu->swapOut = (unsigned long long)sinfo_gen->swapout;
    cpu->nInterrupts = (unsigned long long)sinfo_gen->intr_svcd;
    cpu->nCtxSwitches = (unsigned long long)sinfo_gen->pswitch;

    /* fetch individual cpu stats */

    SGT_COOKIE_INIT(&ck); 
    if (sysget(MPSA_SINFO, (char *) sinfo_cpus, sinfo_ksize * cpu_count, SGT_READ | SGT_CPUS | SGT_SUM, &ck) < 0)
    {
        snmp_log_perror("netsnmp_cpu_arch_load: sysget() failed");
	exit(1);
    }

    for (i = 0; i < cpu_count ; ++i)
    {
        cpu = netsnmp_cpu_get_byIdx(i, 0);

        DEBUGMSGTL(("cpu_sysinfo", "cpu %u kernel: %lu\n", i, sinfo_cpus[i].cpu[CPU_KERNEL]));
        cpu->sys2_ticks  = (unsigned long long)sinfo_cpus[i].cpu[CPU_KERNEL] + (unsigned long long) sinfo_cpus[i].cpu[CPU_SXBRK] + (unsigned long long)sinfo_cpus[i].cpu[CPU_INTR];
        cpu->intrpt_ticks = (unsigned long long)sinfo_cpus[i].cpu[CPU_INTR];
        cpu->user_ticks = (unsigned long long)sinfo_cpus[i].cpu[CPU_USER];
        cpu->wait_ticks   = (unsigned long long)sinfo_cpus[i].cpu[CPU_WAIT];
        cpu->idle_ticks = (unsigned long long)sinfo_cpus[i].cpu[CPU_IDLE];
    }

    return 0;
}