diff --git a/sysdeps/solaris/ChangeLog b/sysdeps/solaris/ChangeLog index 4dfbb42c..0de8c722 100644 --- a/sysdeps/solaris/ChangeLog +++ b/sysdeps/solaris/ChangeLog @@ -1,3 +1,24 @@ +2004-10-11 Benoît Dejean + + * cpu.c: (glibtop_init_cpu_s), (glibtop_get_cpu_s): + * loadavg.c: (glibtop_get_loadavg_s): + * mem.c: (glibtop_init_mem_s), (glibtop_get_mem_s): + * open.c: (glibtop_get_kstats), (glibtop_open_s): + * procargs.c: (glibtop_get_proc_args_s): + * procdata.c: (glibtop_get_proc_data_psinfo_s), + (glibtop_get_proc_data_usage_s), (glibtop_get_proc_credentials_s), + (glibtop_get_proc_status_s): + * proclist.c: (glibtop_get_proclist_s): + * procmap.c: (glibtop_get_proc_map_s): + * procmem.c: (glibtop_get_proc_mem_s): + * procstate.c: (glibtop_get_proc_state_s): + * safeio.c: + * safeio.h: + * shm_limits.c: (glibtop_init_shm_limits_p), + (glibtop_get_shm_limits_p): + * swap.c: (glibtop_get_swap_s): + * uptime.c: (glibtop_get_uptime_s): Updated. Lots of cleanup. + 2004-06-06 Benoît Dejean * proclist.c: (glibtop_get_proclist_s): Removed useless tests. diff --git a/sysdeps/solaris/cpu.c b/sysdeps/solaris/cpu.c index 3ecb3503..430e00b1 100644 --- a/sysdeps/solaris/cpu.c +++ b/sysdeps/solaris/cpu.c @@ -30,14 +30,15 @@ #include -static const unsigned long _glibtop_sysdeps_cpu = +static const unsigned long _glibtop_sysdeps_cpu_freq = +(1L << GLIBTOP_CPU_FREQUENCY); + +static const unsigned long _glibtop_sysdeps_cpu_all = (1L << GLIBTOP_CPU_TOTAL) + (1L << GLIBTOP_CPU_USER) + (1L << GLIBTOP_CPU_SYS) + (1L << GLIBTOP_CPU_IDLE) + (1L << GLIBTOP_XCPU_TOTAL) + (1L << GLIBTOP_XCPU_USER) + (1L << GLIBTOP_XCPU_SYS) + (1L << GLIBTOP_XCPU_IDLE) + -#if LIBGTOP_VERSION_CODE >= 1001002 (1L << GLIBTOP_XCPU_FLAGS) + -#endif (1L << GLIBTOP_CPU_FREQUENCY); /* Init function. */ @@ -45,7 +46,7 @@ static const unsigned long _glibtop_sysdeps_cpu = void glibtop_init_cpu_s (glibtop *server) { - server->sysdeps.cpu = _glibtop_sysdeps_cpu; + server->sysdeps.cpu = _glibtop_sysdeps_cpu_all; } /* Provides information about cpu usage. */ @@ -53,43 +54,41 @@ glibtop_init_cpu_s (glibtop *server) void glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf) { - kstat_ctl_t *kc = server->machine.kc; + kstat_ctl_t * const kc = server->machine.kc; cpu_stat_t cpu_stat; processorid_t cpu; int ncpu, found; - kid_t ret; memset (buf, 0, sizeof (glibtop_cpu)); + buf->frequency = server->machine.ticks; + buf->flags = _glibtop_sysdeps_cpu_freq; + if(!kc) - return; + return; + switch(kstat_chain_update(kc)) { - case -1: assert(0); /* Debugging purposes, shouldn't happen */ + case -1: assert(0); /* Debugging purposes, shouldn't happen */ case 0: break; default: glibtop_get_kstats(server); } - ncpu = server->ncpu; - if (ncpu > GLIBTOP_NCPU) - ncpu = GLIBTOP_NCPU; + + ncpu = MIN(GLIBTOP_NCPU, server->ncpu); for (cpu = 0, found = 0; cpu < GLIBTOP_NCPU && found != ncpu; cpu++) { - kstat_t *ksp = server->machine.cpu_stat_kstat [cpu]; - if (!ksp) continue; + kstat_t * const ksp = server->machine.cpu_stat_kstat [cpu]; + if (!ksp) continue;; ++found; + if(p_online(cpu, P_STATUS) == P_ONLINE) -#if LIBGTOP_VERSION_CODE >= 1001002 buf->xcpu_flags |= (1L << cpu); -#else - ; -#endif else continue; - ret = kstat_read (kc, ksp, &cpu_stat); - if (ret == -1) { + if (kstat_read (kc, ksp, &cpu_stat) == -1) { glibtop_warn_io_r (server, "kstat_read (cpu_stat%d)", cpu); continue; } @@ -97,7 +96,6 @@ glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf) buf->xcpu_idle [cpu] = cpu_stat.cpu_sysinfo.cpu [CPU_IDLE]; buf->xcpu_user [cpu] = cpu_stat.cpu_sysinfo.cpu [CPU_USER]; buf->xcpu_sys [cpu] = cpu_stat.cpu_sysinfo.cpu [CPU_KERNEL]; - buf->xcpu_total [cpu] = buf->xcpu_idle [cpu] + buf->xcpu_user [cpu] + buf->xcpu_sys [cpu]; @@ -106,8 +104,9 @@ glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf) buf->sys += cpu_stat.cpu_sysinfo.cpu [CPU_KERNEL]; } - buf->total = buf->idle + buf->user + buf->sys; - buf->frequency = server->machine.ticks; + if(!found) + return; - buf->flags = _glibtop_sysdeps_cpu; + buf->total = buf->idle + buf->user + buf->sys; + buf->flags = _glibtop_sysdeps_cpu_all; } diff --git a/sysdeps/solaris/loadavg.c b/sysdeps/solaris/loadavg.c index 39f4f445..8a3dd834 100644 --- a/sysdeps/solaris/loadavg.c +++ b/sysdeps/solaris/loadavg.c @@ -51,37 +51,43 @@ glibtop_get_loadavg_s (glibtop *server, glibtop_loadavg *buf) #ifndef HAVE_GETLOADAVG kstat_ctl_t *kc; kstat_t *ksp; - int i; - static const char *avestrings[] = { "avenrun_1min", - "avenrun_5min", - "avenrun_15min" }; + size_t i; + static const char avestrings[][14] = { "avenrun_1min", + "avenrun_5min", + "avenrun_15min" }; #endif memset (buf, 0, sizeof (glibtop_loadavg)); #ifdef HAVE_GETLOADAVG - if (getloadavg (buf->loadavg, 3)) + if (getloadavg (buf->loadavg, 3) != 3) return; + #else if(!(kc = server->machine.kc)) return; + switch(kstat_chain_update(kc)) { case -1: assert(0); /* Debugging, shouldn't happen */ case 0: break; default: glibtop_get_kstats(server); } + if(!(ksp = server->machine.system)) return; + if(kstat_read(kc, ksp, NULL) < 0) return; + for(i = 0; i < 3; ++i) /* Do we have a countof macro? */ { - kstat_named_t *kn; + kstat_named_t *kn; kn = (kstat_named_t *)kstat_data_lookup(ksp, avestrings[i]); if(kn) buf->loadavg[i] = (double)kn->value.ul / FSCALE; } -#endif +#endif /* HAVE_GETLOADAVG */ + buf->flags = _glibtop_sysdeps_loadavg; } diff --git a/sysdeps/solaris/mem.c b/sysdeps/solaris/mem.c index 3be84e0f..32bf8bb0 100644 --- a/sysdeps/solaris/mem.c +++ b/sysdeps/solaris/mem.c @@ -29,22 +29,18 @@ #include -static const unsigned long _glibtop_sysdeps_mem_os_sysconf = -(1L << GLIBTOP_MEM_TOTAL); -static const unsigned long _glibtop_sysdeps_mem_os_kstat = -(1L << GLIBTOP_MEM_FREE) + (1L << GLIBTOP_MEM_USED) + -(1L << GLIBTOP_MEM_LOCKED); -static const unsigned long _glibtop_sysdeps_mem_bunyip = -(1L << GLIBTOP_MEM_SHARED) + (1L << GLIBTOP_MEM_BUFFER) + -(1L << GLIBTOP_MEM_USER); - /* Init function. */ void glibtop_init_mem_s (glibtop *server) { - server->sysdeps.mem = _glibtop_sysdeps_mem_os_sysconf + - _glibtop_sysdeps_mem_os_kstat + _glibtop_sysdeps_mem_bunyip; + server->sysdeps.mem = (1L << GLIBTOP_MEM_TOTAL) + | (1L << GLIBTOP_MEM_FREE) + | (1L << GLIBTOP_MEM_USED) + | (1L << GLIBTOP_MEM_LOCKED) + | (1L << GLIBTOP_MEM_SHARED) + | (1L << GLIBTOP_MEM_BUFFER) + | (1L << GLIBTOP_MEM_USER); } /* Provides information about memory usage. */ @@ -52,76 +48,87 @@ glibtop_init_mem_s (glibtop *server) void glibtop_get_mem_s (glibtop *server, glibtop_mem *buf) { - kstat_ctl_t *kc = server->machine.kc; + kstat_ctl_t * const kc = server->machine.kc; kstat_t *ksp; kstat_named_t *kn; - int pagesize = server->machine.pagesize; -#ifndef KSTAT_DATA_UINT32 -#define ui32 ul +#undef PAGESIZE +#define PAGESIZE (server->machine.pagesize) +#define PAGESHIFT (PAGESIZE + 10) + +#ifdef _LP64 +#define KN_VALUE kn->value.ui64 +#elif !defined(KSTAT_DATA_UINT32) +#define KN_VALUE kn->value.ul +#else +#define KN_VALUE kn->value.ui32 #endif memset (buf, 0, sizeof (glibtop_mem)); - buf->total = (guint64)sysconf(_SC_PHYS_PAGES) << pagesize << 10; - buf->flags = _glibtop_sysdeps_mem_os_sysconf; + buf->total = (guint64) sysconf(_SC_PHYS_PAGES) << PAGESHIFT; + buf->flags = (1 << GLIBTOP_MEM_TOTAL); if(!kc) - return; + return; + switch(kstat_chain_update(kc)) { - case -1: assert(0); /* Debugging purposes, shouldn't happen */ + case -1: assert(0); /* Debugging purposes, shouldn't happen */ case 0: break; default: glibtop_get_kstats(server); } if((ksp = server->machine.syspages) && kstat_read(kc, ksp, NULL) >= 0) { - kn = (kstat_named_t *)kstat_data_lookup(ksp, "pagesfree"); + kn = kstat_data_lookup(ksp, "pagesfree"); if(kn) { -#ifdef _LP64 - buf->free = kn->value.ui64 << pagesize << 10; -#else - buf->free = kn->value.ui32 << pagesize << 10; -#endif + buf->free = (KN_VALUE << PAGESHIFT); buf->used = buf->total - buf->free; + buf->flags |= (1 << GLIBTOP_MEM_FREE); + buf->flags |= (1 << GLIBTOP_MEM_USED); } - kn = (kstat_named_t *)kstat_data_lookup(ksp, "pageslocked"); + + kn = kstat_data_lookup(ksp, "pageslocked"); if(kn) -#ifdef _LP64 - buf->locked = kn->value.ui64 << pagesize; -#else - buf->locked = kn->value.ui32 << pagesize; -#endif - buf->flags += _glibtop_sysdeps_mem_os_kstat; + { + buf->locked = (KN_VALUE << PAGESIZE); + buf->flags |= (1 << GLIBTOP_MEM_LOCKED); + } } /* Bunyip module provides data in multiples of system page size */ if((ksp = server->machine.bunyip) && kstat_read(kc, ksp, NULL) >= 0) { - kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_anon"); + kn = kstat_data_lookup(ksp, "pages_exec"); if(kn) -#ifdef _LP64 - buf->user = kn->value.ui64 << pagesize << 10; -#else - buf->user = kn->value.ui32 << pagesize << 10; -#endif - kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_exec"); + { + buf->shared = (KN_VALUE << PAGESHIFT); + buf->flags |= (1 << GLIBTOP_MEM_SHARED); + } + + kn = kstat_data_lookup(ksp, "pages_vnode"); if(kn) -#ifdef _LP64 - buf->shared = kn->value.ui64 << pagesize << 10; -#else - buf->shared = kn->value.ui32 << pagesize << 10; -#endif - kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_vnode"); + { + buf->buffer = (KN_VALUE << PAGESHIFT); + buf->flags |= (1 << GLIBTOP_MEM_BUFFER); + } + + kn = kstat_data_lookup(ksp, "pages_anon"); if(kn) -#ifdef _LP64 - buf->buffer = kn->value.ui64 << pagesize << 10; -#else - buf->buffer = kn->value.ui32 << pagesize << 10; -#endif - buf->flags += _glibtop_sysdeps_mem_bunyip; + { + buf->user = (KN_VALUE << PAGESHIFT); + buf->flags |= (1 << GLIBTOP_MEM_USER); + } + else + goto user_old_way; + } + else /* Bunyip is not available, let's compute buf->user the old way */ + { + user_old_way: + buf->user = buf->total - buf->free - buf->cached - buf->buffer; + buf->flags |= (1 << GLIBTOP_MEM_USER); } } diff --git a/sysdeps/solaris/open.c b/sysdeps/solaris/open.c index 7df43ca2..e9ba24b5 100644 --- a/sysdeps/solaris/open.c +++ b/sysdeps/solaris/open.c @@ -44,19 +44,21 @@ glibtop_get_kstats(glibtop *server) kstat_t *ksp; int nproc_same, new_ncpu; - new_ncpu = sysconf(_SC_NPROCESSORS_CONF); + server->ncpu = new_ncpu = sysconf(_SC_NPROCESSORS_CONF); + if(!kc) { - server->ncpu = new_ncpu; - server->machine.vminfo_kstat = NULL; - server->machine.system = NULL; - server->machine.syspages = NULL; - server->machine.bunyip = NULL; - return; + server->ncpu = new_ncpu; + server->machine.vminfo_kstat = NULL; + server->machine.system = NULL; + server->machine.syspages = NULL; + server->machine.bunyip = NULL; + return; } do { + ksp = kstat_lookup(kc, "unix", -1, "vminfo"); server->machine.vminfo_kstat = ksp; if(ksp) @@ -64,7 +66,7 @@ glibtop_get_kstats(glibtop *server) kstat_read(kc, ksp, &server->machine.vminfo); /* Don't change snaptime if we only need to reinitialize kstats */ if(!(server->machine.vminfo_snaptime)) - server->machine.vminfo_snaptime = ksp->ks_snaptime; + server->machine.vminfo_snaptime = ksp->ks_snaptime; } /* We don't know why was kstat chain invalidated. It could have @@ -91,15 +93,15 @@ glibtop_get_kstats(glibtop *server) ++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; + server->ncpu = new_ncpu = MIN(new_ncpu, GLIBTOP_NCPU); + for(p = 0, found = 0; p < GLIBTOP_NCPU && found != new_ncpu; ++p) { if(p_online(p, P_STATUS) < 0) @@ -183,14 +185,14 @@ glibtop_open_s (glibtop *server, const char *program_name, switch(kn->data_type) { #ifdef KSTAT_DATA_INT32 - case KSTAT_DATA_INT32: server->machine.boot = kn->value.i32; - break; - case KSTAT_DATA_UINT32: server->machine.boot = kn->value.ui32; - break; - case KSTAT_DATA_INT64: server->machine.boot = kn->value.i64; - break; - case KSTAT_DATA_UINT64: server->machine.boot = kn->value.ui64; - break; + case KSTAT_DATA_INT32: server->machine.boot = kn->value.i32; + break; + case KSTAT_DATA_UINT32: server->machine.boot = kn->value.ui32; + break; + case KSTAT_DATA_INT64: server->machine.boot = kn->value.i64; + break; + case KSTAT_DATA_UINT64: server->machine.boot = kn->value.ui64; + break; #else case KSTAT_DATA_LONG: server->machine.boot = kn->value.l; break; @@ -218,7 +220,7 @@ glibtop_open_s (glibtop *server, const char *program_name, if(!func) func = dlsym(dl, "proc_objname"); /* Solaris 7 */ server->machine.objname = (void (*) - (void *, uintptr_t, const char *, size_t))func; + (void *, uintptr_t, const char *, size_t))func; server->machine.pgrab = (struct ps_prochandle *(*)(pid_t, int, int *)) dlsym(dl, "Pgrab"); server->machine.pfree = (void (*)(void *))dlsym(dl, "Pfree"); diff --git a/sysdeps/solaris/procargs.c b/sysdeps/solaris/procargs.c index 4d8ca0f1..a5bad8bd 100644 --- a/sysdeps/solaris/procargs.c +++ b/sysdeps/solaris/procargs.c @@ -25,6 +25,8 @@ #include #include +#include "glibtop_private.h" + static const unsigned long _glibtop_sysdeps_proc_args = (1L << GLIBTOP_PROC_ARGS_SIZE); @@ -43,40 +45,40 @@ glibtop_get_proc_args_s (glibtop *server, glibtop_proc_args *buf, pid_t pid, unsigned max_len) { #ifdef HAVE_PROCFS_H - struct psinfo pinfo; + struct psinfo pinfo; #else struct prpsinfo pinfo; #endif - int len, i; + unsigned len; char *ret, *p; memset (buf, 0, sizeof (glibtop_proc_args)); if(glibtop_get_proc_data_psinfo_s(server, &pinfo, pid)) - return NULL; + return NULL; + /* strnlen */ for(len = 0; len < PRARGSZ; ++len) if(!(pinfo.pr_psargs[len])) break; - if(max_len) - { - ret = g_malloc(max_len + 1); - if(max_len < len) - len = max_len; - memcpy(ret, pinfo.pr_psargs, len); - ret[len] = 0; - } - else - { - ret = g_malloc(len + 1); - memcpy(ret, pinfo.pr_psargs, len); - ret[len] = 0; - buf->size = len; - buf->flags = _glibtop_sysdeps_proc_args; + + if(max_len && max_len < len) + { + len = max_len; } + + ret = g_malloc(len + 1); + memcpy(ret, pinfo.pr_psargs, len); + ret[len] = 0; + for(p = ret; *p; ++p) - if(*p == ' ') - *p = 0; + { + if(*p == ' ') *p = 0; + } + + buf->size = len; + buf->flags = _glibtop_sysdeps_proc_args; + return ret; } diff --git a/sysdeps/solaris/procdata.c b/sysdeps/solaris/procdata.c index e8353d00..10536e69 100644 --- a/sysdeps/solaris/procdata.c +++ b/sysdeps/solaris/procdata.c @@ -53,14 +53,16 @@ glibtop_get_proc_data_psinfo_s (glibtop *server, struct psinfo *psinfo, pid_t pi char buffer [BUFSIZ]; sprintf (buffer, "/proc/%d/psinfo", (int) pid); + fd = s_open (buffer, O_RDONLY); + if (fd < 0) { glibtop_warn_io_r (server, "open (%s)", buffer); return -1; } - if (s_pread (fd, psinfo, sizeof (struct psinfo), 0) != - sizeof (struct psinfo)) + if (s_pread (fd, psinfo, sizeof (struct psinfo), 0) + != sizeof (struct psinfo)) { s_close (fd); glibtop_warn_io_r (server, "pread (%s)", buffer); @@ -78,14 +80,16 @@ glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t p char buffer [BUFSIZ]; sprintf (buffer, "/proc/%d/usage", (int) pid); + fd = s_open (buffer, O_RDONLY); + if (fd < 0) { glibtop_warn_io_r (server, "open (%s)", buffer); return -1; } - if (s_pread (fd, prusage, sizeof (struct prusage), 0) != - sizeof (struct prusage)) + if (s_pread (fd, prusage, sizeof (struct prusage), 0) + != sizeof (struct prusage)) { s_close (fd); glibtop_warn_io_r (server, "pread (%s)", buffer); @@ -99,7 +103,7 @@ glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t p #if LIBGTOP_VERSION_CODE >= 1001002 int glibtop_get_proc_credentials_s(glibtop *server, - struct prcred *prcred, + struct prcred *prcred, gid_t *groups, pid_t pid) { @@ -108,33 +112,35 @@ glibtop_get_proc_credentials_s(glibtop *server, char buffer[BUFSIZ]; sprintf(buffer, "/proc/%d/cred", (int)pid); + if((fd = s_open(buffer, O_RDONLY)) < 0) { - if(errno != EPERM && errno != EACCES) - glibtop_warn_io_r(server, "open (%s)", buffer); + if(errno != EPERM && errno != EACCES) + glibtop_warn_io_r(server, "open (%s)", buffer); return -1; } - if(s_pread(fd, prcred, sizeof(struct prcred), 0) != - sizeof(struct prcred)) + + if(s_pread(fd, prcred, sizeof(struct prcred), 0) + != sizeof(struct prcred)) { - s_close(fd); + s_close(fd); glibtop_warn_io_r(server, "pread (%s)", buffer); return -1; } + if(prcred->pr_ngroups >= 0) { - if(prcred->pr_ngroups <= GLIBTOP_MAX_GROUPS) - toread = prcred->pr_ngroups * sizeof(gid_t); - else - toread = GLIBTOP_MAX_GROUPS * sizeof(gid_t); - if(s_pread(fd, groups, toread, - &(((struct prcred *)0)->pr_groups[0])) != toread) - prcred->pr_ngroups = 0; + toread = MIN(prcred->pr_ngroups, GLIBTOP_MAX_GROUPS) * sizeof(gid_t); + + if((size_t) s_pread(fd,groups, toread, + G_STRUCT_OFFSET(struct prcred, pr_groups)) + != toread) + prcred->pr_ngroups = 0; } s_close(fd); return 0; } -#endif +#endif /* LIBGTOP_VERSION_CODE >= 1001002 */ int glibtop_get_proc_status_s(glibtop *server, struct pstatus *pstatus, pid_t pid) @@ -145,14 +151,14 @@ glibtop_get_proc_status_s(glibtop *server, struct pstatus *pstatus, pid_t pid) sprintf(buffer, "/proc/%d/status", (int)pid); if((fd = s_open(buffer, O_RDONLY)) < 0) { - if(errno != EPERM && errno != EACCES) - glibtop_warn_io_r(server, "open (%s)", buffer); + if(errno != EPERM && errno != EACCES) + glibtop_warn_io_r(server, "open (%s)", buffer); return -1; } - if(s_pread(fd, pstatus, sizeof(struct pstatus), 0) != - sizeof(struct pstatus)) + if(s_pread(fd, pstatus, sizeof(struct pstatus), 0) + != sizeof(struct pstatus)) { - s_close(fd); + s_close(fd); glibtop_warn_io_r(server, "pread (%s)", buffer); return -1; } @@ -164,7 +170,7 @@ glibtop_get_proc_status_s(glibtop *server, struct pstatus *pstatus, pid_t pid) int glibtop_get_proc_data_psinfo_s (glibtop *server, - struct prpsinfo *psinfo, + struct prpsinfo *psinfo, pid_t pid) { int fd; @@ -173,7 +179,7 @@ glibtop_get_proc_data_psinfo_s (glibtop *server, sprintf (buffer, "/proc/%d", (int) pid); fd = s_open (buffer, O_RDONLY); if (fd < 0) { - if(errno != EPERM && errno != EACCES) + if(errno != EPERM && errno != EACCES) glibtop_warn_io_r (server, "open (%s)", buffer); return -1; } @@ -191,7 +197,7 @@ glibtop_get_proc_data_psinfo_s (glibtop *server, int glibtop_get_proc_data_usage_s (glibtop *server, - struct prusage *prusage, + struct prusage *prusage, pid_t pid) { int fd; @@ -200,7 +206,7 @@ glibtop_get_proc_data_usage_s (glibtop *server, sprintf (buffer, "/proc/%d", (int) pid); fd = s_open (buffer, O_RDONLY); if (fd < 0) { - if(errno != EPERM && errno != EACCES) + if(errno != EPERM && errno != EACCES) glibtop_warn_io_r (server, "open (%s)", buffer); return -1; } @@ -218,7 +224,7 @@ glibtop_get_proc_data_usage_s (glibtop *server, int glibtop_get_proc_credentials_s(glibtop *server, - struct prcred *prcred, + struct prcred *prcred, gid_t *groups, pid_t pid) { @@ -229,13 +235,13 @@ glibtop_get_proc_credentials_s(glibtop *server, sprintf(buffer, "/proc/%d", (int)pid); if((fd = s_open(buffer, O_RDONLY)) < 0) { - if(errno != EPERM && errno != EACCES) - glibtop_warn_io_r(server, "open (%s)", buffer); + if(errno != EPERM && errno != EACCES) + glibtop_warn_io_r(server, "open (%s)", buffer); return -1; } if(ioctl(fd, PIOCCRED, prcred) < 0) { - s_close(fd); + s_close(fd); glibtop_warn_io_r(server, "ioctl(%s, PIOCCRED)", buffer); return -1; } @@ -252,13 +258,13 @@ glibtop_get_proc_status_s(glibtop *server, struct prstatus *pstatus, pid_t pid) sprintf(buffer, "/proc/%d", (int)pid); if((fd = s_open(buffer, O_RDONLY)) < 0) { - if(errno != EPERM && errno != EACCES) - glibtop_warn_io_r(server, "open (%s)", buffer); + if(errno != EPERM && errno != EACCES) + glibtop_warn_io_r(server, "open (%s)", buffer); return -1; } if(ioctl(fd, PIOCSTATUS, pstatus) < 0) { - s_close(fd); + s_close(fd); glibtop_warn_io_r(server, "ioctl(%s, PIOCSTATUS)", buffer); return -1; } diff --git a/sysdeps/solaris/proclist.c b/sysdeps/solaris/proclist.c index 9b3be69e..1024ae03 100644 --- a/sysdeps/solaris/proclist.c +++ b/sysdeps/solaris/proclist.c @@ -24,6 +24,9 @@ #include #include +#include "safeio.h" +#include "glibtop_private.h" + #include #include #include @@ -60,11 +63,11 @@ glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf, DIR *proc; struct dirent *entry; char buffer [BUFSIZ]; - unsigned count, total, pid, mask; + unsigned count, total, pid = 0, mask; unsigned pids [BLOCK_COUNT], *pids_chain = NULL; unsigned pids_size = 0, pids_offset = 0, new_size; struct stat statb; - int len, i, ok; + int len, ok; memset (buf, 0, sizeof (glibtop_proclist)); mask = which & ~GLIBTOP_KERN_PROC_MASK; @@ -92,7 +95,7 @@ glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf, } else { - sprintf(buffer, "/proc/%d", arg); + sprintf(buffer, "/proc/%lld", arg); if(s_stat(buffer, &statb) < 0) return NULL; } @@ -111,23 +114,13 @@ glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf, ok = 1; len = strlen (entry->d_name); /* does it consist entirely of digits? */ -#if 0 /* It does, except for "." and "..". Let's speed up */ - for (i = 0; i < len; i++) - if (!isdigit (entry->d_name [i])) ok = 0; - if (!ok) continue; -#else if(entry->d_name[0] == '.') continue; -#endif /* convert it in a number */ -#if 0 - if (sscanf (entry->d_name, "%u", &pid) != 1) continue; -#else pid = (unsigned)atol(entry->d_name); -#endif #ifdef HAVE_PROCFS_H diff --git a/sysdeps/solaris/procmap.c b/sysdeps/solaris/procmap.c index e4d6f401..2935e417 100644 --- a/sysdeps/solaris/procmap.c +++ b/sysdeps/solaris/procmap.c @@ -27,7 +27,6 @@ #include #include -#include #include "safeio.h" @@ -58,7 +57,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) int fd, i, nmaps, pr_err, heap; #if GLIBTOP_SOLARIS_RELEASE >= 560 prxmap_t *maps; - struct ps_prochandle *Pr; + struct ps_prochandle *Pr = NULL; #else prmap_t *maps; #endif @@ -97,7 +96,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) s_close(fd); return NULL; } - maps = alloca(inode.st_size); + maps = g_alloca(inode.st_size); nmaps = inode.st_size / sizeof(prxmap_t); if(s_pread(fd, maps, inode.st_size, 0) != inode.st_size) { @@ -112,7 +111,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) s_close(fd); return NULL; } - maps = alloca((nmaps + 1) * sizeof(prmap_t)); + maps = g_alloca((nmaps + 1) * sizeof(prmap_t)); if(ioctl(fd, PIOCMAP, maps) < 0) { glibtop_warn_io_r(server, "ioctl(%s, PIOCMAP)", buffer); diff --git a/sysdeps/solaris/procmem.c b/sysdeps/solaris/procmem.c index 6452f0f7..66730ccb 100644 --- a/sysdeps/solaris/procmem.c +++ b/sysdeps/solaris/procmem.c @@ -24,6 +24,8 @@ #include #include +#include "glibtop_private.h" + static const unsigned long _glibtop_sysdeps_proc_mem = (1L << GLIBTOP_PROC_MEM_SIZE) + (1L << GLIBTOP_PROC_MEM_VSIZE) + (1L << GLIBTOP_PROC_MEM_RESIDENT) + (1L << GLIBTOP_PROC_MEM_RSS); @@ -42,7 +44,7 @@ void glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, pid_t pid) { #ifdef HAVE_PROCFS_H - struct psinfo psinfo; + struct psinfo psinfo; #else struct prpsinfo psinfo; int pagesize = server->machine.pagesize; @@ -51,7 +53,7 @@ glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, pid_t pid) memset (buf, 0, sizeof (glibtop_proc_mem)); if(glibtop_get_proc_data_psinfo_s(server, &psinfo, pid)) - return; + return; #ifdef HAVE_PROCFS_H buf->size = buf->vsize = psinfo.pr_size << 10; diff --git a/sysdeps/solaris/procstate.c b/sysdeps/solaris/procstate.c index 75ef6a5a..c356bc94 100644 --- a/sysdeps/solaris/procstate.c +++ b/sysdeps/solaris/procstate.c @@ -27,13 +27,11 @@ #include static const unsigned long _glibtop_sysdeps_proc_state = -#if (LIBGTOP_VERSION_CODE >= 1001002) && defined(HAVE_PROCFS_H) +#ifdef HAVE_PROCFS_H (1L << GLIBTOP_PROC_STATE_HAS_CPU) + (1L << GLIBTOP_PROC_STATE_PROCESSOR) + (1L << GLIBTOP_PROC_STATE_LAST_PROCESSOR) + #endif -#if LIBGTOP_VERSION_CODE >= 1001002 (1L << GLIBTOP_PROC_STATE_RUID) + (1L << GLIBTOP_PROC_STATE_RGID) + -#endif (1L << GLIBTOP_PROC_STATE_CMD) + (1L << GLIBTOP_PROC_STATE_STATE) + (1L << GLIBTOP_PROC_STATE_UID) + (1L << GLIBTOP_PROC_STATE_GID); @@ -63,57 +61,39 @@ glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid) buf->uid = psinfo.pr_euid; buf->gid = psinfo.pr_egid; -#if LIBGTOP_VERSION_CODE >= 1001002 buf->ruid = psinfo.pr_uid; buf->rgid = psinfo.pr_gid; -#endif + #ifdef HAVE_PROCFS_H switch(psinfo.pr_lwp.pr_state) #else - switch(psinfo.pr_state) + switch(psinfo.pr_state) #endif { case SONPROC: -#if (LIBGTOP_VERSION_CODE >= 1001002) && defined(HAVE_PROCFS_H) +#ifdef HAVE_PROCFS_H buf->has_cpu = 1; buf->processor = psinfo.pr_lwp.pr_onpro; + /* FIXME: fallthrough ? */ #endif case SRUN: -#if LIBGTOP_VERSION_CODE >= 1001002 buf->state = GLIBTOP_PROCESS_RUNNING; -#else - buf->state = 'R'; -#endif break; case SZOMB: -#if LIBGTOP_VERSION_CODE >= 1001002 buf->state = GLIBTOP_PROCESS_ZOMBIE; -#else - buf->state = 'Z'; -#endif break; case SSLEEP: -#if LIBGTOP_VERSION_CODE >= 1001002 buf->state = GLIBTOP_PROCESS_INTERRUPTIBLE; -#else - buf->state = 'S'; -#endif break; case SSTOP: -#if LIBGTOP_VERSION_CODE >= 1001002 buf->state = GLIBTOP_PROCESS_STOPPED; -#else - buf->state = 'T'; -#endif break; case SIDL: -#if LIBGTOP_VERSION_CODE >= 1001002 buf->state = GLIBTOP_PROCESS_UNINTERRUPTIBLE; -#else - buf->state = 'D'; -#endif + break; } -#if (LIBGTOP_VERSION_CODE >= 1001002) && defined(HAVE_PROCFS_H) + +#ifdef HAVE_PROCFS_H buf->last_processor = psinfo.pr_lwp.pr_onpro; #endif g_strlcpy (buf->cmd, psinfo.pr_fname, sizeof buf->cmd); diff --git a/sysdeps/solaris/safeio.c b/sysdeps/solaris/safeio.c index ed9c784a..d322fd7e 100644 --- a/sysdeps/solaris/safeio.c +++ b/sysdeps/solaris/safeio.c @@ -26,6 +26,8 @@ #include #include +#include "safeio.h" + int s_open(const char *file, int mode) { diff --git a/sysdeps/solaris/safeio.h b/sysdeps/solaris/safeio.h index f9959dea..aa367691 100644 --- a/sysdeps/solaris/safeio.h +++ b/sysdeps/solaris/safeio.h @@ -22,6 +22,8 @@ #ifndef __GLIBTOP_SAFEIO_H__ #define __GLIBTOP_SAFEIO_H__ +#include + #include #include #include @@ -45,4 +47,4 @@ s_closedir(DIR *); G_END_DECLS -#endif +#endif /* __GLIBTOP_SAFEIO_H__ */ diff --git a/sysdeps/solaris/shm_limits.c b/sysdeps/solaris/shm_limits.c index 7ef86657..08586b76 100644 --- a/sysdeps/solaris/shm_limits.c +++ b/sysdeps/solaris/shm_limits.c @@ -28,18 +28,25 @@ #include static const struct nlist nlst[] = { {"shminfo"}, {NULL} }; + +#if GLIBTOP_SOLARIS_RELEASE < 590 +static const unsigned long _glibtop_sysdeps_shm_limits = +(1L << GLIBTOP_IPC_SHMMAX) + (1L << GLIBTOP_IPC_SHMMIN); + +#else static const unsigned long _glibtop_sysdeps_shm_limits = (1L << GLIBTOP_IPC_SHMMAX) + (1L << GLIBTOP_IPC_SHMMIN) + (1L << GLIBTOP_IPC_SHMMNI) + (1L << GLIBTOP_IPC_SHMSEG); +#endif /* Init function. */ void glibtop_init_shm_limits_p (glibtop *server) { - kvm_t *kd = server->machine.kd; + kvm_t * const kd = server->machine.kd; - if(kd && !kvm_nlist(kd, nlst)) + if(kd && !kvm_nlist(kd, nlst)) server->sysdeps.shm_limits = _glibtop_sysdeps_shm_limits; else server->sysdeps.shm_limits = 0; @@ -50,16 +57,18 @@ glibtop_init_shm_limits_p (glibtop *server) void glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) { - kvm_t *kd = server->machine.kd; + kvm_t * const kd = server->machine.kd; struct shminfo sinfo; memset (buf, 0, sizeof (glibtop_shm_limits)); if(!(server->sysdeps.shm_limits)) - return; + return; + if(kvm_read(kd, nlst[0].n_value, (void *)&sinfo, sizeof(struct shminfo)) != sizeof(struct shminfo)) - return; + return; + buf->shmmax = sinfo.shmmax; buf->shmmni = sinfo.shmmni; #if GLIBTOP_SOLARIS_RELEASE < 590 diff --git a/sysdeps/solaris/swap.c b/sysdeps/solaris/swap.c index ccc554e1..a80e7dd4 100644 --- a/sysdeps/solaris/swap.c +++ b/sysdeps/solaris/swap.c @@ -25,8 +25,8 @@ #include #include -#include -#include +#include +#include #include @@ -47,43 +47,64 @@ glibtop_init_swap_s (glibtop *server) void glibtop_get_swap_s (glibtop *server, glibtop_swap *buf) { - kstat_ctl_t *kc = server->machine.kc; - kstat_t *ksp = server->machine.vminfo_kstat; - guint64 swap_resv, swap_alloc, swap_avail, swap_free; - vminfo_t vminfo; - double rate; - kid_t ret; + swaptbl_t *s = NULL; + int i, n1, n2; - memset (buf, 0, sizeof (glibtop_swap)); + /* we don't care about ste_path, and we're lazy */ + char shared_path[BUFSIZ]; /* hope this is large enough */ - if (!ksp) return; + const int pagesize = getpagesize(); - switch(kstat_chain_update(kc)) + memset(buf, 0, sizeof *buf); + + switch( (n1 = swapctl(SC_GETNSWP, NULL)) ) { - case -1: assert(0); /* Debugging, shouldn't happen */ - case 0: break; - default: glibtop_get_kstats(server); - } - ret = kstat_read (kc, ksp, &vminfo); - - if (ret == -1) { - glibtop_warn_io_r (server, "kstat_read (vminfo)"); + case -1: + glibtop_warn_r(server, "swapctl: GETNSWP"); return; + + case 0: + /* no swapfile */ + goto out_no_swap; + + default: + break; } - rate = (ksp->ks_snaptime - server->machine.vminfo_snaptime) / 1E+9; + /* RTFM */ + s = g_malloc(sizeof(swaptbl_t) + + n1 * sizeof(swapent_t)); - swap_resv = (vminfo.swap_resv - server->machine.vminfo.swap_resv) / rate; - swap_alloc = (vminfo.swap_alloc - server->machine.vminfo.swap_alloc) / rate; - swap_avail = (vminfo.swap_avail - server->machine.vminfo.swap_avail) / rate; - swap_free = (vminfo.swap_free - server->machine.vminfo.swap_free) / rate; + s->swt_n = n1; - memcpy (&server->machine.vminfo, &vminfo, sizeof (vminfo_t)); - server->machine.vminfo_snaptime = ksp->ks_snaptime; + /* initialize string pointers */ + for (i = 0; i < n1; i++) + { + s->swt_ent[i].ste_path = shared_path; + } - buf->total = swap_resv + swap_avail; - buf->used = swap_alloc; - buf->free = buf->total - buf->used; + if ((n2 = swapctl(SC_LIST, s)) < 0) + { + glibtop_warn_r(server, "swapctl: SC_LIST"); + goto out_free; + } - buf->flags = _glibtop_sysdeps_swap; + + /* #swapfile may have changed between the 2 swapctl() calls + * we don't care, we just use the smallest #swapfile */ + for (i = 0; i < MIN(n1, n2); i++) + { + buf->total += s->swt_ent[i].ste_pages; + buf->free += s->swt_ent[i].ste_free; + } + + buf->total *= pagesize; + buf->free *= pagesize; + buf->used = buf->total - buf->free; + + out_no_swap: + buf->flags = _glibtop_sysdeps_swap; + + out_free: + g_free(s); } diff --git a/sysdeps/solaris/uptime.c b/sysdeps/solaris/uptime.c index 7ea2d0bf..9a672bab 100644 --- a/sysdeps/solaris/uptime.c +++ b/sysdeps/solaris/uptime.c @@ -27,10 +27,8 @@ #include static const unsigned long _glibtop_sysdeps_uptime = -#if LIBGTOP_VERSION_CODE >= 1001002 -(1L <machine.boot)) return; -#if LIBGTOP_VERSION_CODE >= 1001002 + buf->boot_time = server->machine.boot; -#endif buf->uptime = time(NULL) - server->machine.boot; buf->flags = _glibtop_sysdeps_uptime;