/*
AND auto nice daemon - renice programs according to their CPU usage.
Copyright (C) 1999-2001 Patrick Schemitz <schemitz@users.sourceforge.net>
http://and.sourceforge.net/
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <kvm.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
#ifdef __FreeBSD__
#include <sys/user.h>
#endif
#include "and.h"
/*
AND -- auto-nice daemon/OpenBSD version.
OpenBSD-specific AND version. Makes excessive use of the OpenBSD
kernel memory interface, kvm, but also works for FreeBSD.
2000, 2002 Patrick Schemitz, <schemitz@users.sourceforge.net>
http://and.sourceforge.net/
*/
static kvm_t *openbsd_kvm = NULL;
static struct kinfo_proc *openbsd_pt = NULL;
static int openbsd_nproc = 0;
static int openbsd_next = 0;
static long openbsd_hz = -1;
static struct and_procent openbsd_proc;
static int openbsd_init ()
{
struct nlist nlst [] = {
{ "_hz" },
{ 0 }
};
kvm_nlist(openbsd_kvm,nlst);
if (nlst[0].n_type == 0) {
and_printf(0,"KVM: nlist failed. Aborting.\n");
abort();
}
if (kvm_read(openbsd_kvm,nlst[0].n_value,(char*)(&openbsd_hz),
sizeof(openbsd_hz)) != sizeof(openbsd_hz)) {
and_printf(0,"KVM: hz symbol empty. Aborting.\n");
abort();
}
return 1;
}
struct and_procent *openbsd_getnext ()
{
if (!openbsd_pt) {
and_printf(0,"KVM: no process table (late detection). Aborting.\n");
abort();
}
if (openbsd_next >= openbsd_nproc) return NULL;
#if defined(__FreeBSD__) && __FreeBSD_version >= 500014
/* Skip kernel threads */
while((openbsd_pt[openbsd_next].ki_flag & P_KTHREAD)
&& openbsd_next < openbsd_nproc)
openbsd_next++;
if (openbsd_next >= openbsd_nproc) return NULL;
strncpy(openbsd_proc.command,openbsd_pt[openbsd_next].ki_comm,1023);
openbsd_proc.command[1023] = 0;
openbsd_proc.pid = openbsd_pt[openbsd_next].ki_pid;
openbsd_proc.nice = openbsd_pt[openbsd_next].ki_nice-20;
openbsd_proc.uid = openbsd_pt[openbsd_next].ki_ruid;
openbsd_proc.gid = openbsd_pt[openbsd_next].ki_rgid;
openbsd_proc.utime = (openbsd_pt[openbsd_next].ki_runtime+500000)/1000000;
#else
strncpy(openbsd_proc.command,openbsd_pt[openbsd_next].kp_proc.p_comm,1023);
openbsd_proc.command[1023] = 0;
openbsd_proc.pid = openbsd_pt[openbsd_next].kp_proc.p_pid;
openbsd_proc.nice = openbsd_pt[openbsd_next].kp_proc.p_nice-20;
openbsd_proc.uid = openbsd_pt[openbsd_next].kp_eproc.e_pcred.p_ruid;
openbsd_proc.gid = openbsd_pt[openbsd_next].kp_eproc.e_pcred.p_rgid;
/* Adapted from top(1) port, as found in the misc@openbsd.org archive */
openbsd_proc.utime = (openbsd_pt[openbsd_next].kp_proc.p_uticks +
openbsd_pt[openbsd_next].kp_proc.p_sticks +
openbsd_pt[openbsd_next].kp_proc.p_iticks)
/ openbsd_hz;
#endif
/*
printf("%-20s %5i %3i %i\n",openbsd_proc.command,openbsd_proc.pid,
openbsd_proc.nice,openbsd_proc.utime);
*/
and_printf(3, "OpenBSD: process %s pid: %d ppid: %d\n",
openbsd_proc.command, openbsd_proc.pid, openbsd_proc.ppid);
openbsd_next++;
return &openbsd_proc;
}
struct and_procent *openbsd_getfirst ()
{
char errmsg [_POSIX2_LINE_MAX];
if (!openbsd_kvm) {
openbsd_kvm = kvm_openfiles(NULL,NULL,NULL,O_RDONLY,errmsg);
if (!openbsd_kvm) {
and_printf(0,"KVM: cannot open (\"%s\"). Aborting.\n",errmsg);
abort();
}
openbsd_init();
}
openbsd_pt = kvm_getprocs(openbsd_kvm,KERN_PROC_ALL,0,&openbsd_nproc);
if (!openbsd_pt) {
and_printf(0,"KVM: cannot retrieve process table. Aborting.\n");
abort();
}
openbsd_next = 0;
return openbsd_getnext();
}
int main (int argc, char** argv)
{
and_setprocreader(&openbsd_getfirst,&openbsd_getnext);
return and_main(argc,argv);
}
syntax highlighted by Code2HTML, v. 0.9.1