diff --git a/sysdeps/solaris/ChangeLog b/sysdeps/solaris/ChangeLog index 5667b055..a7aca39d 100644 --- a/sysdeps/solaris/ChangeLog +++ b/sysdeps/solaris/ChangeLog @@ -1,3 +1,24 @@ +1999-05-02 Drazen Kacar + + * 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 + + procdata.c: Use pread() instead of read(). + 1999-05-02 Drazen Kacar * glibtop_machine.h: added fields for page size, clock ticks and diff --git a/sysdeps/solaris/open.c b/sysdeps/solaris/open.c index 02803b13..e94ff5f7 100644 --- a/sysdeps/solaris/open.c +++ b/sysdeps/solaris/open.c @@ -47,65 +47,76 @@ glibtop_get_kstats(glibtop *server) server->ncpu = new_ncpu; server->machine.vminfo_kstat = NULL; server->machine.system = NULL; + server->machine.syspages = NULL; server->machine.bunyip = NULL; return; } - ksp = kstat_lookup(kc, "unix", -1, "vminfo"); - 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) + do { + ksp = kstat_lookup(kc, "unix", -1, "vminfo"); + server->machine.vminfo_kstat = ksp; + if(ksp) { - if(p_online(p, P_STATUS) < 0) - continue; - sprintf(cpu, "cpu_stat%d", (int)p); - server->machine.cpu_stat_kstat[p] = - kstat_lookup(kc, "cpu_stat", -1, cpu); - ++found; + kstat_read(kc, ksp, &server->machine.vminfo); + server->machine.vminfo_snaptime = ksp->ks_snaptime; } - } - 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"); + /* 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) + { + 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 diff --git a/sysdeps/solaris/procdata.c b/sysdeps/solaris/procdata.c index 4a74df10..7fb8febb 100644 --- a/sysdeps/solaris/procdata.c +++ b/sysdeps/solaris/procdata.c @@ -71,3 +71,26 @@ glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t p close (fd); 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; +} diff --git a/sysdeps/solaris/procstate.c b/sysdeps/solaris/procstate.c index a7d7a143..8e415879 100644 --- a/sysdeps/solaris/procstate.c +++ b/sysdeps/solaris/procstate.c @@ -27,8 +27,11 @@ #include static const unsigned long _glibtop_sysdeps_proc_state = -(1 << GLIBTOP_PROC_STATE_UID) + (1 << GLIBTOP_PROC_STATE_GID) + -(1 << GLIBTOP_PROC_STATE_CMD); +(1L << GLIBTOP_PROC_STATE_CMD) + (1L << GLIBTOP_PROC_STATE_STATE) + +(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. */ @@ -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)) return; - buf->uid = psinfo.pr_uid; - buf->gid = psinfo.pr_gid; + buf->uid = psinfo.pr_euid; + 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); diff --git a/sysdeps/solaris/procuid.c b/sysdeps/solaris/procuid.c index bb65c9d8..7695850e 100644 --- a/sysdeps/solaris/procuid.c +++ b/sysdeps/solaris/procuid.c @@ -26,19 +26,24 @@ #include -static const unsigned long _glibtop_sysdeps_proc_uid = -(1 << GLIBTOP_PROC_UID_EUID) + (1 << GLIBTOP_PROC_UID_UID) + -(1 << GLIBTOP_PROC_UID_EGID) + (1 << GLIBTOP_PROC_UID_GID) + -(1 << GLIBTOP_PROC_UID_PID) + (1 << GLIBTOP_PROC_UID_PPID) + -(1 << GLIBTOP_PROC_UID_PGRP) + (1 << GLIBTOP_PROC_UID_SESSION) + -(1 << GLIBTOP_PROC_UID_TTY); +static const unsigned long _glibtop_sysdeps_proc_uid_psinfo = +(1L << GLIBTOP_PROC_UID_EUID) + (1L << GLIBTOP_PROC_UID_UID) + +(1L << GLIBTOP_PROC_UID_EGID) + (1L << GLIBTOP_PROC_UID_GID) + +(1L << GLIBTOP_PROC_UID_PID) + (1L << GLIBTOP_PROC_UID_PPID) + +(1L << GLIBTOP_PROC_UID_PGRP) + (1L << GLIBTOP_PROC_UID_SESSION) + +(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. */ void 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. */ @@ -47,6 +52,7 @@ void glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid) { struct psinfo psinfo; + struct prcred prcred; 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->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; }