Yet another kstat_chain_update check. Added machine.cpu_stat_kstat[x] =

* open.c (glibtop_get_kstats): Yet another kstat_chain_update
        check. Added machine.cpu_stat_kstat[x] = NULL when processor
        x is not configured.

        * procdata.c (glibtop_get_proc_credentials_s): Read prcred
        structure from /proc.

        * procstate.c (glibtop_get_proc_state_s): Added ruid, rgid,
        has_cpu, processor and last_processor.

        * procuid.c (glibtop_get_proc_uid_s): Added priority, nice,
        suid, sgid, ngroups and groups. The last four will be
        filled only if our process has the authority to read prcred
        structure of another process.

	It's a bit untested for now. :-)
This commit is contained in:
Drazen Kacar
1999-05-02 19:26:24 +00:00
parent 3951c8863f
commit 75141bdb65
5 changed files with 168 additions and 64 deletions

View File

@@ -1,3 +1,24 @@
1999-05-02 Drazen Kacar <dave@srce.hr>
* open.c (glibtop_get_kstats): Yet another kstat_chain_update
check. Added machine.cpu_stat_kstat[x] = NULL when processor
x is not configured.
* procdata.c (glibtop_get_proc_credentials_s): Read prcred
structure from /proc.
* procstate.c (glibtop_get_proc_state_s): Added ruid, rgid,
has_cpu, processor and last_processor.
* procuid.c (glibtop_get_proc_uid_s): Added priority, nice,
suid, sgid, ngroups and groups. The last four will be
filled only if our process has the authority to read prcred
structure of another process.
1999-05-02 Drazen Kacar <dave@srce.hr>
procdata.c: Use pread() instead of read().
1999-05-02 Drazen Kacar <dave@srce.hr> 1999-05-02 Drazen Kacar <dave@srce.hr>
* glibtop_machine.h: added fields for page size, clock ticks and * glibtop_machine.h: added fields for page size, clock ticks and

View File

@@ -47,65 +47,76 @@ glibtop_get_kstats(glibtop *server)
server->ncpu = new_ncpu; server->ncpu = new_ncpu;
server->machine.vminfo_kstat = NULL; server->machine.vminfo_kstat = NULL;
server->machine.system = NULL; server->machine.system = NULL;
server->machine.syspages = NULL;
server->machine.bunyip = NULL; server->machine.bunyip = NULL;
return; return;
} }
ksp = kstat_lookup(kc, "unix", -1, "vminfo"); do {
server->machine.vminfo_kstat = ksp; ksp = kstat_lookup(kc, "unix", -1, "vminfo");
if(ksp) server->machine.vminfo_kstat = ksp;
{ if(ksp)
kstat_read(kc, ksp, &server->machine.vminfo);
server->machine.vminfo_snaptime = ksp->ks_snaptime;
}
/* We don't know why was kstat chain invalidated. It could have
been because the number of processors changed. The sysconf()
man page says that values returned won't change during the
life time of a process, but let's hope that's just an error in
the documentation. */
if(nproc_same = new_ncpu == server->ncpu)
{
int checked, i;
char cpu[20];
for(i = 0, checked = 0; i < GLIBTOP_NCPU || checked == new_ncpu; ++i)
if(server->machine.cpu_stat_kstat[i])
{
sprintf(cpu, "cpu_stat%d", i);
if(!(server->machine.cpu_stat_kstat[i] =
kstat_lookup(kc, "cpu_stat", -1, cpu)))
{
nproc_same = 0;
break;
}
++checked;
}
}
if(!nproc_same)
{
processorid_t p;
int found;
char cpu[20];
if(new_ncpu > GLIBTOP_NCPU)
new_ncpu = GLIBTOP_NCPU;
server->ncpu = new_ncpu;
for(p = 0, found = 0; p < GLIBTOP_NCPU && found != new_ncpu; ++p)
{ {
if(p_online(p, P_STATUS) < 0) kstat_read(kc, ksp, &server->machine.vminfo);
continue; server->machine.vminfo_snaptime = ksp->ks_snaptime;
sprintf(cpu, "cpu_stat%d", (int)p);
server->machine.cpu_stat_kstat[p] =
kstat_lookup(kc, "cpu_stat", -1, cpu);
++found;
} }
}
server->machine.system = kstat_lookup(kc, "unix", -1, "system_misc"); /* We don't know why was kstat chain invalidated. It could have
server->machine.syspages = kstat_lookup(kc, "unix", -1, "system_pages"); been because the number of processors changed. The sysconf()
server->machine.bunyip = kstat_lookup(kc, "bunyip", -1, "mempages"); man page says that values returned won't change during the
life time of a process, but let's hope that's just an error in
the documentation. */
if(nproc_same = new_ncpu == server->ncpu)
{
int checked, i;
char cpu[20];
for(i = 0, checked = 0; i < GLIBTOP_NCPU || checked == new_ncpu; ++i)
if(server->machine.cpu_stat_kstat[i])
{
sprintf(cpu, "cpu_stat%d", i);
if(!(server->machine.cpu_stat_kstat[i] =
kstat_lookup(kc, "cpu_stat", -1, cpu)))
{
nproc_same = 0;
break;
}
++checked;
}
}
if(!nproc_same)
{
processorid_t p;
int found;
char cpu[20];
if(new_ncpu > GLIBTOP_NCPU)
new_ncpu = GLIBTOP_NCPU;
server->ncpu = new_ncpu;
for(p = 0, found = 0; p < GLIBTOP_NCPU && found != new_ncpu; ++p)
{
if(p_online(p, P_STATUS) < 0)
{
server->machine.cpu_stat_kstat[p] = NULL;
continue;
}
sprintf(cpu, "cpu_stat%d", (int)p);
server->machine.cpu_stat_kstat[p] =
kstat_lookup(kc, "cpu_stat", -1, cpu);
++found;
}
}
server->machine.system = kstat_lookup(kc, "unix", -1, "system_misc");
server->machine.syspages = kstat_lookup(kc, "unix", -1, "system_pages");
server->machine.bunyip = kstat_lookup(kc, "bunyip", -1, "mempages");
} while(kstat_chain_update(kc) > 0 &&
(new_ncpu = sysconf(_SC_NPROCESSORS_CONF)));
/* We'll ignore -1 from kstat_chain_update here, since it really
shouldn't happen */
} }
void void

View File

@@ -71,3 +71,26 @@ glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t p
close (fd); close (fd);
return 0; return 0;
} }
int
glibtop_get_proc_credentials_s(glibtop *server, struct prcred *prcred, pid_t pid)
{
int fd;
char buffer[BUFSIZ];
sprintf(buffer, "/proc/%d/prcred", (int)pid);
if((fd = open(buffer, O_RDONLY)) < 0)
{
if(errno != EPERM)
glibtop_warn_io_r(server, "open (%s)", buffer);
return -1;
}
if(pread(fd, prcred, sizeof(struct prcred), 0) != sizeof(struct prcred))
{
close(fd);
glibtop_warn_io_r(server, "read (%s)", buffer);
return -1;
}
close(fd);
return 0;
}

View File

@@ -27,8 +27,11 @@
#include <glibtop_private.h> #include <glibtop_private.h>
static const unsigned long _glibtop_sysdeps_proc_state = static const unsigned long _glibtop_sysdeps_proc_state =
(1 << GLIBTOP_PROC_STATE_UID) + (1 << GLIBTOP_PROC_STATE_GID) + (1L << GLIBTOP_PROC_STATE_CMD) + (1L << GLIBTOP_PROC_STATE_STATE) +
(1 << GLIBTOP_PROC_STATE_CMD); (1L << GLIBTOP_PROC_STATE_UID) + (1L << GLIBTOP_PROC_STATE_GID) +
(1L << GLIBTOP_PROC_STATE_RUID) + (1L << GLIBTOP_PROC_STATE_RGID) +
(1L << GLIBTOP_PROC_STATE_HAS_CPU) + (1L << GLIBTOP_PROC_STATE_PROCESSOR) +
(1L << GLIBTOP_PROC_STATE_LAST_PROCESSOR);
/* Init function. */ /* Init function. */
@@ -50,8 +53,25 @@ glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid)
if (glibtop_get_proc_data_psinfo_s (server, &psinfo, pid)) if (glibtop_get_proc_data_psinfo_s (server, &psinfo, pid))
return; return;
buf->uid = psinfo.pr_uid; buf->uid = psinfo.pr_euid;
buf->gid = psinfo.pr_gid; buf->gid = psinfo.pr_egid;
buf->ruid = psinfo.pr_uid;
buf->rgid = psinfo.pr_gid;
switch(psinfo.pr_lwp.pr_state)
{
case SONPROC: buf->has_cpu = 1;
buf->processor = psinfo.pr_lwp.pr_onpro;
case SRUN: buf->state = GLIBTOP_PROCESS_RUNNING;
break;
case SZOMB: buf->state = GLIBTOP_PROCESS_ZOMBIE;
break;
case SSLEEP:
case SSTOP: buf->state = GLIBTOP_PROCESS_STOPPED;
break;
case SIDL: buf->state = GLIBTOP_PROCESS_UNINTERRUPTIBLE;
}
buf->last_processor = psinfo.pr_lwp.pr_onpro;
strncpy (buf->cmd, psinfo.pr_fname, 39); strncpy (buf->cmd, psinfo.pr_fname, 39);

View File

@@ -26,19 +26,24 @@
#include <glibtop_private.h> #include <glibtop_private.h>
static const unsigned long _glibtop_sysdeps_proc_uid = static const unsigned long _glibtop_sysdeps_proc_uid_psinfo =
(1 << GLIBTOP_PROC_UID_EUID) + (1 << GLIBTOP_PROC_UID_UID) + (1L << GLIBTOP_PROC_UID_EUID) + (1L << GLIBTOP_PROC_UID_UID) +
(1 << GLIBTOP_PROC_UID_EGID) + (1 << GLIBTOP_PROC_UID_GID) + (1L << GLIBTOP_PROC_UID_EGID) + (1L << GLIBTOP_PROC_UID_GID) +
(1 << GLIBTOP_PROC_UID_PID) + (1 << GLIBTOP_PROC_UID_PPID) + (1L << GLIBTOP_PROC_UID_PID) + (1L << GLIBTOP_PROC_UID_PPID) +
(1 << GLIBTOP_PROC_UID_PGRP) + (1 << GLIBTOP_PROC_UID_SESSION) + (1L << GLIBTOP_PROC_UID_PGRP) + (1L << GLIBTOP_PROC_UID_SESSION) +
(1 << GLIBTOP_PROC_UID_TTY); (1L << GLIBTOP_PROC_UID_TTY) + (1L << GLIBTOP_PROC_UID_PRIORITY) +
(1L << GLIBTOP_PROC_UID_NICE);
static const unsigned long _glibtop_sysdeps_proc_uid_prcred =
(1L << GLIBTOP_PROC_UID_SUID) + (1L << GLIBTOP_PROC_UID_SGID) +
(1L << GLIBTOP_PROC_UID_NGROUPS) + (1L << GLIBTOP_PROC_UID_GROUPS);
/* Init function. */ /* Init function. */
void void
glibtop_init_proc_uid_s (glibtop *server) glibtop_init_proc_uid_s (glibtop *server)
{ {
server->sysdeps.proc_uid = _glibtop_sysdeps_proc_uid; server->sysdeps.proc_uid = _glibtop_sysdeps_proc_uid_psinfo +
_glibtop_sysdeps_proc_uid_prcred;
} }
/* Provides detailed information about a process. */ /* Provides detailed information about a process. */
@@ -47,6 +52,7 @@ void
glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid) glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid)
{ {
struct psinfo psinfo; struct psinfo psinfo;
struct prcred prcred;
memset (buf, 0, sizeof (glibtop_proc_uid)); memset (buf, 0, sizeof (glibtop_proc_uid));
@@ -65,5 +71,28 @@ glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid)
buf->session = psinfo.pr_sid; buf->session = psinfo.pr_sid;
buf->tty = psinfo.pr_ttydev; buf->tty = psinfo.pr_ttydev;
buf->flags = _glibtop_sysdeps_proc_uid; buf->priority = psinfo.pr_lwp.pr_pri;
buf->nice = psinfo.pr_lwp.pr_nice;
buf->flags = _glibtop_sysdeps_proc_uid_psinfo;
if(glibtop_get_proc_credentials_s(server, &prcred, pid))
return;
buf->suid = prcred.pr_suid;
buf->sgid = prcred.pr_sgid;
buf->ngroups = (prcred.pr_ngroups <= GLIBTOP_MAX_GROUPS) ?
prcred.pr_ngroups : GLIBTOP_MAX_GROUPS;
if(sizeof(int) == sizeof(gid_t))
memcpy(buf->groups, prcred.pr_groups,
buf->ngroups * sizeof(gid_t));
else
{
int i;
for(i = 0; i < buf->ngroups; ++i)
buf->groups[i] = prcred.pr_groups[i];
}
buf->flags += _glibtop_sysdeps_proc_uid_prcred;
} }