/*
* Copyright (C), 2000-2007 by the monit project group.
* All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* System independent /proc & kvm methods.
*
* @author Jan-Henrik Haukeland, <hauk@tildeslash.com>
* @author Christian Hopp <chopp@iei.tu-clausthal.de>
*
* @version \$Id: process_common.c,v 1.8 2007/07/25 12:54:32 hauk Exp $
*
* @file
*/
#include <config.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_LOADAVG_H
#include <sys/loadavg.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "monitor.h"
#include "process.h"
#include "process_sysdep.h"
/**
* Reads an process dependent entry or the proc files system
* @param buf buffer to write to
* @param buf_size size of buffer "buf"
* @param name name of proc service
* @param pid pid number of the process / or <0 if main directory
* @return TRUE if succeeded otherwise FALSE.
*/
int read_proc_file(char *buf, int buf_size, char * name, int pid) {
int fd;
char filename[STRLEN];
int bytes;
ASSERT(buf);
ASSERT(name);
if ( pid < 0 ) {
snprintf(filename, STRLEN, "/proc/%s", name);
} else {
snprintf(filename, STRLEN, "/proc/%d/%s", pid, name);
}
if ( (fd = open(filename, O_RDONLY)) < 0 ) {
DEBUG("cannot open file %s -- %s\n", filename, STRERROR);
return FALSE;
}
if ( (bytes = read(fd, buf, buf_size-1)) < 0 ) {
close(fd);
DEBUG("cannot read file %s -- %s\n", filename, STRERROR);
return FALSE;
}
/* In case it is a string we have to 0 terminate it our self */
buf[bytes]='\0';
close(fd);
return TRUE;
}
/**
* Get the actual time as a floating point number
* @return time in seconds
*/
double get_float_time(void) {
struct timeval t;
gettimeofday(&t, NULL);
return (double) t.tv_sec * 10 + (double) t.tv_usec / 100000.0;
}
/**
* Connects child and parent in a process treee
* @param parent pointer to parents process tree entry
* @param child pointer to childs process tree entry
* @return TRUE if succeeded otherwise FALSE.
*/
int connectchild(ProcessTree_T * parent, ProcessTree_T * child) {
ProcessTree_T ** tmp;
ASSERT(child);
ASSERT(parent);
if ( parent->pid == 0 || child->pid == 0 ) {
return FALSE;
}
parent->children_num++;
tmp = xcalloc(sizeof(ProcessTree_T *), parent->children_num);
if ( parent->children != NULL ) {
memcpy(tmp, parent->children,
sizeof(ProcessTree_T *) * (parent->children_num - 1));
FREE(parent->children);
}
parent->children = tmp;
parent->children[parent->children_num - 1] = child;
return TRUE;
}
/**
* Fill data in the process tree by recusively walking through it
* @param pt process tree
* @return TRUE if succeeded otherwise FALSE.
*/
void fillprocesstree(ProcessTree_T * pt) {
int i;
ProcessTree_T *parent_pt;
ASSERT(pt);
if (( pt->pid==0 ) || ( pt->visited == 1 )) {
return;
}
pt->visited= 1;
pt->children_sum= pt->children_num;
pt->mem_kbyte_sum= pt->mem_kbyte;
pt->cpu_percent_sum= pt->cpu_percent;
for( i = 0; i < pt->children_num; i++) {
fillprocesstree(pt->children[i]);
}
if ( pt->parent != NULL ) {
parent_pt=pt->parent;
parent_pt->children_sum+=pt->children_sum;
parent_pt->mem_kbyte_sum+=pt->mem_kbyte_sum;
parent_pt->cpu_percent_sum+=pt->cpu_percent_sum;
/* Numerical inaccuracy force us to limit the cpu load to 100%*/
parent_pt->cpu_percent_sum=(pt->cpu_percent_sum>1000?1000:
parent_pt->cpu_percent_sum);
}
}
syntax highlighted by Code2HTML, v. 0.9.1