2004-06-22 06:37:04 +08:00
|
|
|
#include "sigar.h"
|
|
|
|
#include "sigar_private.h"
|
|
|
|
#include "sigar_os.h"
|
|
|
|
#include "sigar_util.h"
|
|
|
|
|
|
|
|
#include <sys/dk.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
int sigar_os_open(sigar_t **sigar)
|
|
|
|
{
|
|
|
|
*sigar = malloc(sizeof(**sigar));
|
|
|
|
|
|
|
|
/* does not change while system is running */
|
|
|
|
pstat_getstatic(&(*sigar)->pstatic,
|
|
|
|
sizeof((*sigar)->pstatic),
|
|
|
|
1, 0);
|
|
|
|
|
|
|
|
(*sigar)->proctab = NULL;
|
|
|
|
|
|
|
|
(*sigar)->ticks = sysconf(_SC_CLK_TCK);
|
|
|
|
|
|
|
|
(*sigar)->last_pid = -1;
|
|
|
|
|
|
|
|
(*sigar)->pinfo = NULL;
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_os_close(sigar_t *sigar)
|
|
|
|
{
|
|
|
|
if (sigar->proctab) {
|
|
|
|
free(sigar->proctab);
|
|
|
|
}
|
|
|
|
if (sigar->pinfo) {
|
|
|
|
free(sigar->pinfo);
|
|
|
|
}
|
|
|
|
free(sigar);
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *sigar_os_error_string(int err)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_mem_get(sigar_t *sigar, sigar_mem_t *mem)
|
|
|
|
{
|
|
|
|
struct pst_dynamic stats;
|
|
|
|
sigar_uint64_t pagesize = sigar->pstatic.page_size;
|
|
|
|
|
|
|
|
mem->total = sigar->pstatic.physical_memory * pagesize;
|
|
|
|
|
|
|
|
sigar_mem_calc_ram(sigar, mem);
|
|
|
|
|
|
|
|
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
|
|
|
|
|
|
|
mem->free = stats.psd_free * pagesize;
|
|
|
|
mem->used = mem->total - mem->free;
|
|
|
|
|
|
|
|
/*XXX*/
|
|
|
|
mem->shared = mem->buffer = mem->cached = 0;
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap)
|
|
|
|
{
|
|
|
|
struct pst_swapinfo swapinfo;
|
|
|
|
int i=0;
|
|
|
|
|
|
|
|
swap->total = swap->free = 0;
|
|
|
|
|
|
|
|
while (pstat_getswap(&swapinfo, sizeof(swapinfo), 1, i++) > 0) {
|
|
|
|
swapinfo.pss_nfpgs *= 4; /* nfpgs is in 512 byte blocks */
|
|
|
|
|
|
|
|
if (swapinfo.pss_nblksenabled == 0) {
|
|
|
|
swapinfo.pss_nblksenabled = swapinfo.pss_nfpgs;
|
|
|
|
}
|
|
|
|
|
|
|
|
swap->total += swapinfo.pss_nblksenabled;
|
|
|
|
swap->free += swapinfo.pss_nfpgs;
|
|
|
|
}
|
|
|
|
|
|
|
|
swap->used = swap->total - swap->free;
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct pst_dynamic stats;
|
|
|
|
|
|
|
|
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
|
|
|
sigar->ncpu = stats.psd_proc_cnt;
|
|
|
|
|
|
|
|
cpu->user = stats.psd_cpu_time[CP_USER];
|
|
|
|
cpu->sys = stats.psd_cpu_time[CP_SYS] + stats.psd_cpu_time[CP_SSYS];
|
|
|
|
cpu->nice = stats.psd_cpu_time[CP_NICE];
|
|
|
|
cpu->idle = stats.psd_cpu_time[CP_IDLE];
|
|
|
|
|
|
|
|
cpu->total = 0;
|
|
|
|
|
|
|
|
/* states above plus CP_BLOCK, CP_SWAIT, etc. (see sys/dk.h) */
|
|
|
|
for (i=0; i<CPUSTATES; i++) {
|
|
|
|
cpu->total += stats.psd_cpu_time[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_cpu_list_get(sigar_t *sigar, sigar_cpu_list_t *cpulist)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct pst_dynamic stats;
|
|
|
|
|
|
|
|
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
|
|
|
sigar->ncpu = stats.psd_proc_cnt;
|
|
|
|
|
|
|
|
sigar_cpu_list_create(cpulist);
|
|
|
|
|
|
|
|
for (i=0; i<sigar->ncpu; i++) {
|
|
|
|
int j;
|
|
|
|
sigar_cpu_t *cpu;
|
|
|
|
struct pst_processor proc;
|
|
|
|
|
|
|
|
if (pstat_getprocessor(&proc, sizeof(proc), 1, i) < 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
SIGAR_CPU_LIST_GROW(cpulist);
|
|
|
|
|
|
|
|
cpu = &cpulist->data[cpulist->number++];
|
|
|
|
|
|
|
|
cpu->user = proc.psp_cpu_time[CP_USER];
|
|
|
|
cpu->sys = proc.psp_cpu_time[CP_SYS] + proc.psp_cpu_time[CP_SSYS];
|
|
|
|
cpu->nice = proc.psp_cpu_time[CP_NICE];
|
|
|
|
cpu->idle = proc.psp_cpu_time[CP_IDLE];
|
|
|
|
|
|
|
|
cpu->total = 0;
|
|
|
|
|
|
|
|
for (j=0; j<CPUSTATES; j++) {
|
|
|
|
cpu->total += proc.psp_cpu_time[j];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_uptime_get(sigar_t *sigar,
|
|
|
|
sigar_uptime_t *uptime)
|
|
|
|
{
|
|
|
|
uptime->uptime = time(NULL) - sigar->pstatic.boot_time;
|
|
|
|
uptime->idletime = 0; /*XXX*/;
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_loadavg_get(sigar_t *sigar,
|
|
|
|
sigar_loadavg_t *loadavg)
|
|
|
|
{
|
|
|
|
struct pst_dynamic stats;
|
|
|
|
|
|
|
|
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
|
|
|
|
|
|
|
loadavg->loadavg[0] = stats.psd_avg_1_min;
|
|
|
|
loadavg->loadavg[1] = stats.psd_avg_5_min;
|
|
|
|
loadavg->loadavg[2] = stats.psd_avg_15_min;
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_proc_list_get(sigar_t *sigar,
|
|
|
|
sigar_proc_list_t *proclist)
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
|
|
|
|
if (!sigar->proctab) {
|
|
|
|
/* malloc this only once per-sigar_t as the size will not change */
|
|
|
|
sigar->proctab = malloc(sizeof(*sigar->proctab) *
|
|
|
|
sigar->pstatic.max_proc);
|
|
|
|
}
|
|
|
|
|
|
|
|
n = pstat_getproc(sigar->proctab, sizeof(*sigar->proctab),
|
|
|
|
sigar->pstatic.max_proc, 0);
|
|
|
|
|
|
|
|
proclist->number = 0;
|
|
|
|
proclist->size = n;
|
|
|
|
proclist->data = malloc(sizeof(*(proclist->data)) * n);
|
|
|
|
|
|
|
|
for (n=0; n<proclist->size; n++) {
|
|
|
|
proclist->data[proclist->number++] =
|
|
|
|
sigar->proctab[n].pst_pid;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_proc_stat_get(sigar_t *sigar,
|
|
|
|
sigar_proc_stat_t *procstat)
|
|
|
|
{
|
|
|
|
int status = /* XXX optimize */
|
|
|
|
sigar_proc_count(sigar, &procstat->total);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sigar_pstat_getproc(sigar_t *sigar, sigar_pid_t pid)
|
|
|
|
{
|
|
|
|
int status, num;
|
|
|
|
time_t timenow = time(NULL);
|
|
|
|
|
|
|
|
if (sigar->pinfo == NULL) {
|
|
|
|
sigar->pinfo = malloc(sizeof(*sigar->pinfo));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sigar->last_pid == pid) {
|
|
|
|
if ((timenow - sigar->last_getprocs) < SIGAR_LAST_PROC_EXPIRE) {
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sigar->last_pid = pid;
|
|
|
|
sigar->last_getprocs = timenow;
|
|
|
|
|
|
|
|
if (pstat_getproc(sigar->pinfo,
|
|
|
|
sizeof(*sigar->pinfo),
|
|
|
|
0, pid) == -1)
|
|
|
|
{
|
|
|
|
return ESRCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid,
|
|
|
|
sigar_proc_mem_t *procmem)
|
|
|
|
{
|
|
|
|
int pagesize = sigar->pstatic.page_size;
|
|
|
|
int status = sigar_pstat_getproc(sigar, pid);
|
|
|
|
struct pst_status *pinfo = sigar->pinfo;
|
|
|
|
|
|
|
|
if (status != SIGAR_OK) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
procmem->size =
|
|
|
|
pinfo->pst_tsize + /* text */
|
|
|
|
pinfo->pst_dsize + /* data */
|
|
|
|
pinfo->pst_ssize; /* stack */
|
|
|
|
|
|
|
|
procmem->size *= pagesize;
|
|
|
|
|
|
|
|
procmem->vsize =
|
|
|
|
pinfo->pst_vtsize + /* text */
|
|
|
|
pinfo->pst_vdsize + /* data */
|
|
|
|
pinfo->pst_vssize; /* stack */
|
|
|
|
|
|
|
|
procmem->vsize *= pagesize;
|
|
|
|
|
|
|
|
procmem->rss = pinfo->pst_rssize * pagesize;
|
|
|
|
|
|
|
|
procmem->share = pinfo->pst_shmsize * pagesize;
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid,
|
|
|
|
sigar_proc_cred_t *proccred)
|
|
|
|
{
|
|
|
|
int status = sigar_pstat_getproc(sigar, pid);
|
|
|
|
struct pst_status *pinfo = sigar->pinfo;
|
|
|
|
|
|
|
|
if (status != SIGAR_OK) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
proccred->uid = pinfo->pst_uid;
|
|
|
|
proccred->gid = pinfo->pst_gid;
|
|
|
|
proccred->euid = pinfo->pst_euid;
|
|
|
|
proccred->egid = pinfo->pst_egid;
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_proc_time_get(sigar_t *sigar, sigar_pid_t pid,
|
|
|
|
sigar_proc_time_t *proctime)
|
|
|
|
{
|
|
|
|
int status = sigar_pstat_getproc(sigar, pid);
|
|
|
|
struct pst_status *pinfo = sigar->pinfo;
|
|
|
|
|
|
|
|
if (status != SIGAR_OK) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
proctime->start_time = pinfo->pst_start;
|
|
|
|
proctime->start_time *= 1000;
|
|
|
|
proctime->utime = pinfo->pst_utime;
|
|
|
|
proctime->stime = pinfo->pst_stime;
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_proc_state_get(sigar_t *sigar, sigar_pid_t pid,
|
|
|
|
sigar_proc_state_t *procstate)
|
|
|
|
{
|
|
|
|
int status = sigar_pstat_getproc(sigar, pid);
|
|
|
|
struct pst_status *pinfo = sigar->pinfo;
|
|
|
|
|
|
|
|
if (status != SIGAR_OK) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SIGAR_SSTRCPY(procstate->name, pinfo->pst_ucomm);
|
|
|
|
procstate->ppid = pinfo->pst_ppid;
|
|
|
|
procstate->tty = makedev(pinfo->pst_term.psd_major,
|
|
|
|
pinfo->pst_term.psd_minor);
|
|
|
|
procstate->priority = pinfo->pst_pri;
|
|
|
|
procstate->nice = pinfo->pst_nice;
|
|
|
|
|
|
|
|
switch (pinfo->pst_stat) {
|
|
|
|
case PS_SLEEP:
|
|
|
|
procstate->state = 'S';
|
|
|
|
break;
|
|
|
|
case PS_RUN:
|
|
|
|
procstate->state = 'R';
|
|
|
|
break;
|
|
|
|
case PS_STOP:
|
|
|
|
procstate->state = 'T';
|
|
|
|
break;
|
|
|
|
case PS_ZOMBIE:
|
|
|
|
procstate->state = 'Z';
|
|
|
|
break;
|
|
|
|
case PS_IDLE:
|
|
|
|
procstate->state = 'D';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX: could be useful elsewhere */
|
|
|
|
static char *sigar_getword(char **line, char stop)
|
|
|
|
{
|
|
|
|
char *pos = *line;
|
|
|
|
int len;
|
|
|
|
char *res;
|
|
|
|
|
|
|
|
while ((*pos != stop) && *pos) {
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = pos - *line;
|
|
|
|
res = (char *)malloc(len + 1);
|
|
|
|
memcpy(res, *line, len);
|
|
|
|
res[len] = 0;
|
|
|
|
|
|
|
|
if (stop) {
|
|
|
|
while (*pos == stop) {
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*line = pos;
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX: pst_cmd is only 64 chars of the command args.
|
|
|
|
* according to HP forums there isn't a way to get them
|
|
|
|
* all if > 64
|
|
|
|
*/
|
|
|
|
int sigar_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
|
|
|
|
sigar_proc_args_t *procargs)
|
|
|
|
{
|
|
|
|
char *args, *arg;
|
|
|
|
struct pst_status status;
|
|
|
|
|
|
|
|
if (pstat_getproc(&status, sizeof(status), 0, pid) == -1) {
|
|
|
|
return ESRCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
args = status.pst_cmd;
|
|
|
|
sigar_proc_args_create(procargs);
|
|
|
|
|
|
|
|
while (*args && (arg = sigar_getword(&args, ' '))) {
|
|
|
|
SIGAR_PROC_ARGS_GROW(procargs);
|
|
|
|
procargs->data[procargs->number++] = arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
|
|
|
sigar_proc_env_t *procenv)
|
|
|
|
{
|
|
|
|
return SIGAR_ENOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_proc_fd_get(sigar_t *sigar, sigar_pid_t pid,
|
|
|
|
sigar_proc_fd_t *procfd)
|
|
|
|
{
|
|
|
|
struct pst_status status;
|
|
|
|
int idx, i, n;
|
|
|
|
struct pst_fileinfo psf[16];
|
|
|
|
|
|
|
|
procfd->total = 0;
|
|
|
|
|
|
|
|
if (pstat_getproc(&status, sizeof(status), 0, pid) == -1) {
|
|
|
|
return ESRCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* man pstat_getfile for index splaination */
|
|
|
|
idx = (status.pst_idx << 16) | (0 & 0xffff);
|
|
|
|
|
|
|
|
while ((n = pstat_getfile(psf, sizeof(psf[0]),
|
|
|
|
sizeof(psf)/sizeof(psf[0]),
|
|
|
|
idx)) > 0)
|
|
|
|
{
|
|
|
|
procfd->total += n;
|
|
|
|
idx = psf[n-1].psf_idx + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n == -1) {
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_proc_exe_get(sigar_t *sigar, sigar_pid_t pid,
|
|
|
|
sigar_proc_exe_t *procexe)
|
|
|
|
{
|
|
|
|
return SIGAR_ENOTIMPL;
|
|
|
|
}
|
|
|
|
|
2004-06-23 03:40:37 +08:00
|
|
|
int sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid,
|
|
|
|
sigar_proc_modules_t *procmods)
|
|
|
|
{
|
|
|
|
return SIGAR_ENOTIMPL;
|
|
|
|
}
|
|
|
|
|
2004-06-22 06:37:04 +08:00
|
|
|
#include <mntent.h>
|
|
|
|
|
|
|
|
int sigar_os_fs_type_get(sigar_file_system_t *fsp)
|
|
|
|
{
|
|
|
|
char *type = fsp->sys_type_name;
|
|
|
|
|
|
|
|
switch (*type) {
|
|
|
|
case 'h':
|
|
|
|
if (strEQ(type, "hfs")) {
|
|
|
|
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
if (strEQ(type, "vxfs")) {
|
|
|
|
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
if (strEQ(type, "cdfs")) {
|
|
|
|
fsp->type = SIGAR_FSTYPE_CDROM;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fsp->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_file_system_list_get(sigar_t *sigar,
|
|
|
|
sigar_file_system_list_t *fslist)
|
|
|
|
{
|
|
|
|
struct mntent ent;
|
|
|
|
char buf[1025];
|
|
|
|
|
|
|
|
FILE *fp;
|
|
|
|
sigar_file_system_t *fsp;
|
|
|
|
|
|
|
|
if (!(fp = setmntent(MNT_CHECKLIST, "r"))) {
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
sigar_file_system_list_create(fslist);
|
|
|
|
|
|
|
|
while (getmntent_r(fp, &ent, buf, sizeof(buf)) == 0) {
|
|
|
|
if ((*(ent.mnt_type) == 's') &&
|
|
|
|
strEQ(ent.mnt_type, "swap"))
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* in this case, devname == "...", for
|
|
|
|
* which statfs chokes on. so skip it.
|
|
|
|
* also notice hpux df command has no swap info.
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
SIGAR_FILE_SYSTEM_LIST_GROW(fslist);
|
|
|
|
|
|
|
|
fsp = &fslist->data[fslist->number++];
|
|
|
|
|
|
|
|
SIGAR_SSTRCPY(fsp->dir_name, ent.mnt_dir);
|
|
|
|
SIGAR_SSTRCPY(fsp->dev_name, ent.mnt_fsname);
|
|
|
|
SIGAR_SSTRCPY(fsp->sys_type_name, ent.mnt_type);
|
|
|
|
sigar_fs_type_init(fsp);
|
|
|
|
}
|
|
|
|
|
|
|
|
endmntent(fp);
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX this is exactly the same as linux and solaris is darn close */
|
|
|
|
#include <sys/vfs.h>
|
|
|
|
|
|
|
|
#define SIGAR_FS_BLOCKS_TO_BYTES(buf, f) \
|
|
|
|
((buf.f * (buf.f_bsize / 512)) >> 1)
|
|
|
|
|
|
|
|
int sigar_file_system_usage_get(sigar_t *sigar,
|
|
|
|
const char *dirname,
|
|
|
|
sigar_file_system_usage_t *fsusage)
|
|
|
|
{
|
|
|
|
struct statfs buf;
|
|
|
|
|
|
|
|
if (statfs(dirname, &buf) != 0) {
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
fsusage->total = SIGAR_FS_BLOCKS_TO_BYTES(buf, f_blocks);
|
|
|
|
fsusage->free = SIGAR_FS_BLOCKS_TO_BYTES(buf, f_bfree);
|
|
|
|
fsusage->avail = SIGAR_FS_BLOCKS_TO_BYTES(buf, f_bavail);
|
|
|
|
fsusage->files = buf.f_files;
|
|
|
|
fsusage->free_files = buf.f_ffree;
|
|
|
|
fsusage->use_percent = sigar_file_system_usage_calc_used(sigar, fsusage);
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_cpu_infos_get(sigar_t *sigar,
|
|
|
|
sigar_cpu_infos_t *cpu_infos)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct pst_dynamic stats;
|
|
|
|
|
|
|
|
pstat_getdynamic(&stats, sizeof(stats), 1, 0);
|
|
|
|
sigar->ncpu = stats.psd_proc_cnt;
|
|
|
|
|
|
|
|
sigar_cpu_infos_create(cpu_infos);
|
|
|
|
|
|
|
|
for (i=0; i<sigar->ncpu; i++) {
|
|
|
|
sigar_cpu_info_t *info;
|
|
|
|
struct pst_processor proc;
|
|
|
|
|
|
|
|
if (pstat_getprocessor(&proc, sizeof(proc), 1, i) < 0) {
|
|
|
|
perror("pstat_getprocessor");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
SIGAR_CPU_INFOS_GROW(cpu_infos);
|
|
|
|
|
|
|
|
info = &cpu_infos->data[cpu_infos->number++];
|
|
|
|
|
|
|
|
SIGAR_SSTRCPY(info->vendor, "HP"); /*XXX*/
|
|
|
|
SIGAR_SSTRCPY(info->model, "PA RISC"); /*XXX*/
|
|
|
|
info->mhz = sigar->ticks * proc.psp_iticksperclktick / 1000000;
|
|
|
|
info->cache_size = -1; /*XXX*/
|
|
|
|
}
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_net_route_list_get(sigar_t *sigar,
|
|
|
|
sigar_net_route_list_t *routelist)
|
|
|
|
{
|
|
|
|
int fd, count, i;
|
|
|
|
unsigned int len;
|
|
|
|
struct nmparms parms;
|
|
|
|
mib_ipRouteEnt *routes;
|
|
|
|
sigar_net_route_t *route;
|
|
|
|
|
|
|
|
if ((fd = open_mib("/dev/ip", O_RDWR, 0, 0)) < 0) {
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = sizeof(count);
|
|
|
|
parms.objid = ID_ipRouteNumEnt;
|
|
|
|
parms.buffer = &count;
|
|
|
|
parms.len = &len;
|
|
|
|
|
|
|
|
if (get_mib_info(fd, &parms) < 0) {
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = count * sizeof(*routes);
|
|
|
|
routes = malloc(len);
|
|
|
|
|
|
|
|
parms.objid = ID_ipRouteTable;
|
|
|
|
parms.buffer = routes;
|
|
|
|
parms.len = &len;
|
|
|
|
|
|
|
|
if (get_mib_info(fd, &parms) < 0) {
|
|
|
|
free(routes);
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
routelist->size = routelist->number = 0;
|
|
|
|
|
|
|
|
sigar_net_route_list_create(routelist);
|
|
|
|
|
|
|
|
for (i=0; i<count; i++) {
|
|
|
|
mib_ipRouteEnt *ent = &routes[i];
|
|
|
|
|
|
|
|
SIGAR_NET_ROUTE_LIST_GROW(routelist);
|
|
|
|
|
|
|
|
route = &routelist->data[routelist->number++];
|
|
|
|
SIGAR_ZERO(route); /* XXX: other fields */
|
|
|
|
|
|
|
|
route->destination = ent->Dest;
|
|
|
|
route->mask = ent->Mask;
|
|
|
|
route->gateway = ent->NextHop;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(routes);
|
|
|
|
close_mib(fd);
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int get_mib_ifstat(sigar_t *sigar,
|
|
|
|
const char *name,
|
|
|
|
mib_ifEntry *mib)
|
|
|
|
{
|
|
|
|
int fd, count, i;
|
|
|
|
unsigned int len;
|
|
|
|
nmapi_phystat *stat;
|
|
|
|
struct nmparms parms;
|
|
|
|
|
|
|
|
if ((fd = open_mib("/dev/ip", O_RDWR, 0, 0)) < 0) {
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = sizeof(count);
|
|
|
|
parms.objid = ID_ifNumber;
|
|
|
|
parms.buffer = &count;
|
|
|
|
parms.len = &len;
|
|
|
|
|
|
|
|
if (get_mib_info(fd, &parms) < 0) {
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = sizeof(nmapi_phystat) * count;
|
|
|
|
|
|
|
|
if (sigar->ifconf_len < len) {
|
|
|
|
sigar->ifconf_buf = realloc(sigar->ifconf_buf, len);
|
|
|
|
sigar->ifconf_len = len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (get_physical_stat(sigar->ifconf_buf, &len) < 0) {
|
|
|
|
close_mib(fd);
|
|
|
|
return errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0, stat = (nmapi_phystat *)sigar->ifconf_buf;
|
|
|
|
i<count;
|
|
|
|
i++, stat++)
|
|
|
|
{
|
|
|
|
if (strEQ(stat->nm_device, name)) {
|
|
|
|
memcpy(mib, &stat->if_entry, sizeof(*mib));
|
|
|
|
close_mib(fd);
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close_mib(fd);
|
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_net_interface_stat_get(sigar_t *sigar, const char *name,
|
|
|
|
sigar_net_interface_stat_t *ifstat)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
mib_ifEntry mib;
|
|
|
|
|
|
|
|
status = get_mib_ifstat(sigar, name, &mib);
|
|
|
|
|
|
|
|
if (status != SIGAR_OK) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
ifstat->rx_bytes = mib.ifInOctets;
|
|
|
|
ifstat->rx_packets = mib.ifInUcastPkts + mib.ifInNUcastPkts;
|
|
|
|
ifstat->rx_errors = mib.ifInErrors;
|
|
|
|
ifstat->rx_dropped = mib.ifInDiscards;
|
|
|
|
ifstat->rx_overruns = 0; /*XXX*/
|
|
|
|
ifstat->rx_frame = 0; /*XXX*/
|
|
|
|
|
|
|
|
ifstat->tx_bytes = mib.ifOutOctets;
|
|
|
|
ifstat->tx_packets = mib.ifOutUcastPkts + mib.ifOutNUcastPkts;
|
|
|
|
ifstat->tx_errors = mib.ifOutErrors;
|
|
|
|
ifstat->tx_dropped = mib.ifOutDiscards;
|
|
|
|
ifstat->tx_overruns = 0; /*XXX*/
|
|
|
|
ifstat->tx_collisions = 0; /*XXX*/
|
|
|
|
ifstat->tx_carrier = 0; /*XXX*/
|
|
|
|
|
|
|
|
return SIGAR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sigar_net_connection_list_get(sigar_t *sigar,
|
|
|
|
sigar_net_connection_list_t *connlist,
|
|
|
|
int flags)
|
|
|
|
{
|
|
|
|
return SIGAR_ENOTIMPL;
|
|
|
|
}
|