📄 hr_proc.c
字号:
/* * Host Resources MIB - proc processor group implementation - hr_proc.c * */#include <net-snmp/net-snmp-config.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include <ctype.h>#include "host_res.h"#include "hr_proc.h"#include <net-snmp/agent/auto_nlist.h>#include <net-snmp/agent/agent_read_config.h>#include "ucd-snmp/loadave.h"#define HRPROC_MONOTONICALLY_INCREASING /********************* * * Kernel & interface information, * and internal forward declarations * *********************/extern void Init_HR_Proc(void);extern int Get_Next_HR_Proc(void);const char *describe_proc(int);int header_hrproc(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **);#ifdef linuxvoid detect_hrproc(void);#endif#ifdef solaris2#define MAX_NUM_HRPROC 128 /* will handle up to 128 processors */#include <kstat.h>#include <kernel_sunos5.h>hrtime_t update_time = NULL;static int ncpus = 0; /* derived from kstat system_misc ncpus*/struct cpuinfo { int id; char state[10]; int state_begin; char cpu_type[15]; char fpu_type[15]; int clock_MHz; }; /* derived from kstat cpu_info*/static struct cpuinfo cpu[MAX_NUM_HRPROC];static char proc_description[96]; /* buffer to hold description of current cpu*/extern void kstat_CPU(void);int proc_status(int);#else#define MAX_NUM_HRPROC 32char proc_descriptions[MAX_NUM_HRPROC][BUFSIZ];#endif /*solaris 2*/ /********************* * * Initialisation & common implementation functions * *********************/static int HRP_index;static int HRP_max_index = 1;#define HRPROC_ID 1#define HRPROC_LOAD 2struct variable4 hrproc_variables[] = { {HRPROC_ID, ASN_OBJECT_ID, RONLY, var_hrproc, 2, {1, 1}}, {HRPROC_LOAD, ASN_INTEGER, RONLY, var_hrproc, 2, {1, 2}}};oid hrproc_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 3 };voidinit_hr_proc(void){ init_device[HRDEV_PROC] = Init_HR_Proc; next_device[HRDEV_PROC] = Get_Next_HR_Proc; device_descr[HRDEV_PROC] = describe_proc;#ifdef solaris2 device_status[HRDEV_PROC] = proc_status; update_time = NULL;#endif#ifdef HRPROC_MONOTONICALLY_INCREASING dev_idx_inc[HRDEV_PROC] = 1;#endif#ifdef linux detect_hrproc();#endif REGISTER_MIB("host/hr_proc", hrproc_variables, variable4, hrproc_variables_oid);}/* * header_hrproc(... * Arguments: * vp IN - pointer to variable entry that points here * name IN/OUT - IN/name requested, OUT/name found * length IN/OUT - length of IN/OUT oid's * exact IN - TRUE if an exact match was requested * var_len OUT - length of variable or 0 if function returned * write_method * */intheader_hrproc(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method){#define HRPROC_ENTRY_NAME_LENGTH 11 oid newname[MAX_OID_LEN]; int proc_idx, LowIndex = -1; int result; DEBUGMSGTL(("host/hr_proc", "var_hrproc: ")); DEBUGMSGOID(("host/hr_proc", name, *length)); DEBUGMSG(("host/hr_proc", " %d\n", exact)); memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid)); /* * Find "next" proc entry */ Init_HR_Proc(); for (;;) { proc_idx = Get_Next_HR_Proc(); if (proc_idx == -1) break; newname[HRPROC_ENTRY_NAME_LENGTH] = proc_idx; result = snmp_oid_compare(name, *length, newname, vp->namelen + 1); if (exact && (result == 0)) { LowIndex = proc_idx; /* * Save processor status information */ break; } if ((!exact && (result < 0)) && (LowIndex == -1 || proc_idx < LowIndex)) { LowIndex = proc_idx; /* * Save processor status information */#ifdef HRPROC_MONOTONICALLY_INCREASING break;#endif } } if (LowIndex == -1) { DEBUGMSGTL(("host/hr_proc", "... index out of range\n")); return (MATCH_FAILED); } memcpy((char *) name, (char *) newname, (vp->namelen + 1) * sizeof(oid)); *length = vp->namelen + 1; *write_method = 0; *var_len = sizeof(long); /* default to 'long' results */ DEBUGMSGTL(("host/hr_proc", "... get proc stats ")); DEBUGMSGOID(("host/hr_proc", name, *length)); DEBUGMSG(("host/hr_proc", "\n")); return LowIndex;} /********************* * * System specific implementation functions * *********************/u_char *var_hrproc(struct variable * vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method){ int proc_idx; double avenrun[3]; proc_idx = header_hrproc(vp, name, length, exact, var_len, write_method); if (proc_idx == MATCH_FAILED) return NULL; if (try_getloadavg(&avenrun[0], sizeof(avenrun) / sizeof(avenrun[0])) == -1) return NULL; switch (vp->magic) { case HRPROC_ID: *var_len = nullOidLen; return (u_char *) nullOid; case HRPROC_LOAD:#if NO_DUMMY_VALUES return NULL;#endif long_return = avenrun[0] * 100; /* 1 minute average */ if (long_return > 100) long_return = 100; return (u_char *) & long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrproc\n", vp->magic)); } return NULL;} /********************* * * Internal implementation functions * *********************/voidInit_HR_Proc(void){#ifdef solaris2 hrtime_t current_time;#endif HRP_index = 0;#ifdef solaris2 current_time = gethrtime(); if (current_time > update_time + 2000000000) { /* two seconds */ kstat_CPU(); update_time = gethrtime(); }#endif}intGet_Next_HR_Proc(void){ if (HRP_index < HRP_max_index) return (HRDEV_PROC << HRDEV_TYPE_SHIFT) + HRP_index++; else return -1;}const char *describe_proc(int idx){#ifdef _SC_CPU_VERSION int result; result = sysconf(_SC_CPU_VERSION); switch (result) { case CPU_HP_MC68020: return (" Motorola MC68020 "); case CPU_HP_MC68030: return (" Motorola MC68030 "); case CPU_HP_MC68040: return (" Motorola MC68040 "); case CPU_PA_RISC1_0: return (" HP PA-RISC 1.0 "); case CPU_PA_RISC1_1: return (" HP PA-RISC 1.1 "); case CPU_PA_RISC1_2: return (" HP PA-RISC 1.2 "); case CPU_PA_RISC2_0: return (" HP PA-RISC 2.0 "); default: return ("An electronic chip with an HP label"); }#elif linux return (proc_descriptions[idx & HRDEV_TYPE_MASK]);#elif solaris2 int cidx = idx & HRDEV_TYPE_MASK; snprintf(proc_description,sizeof(proc_description)-1, "CPU %d Sun %d MHz %s with %s FPU %s", cpu[cidx].id,cpu[cidx].clock_MHz,cpu[cidx].cpu_type,cpu[cidx].fpu_type,cpu[cidx].state); return proc_description;#else return ("An electronic chip that makes the computer work.");#endif}#ifdef linuxvoid detect_hrproc(void){ int i; char tmpbuf[BUFSIZ], *cp; FILE *fp; /* * Clear the buffers... */ for ( i=0 ; i<MAX_NUM_HRPROC; i++ ) { memset( proc_descriptions[i], '\0', BUFSIZ); } /* * ... and try to interpret the CPU information */ fp = fopen("/proc/cpuinfo", "r"); if (!fp) { sprintf( proc_descriptions[0], "An electronic chip that makes the computer work."); return; } i = 0; while (fgets(tmpbuf, BUFSIZ, fp)) { if ( !strncmp( tmpbuf, "vendor_id", 9)) { /* Stomp on trailing newline... */ cp = &tmpbuf[strlen(tmpbuf)-1]; *cp = 0; /* ... and then extract the value */ cp = index( tmpbuf, ':'); cp++; while ( cp && isspace(*cp)) cp++; snprintf( proc_descriptions[i], BUFSIZ, "%s", cp); } if ( !strncmp( tmpbuf, "model name", 10)) { /* Stomp on trailing newline... */ cp = &tmpbuf[strlen(tmpbuf)-1]; *cp = 0; /* ... and then extract the value */ cp = index( tmpbuf, ':'); cp++; while ( cp && isspace(*cp)) cp++; strncat( proc_descriptions[i], ": ", BUFSIZ-strlen(proc_descriptions[i])); strncat( proc_descriptions[i], cp, BUFSIZ-strlen(proc_descriptions[i])); i++; if (i >= MAX_NUM_HRPROC) { i--; break; } } } HRP_max_index = i; fclose(fp); return;}#endif /* linux */#ifdef solaris2void kstat_CPU(void){/* this routine asks the OS for the number of CPU's and uses that value * to set HRP_max_index for later use. Then it asks the OS for * specific details of each CPU. In Solaris, you cannot trust the * first CPU to be 0 or for CPU 0 to even exist, hence there is a * CPU id, state, cpu type, fpu type, state_begin (what does this do??) * and CPU speed. Results are stuffed into the cpu array (see above). * * In keeping with the spirit of the RFC, the number and index of CPU's * is considered to be constant. Hence, if you start yanking or adding * CPU modules eg. on a V880, you will need to start and stop the daemon. */ int i_cpu = -1; int i,old_ncpus; kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *ks_data; old_ncpus = ncpus; for (i = 0; i < ncpus; i++) { strncpy(cpu[i].state,"missing",sizeof(cpu[i].state)); cpu[i].state[sizeof(cpu[i].state)-1]='\0'; /* null terminate */ cpu[i].id = 999999; cpu[i].clock_MHz = 999999; strncpy(cpu[i].cpu_type,"missing",sizeof(cpu[i].cpu_type)); cpu[i].state[sizeof(cpu[i].cpu_type)-1]='\0'; /* null terminate */ strncpy(cpu[i].fpu_type,"missing",sizeof(cpu[i].fpu_type)); cpu[i].state[sizeof(cpu[i].cpu_type)-1]='\0'; /* null terminate */ } getKstat("system_misc", "ncpus", &ncpus); if (ncpus > old_ncpus){ HRP_max_index = ncpus; /* the MIB says to retain indexes */ } if ((old_ncpus != ncpus)&&(old_ncpus != 0)) { if (ncpus > old_ncpus){ snmp_log(LOG_NOTICE, "hr_proc: Cool ! Number of CPUs increased, must be hot-pluggable.\n"); } else { snmp_log(LOG_NOTICE, "hr_proc: Lost at least one CPU, RIP.\n"); } } if ((kc = kstat_open()) == NULL) { DEBUGMSGTL(("hr_proc", "kstat_open failed")); } else { for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) { if (ksp->ks_type == KSTAT_TYPE_NAMED && strcmp(ksp->ks_module, "cpu_info") == 0 && strcmp(ksp->ks_class, "misc") == 0) { if (kstat_read(kc, ksp, NULL) == -1) { DEBUGMSGTL(("hr_proc", "kstat_read failed")); } else { i_cpu++; i = 0; cpu[i_cpu].id = ksp->ks_instance; for (ks_data = ksp->ks_data; i < ksp->ks_ndata; i++, ks_data++) { if (strcmp(ks_data->name,"state")==0) { strncpy(cpu[i_cpu].state,ks_data->value.c,sizeof(cpu[i_cpu].state)); cpu[i_cpu].state[sizeof(cpu[i_cpu].state)-1]='\0'; /* null terminate */ continue; } else if (strcmp(ks_data->name,"state_begin")==0) { cpu[i_cpu].state_begin=ks_data->value.i32; continue; } else if (strcmp(ks_data->name,"cpu_type")==0) { strncpy(cpu[i_cpu].cpu_type,ks_data->value.c,sizeof(cpu[i_cpu].cpu_type)); cpu[i_cpu].state[sizeof(cpu[i_cpu].cpu_type)-1]='\0'; /* null terminate */ continue; } else if (strcmp(ks_data->name,"fpu_type")==0) { strncpy(cpu[i_cpu].fpu_type,ks_data->value.c,sizeof(cpu[i_cpu].fpu_type)); cpu[i_cpu].state[sizeof(cpu[i_cpu].fpu_type)-1]='\0'; /* null terminate */ continue; } else if (strcmp(ks_data->name,"clock_MHz")==0) { cpu[i_cpu].clock_MHz=ks_data->value.i32; continue; } else { DEBUGMSGTL(("hr_proc","kstat unexpected cpu parameter")); } } } } } } kstat_close(kc);}intproc_status(int idx){ /* * hrDeviceStatus OBJECT-TYPE * SYNTAX INTEGER { * unknown(1), running(2), warning(3), testing(4), down(5) * } */ int cidx = idx & HRDEV_TYPE_MASK; if (strcmp(cpu[cidx].state,"on-line")==0) { return 2; /* running */ } else if (strcmp(cpu[cidx].state,"off-line")==0) { return 5; /* down */ } else if (strcmp(cpu[cidx].state,"missing")==0) { return 3; /* warning, went missing, see above */ } else if (strcmp(cpu[cidx].state,"testing")==0) { return 4; /* somebody must be testing code up above */ } else { return 1; /* unknown */ }}#endif /* solaris2 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -