diff --git a/sysdeps/freebsd/Makefile.am b/sysdeps/freebsd/Makefile.am index 40aae758..259f303f 100644 --- a/sysdeps/freebsd/Makefile.am +++ b/sysdeps/freebsd/Makefile.am @@ -1,6 +1,6 @@ LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@ -INCLUDES = -I$(includedir) -I$(top_builddir) -I$(top_srcdir) @machine_incs@ \ +INCLUDES = -I$(top_builddir) -I$(top_srcdir) @machine_incs@ \ -I$(top_srcdir)/include -I$(top_srcdir)/intl @GUILE_INCS@ \ -DGTOPLOCALEDIR=\"$(datadir)/locale\" -D_GNU_SOURCE diff --git a/sysdeps/freebsd/glibtop_suid.h b/sysdeps/freebsd/glibtop_suid.h index bff87930..ddbca208 100644 --- a/sysdeps/freebsd/glibtop_suid.h +++ b/sysdeps/freebsd/glibtop_suid.h @@ -24,6 +24,12 @@ __BEGIN_DECLS +#define KI_PROC(ki) (&(ki))->kp_proc) +#define KI_EPROC(ki) (&(ki))->kp_eproc) + +#define FORCEUREAD 1 +#define UREADOK(ki) (FORCEUREAD || (KI_PROC(ki)->p_flag & P_INMEM)) + static inline void glibtop_suid_enter (glibtop *server) { setregid (server->machine.gid, server->machine.egid); }; diff --git a/sysdeps/freebsd/open.c b/sysdeps/freebsd/open.c index 123d1352..66b0f9e3 100644 --- a/sysdeps/freebsd/open.c +++ b/sysdeps/freebsd/open.c @@ -52,8 +52,6 @@ glibtop_open_p (glibtop *server, const char *program_name, { fprintf (stderr, "DEBUG (%d): glibtop_open_p ()\n", getpid ()); - sleep (5); - /* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */ server->name = program_name; diff --git a/sysdeps/freebsd/prockernel.c b/sysdeps/freebsd/prockernel.c index 17a42c29..494ef2e3 100644 --- a/sysdeps/freebsd/prockernel.c +++ b/sysdeps/freebsd/prockernel.c @@ -38,14 +38,16 @@ static const unsigned long _glibtop_sysdeps_proc_kernel = (1 << GLIBTOP_PROC_KERNEL_K_FLAGS) + -(1 << GLIBTOP_PROC_KERNEL_MIN_FLT) + -(1 << GLIBTOP_PROC_KERNEL_MAJ_FLT) + -(1 << GLIBTOP_PROC_KERNEL_CMIN_FLT) + -(1 << GLIBTOP_PROC_KERNEL_CMAJ_FLT) + (1 << GLIBTOP_PROC_KERNEL_KSTK_ESP) + (1 << GLIBTOP_PROC_KERNEL_KSTK_EIP) + (1 << GLIBTOP_PROC_KERNEL_WCHAN); +static const unsigned long _glibtop_sysdeps_proc_kernel_user = +(1 << GLIBTOP_PROC_KERNEL_MIN_FLT) + +(1 << GLIBTOP_PROC_KERNEL_MAJ_FLT) + +(1 << GLIBTOP_PROC_KERNEL_CMIN_FLT) + +(1 << GLIBTOP_PROC_KERNEL_CMAJ_FLT); + /* Init function. */ void @@ -61,56 +63,47 @@ glibtop_get_proc_kernel_p (glibtop *server, { struct kinfo_proc *pinfo; struct i386tss *pcb_tss; - struct pstats ps; - struct user usr; + struct user *u_addr = (struct user *)USRSTACK; + struct pstats pstats; int f, count; glibtop_init_p (server, GLIBTOP_SYSDEPS_PROC_KERNEL, 0); memset (buf, 0, sizeof (glibtop_proc_kernel)); - /* Get the information pertaining to the given PID */ + /* Get the process information */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); - if (count != 1) { - return; /* the 0-filled struct, since we can't get any info */ + if ((pinfo == NULL) || (count != 1)) + glibtop_error_io_r (server, "kvm_getprocs (%d)", pid); + + /* Taken from `saveuser ()' in `/usr/src/bin/ps/ps.c'. */ + + if ((pinfo [0].kp_proc.p_flag & P_INMEM) && + kvm_uread (server->machine.kd, pinfo [0].kp_proc, + (unsigned long) &u_addr->u_stats, + (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) { + /* + * The u-area might be swapped out, and we can't get + * at it because we have a crashdump and no swap. + * If it's here fill in these fields, otherwise, just + * leave them 0. + */ + + buf->min_flt = (u_int64_t) pstats.p_ru.ru_minflt; + buf->maj_flt = (u_int64_t) pstats.p_ru.ru_majflt; + buf->cmin_flt = (u_int64_t) pstats.p_cru.ru_minflt; + buf->cmaj_flt = (u_int64_t) pstats.p_cru.ru_majflt; + + buf->flags |= _glibtop_sysdeps_proc_kernel_user; } - f = open ("/dev/kmem", O_RDONLY, NULL); - if (f == NULL) - glibtop_error_io_r (server, "open (/dev/kmem)"); - - /* Read the p_stats struct from kernel memory */ - lseek (f, (long) pinfo[0].kp_proc.p_stats, SEEK_SET); - if (read (f, &ps, sizeof (struct pstats))) - glibtop_error_io_r (server, "read"); - /* Read the struct at kp_proc.p_addr */ - lseek (f, (long) pinfo[0].kp_proc.p_addr, SEEK_SET); - if (read(f, &usr, sizeof (struct user))) - glibtop_error_io_r (server, "read"); - close (f); - - - /* kflags: - kinfo_proc.e_flag? - proc.p_flag - proc.p_stat - */ - buf->k_flags = pinfo[0].kp_eproc.e_flag; - - /* min_flt: rusage.ru_minflt */ - buf->min_flt = ps.p_ru.ru_minflt; - /* maj_flt: rusage.ru_majflt */ - buf->maj_flt = ps.p_ru.ru_majflt; - /* cmin_flt: */ - buf->cmin_flt = ps.p_cru.ru_minflt; - /* cmaj_flt: */ - buf->cmaj_flt = ps.p_cru.ru_majflt; - +#if 0 /* kstk_esp: pcb_tss.tss_esp */ buf->kstk_esp = (u_int64_t) usr.u_pcb.pcb_ksp; /* kstk_eip: pcb_tss.tss_eip */ buf->kstk_eip = (u_int64_t) usr.u_pcb.pcb_pc; +#endif /* wchan : kinfo_proc.proc.p_wchan */ - buf->wchan = (u_int64_t) pinfo[0].kp_proc.p_wchan; + buf->wchan = (u_int64_t) pinfo [0].kp_proc.p_wchan; } diff --git a/sysdeps/freebsd/procmem.c b/sysdeps/freebsd/procmem.c index 5e7f0660..e2295856 100644 --- a/sysdeps/freebsd/procmem.c +++ b/sysdeps/freebsd/procmem.c @@ -56,6 +56,7 @@ void glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, pid_t pid) { +#if 0 struct kinfo_proc *pinfo; struct vmspace vms; struct vm_map vmm; @@ -123,4 +124,5 @@ glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, /* Set the flags */ buf->flags = _glibtop_sysdeps_proc_mem; +#endif } diff --git a/sysdeps/freebsd/procsignal.c b/sysdeps/freebsd/procsignal.c index d72f80f1..51436888 100644 --- a/sysdeps/freebsd/procsignal.c +++ b/sysdeps/freebsd/procsignal.c @@ -45,28 +45,36 @@ glibtop_get_proc_signal_p (glibtop *server, pid_t pid) { struct kinfo_proc *pinfo; + int count = 0; glibtop_init_p (server, GLIBTOP_SYSDEPS_PROC_SIGNAL, 0); memset (buf, 0, sizeof (glibtop_proc_signal)); + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) + glibtop_error_io_r (server, "kvm_getprocs (%d)", pid); + /* signal: mask of pending signals. - pinfo[0].kp_proc.p_siglist - */ - buf->signal = pinfo[0].kp_proc.p_siglist; + * pinfo [0].kp_proc.p_siglist + */ + buf->signal = pinfo [0].kp_proc.p_siglist; /* blocked: mask of blocked signals. - pinfo[0].kp_proc.p_sigmask - */ - buf->blocked = pinfo[0].kp_proc.p_sigmask; + * pinfo [0].kp_proc.p_sigmask + */ + buf->blocked = pinfo [0].kp_proc.p_sigmask; /* sigignore: mask of ignored signals. - pinfo[0].kp_proc.p_sigignore + * pinfo [0].kp_proc.p_sigignore */ - buf->sigignore = pinfo[0].kp_proc.p_sigignore; + buf->sigignore = pinfo [0].kp_proc.p_sigignore; /* sigcatch: mask of caught signals. - pinfo[0].kp_proc.p_sigcatch + * pinfo [0].kp_proc.p_sigcatch */ - buf->sigcatch = pinfo[0].kp_proc.p_sigcatch; + buf->sigcatch = pinfo [0].kp_proc.p_sigcatch; + + buf->flags = _glibtop_sysdeps_proc_signal; } diff --git a/sysdeps/freebsd/procstate.c b/sysdeps/freebsd/procstate.c index cf8c94d4..da9dd75e 100644 --- a/sysdeps/freebsd/procstate.c +++ b/sysdeps/freebsd/procstate.c @@ -25,11 +25,11 @@ #include +#include + static const unsigned long _glibtop_sysdeps_proc_state = -(1 << GLIBTOP_PROC_STATE_CMD) + -(1 << GLIBTOP_PROC_STATE_STATE) + -(1 << GLIBTOP_PROC_STATE_UID) + -(1 << GLIBTOP_PROC_STATE_GID); +(1 << GLIBTOP_PROC_STATE_CMD) + (1 << GLIBTOP_PROC_STATE_STATE) + +(1 << GLIBTOP_PROC_STATE_UID) + (1 << GLIBTOP_PROC_STATE_GID); /* Init function. */ @@ -46,10 +46,26 @@ glibtop_get_proc_state_p (glibtop *server, glibtop_proc_state *buf, pid_t pid) { + struct kinfo_proc *pinfo; + int count = 0; + glibtop_init_p (server, GLIBTOP_SYSDEPS_PROC_STATE, 0); memset (buf, 0, sizeof (glibtop_proc_state)); + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) + glibtop_error_io_r (server, "kvm_getprocs (%d)", pid); + + strncpy (buf->cmd, pinfo [0].kp_proc.p_comm, sizeof (buf->cmd)-1); + buf->cmd [sizeof (buf->cmd)-1] = 0; + + buf->uid = pinfo [0].kp_eproc.e_pcred.p_svuid; + buf->gid = pinfo [0].kp_eproc.e_pcred.p_svgid; + + buf->state = pinfo [0].kp_proc.p_stat; + /* Set the flags for the data we're about to return*/ buf->flags = _glibtop_sysdeps_proc_state; }