diff --git a/examples/timings.c b/examples/timings.c new file mode 100644 index 00000000..6b79ac21 --- /dev/null +++ b/examples/timings.c @@ -0,0 +1,362 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#ifndef PROFILE_COUNT +#define PROFILE_COUNT 100000L +#endif + +#ifndef PROFILE_COUNT_EXPENSIVE +#define PROFILE_COUNT_EXPENSIVE 10000L +#endif + +#define ELAPSED_UTIME ((unsigned long) elapsed_utime.tv_sec * 1000000 + (unsigned long) elapsed_utime.tv_usec) +#define ELAPSED_STIME ((unsigned long) elapsed_stime.tv_sec * 1000000 + (unsigned long) elapsed_stime.tv_usec) + +#if defined(__bsdi__) +#define timeradd(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ + } while (0) +#define timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + +int +main (int argc, char *argv []) +{ + glibtop_union data; + glibtop_sysdeps sysdeps; + unsigned c, count, port, i, *ptr; + struct rusage total_start, total_end; + struct rusage rusage_start, rusage_end; + struct timeval elapsed_utime, elapsed_stime; + char buffer [BUFSIZ]; + pid_t pid, ppid; + char *args; + + count = PROFILE_COUNT; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, GTOPLOCALEDIR); + textdomain (PACKAGE); + + printf ("%-12s (%-10s): %7s - %9s - %9s\n", + "Feature", "Flags", "Count", "utime", "stime"); + printf ("-------------------------------------------" + "---------------\n"); + + glibtop_init_r (&glibtop_global_server, 0, 0); + + getrusage (RUSAGE_SELF, &total_start); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_cpu (&data.cpu); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("CPU (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.cpu.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT_EXPENSIVE; c++) + glibtop_get_mem (&data.mem); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Memory (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.mem.flags, PROFILE_COUNT_EXPENSIVE, + (long double) ELAPSED_UTIME / PROFILE_COUNT_EXPENSIVE, + (long double) ELAPSED_STIME / PROFILE_COUNT_EXPENSIVE); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT_EXPENSIVE; c++) + glibtop_get_swap (&data.swap); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Swap (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.swap.flags, PROFILE_COUNT_EXPENSIVE, + (long double) ELAPSED_UTIME / PROFILE_COUNT_EXPENSIVE, + (long double) ELAPSED_STIME / PROFILE_COUNT_EXPENSIVE); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_uptime (&data.uptime); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Uptime (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.uptime.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_loadavg (&data.loadavg); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Loadavg (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.loadavg.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + printf ("\n"); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT_EXPENSIVE; c++) { + ptr = glibtop_get_proclist (&data.proclist, 0, 0); + glibtop_free (ptr); + } + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Proclist (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.proclist.flags, + PROFILE_COUNT_EXPENSIVE, + (long double) ELAPSED_UTIME / PROFILE_COUNT_EXPENSIVE, + (long double) ELAPSED_STIME / PROFILE_COUNT_EXPENSIVE); + + pid = getpid (); + + printf ("\n"); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_proc_state (&data.proc_state, pid); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Proc_State (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.proc_state.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_proc_uid (&data.proc_uid, pid); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Proc_Uid (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.proc_uid.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_proc_mem (&data.proc_mem, pid); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Proc_Mem (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.proc_mem.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_proc_segment (&data.proc_segment, pid); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Proc_Segment (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.proc_segment.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_proc_time (&data.proc_time, pid); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Proc_Time (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.proc_time.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_proc_signal (&data.proc_signal, pid); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Proc_Signal (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.proc_signal.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + getrusage (RUSAGE_SELF, &rusage_start); + + for (c = 0; c < PROFILE_COUNT; c++) + glibtop_get_proc_kernel (&data.proc_kernel, pid); + + getrusage (RUSAGE_SELF, &rusage_end); + + timersub (&rusage_end.ru_utime, &rusage_start.ru_utime, + &elapsed_utime); + + timersub (&rusage_end.ru_stime, &rusage_start.ru_stime, + &elapsed_stime); + + printf ("Proc_Kernel (0x%08lx): %7lu - %9.2Lf - %9.2Lf\n", + (unsigned long) data.proc_kernel.flags, PROFILE_COUNT, + (long double) ELAPSED_UTIME / PROFILE_COUNT, + (long double) ELAPSED_STIME / PROFILE_COUNT); + + getrusage (RUSAGE_SELF, &total_end); + + timersub (&total_end.ru_utime, &total_start.ru_utime, + &elapsed_utime); + + timersub (&total_end.ru_stime, &total_start.ru_stime, + &elapsed_stime); + + printf ("-------------------------------------------" + "---------------\n"); + + printf ("%-36s %9lu - %9lu\n\n", "TOTAL", + ELAPSED_UTIME, ELAPSED_STIME); + + printf ("All timings are in clock ticks " + "(1000000 ticks per second).\n\n"); + + glibtop_close (); + + exit (0); +} diff --git a/include/glibtop/limits.h b/include/glibtop/limits.h new file mode 100644 index 00000000..7f878333 --- /dev/null +++ b/include/glibtop/limits.h @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_LIMITS_H__ +#define __GLIBTOP_LIMITS_H__ + +#include + +BEGIN_LIBGTOP_DECLS + +/* Nobody should really be using more than 64 processors. */ +#define GLIBTOP_NCPU 64 + +END_LIBGTOP_DECLS + +#endif diff --git a/kernel/sysctl/.cvsignore b/kernel/sysctl/.cvsignore new file mode 100644 index 00000000..9ff296a7 --- /dev/null +++ b/kernel/sysctl/.cvsignore @@ -0,0 +1 @@ +*.flags diff --git a/kernel/sysctl/Makefile b/kernel/sysctl/Makefile new file mode 100644 index 00000000..77dd277a --- /dev/null +++ b/kernel/sysctl/Makefile @@ -0,0 +1,22 @@ +# +# Makefile for the LibGTop linux sysctl interface. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now in the main makefile... + +O_TARGET := kernel.o +ifeq ($(CONFIG_LIBGTOP),y) +O_OJBS := main.o libgtop.o +else +O_OBJS := main.o +endif +OX_OBJS := libgtop_syms.o + +ifeq ($(CONFIG_LIBGTOP),m) +M_OBJS := libgtop.o +endif + +include $(TOPDIR)/Rules.make diff --git a/kernel/sysctl/libgtop.c b/kernel/sysctl/libgtop.c new file mode 100644 index 00000000..8c769644 --- /dev/null +++ b/kernel/sysctl/libgtop.c @@ -0,0 +1,1268 @@ +/* + * linux/libgtop/module.c + * Copyright (C) 1999 Martin Baulig + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +EXPORT_NO_SYMBOLS; + +static int system_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, void *newval, + size_t newlen, void **context); + +static int proc_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, void *newval, + size_t newlen, void **context); + +static int proc_args_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, + void **context); + +static int proc_maps_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, + void **context); + +#if CONFIG_NET + +#include + +static int proc_net_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, + void **context); + +#endif /* CONFIG_NET */ + +static int libgtop_sysctl_version = 2; +static int libgtop_update_expensive = 5000; + +static struct ctl_table_header *libgtop_sysctl_header = NULL; + +static libgtop_stat_t libgtop_stat; +static unsigned int libgtop_mem_timestamp = 0; +static libgtop_mem_t libgtop_mem; +static unsigned int libgtop_swap_timestamp = 0; +static libgtop_swap_t libgtop_swap; + +static libgtop_proclist_t libgtop_proclist; +static libgtop_proc_state_t libgtop_proc_state; +static libgtop_proc_kernel_t libgtop_proc_kernel; +static libgtop_proc_segment_t libgtop_proc_segment; +static libgtop_proc_mem_t libgtop_proc_mem; +static libgtop_proc_signal_t libgtop_proc_signal; + +static ctl_table libgtop_table[]; +static ctl_table libgtop_root_table[] = { + {CTL_LIBGTOP, "libgtop", NULL, 0, 0555, libgtop_table}, + {0} +}; + +#ifdef MODULE +static +#endif +ctl_table libgtop_table[] = { + {LIBGTOP_VERSION, "version", &libgtop_sysctl_version, + sizeof (int), 0444, NULL, &proc_dointvec}, + {LIBGTOP_UPDATE_EXPENSIVE, "update_expensive", + &libgtop_update_expensive, sizeof (int), 0664, NULL, &proc_dointvec}, + {LIBGTOP_STAT, NULL, &libgtop_stat, sizeof (libgtop_stat), + 0444, NULL, NULL, &system_ctl_handler}, + {LIBGTOP_MEM, NULL, &libgtop_mem, sizeof (libgtop_mem), + 0444, NULL, NULL, &system_ctl_handler}, + {LIBGTOP_SWAP, NULL, &libgtop_swap, sizeof (libgtop_swap), + 0444, NULL, NULL, &system_ctl_handler}, + {LIBGTOP_PROCLIST, NULL, &libgtop_proclist, sizeof (libgtop_proclist), + 0444, NULL, NULL, &system_ctl_handler}, + {LIBGTOP_PROC_STATE, NULL, &libgtop_proc_state, + sizeof (libgtop_proc_state), 0444, NULL, NULL, &proc_ctl_handler}, + {LIBGTOP_PROC_KERNEL, NULL, &libgtop_proc_kernel, + sizeof (libgtop_proc_kernel), 0444, NULL, NULL, &proc_ctl_handler}, + {LIBGTOP_PROC_SEGMENT, NULL, &libgtop_proc_segment, + sizeof (libgtop_proc_segment), 0444, NULL, NULL, &proc_ctl_handler}, + {LIBGTOP_PROC_MEM, NULL, &libgtop_proc_mem, + sizeof (libgtop_proc_mem), 0444, NULL, NULL, &proc_ctl_handler}, + {LIBGTOP_PROC_SIGNAL, NULL, &libgtop_proc_signal, + sizeof (libgtop_proc_signal), 0444, NULL, NULL, &proc_ctl_handler}, + {LIBGTOP_PROC_ARGS, NULL, NULL, 0, 0444, NULL, NULL, + &proc_args_ctl_handler}, + {LIBGTOP_PROC_MAPS, NULL, NULL, 0, 0444, NULL, NULL, + &proc_maps_ctl_handler}, +#if CONFIG_NET + /* You cannot actually "write" this value; we just use this to + * pass the device name as parameter. */ + {LIBGTOP_NETLOAD, NULL, NULL, 0, 0666, NULL, NULL, + &proc_net_ctl_handler}, +#endif + {0} +}; + +#ifdef MODULE +static void +libgtop_sysctl_register(void) +{ + static int initialized = 0; + + if (initialized == 1) + return; + + libgtop_sysctl_header = register_sysctl_table(libgtop_root_table, 1); + initialized = 1; +} + +static void +libgtop_sysctl_unregister(void) +{ + unregister_sysctl_table(libgtop_sysctl_header); +} + +int init_module(void) +{ + libgtop_sysctl_register(); + return 0; +} + +void cleanup_module(void) +{ + libgtop_sysctl_unregister(); +} + +#endif /* MODULE */ + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +static unsigned long +get_wchan (struct task_struct *p) +{ + if (!p || p == current || p->state == TASK_RUNNING) + return 0; +#if defined(__i386__) + { + unsigned long ebp, esp, eip; + unsigned long stack_page; + int count = 0; + + stack_page = (unsigned long)p; + esp = p->tss.esp; + if (!stack_page || esp < stack_page || esp >= 8188+stack_page) + return 0; + /* include/asm-i386/system.h:switch_to() pushes ebp last. */ + ebp = *(unsigned long *) esp; + do { + if (ebp < stack_page || ebp >= 8188+stack_page) + return 0; + eip = *(unsigned long *) (ebp+4); + if (eip < first_sched || eip >= last_sched) + return eip; + ebp = *(unsigned long *) ebp; + } while (count++ < 16); + } +#elif defined(__alpha__) + /* + * This one depends on the frame size of schedule(). Do a + * "disass schedule" in gdb to find the frame size. Also, the + * code assumes that sleep_on() follows immediately after + * interruptible_sleep_on() and that add_timer() follows + * immediately after interruptible_sleep(). Ugly, isn't it? + * Maybe adding a wchan field to task_struct would be better, + * after all... + */ + { + unsigned long schedule_frame; + unsigned long pc; + + pc = thread_saved_pc(&p->tss); + if (pc >= first_sched && pc < last_sched) { + schedule_frame = ((unsigned long *)p->tss.ksp)[6]; + return ((unsigned long *)schedule_frame)[12]; + } + return pc; + } +#elif defined(__mc68000__) + { + unsigned long fp, pc; + unsigned long stack_page; + int count = 0; + + stack_page = (unsigned long)p; + fp = ((struct switch_stack *)p->tss.ksp)->a6; + do { + if (fp < stack_page+sizeof(struct task_struct) || + fp >= 8184+stack_page) + return 0; + pc = ((unsigned long *)fp)[1]; + /* FIXME: This depends on the order of these functions. */ + if (pc < first_sched || pc >= last_sched) + return pc; + fp = *(unsigned long *) fp; + } while (count++ < 16); + } +#elif defined(__powerpc__) + return (p->tss.wchan); +#elif defined (CONFIG_ARM) + { + unsigned long fp, lr; + unsigned long stack_page; + int count = 0; + + stack_page = 4096 + (unsigned long)p; + fp = get_css_fp (&p->tss); + do { + if (fp < stack_page || fp > 4092+stack_page) + return 0; + lr = pc_pointer (((unsigned long *)fp)[-1]); + if (lr < first_sched || lr > last_sched) + return lr; + fp = *(unsigned long *) (fp - 12); + } while (count ++ < 16); + } +#elif defined (__sparc__) + { + unsigned long pc, fp, bias = 0; + unsigned long task_base = (unsigned long) p; + struct reg_window *rw; + int count = 0; + +#ifdef __sparc_v9__ + bias = STACK_BIAS; +#endif + fp = p->tss.ksp + bias; + do { + /* Bogus frame pointer? */ + if (fp < (task_base + sizeof(struct task_struct)) || + fp >= (task_base + (2 * PAGE_SIZE))) + break; + rw = (struct reg_window *) fp; + pc = rw->ins[7]; + if (pc < first_sched || pc >= last_sched) + return pc; + fp = rw->ins[6] + bias; + } while (++count < 16); + } +#endif + return 0; +} + +#if defined(__i386__) +# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) +# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) +#elif defined(__alpha__) + /* + * See arch/alpha/kernel/ptrace.c for details. + */ +# define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \ + + (long)&((struct pt_regs *)0)->reg) +# define KSTK_EIP(tsk) \ + (*(unsigned long *)(PT_REG(pc) + PAGE_SIZE + (unsigned long)(tsk))) +# define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp) +#elif defined(CONFIG_ARM) +# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) +# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020]) +#elif defined(__mc68000__) +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->tss.esp0 > PAGE_SIZE && \ + MAP_NR((tsk)->tss.esp0) < max_mapnr) \ + eip = ((struct pt_regs *) (tsk)->tss.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp) +#elif defined(__powerpc__) +#define KSTK_EIP(tsk) ((tsk)->tss.regs->nip) +#define KSTK_ESP(tsk) ((tsk)->tss.regs->gpr[1]) +#elif defined (__sparc_v9__) +# define KSTK_EIP(tsk) ((tsk)->tss.kregs->tpc) +# define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP]) +#elif defined(__sparc__) +# define KSTK_EIP(tsk) ((tsk)->tss.kregs->pc) +# define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP]) +#endif +; + +static inline void +task_mem (struct task_struct *p, libgtop_proc_segment_t *proc_segment) +{ + struct mm_struct * mm = p->mm; + + if (mm && mm != &init_mm) { + struct vm_area_struct * vma = mm->mmap; + unsigned long data = 0, stack = 0; + unsigned long exec = 0, lib = 0; + unsigned long vsize = 0; + + for (vma = mm->mmap; vma; vma = vma->vm_next) { + unsigned long len = (vma->vm_end - vma->vm_start) >> 10; + vsize += len; + if (!vma->vm_file) { + data += len; + if (vma->vm_flags & VM_GROWSDOWN) + stack += len; + continue; + } + if (vma->vm_flags & VM_WRITE) + continue; + if (vma->vm_flags & VM_EXEC) { + exec += len; + if (vma->vm_flags & VM_EXECUTABLE) + continue; + lib += len; + } + } + + proc_segment->vsize = vsize; + proc_segment->data = data; + proc_segment->stack = stack; + proc_segment->exec = exec; + proc_segment->lib = lib; + } +} + +static inline void +statm_pte_range (pmd_t * pmd, unsigned long address, unsigned long size, + int * pages, int * shared, int * dirty, int * total) +{ + pte_t * pte; + unsigned long end; + + if (pmd_none(*pmd)) + return; + if (pmd_bad(*pmd)) { + printk("statm_pte_range: bad pmd (%08lx)\n", pmd_val(*pmd)); + pmd_clear(pmd); + return; + } + pte = pte_offset(pmd, address); + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + do { + pte_t page = *pte; + + address += PAGE_SIZE; + pte++; + if (pte_none(page)) + continue; + ++*total; + if (!pte_present(page)) + continue; + ++*pages; + if (pte_dirty(page)) + ++*dirty; + if (MAP_NR(pte_page(page)) >= max_mapnr) + continue; + if (atomic_read(&mem_map[MAP_NR(pte_page(page))].count) > 1) + ++*shared; + } while (address < end); +} + +static inline void +statm_pmd_range (pgd_t * pgd, unsigned long address, unsigned long size, + int * pages, int * shared, int * dirty, int * total) +{ + pmd_t * pmd; + unsigned long end; + + if (pgd_none(*pgd)) + return; + if (pgd_bad(*pgd)) { + printk("statm_pmd_range: bad pgd (%08lx)\n", pgd_val(*pgd)); + pgd_clear(pgd); + return; + } + pmd = pmd_offset(pgd, address); + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + do { + statm_pte_range (pmd, address, end - address, pages, + shared, dirty, total); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address < end); +} + +static void +statm_pgd_range (pgd_t * pgd, unsigned long address, unsigned long end, + int * pages, int * shared, int * dirty, int * total) +{ + while (address < end) { + statm_pmd_range (pgd, address, end - address, pages, + shared, dirty, total); + address = (address + PGDIR_SIZE) & PGDIR_MASK; + pgd++; + } +} + +static void +get_statm (struct task_struct *tsk, libgtop_proc_mem_t *proc_mem) +{ + int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0; + unsigned long data=0, stack=0, exec=0, lib=0; + unsigned long vsize = 0; + + if (tsk->mm && tsk->mm != &init_mm) { + struct vm_area_struct * vma = tsk->mm->mmap; + + while (vma) { + unsigned long len = (vma->vm_end - vma->vm_start) >> 10; + pgd_t *pgd = pgd_offset(tsk->mm, vma->vm_start); + int pages = 0, shared = 0, dirty = 0, total = 0; + + vsize += len; + + statm_pgd_range (pgd, vma->vm_start, vma->vm_end, + &pages, &shared, &dirty, &total); + resident += pages; + share += shared; + dt += dirty; + size += total; + if (vma->vm_flags & VM_EXECUTABLE) + trs += pages; /* text */ + else if (vma->vm_flags & VM_GROWSDOWN) + drs += pages; /* stack */ + else if (vma->vm_end > 0x60000000) + lrs += pages; /* library */ + else + drs += pages; + + if (!vma->vm_file) { + data += len; + if (vma->vm_flags & VM_GROWSDOWN) + stack += len; + vma = vma->vm_next; + continue; + } + if (vma->vm_flags & VM_WRITE) { + vma = vma->vm_next; + continue; + } + if (vma->vm_flags & VM_EXEC) { + exec += len; + if (vma->vm_flags & VM_EXECUTABLE) { + vma = vma->vm_next; + continue; + } + lib += len; + } + + vma = vma->vm_next; + } + } + + proc_mem->segment.vsize = vsize; + proc_mem->segment.data = data; + proc_mem->segment.stack = stack; + proc_mem->segment.exec = exec; + proc_mem->segment.lib = lib; + + proc_mem->size = size; + proc_mem->resident = resident; + proc_mem->share = share; + proc_mem->trs = trs; + proc_mem->lrs = lrs; + proc_mem->drs = drs; + proc_mem->dt = dt; +} + +static void +collect_sigign_sigcatch (struct task_struct *p, sigset_t *ign, + sigset_t *catch) +{ + struct k_sigaction *k; + int i; + + sigemptyset(ign); + sigemptyset(catch); + + if (p->sig) { + k = p->sig->action; + for (i = 1; i <= _NSIG; ++i, ++k) { + if (k->sa.sa_handler == SIG_IGN) + sigaddset(ign, i); + else if (k->sa.sa_handler != SIG_DFL) + sigaddset(catch, i); + } + } +} + +static void +task_sig (struct task_struct *p, libgtop_proc_signal_t *proc_signal) +{ + sigset_t ignore, catch; + int i, nsig; + + if (_NSIG_WORDS > LIBGTOP_NSIG) + nsig = LIBGTOP_NSIG; + else + nsig = _NSIG_WORDS; + + collect_sigign_sigcatch (p, &ignore, &catch); + + for (i = 0; i < nsig; i++) { + proc_signal->signal [i] = p->signal.sig [i]; + proc_signal->blocked [i] = p->blocked.sig [i]; + proc_signal->ignore [i] = ignore.sig [i]; + proc_signal->catch [i] = catch.sig [i]; + } +} + +static int +libgtop_sysctl (ctl_table *table, int nlen, int *name) +{ + extern unsigned long total_forks; + int index, tindex, tty, which, arg; + libgtop_stat_t *lstat; + libgtop_mem_t *mem; + libgtop_swap_t *swap; + libgtop_proclist_t *proclist; + struct task_struct *tsk = NULL; + struct sysinfo i; + + switch (table->ctl_name) { + case LIBGTOP_STAT: + lstat = table->data; + lstat->cpu.total = jiffies; + lstat->cpu.user = kstat.cpu_user; + lstat->cpu.nice = kstat.cpu_nice; + lstat->cpu.sys = kstat.cpu_system; + lstat->cpu.idle = jiffies*smp_num_cpus - + (lstat->cpu.user + lstat->cpu.nice + lstat->cpu.sys); +#ifdef __SMP__ + for (i = 0; i < smp_num_cpus; i++) { + lstat->xcpu[i].user = kstat.per_cpu_user[cpu_logical_map(i)]; + lstat->xcpu[i].nice = kstat.per_cpu_nice[cpu_logical_map(i)]; + lstat->xcpu[i].sys = kstat.per_cpu_system[cpu_logical_map(i)]; + lstat->xcpu[i].idle = jiffies - + (lstat->xcpu[i].user + lstat->xcpu[i].nice + + lstat->xcpu[i].sys); + } + + lstat->ncpu = smp_num_cpus; +#else + lstat->ncpu = 0; +#endif + + lstat->frequency = HZ; + + lstat->loadavg [0] = (double) avenrun [0] / (1 << FSHIFT); + lstat->loadavg [1] = (double) avenrun [1] / (1 << FSHIFT); + lstat->loadavg [2] = (double) avenrun [2] / (1 << FSHIFT); + + lstat->pgpgin = kstat.pgpgin; + lstat->pgpgout = kstat.pgpgout; + lstat->pswpin = kstat.pswpin; + lstat->pswpout = kstat.pswpout; + + lstat->context_swtch = kstat.context_swtch; + lstat->boot_time = xtime.tv_sec - jiffies / HZ; + lstat->total_forks = total_forks; + break; + case LIBGTOP_MEM: + if (jiffies - libgtop_mem_timestamp < libgtop_update_expensive) + return 0; + libgtop_mem_timestamp = jiffies; + + mem = table->data; + si_meminfo (&i); + + mem->totalram = i.totalram; + mem->freeram = i.freeram; + mem->sharedram = i.sharedram; + mem->bufferram = i.bufferram; +#if 0 + mem->cachedram = page_cache_size * PAGE_SIZE; +#endif + return 0; + case LIBGTOP_SWAP: + if (jiffies - libgtop_swap_timestamp < libgtop_update_expensive) + return 0; + libgtop_swap_timestamp = jiffies; + + swap = table->data; + si_swapinfo (&i); + + swap->totalswap = i.totalswap; + swap->freeswap = i.freeswap; + return 0; + case LIBGTOP_PROCLIST: + proclist = table->data; + + if (nlen == 1) { + which = 0; + arg = 0; + } else if (nlen == 2) { + which = name [1]; + arg = 0; + } else if (nlen == 3) { + which = name [1]; + arg = name [2]; + } else { + return -EINVAL; + } + + tsk = task [0]; + read_lock (&tasklist_lock); + for (index = tindex = 0; (index <= nr_tasks) && tsk->next_task; + index++, tsk = tsk->next_task) { + if (tsk->pid == 0) continue; + switch (which & LIBGTOP_PROCLIST_MASK) { + case LIBGTOP_PROCLIST_PID: + if (tsk->pid != arg) continue; + break; + case LIBGTOP_PROCLIST_PGRP: + if (tsk->pgrp != arg) continue; + break; + case LIBGTOP_PROCLIST_SESSION: + if (tsk->session != arg) continue; + break; + case LIBGTOP_PROCLIST_TTY: + tty = tsk->tty ? + kdev_t_to_nr (tsk->tty->device) : 0; + if (tty != arg) continue; + break; + case LIBGTOP_PROCLIST_UID: + if (tsk->uid != arg) continue; + break; + case LIBGTOP_PROCLIST_RUID: + if (tsk->euid != arg) continue; + break; + } + + if ((which & LIBGTOP_EXCLUDE_IDLE) && (tsk->state != 0)) + continue; + + if ((which & LIBGTOP_EXCLUDE_NOTTY) && (tsk->tty == NULL)) + continue; + + proclist->pids [tindex++] = tsk->pid; + } + + proclist->count = tindex; + proclist->nr_running = nr_running; + proclist->last_pid = last_pid; + proclist->nr_tasks = tindex; + read_unlock(&tasklist_lock); + return 0; + default: + return -EINVAL; + } + + return 0; +} + +static int +libgtop_sysctl_proc (ctl_table *table, int nlen, int *name, + struct task_struct *tsk) +{ + libgtop_proc_state_t *proc_state; + libgtop_proc_kernel_t *proc_kernel; + libgtop_proc_segment_t *proc_segment; + libgtop_proc_signal_t *proc_signal; + libgtop_proc_mem_t *proc_mem; + int i; + + switch (table->ctl_name) { + case LIBGTOP_PROC_STATE: + proc_state = table->data; + memset (proc_state, 0, sizeof (libgtop_proc_state_t)); + + proc_state->uid = tsk->uid; + proc_state->gid = tsk->gid; + proc_state->flags = tsk->flags; + memcpy (proc_state->comm, tsk->comm, sizeof (proc_state->comm)); + proc_state->uid = tsk->uid; + proc_state->euid = tsk->euid; + proc_state->suid = tsk->suid; + proc_state->fsuid = tsk->fsuid; + + proc_state->gid = tsk->gid; + proc_state->egid = tsk->egid; + proc_state->sgid = tsk->sgid; + proc_state->fsgid = tsk->fsgid; + + proc_state->pid = tsk->pid; + proc_state->pgrp = tsk->pgrp; + proc_state->ppid = tsk->p_pptr->pid; + + proc_state->session = tsk->session; + proc_state->tty = tsk->tty ? + kdev_t_to_nr (tsk->tty->device) : 0; + proc_state->tpgid = tsk->tty ? tsk->tty->pgrp : -1; + + proc_state->priority = tsk->priority; + proc_state->counter = tsk->counter; + proc_state->def_priority = DEF_PRIORITY; + + proc_state->utime = tsk->times.tms_utime; + proc_state->stime = tsk->times.tms_stime; + proc_state->cutime = tsk->times.tms_cutime; + proc_state->cstime = tsk->times.tms_cstime; + + proc_state->start_time = tsk->start_time; + +#ifdef __SMP__ + for (i = 0; i < NR_CPUS; i++) { + proc_state->per_cpu_utime [i] = tsk->per_cpu_utime [i]; + proc_state->per_cpu_stime [i] = tsk->per_cpu_stime [i]; + } +#endif + + proc_state->has_cpu = tsk->has_cpu; + proc_state->processor = tsk->processor; + proc_state->last_processor = tsk->last_processor; + + proc_state->policy = tsk->policy; + proc_state->rt_priority = tsk->rt_priority; + + proc_state->it_real_value = tsk->it_real_value; + proc_state->it_prof_value = tsk->it_prof_value; + proc_state->it_virt_value = tsk->it_virt_value; + proc_state->it_real_incr = tsk->it_real_incr; + proc_state->it_prof_incr = tsk->it_prof_incr; + proc_state->it_virt_incr = tsk->it_virt_incr; + + proc_state->min_flt = tsk->min_flt; + proc_state->cmin_flt = tsk->cmin_flt; + proc_state->maj_flt = tsk->maj_flt; + proc_state->cmaj_flt = tsk->cmaj_flt; + + proc_state->nswap = tsk->nswap; + proc_state->cnswap = tsk->cnswap; + + proc_state->kesp = KSTK_ESP(tsk); + proc_state->keip = KSTK_EIP(tsk); + + if (tsk->mm && tsk->mm != &init_mm) { + proc_state->context = tsk->mm->context; + proc_state->start_code = tsk->mm->start_code; + proc_state->end_code = tsk->mm->end_code; + proc_state->start_data = tsk->mm-> start_data; + proc_state->end_data = tsk->mm->end_data; + proc_state->start_brk = tsk->mm->start_brk; + proc_state->brk = tsk->mm->brk; + proc_state->start_stack = tsk->mm->start_stack; + proc_state->start_mmap = tsk->mm->mmap ? + tsk->mm->mmap->vm_start : 0; + proc_state->arg_start = tsk->mm->arg_start; + proc_state->arg_end = tsk->mm->arg_end; + proc_state->env_start = tsk->mm->env_start; + proc_state->env_end = tsk->mm->env_end; + proc_state->rss = tsk->mm->rss << PAGE_SHIFT; + proc_state->total_vm = tsk->mm->total_vm; + proc_state->locked_vm = tsk->mm->locked_vm; + + } + proc_state->rlim = tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0; + + proc_state->ngroups = tsk->ngroups; + for (i = 0; i < min (tsk->ngroups, LIBGTOP_MAX_GROUPS); i++) + proc_state->groups [i] = tsk->groups [i]; + + if (tsk->state & TASK_INTERRUPTIBLE) + proc_state->state |= LIBGTOP_TASK_INTERRUPTIBLE; + if (tsk->state & TASK_UNINTERRUPTIBLE) + proc_state->state |= LIBGTOP_TASK_UNINTERRUPTIBLE; + if (tsk->state & TASK_ZOMBIE) + proc_state->state |= LIBGTOP_TASK_ZOMBIE; + if (tsk->state & TASK_STOPPED) + proc_state->state |= LIBGTOP_TASK_STOPPED; + if (tsk->state & TASK_SWAPPING) + proc_state->state |= LIBGTOP_TASK_SWAPPING; + + if (!(tsk->state & (TASK_RUNNING | TASK_INTERRUPTIBLE | + TASK_UNINTERRUPTIBLE | TASK_ZOMBIE | + TASK_STOPPED | TASK_SWAPPING))) + proc_state->state |= LIBGTOP_TASK_RUNNING; + break; + case LIBGTOP_PROC_KERNEL: + proc_kernel = table->data; + memset (proc_kernel, 0, sizeof (libgtop_proc_kernel_t)); + + proc_kernel->wchan = get_wchan (tsk); + break; + case LIBGTOP_PROC_SEGMENT: + proc_segment = table->data; + memset (proc_segment, 0, sizeof (libgtop_proc_segment_t)); + + task_mem (tsk, proc_segment); + break; + case LIBGTOP_PROC_MEM: + proc_mem = table->data; + memset (proc_mem, 0, sizeof (libgtop_proc_mem_t)); + + get_statm (tsk, proc_mem); + /* Use LIBGTOP_PROC_STAT if you only want rss and rlim. */ + proc_mem->rss = tsk->mm->rss << PAGE_SHIFT; + proc_mem->rlim = tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0; + break; + case LIBGTOP_PROC_SIGNAL: + proc_signal = table->data; + memset (proc_signal, 0, sizeof (libgtop_proc_signal_t)); + + task_sig (tsk, proc_signal); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int +system_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, void *newval, + size_t newlen, void **context) +{ + int ret, len, len_name; + + if (!table->data || !table->maxlen) + return -ENOTDIR; + + if (!oldval || !oldlenp || get_user(len, oldlenp)) + return -EFAULT; + + if (!name || !nlen || get_user(len_name, name)) + return -EFAULT; + + if (len != table->maxlen) + return -EFAULT; + + ret = libgtop_sysctl (table, nlen, name); + if (ret) return ret; + + if(copy_to_user(oldval, table->data, len)) + return -EFAULT; + + return 1; +} + +static int +proc_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, void *newval, + size_t newlen, void **context) +{ + struct task_struct *tsk = NULL; + int ret, len, len_name; + + if (!table->data || !table->maxlen) + return -ENOTDIR; + + if (!oldval || !oldlenp || get_user(len, oldlenp)) + return -EFAULT; + + if (!name || !nlen || get_user(len_name, name)) + return -EFAULT; + + if (len != table->maxlen) + return -EFAULT; + + if (nlen != 2) + return -EFAULT; + + read_lock (&tasklist_lock); + tsk = find_task_by_pid (name [1]); + /* FIXME!! This should be done after the last use */ + read_unlock(&tasklist_lock); + + if (tsk == NULL) + return -ESRCH; + + ret = libgtop_sysctl_proc (table, nlen, name, tsk); + if (ret) return ret; + + if(copy_to_user(oldval, table->data, len)) + return -EFAULT; + + return 1; +} + +static unsigned long +get_phys_addr (struct task_struct * p, unsigned long ptr) +{ + pgd_t *page_dir; + pmd_t *page_middle; + pte_t pte; + + if (!p || !p->mm || ptr >= TASK_SIZE) + return 0; + /* Check for NULL pgd .. shouldn't happen! */ + if (!p->mm->pgd) { + printk("get_phys_addr: pid %d has NULL pgd!\n", p->pid); + return 0; + } + + page_dir = pgd_offset(p->mm,ptr); + if (pgd_none(*page_dir)) + return 0; + if (pgd_bad(*page_dir)) { + printk("bad page directory entry %08lx\n", pgd_val(*page_dir)); + pgd_clear(page_dir); + return 0; + } + page_middle = pmd_offset(page_dir,ptr); + if (pmd_none(*page_middle)) + return 0; + if (pmd_bad(*page_middle)) { + printk("bad page middle entry %08lx\n", pmd_val(*page_middle)); + pmd_clear(page_middle); + return 0; + } + pte = *pte_offset(page_middle,ptr); + if (!pte_present(pte)) + return 0; + return pte_page(pte) + (ptr & ~PAGE_MASK); +} + +static int +get_array (struct task_struct *p, unsigned long start, unsigned long end, + char * buffer) +{ + unsigned long addr; + int size = 0, result = 0; + char c; + + if (start >= end) + return result; + for (;;) { + addr = get_phys_addr (p, start); + if (!addr) + return result; + do { + c = *(char *) addr; + if (!c) + result = size; + if (size < PAGE_SIZE) + buffer[size++] = c; + else + return result; + addr++; + start++; + if (!c && start >= end) + return result; + } while (addr & ~PAGE_MASK); + } + + return result; +} + +static int +proc_args_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, void *newval, + size_t newlen, void **context) +{ + struct task_struct *tsk = NULL; + int ret, len, len_name; + unsigned long page; + + if (!oldval || !oldlenp || get_user (len, oldlenp)) + return -EFAULT; + + if (!name || !nlen || get_user (len_name, name)) + return -EFAULT; + + if (nlen != 2) + return -EFAULT; + + read_lock (&tasklist_lock); + tsk = find_task_by_pid (name [1]); + /* FIXME!! This should be done after the last use */ + read_unlock (&tasklist_lock); + + if (!tsk || !tsk->mm) + return -ESRCH; + + if (!(page = __get_free_page (GFP_KERNEL))) + return -ENOMEM; + + ret = get_array (tsk, tsk->mm->arg_start, + tsk->mm->arg_end, (char *) page); + if (ret < 0) { + free_page (page); + return ret; + } + + if (ret < len) + len = ret; + + if (put_user (len, oldlenp)) + goto err_fault_free_page; + + if (copy_to_user (oldval, (void *) page, len)) + goto err_fault_free_page; + + free_page (page); + return 1; + + err_fault_free_page: + free_page (page); + return -EFAULT; +} + +static int +proc_maps_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, void *newval, + size_t newlen, void **context) +{ + struct task_struct *p = NULL; + struct vm_area_struct * map, * next; + int i, len, len_name, retval = -EINVAL; + libgtop_proc_maps_t *proc_maps; + size_t count, wrote = 0; + loff_t lineno = 0; + int volatile_task; + + if (!oldlenp || get_user (len, oldlenp)) + return -EFAULT; + + if (!name || !nlen || get_user (len_name, name)) + return -EFAULT; + + if (nlen != 2) + return -EFAULT; + + read_lock (&tasklist_lock); + p = find_task_by_pid (name [1]); + /* FIXME!! This should be done after the last use */ + read_unlock (&tasklist_lock); + + if (!p || !p->mm) + return -ESRCH; + + if (len % sizeof (libgtop_proc_maps_t)) + return -EINVAL; + + count = len / sizeof (libgtop_proc_maps_t); + + if (!(proc_maps = kmalloc (sizeof (libgtop_proc_maps_t), GFP_KERNEL))) + return -ENOMEM; + + if (!p->mm || p->mm == &init_mm) + goto write_len_out; + + /* Check whether the mmaps could change if we sleep */ + volatile_task = (p != current || atomic_read (&p->mm->count) > 1); + + if (count == 0) { + /* Only get total count. */ + for (map = p->mm->mmap, i = 0; map; map = map->vm_next, i++) + continue; + wrote = i; + goto write_len_success; + } + + /* quickly go to line lineno */ + for (map = p->mm->mmap, i = 0; map && (i < lineno); + map = map->vm_next, i++) + continue; + + for ( ; map; map = next) { + memset (proc_maps, 0, sizeof (libgtop_proc_maps_t)); + + /* + * Get the next vma now (but it won't be used if we sleep). + */ + next = map->vm_next; + + proc_maps->header.start = map->vm_start; + proc_maps->header.end = map->vm_end; + proc_maps->header.offset = map->vm_offset; + + proc_maps->header.perm = map->vm_flags; + + if (map->vm_file != NULL) { + char *line = d_path (map->vm_file->f_dentry, proc_maps->filename, + LIBGTOP_MAP_PATH_LEN); + + proc_maps->filename [LIBGTOP_MAP_PATH_LEN-1] = '\0'; + proc_maps->header.filename_offset = line - proc_maps->filename; + + proc_maps->header.device = + map->vm_file->f_dentry->d_inode->i_dev; + proc_maps->header.inode = + map->vm_file->f_dentry->d_inode->i_ino; + } + + /* Copy current entry to user space. */ + if (copy_to_user (oldval, proc_maps, sizeof (*proc_maps))) { + retval = -EFAULT; + goto free_page_out; + } + + wrote += sizeof (*proc_maps); + + oldval += sizeof (*proc_maps); + len -= sizeof (*proc_maps); + count--; + + /* If there are no more entries, we don't have to worry about space. */ + if (next == NULL) + goto write_len_success; + + if (len < sizeof (*proc_maps)) { + retval = -EFAULT; + goto write_len_out; + } + + if (count == 0) { + retval = -E2BIG; + goto write_len_out; + } + } + + retval = -ENOSYS; + goto free_page_out; + + return retval; + + write_len_success: + retval = 1; + + write_len_out: + if (put_user (wrote, oldlenp)) { + retval = -EFAULT; + goto free_page_out; + } + + free_page_out: + kfree (proc_maps); + return retval; +} + +#if CONFIG_NET + +static int +proc_net_ctl_handler (ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, void *newval, + size_t newlen, void **context) +{ + int len, len_name, retval = -ENOSYS; + struct net_device_stats *stats; + libgtop_netload_t netload; + struct device *dev; + char *dev_name; + + if (!oldlenp || get_user (len, oldlenp)) + return -EFAULT; + + if (len != sizeof (libgtop_netload_t)) + return -EFAULT; + + if (!name || !nlen || get_user (len_name, name)) + return -EFAULT; + + if (nlen != 1) + return -EFAULT; + + /* Allocate memory for device name. */ + if (newlen > PAGE_SIZE) + return -ENOMEM; + + if (!(dev_name = kmalloc (newlen+1, GFP_KERNEL))) + return -ENOMEM; + + /* Copy device name from user space. */ + if (copy_from_user (dev_name, newval, newlen)) { + retval = -EFAULT; + goto free_name_out; + } + dev_name [newlen] = '\0'; + + dev = dev_get (dev_name); + if (!dev) { + retval = -ENODEV; + goto free_name_out; + } + + if (!dev->get_stats) { + retval = -ENODEV; + goto free_name_out; + } + + stats = dev->get_stats (dev); + + if (!stats) { + retval = -ENODEV; + goto free_name_out; + } + + netload.rx_packets = stats->rx_packets; + netload.tx_packets = stats->tx_packets; + + netload.rx_bytes = stats->rx_bytes; + netload.tx_bytes = stats->tx_bytes; + + netload.rx_errors = stats->rx_errors; + netload.tx_errors = stats->tx_errors; + + netload.rx_dropped = stats->rx_dropped; + netload.tx_dropped = stats->tx_dropped; + + netload.multicast = stats->multicast; + netload.collisions = stats->collisions; + + netload.rx_length_errors = stats->rx_length_errors; + netload.rx_over_errors = stats->rx_over_errors; + netload.rx_crc_errors = stats->rx_crc_errors; + netload.rx_frame_errors = stats->rx_frame_errors; + netload.rx_fifo_errors = stats->rx_fifo_errors; + netload.rx_missed_errors = stats->rx_missed_errors; + + netload.tx_aborted_errors = stats->tx_aborted_errors; + netload.tx_carrier_errors = stats->tx_carrier_errors; + netload.tx_fifo_errors = stats->tx_fifo_errors; + netload.tx_heartbeat_errors = stats->tx_heartbeat_errors; + netload.tx_window_errors = stats->tx_window_errors; + + netload.rx_compressed = stats->rx_compressed; + netload.tx_compressed = stats->tx_compressed; + + if (copy_to_user (oldval, (void *) &netload, len)) { + retval = -EFAULT; + goto free_name_out; + } + + retval = 1; + + free_name_out: + kfree (dev_name); + return retval; +} + +#endif /* CONFIG_NET */ diff --git a/kernel/sysctl/libgtop.h b/kernel/sysctl/libgtop.h new file mode 100644 index 00000000..f43a91c5 --- /dev/null +++ b/kernel/sysctl/libgtop.h @@ -0,0 +1,242 @@ +#ifndef _LINUX_LIBGTOP_H +#define _LINUX_LIBGTOP_H 1 + +#include + +enum { + LIBGTOP_VERSION = 1, + LIBGTOP_UPDATE_EXPENSIVE, + LIBGTOP_STAT = 101, + LIBGTOP_MEM, + LIBGTOP_SWAP, + LIBGTOP_PROCLIST = 201, + LIBGTOP_PROC_STATE = 211, + LIBGTOP_PROC_KERNEL, + LIBGTOP_PROC_SEGMENT, + LIBGTOP_PROC_MEM, + LIBGTOP_PROC_SIGNAL, + LIBGTOP_PROC_ARGS = 251, + LIBGTOP_PROC_MAPS, + LIBGTOP_NETLOAD = 301 +}; + +enum { + LIBGTOP_PROCLIST_ALL = 0, + LIBGTOP_PROCLIST_PID, + LIBGTOP_PROCLIST_PGRP, + LIBGTOP_PROCLIST_SESSION, + LIBGTOP_PROCLIST_TTY, + LIBGTOP_PROCLIST_UID, + LIBGTOP_PROCLIST_RUID +}; + +#define LIBGTOP_NSIG 4 + +#define LIBGTOP_PROCLIST_MASK 15 +#define LIBGTOP_MAX_GROUPS 32 + +#define LIBGTOP_EXCLUDE_IDLE 0x1000 +#define LIBGTOP_EXCLUDE_SYSTEM 0x2000 +#define LIBGTOP_EXCLUDE_NOTTY 0x4000 + +#define LIBGTOP_TASK_RUNNING 1 +#define LIBGTOP_TASK_INTERRUPTIBLE 2 +#define LIBGTOP_TASK_UNINTERRUPTIBLE 4 +#define LIBGTOP_TASK_ZOMBIE 8 +#define LIBGTOP_TASK_STOPPED 16 +#define LIBGTOP_TASK_SWAPPING 32 + +#define LIBGTOP_VM_READ 0x0001 /* currently active flags */ +#define LIBGTOP_VM_WRITE 0x0002 +#define LIBGTOP_VM_EXEC 0x0004 +#define LIBGTOP_VM_SHARED 0x0008 + +#define LIBGTOP_VM_MAYREAD 0x0010 /* limits for mprotect() etc */ +#define LIBGTOP_VM_MAYWRITE 0x0020 +#define LIBGTOP_VM_MAYEXEC 0x0040 +#define LIBGTOP_VM_MAYSHARE 0x0080 + +#define LIBGTOP_VM_GROWSDOWN 0x0100 /* general info on the segment */ +#define LIBGTOP_VM_GROWSUP 0x0200 +#define LIBGTOP_VM_SHM 0x0400 /* shared memory area, don't swap out */ +#define LIBGTOP_VM_DENYWRITE 0x0800 /* ETXTBSY on write attempts.. */ + +#define LIBGTOP_VM_EXECUTABLE 0x1000 +#define LIBGTOP_VM_LOCKED 0x2000 +#define LIBGTOP_VM_IO 0x4000 /* Memory mapped I/O or similar */ + +#define LIBGTOP_MAP_PATH_LEN (PAGE_SIZE - sizeof (libgtop_proc_maps_header_t)) + +#ifndef min +#define min(a,b) ((a < b) ? a : b) +#endif + +typedef struct libgtop_stat libgtop_stat_t; + +typedef struct libgtop_cpu libgtop_cpu_t; +typedef struct libgtop_mem libgtop_mem_t; +typedef struct libgtop_swap libgtop_swap_t; +typedef struct libgtop_proclist libgtop_proclist_t; + +typedef struct libgtop_proc_state libgtop_proc_state_t; +typedef struct libgtop_proc_kernel libgtop_proc_kernel_t; +typedef struct libgtop_proc_segment libgtop_proc_segment_t; +typedef struct libgtop_proc_mem libgtop_proc_mem_t; +typedef struct libgtop_proc_signal libgtop_proc_signal_t; + +typedef struct libgtop_proc_maps_header libgtop_proc_maps_header_t; +typedef struct libgtop_proc_maps libgtop_proc_maps_t; + +typedef struct libgtop_netload libgtop_netload_t; + +struct libgtop_cpu +{ + unsigned long total; /* Total CPU Time */ + unsigned long user; /* CPU Time in User Mode */ + unsigned long nice; /* CPU Time in User Mode (nice) */ + unsigned long sys; /* CPU Time in System Mode */ + unsigned long idle; /* CPU Time in the Idle Task */ +}; + +struct libgtop_mem +{ + unsigned long totalram; /* Total usable main memory size */ + unsigned long freeram; /* Available memory size */ + unsigned long sharedram; /* Amount of shared memory */ + unsigned long bufferram; /* Memory used by buffers */ + unsigned long cachedram; +}; + +struct libgtop_swap +{ + unsigned long totalswap; /* Total swap space size */ + unsigned long freeswap; /* swap space still available */ +}; + +struct libgtop_proclist +{ + int count; + int nr_running, nr_tasks, last_pid; + unsigned pids [NR_TASKS]; +}; + +struct libgtop_stat +{ + int ncpu; /* Number of CPUs */ + unsigned long frequency; /* Tick frequency (HZ) */ + libgtop_cpu_t cpu; /* CPU statistics */ + libgtop_cpu_t xcpu [NR_CPUS]; /* SMP per-CPU statistics */ + double loadavg [3]; /* Load average */ + unsigned long total_forks; /* Total # of forks */ + unsigned int context_swtch; /* Total # of context switches */ + unsigned long boot_time; /* Boot time (seconds s. epoch) */ + unsigned int pgpgin, pgpgout; /* # of pages paged in/out */ + unsigned int pswpin, pswpout; /* # of swap pgs brought in/out */ +}; + +struct libgtop_proc_state +{ + long state; + unsigned long flags; + char comm [16]; + int uid, euid, suid, fsuid; + int gid, egid, sgid, fsgid; + int pid, pgrp, ppid; + int session; + unsigned int tty; + int tpgid; + long priority, counter, def_priority; + long utime, stime, cutime, cstime, start_time; + long per_cpu_utime [NR_CPUS], per_cpu_stime [NR_CPUS]; + int has_cpu, processor, last_processor; + + unsigned long context; + unsigned long start_code, end_code, start_data, end_data; + unsigned long start_brk, brk, start_stack, start_mmap; + unsigned long arg_start, arg_end, env_start, env_end; + unsigned long rss, rlim, total_vm, locked_vm; + + unsigned long policy, rt_priority; + unsigned long it_real_value, it_prof_value, it_virt_value; + unsigned long it_real_incr, it_prof_incr, it_virt_incr; + + unsigned long keip, kesp; + unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; + unsigned long nswap, cnswap; + + int ngroups, groups [LIBGTOP_MAX_GROUPS]; +}; + +struct libgtop_proc_kernel +{ + unsigned long wchan; +}; + +struct libgtop_proc_segment +{ + unsigned long vsize, data, exec, stack, lib; +}; + +struct libgtop_proc_mem +{ + libgtop_proc_segment_t segment; + int size, resident, share, trs, lrs, drs, dt; + unsigned long rss, rlim; +}; + +struct libgtop_proc_signal +{ + unsigned long signal [LIBGTOP_NSIG]; + unsigned long blocked [LIBGTOP_NSIG]; + unsigned long ignore [LIBGTOP_NSIG]; + unsigned long catch [LIBGTOP_NSIG]; +}; + +struct libgtop_proc_maps_header +{ + unsigned long start, end, offset, perm; + off_t filename_offset; + ino_t inode; + dev_t device; +} __attribute__ ((aligned (64))); + +struct libgtop_proc_maps +{ + libgtop_proc_maps_header_t header; + char filename [LIBGTOP_MAP_PATH_LEN]; +}; + +struct libgtop_netload +{ + unsigned long rx_packets; /* total packets received */ + unsigned long tx_packets; /* total packets transmitted */ + unsigned long rx_bytes; /* total bytes received */ + unsigned long tx_bytes; /* total bytes transmitted */ + unsigned long rx_errors; /* bad packets received */ + unsigned long tx_errors; /* packet transmit problems */ + unsigned long rx_dropped; /* no space in linux buffers */ + unsigned long tx_dropped; /* no space available in linux */ + unsigned long multicast; /* multicast packets received */ + unsigned long collisions; + + /* detailed rx_errors: */ + unsigned long rx_length_errors; + unsigned long rx_over_errors; /* receiver ring buff overflow */ + unsigned long rx_crc_errors; /* recved pkt with crc error */ + unsigned long rx_frame_errors; /* recv'd frame alignment error */ + unsigned long rx_fifo_errors; /* recv'r fifo overrun */ + unsigned long rx_missed_errors; /* receiver missed packet */ + + /* detailed tx_errors */ + unsigned long tx_aborted_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; + unsigned long tx_heartbeat_errors; + unsigned long tx_window_errors; + + /* for cslip etc */ + unsigned long rx_compressed; + unsigned long tx_compressed; +}; + +#endif diff --git a/kernel/sysctl/libgtop_syms.c b/kernel/sysctl/libgtop_syms.c new file mode 100644 index 00000000..ddffc3f7 --- /dev/null +++ b/kernel/sysctl/libgtop_syms.c @@ -0,0 +1,30 @@ +/* + * linux/libgtop/libgtop_syms.c + * Copyright (C) 1999 Martin Baulig + */ + +#include +#include + +#include + +#include +#include +#include + +extern unsigned long total_forks; + +EXPORT_SYMBOL(task); +EXPORT_SYMBOL(init_mm); +EXPORT_SYMBOL(pidhash); +EXPORT_SYMBOL(avenrun); +EXPORT_SYMBOL(nr_running); +EXPORT_SYMBOL(nr_tasks); +EXPORT_SYMBOL(last_pid); +EXPORT_SYMBOL(total_forks); +EXPORT_SYMBOL(si_swapinfo); + +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +EXPORT_SYMBOL(scheduling_functions_start_here); +EXPORT_SYMBOL(scheduling_functions_end_here); diff --git a/kernel/sysctl/main.c b/kernel/sysctl/main.c new file mode 100644 index 00000000..6d391eb4 --- /dev/null +++ b/kernel/sysctl/main.c @@ -0,0 +1,4 @@ +/* + * linux/libgtop/main.c + * Copyright (C) 1999 Martin Baulig + */ diff --git a/kernel/sysctl/patch-2.2.1 b/kernel/sysctl/patch-2.2.1 new file mode 100644 index 00000000..1781b921 --- /dev/null +++ b/kernel/sysctl/patch-2.2.1 @@ -0,0 +1,81 @@ +diff -ru linux-2.2.1/Makefile hacker/Makefile +--- linux-2.2.1/Makefile Sun Jan 31 22:45:42 1999 ++++ hacker/Makefile Sun Mar 21 16:10:41 1999 +@@ -109,6 +109,7 @@ + DRIVERS =drivers/block/block.a \ + drivers/char/char.a \ + drivers/misc/misc.a ++EXTRAS = + LIBS =$(TOPDIR)/lib/lib.a + SUBDIRS =kernel drivers mm fs net ipc lib + +@@ -186,6 +187,11 @@ + DRIVERS := $(DRIVERS) drivers/net/irda/irda_drivers.a + endif + ++ifdef CONFIG_LIBGTOP ++SUBDIRS := $(SUBDIRS) libgtop ++EXTRAS := $(EXTRAS) libgtop/kernel.o ++endif ++ + include arch/$(ARCH)/Makefile + + .S.s: +@@ -206,6 +212,7 @@ + $(FILESYSTEMS) \ + $(NETWORKS) \ + $(DRIVERS) \ ++ $(EXTRAS) \ + $(LIBS) \ + --end-group \ + -o vmlinux +diff -ru linux-2.2.1/arch/i386/config.in hacker/arch/i386/config.in +--- linux-2.2.1/arch/i386/config.in Sun Jan 31 22:25:25 1999 ++++ hacker/arch/i386/config.in Sat Mar 20 18:26:18 1999 +@@ -84,6 +84,9 @@ + bool 'System V IPC' CONFIG_SYSVIPC + bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT + bool 'Sysctl support' CONFIG_SYSCTL ++if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then ++ tristate 'LibGTop support' CONFIG_LIBGTOP ++fi + tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT + tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF + tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC +diff -ru linux-2.2.1/include/linux/sysctl.h hacker/include/linux/sysctl.h +--- linux-2.2.1/include/linux/sysctl.h Sun Jan 31 22:24:14 1999 ++++ hacker/include/linux/sysctl.h Sat Mar 20 19:12:54 1999 +@@ -56,7 +56,8 @@ + CTL_PROC=4, /* Process info */ + CTL_FS=5, /* Filesystems */ + CTL_DEBUG=6, /* Debugging */ +- CTL_DEV=7 /* Devices */ ++ CTL_DEV=7, /* Devices */ ++ CTL_LIBGTOP=408 /* LibGTop */ + }; + + +diff -ru linux-2.2.1/kernel/sysctl.c hacker/kernel/sysctl.c +--- linux-2.2.1/kernel/sysctl.c Sun Jan 31 22:24:43 1999 ++++ hacker/kernel/sysctl.c Sat Mar 20 19:24:34 1999 +@@ -82,7 +82,9 @@ + static ctl_table fs_table[]; + static ctl_table debug_table[]; + static ctl_table dev_table[]; +- ++#ifdef CONFIG_LIBGTOP ++extern ctl_table libgtop_table[]; ++#endif + + /* /proc declarations: */ + +@@ -148,6 +150,9 @@ + {CTL_FS, "fs", NULL, 0, 0555, fs_table}, + {CTL_DEBUG, "debug", NULL, 0, 0555, debug_table}, + {CTL_DEV, "dev", NULL, 0, 0555, dev_table}, ++#ifdef CONFIG_LIBGTOP ++ {CTL_LIBGTOP, "libgtop", NULL, 0, 0555, libgtop_table}, ++#endif + {0} + }; + diff --git a/lib/lib.pl b/lib/lib.pl index 5fb09eac..f5502b96 100755 --- a/lib/lib.pl +++ b/lib/lib.pl @@ -36,6 +36,10 @@ print 'static void'; print '_glibtop_missing_feature (glibtop *server, const char *feature,'; print "\t\t\t const u_int64_t present, u_int64_t *required)"; print '{'; +print "\tu_int64_t old_required = *required;\n"; +print "\t/* Return if we have all required fields. */"; +print "\tif ((~present & old_required) == 0)"; +print "\t\treturn;\n"; print "\tswitch (server->error_method) {"; print "\tcase GLIBTOP_ERROR_METHOD_WARN_ONCE:"; print "\t\t*required &= present;"; @@ -43,13 +47,13 @@ print "\tcase GLIBTOP_ERROR_METHOD_WARN:"; print "\t\tglibtop_warn_r (server,"; print "\t\t\t\t_(\"glibtop_get_%s (): Client requested \""; print "\t\t\t\t \"field mask %05Lx, but only have %05Lx.\"),"; -print "\t\t\t\t feature, required, present);"; +print "\t\t\t\t feature, old_required, present);"; print "\t\tbreak;"; print "\tcase GLIBTOP_ERROR_METHOD_ABORT:"; print "\t\tglibtop_error_r (server,"; print "\t\t\t\t _(\"glibtop_get_%s (): Client requested \""; print "\t\t\t\t \"field mask %05x, but only have %05x.\"),"; -print "\t\t\t\t feature, required, present);"; +print "\t\t\t\t feature, old_required, present);"; print "\t\tbreak;"; print "\t}"; print '}'; diff --git a/misc/timings/timings.linux-proc b/misc/timings/timings.linux-proc new file mode 100644 index 00000000..3183e9cb --- /dev/null +++ b/misc/timings/timings.linux-proc @@ -0,0 +1,26 @@ +This statistics were made on a PPRO 200 running Linux 2.2.1 +reading everything from /proc while the system was idle. + + +Feature (Flags ): Count - utime - stime +---------------------------------------------------------- +CPU (0x000007ff): 100000 - 13.90 - 181.80 +Memory (0x0000007f): 10000 - 32.00 - 8061.00 +Swap (0x0000001f): 10000 - 46.00 - 8130.00 +Uptime (0x00000003): 100000 - 19.60 - 72.20 +Loadavg (0x0000000f): 100000 - 32.40 - 77.10 + +Proclist (0x00000007): 10000 - 2250.00 - 4419.00 + +Proc_State (0x0000000f): 100000 - 40.70 - 221.00 +Proc_Uid (0x00000fff): 100000 - 72.40 - 327.30 +Proc_Mem (0x0000003f): 100000 - 65.70 - 283.90 +Proc_Segment (0x000000f5): 100000 - 76.50 - 281.10 +Proc_Time (0x000001ff): 100000 - 37.00 - 160.90 +Proc_Signal (0x0000000f): 100000 - 52.50 - 148.50 +Proc_Kernel (0x0000017f): 100000 - 56.70 - 153.50 +---------------------------------------------------------- +TOTAL 70030000 - 396830000 + +All timings are in clock ticks (1000000 ticks per second). + diff --git a/misc/timings/timings.linux-sysctl b/misc/timings/timings.linux-sysctl new file mode 100644 index 00000000..b6cf9612 --- /dev/null +++ b/misc/timings/timings.linux-sysctl @@ -0,0 +1,27 @@ +This statistics were made on a PPRO 200 running Linux 2.2.1 +(the same machine I made the timings.linux-proc on) with my +new sysctl () based kernel module. + + +Feature (Flags ): Count - utime - stime +---------------------------------------------------------- +CPU (0x0000003f): 100000 - 3.50 - 5.40 +Memory (0x0000003f): 10000 - 3.00 - 6.00 +Swap (0x0000001f): 10000 - 10.00 - 7.00 +Uptime (0x00000003): 100000 - 2.30 - 7.00 +Loadavg (0x00000001): 100000 - 3.00 - 5.60 + +Proclist (0x00000007): 10000 - 13.00 - 46.00 + +Proc_State (0x0000000d): 100000 - 3.20 - 7.70 +Proc_Uid (0x00000fff): 100000 - 3.60 - 7.40 +Proc_Mem (0x0000003f): 100000 - 4.10 - 34.30 +Proc_Segment (0x000000ff): 100000 - 5.90 - 41.50 +Proc_Time (0x0000013d): 100000 - 3.50 - 7.50 +Proc_Signal (0x0000000f): 100000 - 2.70 - 8.80 +Proc_Kernel (0x000000fe): 100000 - 4.00 - 13.30 +---------------------------------------------------------- +TOTAL 3840000 - 14440000 + +All timings are in clock ticks (1000000 ticks per second). + diff --git a/po/de.po b/po/de.po index c9627653..ccba050f 100644 --- a/po/de.po +++ b/po/de.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: libgtop VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Martin Baulig \n" "Language-Team: Martin Baulig \n" diff --git a/po/es.po b/po/es.po index b3bf8034..de239e3c 100644 --- a/po/es.po +++ b/po/es.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: glibtop 1.0.0\n" -"POT-Creation-Date: 1999-02-23 13:48+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: 1998-12-13 04:38+0100\n" "Last-Translator: Pablo Saratxaga \n" "Language-Team: Pablo Saratxaga \n" diff --git a/po/es_DO.po b/po/es_DO.po index f77ea9c6..b001cd41 100644 --- a/po/es_DO.po +++ b/po/es_DO.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/po/es_GT.po b/po/es_GT.po index f77ea9c6..b001cd41 100644 --- a/po/es_GT.po +++ b/po/es_GT.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/po/es_HN.po b/po/es_HN.po index f77ea9c6..b001cd41 100644 --- a/po/es_HN.po +++ b/po/es_HN.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/po/es_MX.po b/po/es_MX.po index f77ea9c6..b001cd41 100644 --- a/po/es_MX.po +++ b/po/es_MX.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/po/es_PA.po b/po/es_PA.po index f77ea9c6..b001cd41 100644 --- a/po/es_PA.po +++ b/po/es_PA.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/po/es_PE.po b/po/es_PE.po index f77ea9c6..b001cd41 100644 --- a/po/es_PE.po +++ b/po/es_PE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/po/es_SV.po b/po/es_SV.po index f77ea9c6..b001cd41 100644 --- a/po/es_SV.po +++ b/po/es_SV.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/po/fi.po b/po/fi.po new file mode 100644 index 00000000..4b86b3b1 --- /dev/null +++ b/po/fi.po @@ -0,0 +1,1227 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 1999-04-18 12:37-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" + +#: sysdeps/names/cpu.c:45 +msgid "Total CPU Time" +msgstr "CPU-aika kaikkiaan" + +#: sysdeps/names/cpu.c:46 +msgid "CPU Time in User Mode" +msgstr "CPU-aika käyttäjätilassa" + +#: sysdeps/names/cpu.c:47 +msgid "CPU Time in User Mode (nice)" +msgstr "CPU-aika käyttäjätilassa (alhaisella prioriteetilla)" + +#: sysdeps/names/cpu.c:48 +msgid "CPU Time in System Mode" +msgstr "CPU-aika kernelissä" + +#: sysdeps/names/cpu.c:49 +msgid "CPU Time in the Idle Task" +msgstr "CPU-aikaa tuhlattu" + +#: sysdeps/names/cpu.c:50 +msgid "Tick Frequency" +msgstr "Tikitystaajuus" + +#: sysdeps/names/cpu.c:51 +msgid "SMP Total CPU Time" +msgstr "SMP CPU-aika kaikkiaan" + +#: sysdeps/names/cpu.c:52 +msgid "SMP CPU Time in User Mode" +msgstr "SMP CPU-aika käyttäjätilassa" + +#: sysdeps/names/cpu.c:53 +msgid "SMP CPU Time in User Mode (nice)" +msgstr "SMP CPU-aika käyttäjätilassa (alhaisella prioriteetilla)" + +#: sysdeps/names/cpu.c:54 +msgid "SMP CPU Time in System Mode" +msgstr "SMP CPU-aika kernelissä" + +#: sysdeps/names/cpu.c:55 +msgid "SMP CPU Time in the Idle Task" +msgstr "SMP CPU-aikaa tuhlattu" + +#: sysdeps/names/cpu.c:56 sysdeps/names/cpu.c:72 sysdeps/names/proctime.c:66 +msgid "SMP CPU Flags" +msgstr "SMP CPU-liput" + +#: sysdeps/names/cpu.c:61 sysdeps/names/cpu.c:67 +msgid "Number of clock ticks since system boot" +msgstr "Kellon tikityksiä systeemin käynnistyksen jälkeen" + +#: sysdeps/names/cpu.c:62 sysdeps/names/cpu.c:68 +msgid "Number of clock ticks the system spent in user mode" +msgstr "Kellon tikityksiä käyttäjätilassa" + +#: sysdeps/names/cpu.c:63 sysdeps/names/cpu.c:69 +msgid "Number of clock ticks the system spent in user mode (nice)" +msgstr "Kellon tikityksiä käyttäjätilassa (alhaisella prioriteetilla)" + +#: sysdeps/names/cpu.c:64 sysdeps/names/cpu.c:70 +msgid "Number of clock ticks the system spent in system mode" +msgstr "Kellon tikityksiä kernelissä" + +#: sysdeps/names/cpu.c:65 sysdeps/names/cpu.c:71 +msgid "Number of clock ticks the system spent in the idle task" +msgstr "Kellon tikityksiä hukattu" + +#: sysdeps/names/cpu.c:66 +msgid "Tick frequency (default is 100)" +msgstr "Tikitysten taajuus (oletusarvo 100)" + +#: sysdeps/names/fsusage.c:41 sysdeps/names/fsusage.c:50 +msgid "Total blocks" +msgstr "Blokkeja yhteensä" + +#: sysdeps/names/fsusage.c:42 +msgid "Free blocks" +msgstr "Vapaita blokkeja" + +#: sysdeps/names/fsusage.c:43 +msgid "Available blocks" +msgstr "Saatavissa olevia blokkeja" + +#: sysdeps/names/fsusage.c:44 sysdeps/names/fsusage.c:53 +msgid "Total file nodes" +msgstr "Tiedostoja yhteensä" + +#: sysdeps/names/fsusage.c:45 sysdeps/names/fsusage.c:54 +msgid "Free file nodes" +msgstr "Vapaita tiedostoja" + +#: sysdeps/names/fsusage.c:51 +msgid "Free blocks available to the superuser" +msgstr "Vapaita blokkeja varattuna ylikäyttäjälle" + +#: sysdeps/names/fsusage.c:52 +msgid "Free blocks available to non-superusers" +msgstr "Vapaita blokkeja tavallisille käyttäjille" + +#: sysdeps/names/loadavg.c:41 +msgid "Load Average" +msgstr "Kuormituskeskiarvo" + +#: sysdeps/names/loadavg.c:42 +msgid "Running Tasks" +msgstr "Töitä käynnissä" + +#: sysdeps/names/loadavg.c:43 +msgid "Number of Tasks" +msgstr "Töitten määrä" + +#: sysdeps/names/loadavg.c:44 sysdeps/names/loadavg.c:52 +msgid "Last PID" +msgstr "Viimeisin prosessinnumero" + +#: sysdeps/names/loadavg.c:49 +msgid "Number of jobs running simultaneously averaged over 1, 5 and 15 minutes" +msgstr "Yhtäaikaisten töitten määrä keskiarvotettuna 1, 5 ja 15 minuutilta" + +#: sysdeps/names/loadavg.c:50 +msgid "Number of tasks currently running" +msgstr "Käynnissä olevien töitten määrä" + +#: sysdeps/names/loadavg.c:51 +msgid "Total number of tasks" +msgstr "Töitten kokonaismäärä" + +#: sysdeps/names/mem.c:43 +msgid "Total Memory" +msgstr "Muistia yhteensä" + +#: sysdeps/names/mem.c:44 +msgid "Used Memory" +msgstr "Käytetty muisti" + +#: sysdeps/names/mem.c:45 +msgid "Free Memory" +msgstr "Vapaa muisti" + +#: sysdeps/names/mem.c:46 +msgid "Shared Memory" +msgstr "Jaettu muisti" + +#: sysdeps/names/mem.c:47 +msgid "Buffers" +msgstr "Puskurit" + +#: sysdeps/names/mem.c:48 +msgid "Cached" +msgstr "Välimuisti" + +#: sysdeps/names/mem.c:49 +msgid "User" +msgstr "Käyttäjä" + +#: sysdeps/names/mem.c:50 +msgid "Locked" +msgstr "Lukittu" + +#: sysdeps/names/mem.c:55 +msgid "Total physical memory in kB" +msgstr "Fyysinen muistin koko (kB)" + +#: sysdeps/names/mem.c:56 +msgid "Used memory size in kB" +msgstr "Käytetty muistin koko (kB)" + +#: sysdeps/names/mem.c:57 +msgid "Free memory size in kB" +msgstr "Vapaan muistin koko (kB)" + +#: sysdeps/names/mem.c:58 +msgid "Shared memory size in kB" +msgstr "Jaetun muistin koko (kB)" + +#: sysdeps/names/mem.c:59 +msgid "Size of buffers kB" +msgstr "Puskurimuistin koko (kB)" + +#: sysdeps/names/mem.c:60 +msgid "Size of cached memory in kB" +msgstr "Välimuistina käytetyn muistin koko (kB)" + +#: sysdeps/names/mem.c:61 +msgid "Memory used from user processes in kB" +msgstr "Käyttäjien prosessien käyttämä muisti (kB)" + +#: sysdeps/names/mem.c:62 +msgid "Memory in locked pages in kB" +msgstr "Lukittujen sivujen käyttämä muisti (kB)" + +#: sysdeps/names/mountlist.c:40 sysdeps/names/mountlist.c:47 +#: sysdeps/names/proclist.c:40 sysdeps/names/proclist.c:47 +#: sysdeps/names/procmap.c:40 sysdeps/names/procmap.c:47 +msgid "Number of list elements" +msgstr "Listan elementtien määrä" + +#: sysdeps/names/mountlist.c:41 sysdeps/names/mountlist.c:48 +#: sysdeps/names/proclist.c:41 sysdeps/names/proclist.c:48 +#: sysdeps/names/procmap.c:41 sysdeps/names/procmap.c:48 +msgid "Total size of list" +msgstr "Listan koko byteinä" + +#: sysdeps/names/mountlist.c:42 sysdeps/names/mountlist.c:49 +#: sysdeps/names/proclist.c:42 sysdeps/names/proclist.c:49 +#: sysdeps/names/procmap.c:42 sysdeps/names/procmap.c:49 +msgid "Size of a single list element" +msgstr "Yhden listanelementin koko" + +#: sysdeps/names/msg_limits.c:42 sysdeps/names/msg_limits.c:53 +msgid "Size in kilobytes of message pool" +msgstr "Viestialtaan koko kiloina" + +#: sysdeps/names/msg_limits.c:43 sysdeps/names/msg_limits.c:54 +msgid "Number of entries in message map" +msgstr "Viestikartan rivien määrä" + +#: sysdeps/names/msg_limits.c:44 sysdeps/names/msg_limits.c:55 +msgid "Max size of message" +msgstr "Viestin suurin pituus" + +#: sysdeps/names/msg_limits.c:45 sysdeps/names/msg_limits.c:56 +msgid "Default max size of queue" +msgstr "Jonon maksimikoon oletusarvo" + +#: sysdeps/names/msg_limits.c:46 sysdeps/names/msg_limits.c:57 +msgid "Max queues system wide" +msgstr "Maksimi jonojen määrä kokos systeemissä" + +#: sysdeps/names/msg_limits.c:47 sysdeps/names/msg_limits.c:58 +msgid "Message segment size" +msgstr "Viestisegmentin koko" + +#: sysdeps/names/msg_limits.c:48 sysdeps/names/msg_limits.c:59 +msgid "Number of system message headers" +msgstr "Viestiotsikoiden määrä systeemissä" + +#: sysdeps/names/prockernel.c:44 +msgid "K_Flags" +msgstr "" + +#: sysdeps/names/prockernel.c:44 +msgid "Min_Flt" +msgstr "" + +#: sysdeps/names/prockernel.c:44 +msgid "Maj_Flt" +msgstr "" + +#: sysdeps/names/prockernel.c:44 +msgid "CMin_Flt" +msgstr "" + +#: sysdeps/names/prockernel.c:45 +msgid "CMaj_Flt" +msgstr "" + +#: sysdeps/names/prockernel.c:45 +msgid "KStk_ESP" +msgstr "" + +#: sysdeps/names/prockernel.c:45 +msgid "KStk_EIP" +msgstr "" + +#: sysdeps/names/prockernel.c:45 +msgid "NWChan" +msgstr "" + +#: sysdeps/names/prockernel.c:46 +msgid "WChan" +msgstr "" + +#. K_Flags +#: sysdeps/names/prockernel.c:52 +msgid "" +"Kernel flags of the process.\n" +"\n" +"On Linux, currently every flag has the math bit set, because crt0.s checks " +"for math emulation, so this is not included in the output.\n" +"\n" +"This is probably a bug, as not every process is a compiled C program.\n" +"\n" +"The math bit should be a decimal 4, and the traced bit is decimal 10." +msgstr "" +"Kernelin prosessia koskevat liput.\n" +"\n" +"Linuxissa kaikkien prosessien math-bitti on asetettu, sillä crt0.s tarkistaa " +"onko matematiikkaemulaatiolle tarvetta, joten sitä ei ole mukana.\n" +"\n" +"Tämä on todennäköisesti bugi, koska kaikki prosessit eivät ole C-ohjelmia.\n" +"\n" +"Math-bitti on desimaali 4 ja seurattu-bitti on desimaali 10." + + +#. Min_Flt +#: sysdeps/names/prockernel.c:61 +msgid "" +"The number of minor faults the process has made, those which have not " +"required loading a memory page from disk." +msgstr "" +"Prosessin tekemien vähempien sivunhakujen määrä, eli ne joita varten " +"ei tarvinnut hakea muistisivua levyltä." + +#. Maj_Flt +#: sysdeps/names/prockernel.c:64 +msgid "" +"The number of major faults the process has made, those which have required " +"loading a memory page from disk." +msgstr "" +"Prosessin tekemien suurempien sivunhakujen määrä, eli ne joita varten " +"tarvittiin muistisivu levyltä." + + +#. CMin_Flt +#: sysdeps/names/prockernel.c:67 +msgid "The number of minor faults that the process and its children have made." +msgstr "Prosessin ja sen lasten vähempien sivunhakujen määrä" + +#. CMaj_Flt +#: sysdeps/names/prockernel.c:70 +msgid "The number of major faults that the process and its children have made." +msgstr "Prosessin ja sen lasten suurempien sivunhakujen määrä" + +#. KStk_ESP +#: sysdeps/names/prockernel.c:73 +msgid "" +"The current value of esp (32-bit stack pointer), as found in the kernel " +"stack page for the process." +msgstr "" +"Esp:n (32-bittinen pino-osoittimen) tämänhetkinen arvo, joka saatiin " +"prosessin pinosivulta kernelistä." + +#. KStk_EIP +#: sysdeps/names/prockernel.c:76 +msgid "The current EIP (32-bit instruction pointer)." +msgstr "Tämänhetkinen EIP (32-bittinen suoritusosoitin)." + +#. NWChan +#: sysdeps/names/prockernel.c:78 +msgid "" +"This is the \"channel\" in which the process is waiting. This is the " +"address of a system call, and can be looked up in a namelist if you need a " +"textual name. (If you have an up-to-date /etc/psdatabase, then try ps -l to " +"see the WCHAN field in action)" +msgstr "" +"Tätä \"kanavaa\" prosessi odottaa. Tämä on systeemikutsun osoite ja " +"voidaan etsiä nimiluettelosta jos haluat sen tekstinä. (Jos sinulla on " +"päivitetty /etc/psdatabase, koita ps -l jotta näet WCHAN-kentän toiminnassa)" + +#. WChan +#: sysdeps/names/prockernel.c:83 +msgid "This is the textual name of the `nwchan' field." +msgstr "nwchan-kentän tekstinimi" + +#: sysdeps/names/procmem.c:49 +msgid "Size" +msgstr "Koko" + +#: sysdeps/names/procmem.c:49 +msgid "Virtual" +msgstr "Virtuaalinen" + +#: sysdeps/names/procmem.c:49 +msgid "Resident" +msgstr "Muistissa" + +#: sysdeps/names/procmem.c:49 +msgid "Share" +msgstr "Jaettu" + +#: sysdeps/names/procmem.c:50 +msgid "Resident Set Size" +msgstr "Prosessin muistissa oleva koko" + +#: sysdeps/names/procmem.c:50 +msgid "Resident Set Size Limit" +msgstr "Prosessin muistissa olevan koon raja" + +#: sysdeps/names/procmem.c:55 +msgid "Total # of pages of memory" +msgstr "Muistisivuja yhteensä" + +#: sysdeps/names/procmem.c:56 +msgid "Number of pages of virtual memory" +msgstr "Virtuaalimuistisivuja yhteensä" + +#: sysdeps/names/procmem.c:57 +msgid "Number of residnet set (non-swapped) pages" +msgstr "Fyysisessä muistissa (ei swapissa) olevien sivujen määrä" + +#: sysdeps/names/procmem.c:58 +msgid "Number of pages of shared (mmap'd) memory" +msgstr "Jaetun muistin (mmap) sivujen määrä" + +#: sysdeps/names/procmem.c:59 +msgid "" +"Number of pages the process has in real memory, minus 3 for administrative " +"purposes. This is just the pages which count towards text, data, or stack " +"space. This does not include pages which have not been demand-loaded in, or " +"which are swapped out." +msgstr "" +"Prosessin fyysisessä muistissa olevien sivujen määrä, miinus 3 järjestelyjä " +"varten. Tässä on vain sivut, jotka ovat text, data tai pinomuistiavaruuksia. " +"Ei sisällä sivuja joita ei ole vielä haettu levyltä tai jotka on swapattu " +"levylle." + +#: sysdeps/names/procmem.c:64 +msgid "" +"Current limit in bytes on the rss of the process (usually 2,147,483,647)." +msgstr "" +"Tämänhetkinen raja prosessin fyysisessä muistissa olevalle koolle " +"(yleensä 2 147 483 647)." + +#: sysdeps/names/procsegment.c:50 +msgid "Text_RSS" +msgstr "" + +#: sysdeps/names/procsegment.c:50 +msgid "ShLib_RSS" +msgstr "" + +#: sysdeps/names/procsegment.c:50 +msgid "Data_RSS" +msgstr "" + +#: sysdeps/names/procsegment.c:50 +msgid "Stack_RSS" +msgstr "" + +#: sysdeps/names/procsegment.c:51 +msgid "Dirty Size" +msgstr "" + +#: sysdeps/names/procsegment.c:51 +msgid "Start_Code" +msgstr "" + +#: sysdeps/names/procsegment.c:51 +msgid "End_Code" +msgstr "" + +#: sysdeps/names/procsegment.c:52 +msgid "Start_Data" +msgstr "" + +#: sysdeps/names/procsegment.c:52 +msgid "End_Data" +msgstr "" + +#: sysdeps/names/procsegment.c:52 +msgid "Start_Brk" +msgstr "" + +#: sysdeps/names/procsegment.c:52 +msgid "Brk" +msgstr "" + +#: sysdeps/names/procsegment.c:53 +msgid "Start_Stack" +msgstr "" + +#: sysdeps/names/procsegment.c:53 +msgid "Start_MMap" +msgstr "" + +#: sysdeps/names/procsegment.c:53 sysdeps/names/procsegment.c:72 +msgid "Arg_Start" +msgstr "" + +#: sysdeps/names/procsegment.c:54 sysdeps/names/procsegment.c:73 +msgid "Arg_End" +msgstr "" + +#: sysdeps/names/procsegment.c:54 sysdeps/names/procsegment.c:74 +msgid "Env_Start" +msgstr "" + +#: sysdeps/names/procsegment.c:54 sysdeps/names/procsegment.c:75 +msgid "Env_End" +msgstr "" + +#: sysdeps/names/procsegment.c:59 +msgid "Text resident set size" +msgstr "" + +#: sysdeps/names/procsegment.c:60 +msgid "Shared-Lib resident set size" +msgstr "" + +#: sysdeps/names/procsegment.c:61 +msgid "Data resident set size" +msgstr "" + +#: sysdeps/names/procsegment.c:62 +msgid "Stack resident set size" +msgstr "" + +#: sysdeps/names/procsegment.c:63 +msgid "Total size of dirty pages" +msgstr "" + +#: sysdeps/names/procsegment.c:64 +msgid "Address of beginning of code segment" +msgstr "" + +#: sysdeps/names/procsegment.c:65 +msgid "Address of end of code segment" +msgstr "" + +#: sysdeps/names/procsegment.c:66 +msgid "Address of beginning of data segment" +msgstr "" + +#: sysdeps/names/procsegment.c:67 +msgid "Address of end of data segment" +msgstr "" + +#: sysdeps/names/procsegment.c:68 +msgid "Brk_Start" +msgstr "" + +#: sysdeps/names/procsegment.c:69 +msgid "Brk_End" +msgstr "" + +#: sysdeps/names/procsegment.c:70 +msgid "Address of the bottom of stack segment" +msgstr "" + +#: sysdeps/names/procsegment.c:71 +msgid "Start of mmap()ed areas" +msgstr "" + +#: sysdeps/names/procsignal.c:42 +msgid "Signal" +msgstr "" + +#: sysdeps/names/procsignal.c:42 +msgid "Blocked" +msgstr "" + +#: sysdeps/names/procsignal.c:42 +msgid "SigIgnore" +msgstr "" + +#: sysdeps/names/procsignal.c:42 +msgid "SigCatch" +msgstr "" + +#: sysdeps/names/procsignal.c:47 +msgid "Mask of pending signals" +msgstr "" + +#: sysdeps/names/procsignal.c:48 +msgid "Mask of blocked signals" +msgstr "" + +#: sysdeps/names/procsignal.c:49 +msgid "Mask of ignored signals" +msgstr "" + +#: sysdeps/names/procsignal.c:50 +msgid "Mask of caught signals" +msgstr "" + +#: sysdeps/names/procstate.c:45 +msgid "Cmd" +msgstr "" + +#: sysdeps/names/procstate.c:45 +msgid "State" +msgstr "" + +#: sysdeps/names/procstate.c:45 +msgid "UID" +msgstr "" + +#: sysdeps/names/procstate.c:45 +msgid "GID" +msgstr "" + +#: sysdeps/names/procstate.c:45 +msgid "RUID" +msgstr "" + +#: sysdeps/names/procstate.c:46 +msgid "RGID" +msgstr "" + +#: sysdeps/names/procstate.c:46 +msgid "Has CPU" +msgstr "" + +#: sysdeps/names/procstate.c:46 +msgid "Processor" +msgstr "" + +#: sysdeps/names/procstate.c:47 +msgid "Last Processor" +msgstr "" + +#: sysdeps/names/procstate.c:52 +msgid "Basename of executable file in call to exec()" +msgstr "" + +#: sysdeps/names/procstate.c:53 +msgid "Single-Char code for process state (S=sleeping)" +msgstr "" + +#: sysdeps/names/procstate.c:54 +msgid "effective UID of process" +msgstr "" + +#: sysdeps/names/procstate.c:55 +msgid "effective GID of process" +msgstr "" + +#: sysdeps/names/procstate.c:56 +msgid "real UID of process" +msgstr "" + +#: sysdeps/names/procstate.c:57 +msgid "real GID of process" +msgstr "" + +#: sysdeps/names/procstate.c:58 +msgid "has_cpu" +msgstr "" + +#: sysdeps/names/procstate.c:59 +msgid "processor" +msgstr "" + +#: sysdeps/names/procstate.c:60 +msgid "last_processor" +msgstr "" + +#: sysdeps/names/proctime.c:46 +msgid "Start_Time" +msgstr "" + +#: sysdeps/names/proctime.c:46 +msgid "RTime" +msgstr "" + +#: sysdeps/names/proctime.c:46 +msgid "UTime" +msgstr "" + +#: sysdeps/names/proctime.c:46 +msgid "STime" +msgstr "" + +#: sysdeps/names/proctime.c:47 +msgid "CUTime" +msgstr "" + +#: sysdeps/names/proctime.c:47 +msgid "CSTime" +msgstr "" + +#: sysdeps/names/proctime.c:47 +msgid "TimeOut" +msgstr "" + +#: sysdeps/names/proctime.c:47 +msgid "It_Real_Value" +msgstr "" + +#: sysdeps/names/proctime.c:48 +msgid "Frequency" +msgstr "" + +#: sysdeps/names/proctime.c:48 +msgid "XCPU_UTime" +msgstr "" + +#: sysdeps/names/proctime.c:48 +msgid "XCPU_STime" +msgstr "" + +#: sysdeps/names/proctime.c:49 +msgid "XCPU_Flags" +msgstr "" + +#: sysdeps/names/proctime.c:54 +msgid "Start time of process in seconds since the epoch" +msgstr "" + +#: sysdeps/names/proctime.c:55 +msgid "Real time accumulated by process (should be utime + stime)" +msgstr "" + +#: sysdeps/names/proctime.c:56 +msgid "user-mode CPU time accumulated by process" +msgstr "" + +#: sysdeps/names/proctime.c:57 +msgid "kernel-mode CPU time accumulated by process" +msgstr "" + +#: sysdeps/names/proctime.c:58 +msgid "cumulative utime of process and reaped children" +msgstr "" + +#: sysdeps/names/proctime.c:59 +msgid "cumulative stime of process and reaped children" +msgstr "" + +#: sysdeps/names/proctime.c:60 +msgid "The time (in jiffies) of the process's next timeout" +msgstr "" + +#: sysdeps/names/proctime.c:61 +msgid "" +"The time (in jiffies) before the next SIGALRM is sent to the process due to " +"an interval timer." +msgstr "" + +#: sysdeps/names/proctime.c:63 +msgid "Tick frequency" +msgstr "" + +#: sysdeps/names/proctime.c:64 +msgid "SMP user-mode CPU time accumulated by process" +msgstr "" + +#: sysdeps/names/proctime.c:65 +msgid "SMP kernel-mode CPU time accumulated by process" +msgstr "" + +#: sysdeps/names/procuid.c:48 +msgid "Uid" +msgstr "" + +#: sysdeps/names/procuid.c:48 +msgid "EUid" +msgstr "" + +#: sysdeps/names/procuid.c:48 +msgid "Gid" +msgstr "" + +#: sysdeps/names/procuid.c:48 +msgid "EGid" +msgstr "" + +#: sysdeps/names/procuid.c:48 +msgid "SUid" +msgstr "" + +#: sysdeps/names/procuid.c:49 +msgid "SGid" +msgstr "" + +#: sysdeps/names/procuid.c:49 +msgid "FsUid" +msgstr "" + +#: sysdeps/names/procuid.c:49 +msgid "FsGid" +msgstr "" + +#: sysdeps/names/procuid.c:49 +msgid "Pid" +msgstr "" + +#: sysdeps/names/procuid.c:50 +msgid "PPid" +msgstr "" + +#: sysdeps/names/procuid.c:50 +msgid "PGrp" +msgstr "" + +#: sysdeps/names/procuid.c:50 +msgid "Session" +msgstr "" + +#: sysdeps/names/procuid.c:50 +msgid "Tty" +msgstr "" + +#: sysdeps/names/procuid.c:51 +msgid "TPGid" +msgstr "" + +#: sysdeps/names/procuid.c:51 +msgid "Priority" +msgstr "" + +#: sysdeps/names/procuid.c:51 +msgid "Nice" +msgstr "" + +#: sysdeps/names/procuid.c:51 +msgid "NGroups" +msgstr "" + +#: sysdeps/names/procuid.c:52 +msgid "Groups" +msgstr "" + +#: sysdeps/names/procuid.c:57 +msgid "User ID" +msgstr "" + +#: sysdeps/names/procuid.c:58 +msgid "Effective User ID" +msgstr "" + +#: sysdeps/names/procuid.c:59 +msgid "Group ID" +msgstr "" + +#: sysdeps/names/procuid.c:60 +msgid "Effective Group ID" +msgstr "" + +#: sysdeps/names/procuid.c:61 +msgid "Saved User ID" +msgstr "" + +#: sysdeps/names/procuid.c:62 +msgid "Saved Group ID" +msgstr "" + +#: sysdeps/names/procuid.c:63 +msgid "Filesystem User ID" +msgstr "" + +#: sysdeps/names/procuid.c:64 +msgid "Filesystem Group ID" +msgstr "" + +#: sysdeps/names/procuid.c:65 +msgid "Process ID" +msgstr "" + +#: sysdeps/names/procuid.c:66 +msgid "PID of parent process" +msgstr "" + +#: sysdeps/names/procuid.c:67 +msgid "Process group ID" +msgstr "" + +#: sysdeps/names/procuid.c:68 +msgid "Session ID" +msgstr "" + +#: sysdeps/names/procuid.c:69 +msgid "Full device number of controlling terminal" +msgstr "" + +#: sysdeps/names/procuid.c:70 +msgid "Terminal process group ID" +msgstr "" + +#: sysdeps/names/procuid.c:71 +msgid "Kernel scheduling priority" +msgstr "" + +#: sysdeps/names/procuid.c:72 +msgid "Standard unix nice level of process" +msgstr "" + +#: sysdeps/names/procuid.c:73 +msgid "Number of additional process groups" +msgstr "" + +#: sysdeps/names/procuid.c:74 +msgid "Additional process groups" +msgstr "" + +#: sysdeps/names/sem_limits.c:44 sysdeps/names/sem_limits.c:58 +msgid "Number of entries in semaphore map" +msgstr "" + +#: sysdeps/names/sem_limits.c:45 sysdeps/names/sem_limits.c:59 +msgid "Max number of arrays" +msgstr "" + +#: sysdeps/names/sem_limits.c:46 sysdeps/names/sem_limits.c:60 +msgid "Max semaphores system wide" +msgstr "" + +#: sysdeps/names/sem_limits.c:47 sysdeps/names/sem_limits.c:61 +msgid "Number of undo structures system wide" +msgstr "" + +#: sysdeps/names/sem_limits.c:48 sysdeps/names/sem_limits.c:62 +msgid "Max semaphores per array" +msgstr "" + +#: sysdeps/names/sem_limits.c:49 sysdeps/names/sem_limits.c:63 +msgid "Max ops per semop call" +msgstr "" + +#: sysdeps/names/sem_limits.c:50 sysdeps/names/sem_limits.c:64 +msgid "Max number of undo entries per process" +msgstr "" + +#: sysdeps/names/sem_limits.c:51 sysdeps/names/sem_limits.c:65 +msgid "sizeof struct sem_undo" +msgstr "" + +#: sysdeps/names/sem_limits.c:52 sysdeps/names/sem_limits.c:66 +msgid "Semaphore max value" +msgstr "" + +#: sysdeps/names/sem_limits.c:53 sysdeps/names/sem_limits.c:67 +msgid "Adjust on exit max value" +msgstr "" + +#: sysdeps/names/shm_limits.c:41 sysdeps/names/shm_limits.c:50 +msgid "Max segment size" +msgstr "" + +#: sysdeps/names/shm_limits.c:42 sysdeps/names/shm_limits.c:51 +msgid "Min segment size" +msgstr "" + +#: sysdeps/names/shm_limits.c:43 sysdeps/names/shm_limits.c:52 +msgid "Max number of segments" +msgstr "" + +#: sysdeps/names/shm_limits.c:44 sysdeps/names/shm_limits.c:53 +msgid "Max shared segments per process" +msgstr "" + +#: sysdeps/names/shm_limits.c:45 sysdeps/names/shm_limits.c:54 +msgid "Max total shared memory" +msgstr "" + +#: sysdeps/names/swap.c:41 sysdeps/names/swap.c:50 +msgid "Total Swap Space" +msgstr "" + +#: sysdeps/names/swap.c:42 sysdeps/names/swap.c:51 +msgid "Used Swap Space" +msgstr "" + +#: sysdeps/names/swap.c:43 sysdeps/names/swap.c:52 +msgid "Free Swap Space" +msgstr "" + +#: sysdeps/names/swap.c:44 +msgid "Page In" +msgstr "" + +#: sysdeps/names/swap.c:45 +msgid "Page Out" +msgstr "" + +#: sysdeps/names/swap.c:53 +msgid "Total number of swap pages that have been brought in since system boot" +msgstr "" + +#: sysdeps/names/swap.c:55 +msgid "Total number of swap pages that have been brought out since system boot" +msgstr "" + +#: sysdeps/names/sysdeps.c:51 sysdeps/names/sysdeps.c:78 +msgid "Server Features" +msgstr "" + +#: sysdeps/names/sysdeps.c:52 sysdeps/names/sysdeps.c:79 +msgid "CPU Usage" +msgstr "" + +#: sysdeps/names/sysdeps.c:53 sysdeps/names/sysdeps.c:80 +msgid "Memory Usage" +msgstr "" + +#: sysdeps/names/sysdeps.c:54 sysdeps/names/sysdeps.c:81 +msgid "Swap Usage" +msgstr "" + +#: sysdeps/names/sysdeps.c:55 sysdeps/names/sysdeps.c:82 +msgid "System Uptime" +msgstr "" + +#: sysdeps/names/sysdeps.c:56 sysdeps/names/sysdeps.c:83 +msgid "Load Averange" +msgstr "" + +#: sysdeps/names/sysdeps.c:57 sysdeps/names/sysdeps.c:84 +msgid "Shared Memory Limits" +msgstr "" + +#: sysdeps/names/sysdeps.c:58 sysdeps/names/sysdeps.c:85 +msgid "Message Queue Limits" +msgstr "" + +#: sysdeps/names/sysdeps.c:59 sysdeps/names/sysdeps.c:86 +msgid "Semaphore Set Limits" +msgstr "" + +#: sysdeps/names/sysdeps.c:60 sysdeps/names/sysdeps.c:87 +msgid "List of running Processes" +msgstr "" + +#: sysdeps/names/sysdeps.c:61 sysdeps/names/sysdeps.c:88 +msgid "Process Status information" +msgstr "" + +#: sysdeps/names/sysdeps.c:62 sysdeps/names/sysdeps.c:89 +msgid "Process UID and TTY information" +msgstr "" + +#: sysdeps/names/sysdeps.c:63 sysdeps/names/sysdeps.c:90 +msgid "Process Memory information" +msgstr "" + +#: sysdeps/names/sysdeps.c:64 sysdeps/names/sysdeps.c:91 +msgid "Process Time information" +msgstr "" + +#: sysdeps/names/sysdeps.c:65 sysdeps/names/sysdeps.c:92 +msgid "Process Signal information" +msgstr "" + +#: sysdeps/names/sysdeps.c:66 sysdeps/names/sysdeps.c:93 +msgid "Process Kernel Data information" +msgstr "" + +#: sysdeps/names/sysdeps.c:67 sysdeps/names/sysdeps.c:94 +msgid "Process Segment information" +msgstr "" + +#: sysdeps/names/sysdeps.c:68 +msgid "Process Arguments" +msgstr "" + +#: sysdeps/names/sysdeps.c:69 sysdeps/names/sysdeps.c:96 +msgid "Process Memory Map" +msgstr "" + +#: sysdeps/names/sysdeps.c:70 +msgid "Mount List" +msgstr "Mounttiluettelo" + +#: sysdeps/names/sysdeps.c:71 sysdeps/names/sysdeps.c:98 +msgid "File System Usage" +msgstr "Tiedostojärjestelmän käyttö" + +#: sysdeps/names/sysdeps.c:72 sysdeps/names/sysdeps.c:99 +msgid "Network Load" +msgstr "Verkon kuormitus" + +#: sysdeps/names/sysdeps.c:73 sysdeps/names/sysdeps.c:100 +msgid "PPP Statistics" +msgstr "PPP-tilastot" + +#: sysdeps/names/sysdeps.c:95 +msgid "Command line arguments of the process" +msgstr "Komentoriviparametrit prosessille" + +#: sysdeps/names/sysdeps.c:97 +msgid "List of currently mounted filesystems" +msgstr "Mountatut tiedostojärjestelmät" + +#: sysdeps/names/uptime.c:40 +msgid "Uptime" +msgstr "Pystyssä" + +#: sysdeps/names/uptime.c:41 +msgid "Idletime" +msgstr "Tuhlattu aika" + +#: sysdeps/names/uptime.c:42 +msgid "Boot time" +msgstr "Käynnistysaika" + +#: sysdeps/names/uptime.c:47 +msgid "Time in seconds since system boot" +msgstr "Aika käynnistyksestä sekunneissa" + +#: sysdeps/names/uptime.c:48 +msgid "Time in seconds the system spent in the idle task since system boot" +msgstr "Aika sekunneissa, jonka systeemi on tuhlannut käynnistyksen jälkeen" + +#: sysdeps/names/uptime.c:49 +msgid "Boot time (seconds sice epoch)" +msgstr "Koneen käynnistysaika (sekuntia epochin jälkeen)" + +#: support/error.c:109 +msgid "Unknown system error" +msgstr "Tuntematon systeemivirhe" + +#: support/getopt.c:669 +#, c-format +msgid "%s: option `%s' is ambiguous\n" +msgstr "" + +#: support/getopt.c:693 +#, c-format +msgid "%s: option `--%s' doesn't allow an argument\n" +msgstr "" + +#: support/getopt.c:698 +#, c-format +msgid "%s: option `%c%s' doesn't allow an argument\n" +msgstr "" + +#: support/getopt.c:715 support/getopt.c:888 +#, c-format +msgid "%s: option `%s' requires an argument\n" +msgstr "" + +#. --option +#: support/getopt.c:744 +#, c-format +msgid "%s: unrecognized option `--%s'\n" +msgstr "" + +#. +option or -option +#: support/getopt.c:748 +#, c-format +msgid "%s: unrecognized option `%c%s'\n" +msgstr "" + +#. 1003.2 specifies the format of this message. +#: support/getopt.c:774 +#, c-format +msgid "%s: illegal option -- %c\n" +msgstr "" + +#: support/getopt.c:777 +#, c-format +msgid "%s: invalid option -- %c\n" +msgstr "" + +#. 1003.2 specifies the format of this message. +#: support/getopt.c:807 support/getopt.c:937 +#, c-format +msgid "%s: option requires an argument -- %c\n" +msgstr "" + +#: support/getopt.c:854 +#, c-format +msgid "%s: option `-W %s' is ambiguous\n" +msgstr "" + +#: support/getopt.c:872 +#, c-format +msgid "%s: option `-W %s' doesn't allow an argument\n" +msgstr "" + +#: lib/read.c:71 +#, c-format +msgid "read %d bytes" +msgstr "" + +#: lib/read_data.c:49 +msgid "read data size" +msgstr "" + +#: lib/read_data.c:66 +#, c-format +msgid "read data %d bytes" +msgstr "" + +#: lib/write.c:48 +#, c-format +msgid "write %d bytes" +msgstr "" + +#: src/daemon/gnuserv.c:445 +msgid "Enable debugging" +msgstr "" + +#: src/daemon/gnuserv.c:445 +msgid "DEBUG" +msgstr "" + +#: src/daemon/gnuserv.c:447 +msgid "Enable verbose output" +msgstr "" + +#: src/daemon/gnuserv.c:447 +msgid "VERBOSE" +msgstr "" + +#: src/daemon/gnuserv.c:449 +msgid "Don't fork into background" +msgstr "Älä forkkaa taustalle" + +#: src/daemon/gnuserv.c:449 +msgid "NO-DAEMON" +msgstr "" + +#: src/daemon/gnuserv.c:451 +msgid "Invoked from inetd" +msgstr "Käynnistetty inetd-prosssista" + +#: src/daemon/gnuserv.c:451 +msgid "INETD" +msgstr "" + +#: src/daemon/gnuserv.c:485 +#, c-format +msgid "" +"Error on option %s: %s.\n" +"Run '%s --help' to see a full list of available command line options.\n" +msgstr "" +"Virhe valinnasta %s: %s.\n" +"Aja '%s --help' nähdäksesi luettelon komentorivivalinnoista.\n" diff --git a/po/fr.po b/po/fr.po index ce1feaa4..a71fd16f 100644 --- a/po/fr.po +++ b/po/fr.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: libgtop VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Vincent Renardias \n" "Language-Team: Vincent Renardias \n" diff --git a/po/ja.po b/po/ja.po index 1f157fba..d153bdb5 100644 --- a/po/ja.po +++ b/po/ja.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: libgtop VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: 1998-12-11 06:53+09:00\n" "Last-Translator: Eiichiro ITANI \n" "Language-Team: \n" diff --git a/po/ko.po b/po/ko.po index 96785c73..750c13b9 100644 --- a/po/ko.po +++ b/po/ko.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: libgtop VERSION\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: 1999-02-04 14:31:38+0900\n" "Last-Translator: Sung-Hyun Nam \n" "Language-Team: Korean \n" diff --git a/po/no.po b/po/no.po index 8c02da75..9166fc0e 100644 --- a/po/no.po +++ b/po/no.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: libgtop 0.99.3\n" -"POT-Creation-Date: 1999-02-27 22:24+0100\n" +"POT-Creation-Date: 1999-03-01 22:58+0100\n" "PO-Revision-Date: 1999-01-27 23:22+0100\n" "Last-Translator: Kjartan Maraas \n" "Language-Team: Norwegian \n" diff --git a/sysdeps/freebsd/ChangeLog b/sysdeps/freebsd/ChangeLog index 11fac2a7..05ef11c6 100644 --- a/sysdeps/freebsd/ChangeLog +++ b/sysdeps/freebsd/ChangeLog @@ -1,3 +1,30 @@ +Thu Apr 8 23:47:29 1999 Timur Bakeyev + + * cpu.c, mem.c, netload.c, procargs.c, procstate.c, proctime.c, + sem_limits.c, shm_limits.c, swap.c: Added initial port for BSD/OS + (aka BSDI) 2.x and 3.x. 4.x should also(?) work. + + Still, this port require more close look and extended check. + +1999-03-19 Martin Baulig + + Added basic support for BSDI. It compiles without problems on + BSDI 2.1 and 3.1, but it is *untested* - I'm neither root on + the machine nor have I access to /dev/kmem, so I don't know + whether it will work. + + You need to give configure the `--enable-hacker-mode' parameter + to use the code. + + If someone can verify whether it actually works, please let me + know. + +1999-03-18 Martin Baulig + + * ppp.c: Don't use `sppp.pp_phase' if we don't HAVE_I4B_ACCT. + This is an ugly hack until someone tells me which versions have + this field and which not. + 1999-02-25 Martin Baulig * prockernel.c, proctime.c: Applied patch Stanislav Grozev for diff --git a/sysdeps/freebsd/cpu.c b/sysdeps/freebsd/cpu.c index 647271f2..972b338a 100644 --- a/sysdeps/freebsd/cpu.c +++ b/sysdeps/freebsd/cpu.c @@ -34,7 +34,11 @@ static const unsigned long _glibtop_sysdeps_cpu = /* nlist structure for kernel access */ static struct nlist nlst [] = { +#ifdef __bsdi__ + { "_cpustats" }, +#else { "_cp_time" }, +#endif { 0 } }; diff --git a/sysdeps/freebsd/mem.c b/sysdeps/freebsd/mem.c index d76ee838..e8b774d8 100644 --- a/sysdeps/freebsd/mem.c +++ b/sysdeps/freebsd/mem.c @@ -33,7 +33,8 @@ static const unsigned long _glibtop_sysdeps_mem = (1 << GLIBTOP_MEM_TOTAL) + (1 << GLIBTOP_MEM_USED) + -(1 << GLIBTOP_MEM_FREE) + (1 << GLIBTOP_MEM_SHARED) + +(1 << GLIBTOP_MEM_FREE) + +(1 << GLIBTOP_MEM_SHARED) + (1 << GLIBTOP_MEM_BUFFER) + #ifdef __FreeBSD__ (1 << GLIBTOP_MEM_CACHED) + @@ -53,7 +54,9 @@ static int pageshift; /* log base 2 of the pagesize */ /* nlist structure for kernel access */ static struct nlist nlst [] = { { "_cnt" }, -#ifdef __FreeBSD__ +#if defined(__bsdi__) + { "_bufcachemem" }, +#elif defined(__FreeBSD__) { "_bufspace" }, #else { "_bufpages" }, @@ -62,8 +65,12 @@ static struct nlist nlst [] = { }; /* MIB array for sysctl */ -/* static int mib_length=2; */ +static int mib_length=2; +#ifdef __bsdi__ +static int mib [] = { CTL_VM, VM_TOTAL }; +#else static int mib [] = { CTL_VM, VM_METER }; +#endif /* Init function. */ @@ -135,7 +142,7 @@ glibtop_get_mem_p (glibtop *server, glibtop_mem *buf) /* convert memory stats to Kbytes */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) v_total_count = vmm.v_page_count; #else v_total_count = vmm.v_kernel_pages + diff --git a/sysdeps/freebsd/msg_limits.c b/sysdeps/freebsd/msg_limits.c index 4ab2eb5f..be4b9d9f 100644 --- a/sysdeps/freebsd/msg_limits.c +++ b/sysdeps/freebsd/msg_limits.c @@ -27,9 +27,26 @@ #include +#if (defined __bsdi__) && (_BSDI_VERSION < 199700) +/* Older versions of BSDI don't seem to have this. */ + +void +glibtop_init_msg_limits_p (glibtop *server) +{ } + +void +glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf) +{ + glibtop_init_p (server, (1 << GLIBTOP_SYSDEPS_MSG_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_msg_limits)); +} + +#else + /* #define KERNEL to get declaration of `struct msginfo'. */ -#ifdef __FreeBSD__ +#if (defined __FreeBSD__) || (defined __bsdi__) #define KERNEL 1 #else #define _KERNEL 1 @@ -93,3 +110,6 @@ glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf) buf->flags = _glibtop_sysdeps_msg_limits; } + +#endif /* either a newer BSDI or no BSDI at all. */ + diff --git a/sysdeps/freebsd/netload.c b/sysdeps/freebsd/netload.c index 882b9152..30821048 100644 --- a/sysdeps/freebsd/netload.c +++ b/sysdeps/freebsd/netload.c @@ -107,7 +107,7 @@ glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, sizeof (ifnet)) != sizeof (ifnet)) glibtop_error_io_r (server, "kvm_read (ifnetaddr)"); -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) if (kvm_read (server->machine.kd, (u_long) ifnet.if_name, tname, 16) != 16) glibtop_error_io_r (server, "kvm_read (if_name)"); @@ -116,9 +116,9 @@ glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, tname [15] = 0; #endif -#if (defined __FreeBSD__) && (__FreeBSD_version >= 300000) +#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) ifaddraddr = (u_long) ifnet.if_addrhead.tqh_first; -#elif (defined __FreeBSD__) +#elif defined(__FreeBSD__) || defined(__bsdi__) ifaddraddr = (u_long) ifnet.if_addrlist; #else ifaddraddr = (u_long) ifnet.if_addrlist.tqh_first; @@ -194,18 +194,18 @@ glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, return; } -#if (defined __FreeBSD__) && (__FreeBSD_version >= 300000) +#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) ifaddraddr = (u_long)ifaddr.ifa.ifa_link.tqe_next; -#elif (defined __FreeBSD__) +#elif defined(__FreeBSD__) || defined(__bsdi__) ifaddraddr = (u_long)ifaddr.ifa.ifa_next; #else ifaddraddr = (u_long)ifaddr.ifa.ifa_list.tqe_next; #endif } -#if (defined __FreeBSD__) && (__FreeBSD_version >= 300000) +#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) ifnetaddr = (u_long) ifnet.if_link.tqe_next; -#elif (defined __FreeBSD__) +#elif defined(__FreeBSD__) || defined(__bsdi__) ifnetaddr = (u_long) ifnet.if_next; #else ifnetaddr = (u_long) ifnet.if_list.tqe_next; diff --git a/sysdeps/freebsd/ppp.c b/sysdeps/freebsd/ppp.c index 895a6bbc..093148a1 100644 --- a/sysdeps/freebsd/ppp.c +++ b/sysdeps/freebsd/ppp.c @@ -110,10 +110,15 @@ glibtop_get_ppp_p (glibtop *server, glibtop_ppp *buf, unsigned short device) #ifdef HAVE_I4B_ACCT phase = data.sc_if_un.scu_sp.pp_phase; #else + /* FIXME: Which FreeBSD version have this field and + * which not. */ +#if 0 phase = data.pp_phase; +#endif #endif switch (phase) { +#ifdef HAVE_I4B_ACCT case PHASE_DEAD: case PHASE_TERMINATE: buf->state = GLIBTOP_PPP_STATE_HANGUP; @@ -122,6 +127,7 @@ glibtop_get_ppp_p (glibtop *server, glibtop_ppp *buf, unsigned short device) case PHASE_NETWORK: buf->state = GLIBTOP_PPP_STATE_ONLINE; break; +#endif default: buf->state = GLIBTOP_PPP_STATE_UNKNOWN; break; diff --git a/sysdeps/freebsd/procargs.c b/sysdeps/freebsd/procargs.c index c6d0c1b5..84a0a619 100644 --- a/sysdeps/freebsd/procargs.c +++ b/sysdeps/freebsd/procargs.c @@ -54,8 +54,10 @@ glibtop_get_proc_args_p (glibtop *server, glibtop_proc_args *buf, unsigned size = 0, pos = 0; int count; +#ifndef __bsdi__ char filename [BUFSIZ]; struct stat statb; +#endif glibtop_init_p (server, (1 << GLIBTOP_SYSDEPS_PROC_ARGS), 0); @@ -64,8 +66,10 @@ glibtop_get_proc_args_p (glibtop *server, glibtop_proc_args *buf, /* swapper, init, pagedaemon, vmdaemon, update - this doen't work. */ if (pid < 5) return NULL; +#ifndef __bsdi__ sprintf (filename, "/proc/%d/mem", pid); if (stat (filename, &statb)) return NULL; +#endif glibtop_suid_enter (server); diff --git a/sysdeps/freebsd/prockernel.c b/sysdeps/freebsd/prockernel.c index e8654783..b1dc4c76 100644 --- a/sysdeps/freebsd/prockernel.c +++ b/sysdeps/freebsd/prockernel.c @@ -31,10 +31,12 @@ #include #include #include -#ifndef __OpenBSD__ +#if (!defined __OpenBSD__) && (!defined __bsdi__) #include #endif +#ifndef __bsdi__ #include +#endif #ifdef __FreeBSD__ #include #endif @@ -122,7 +124,7 @@ glibtop_get_proc_kernel_p (glibtop *server, /* NOTE: You need to mount the /proc filesystem to make * `kvm_uread' work. */ - sprintf (filename, "/proc/%d/mem", pid); + sprintf (filename, "/proc/%d/mem", (int) pid); if (stat (filename, &statb)) return; glibtop_suid_enter (server); @@ -162,7 +164,11 @@ glibtop_get_proc_kernel_p (glibtop *server, #endif #else buf->kstk_esp = (u_int64_t) pcb.pcb_tss.tss_esp0; +#ifdef __bsdi__ + buf->kstk_eip = (u_int64_t) pcb.pcb_tss.tss_eip; +#else buf->kstk_eip = (u_int64_t) pcb.pcb_tss.__tss_eip; +#endif buf->flags |= _glibtop_sysdeps_proc_kernel_pcb; #endif diff --git a/sysdeps/freebsd/procmap.c b/sysdeps/freebsd/procmap.c index 41bba26e..e4944e4d 100644 --- a/sysdeps/freebsd/procmap.c +++ b/sysdeps/freebsd/procmap.c @@ -42,7 +42,7 @@ #include #include -#ifndef __OpenBSD__ +#if (!defined __OpenBSD__) && (!defined __bsdi__) #include #endif #include diff --git a/sysdeps/freebsd/procmem.c b/sysdeps/freebsd/procmem.c index 67944fc4..42140a7d 100644 --- a/sysdeps/freebsd/procmem.c +++ b/sysdeps/freebsd/procmem.c @@ -39,7 +39,7 @@ #include #include -#ifndef __OpenBSD__ +#if (!defined __OpenBSD__) && (!defined __bsdi__) #include #endif #include diff --git a/sysdeps/freebsd/procstate.c b/sysdeps/freebsd/procstate.c index e60d05b9..e1a2476d 100644 --- a/sysdeps/freebsd/procstate.c +++ b/sysdeps/freebsd/procstate.c @@ -27,13 +27,14 @@ #include -#ifndef __OpenBSD__ +#if !defined(__OpenBSD__) +//&& (!defined __bsdi__) #include #endif 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_UID) + +(1 << GLIBTOP_PROC_STATE_GID); /* Init function. */ @@ -73,27 +74,28 @@ glibtop_get_proc_state_p (glibtop *server, buf->uid = pinfo [0].kp_eproc.e_pcred.p_svuid; buf->gid = pinfo [0].kp_eproc.e_pcred.p_svgid; - switch (pinfo [0].kp_proc.p_stat) { - case SIDL: - buf->state = 'I'; - break; - case SRUN: - buf->state = 'R'; - break; - case SSLEEP: - buf->state = 'S'; - break; - case SSTOP: - buf->state = 'T'; - break; - case SZOMB: - buf->state = 'Z'; - break; - default: - buf->state = '?'; - break; - } - /* Set the flags for the data we're about to return*/ buf->flags = _glibtop_sysdeps_proc_state; + + switch (pinfo [0].kp_proc.p_stat) { + case SIDL: + buf->state = 0; + break; + case SRUN: + buf->state = GLIBTOP_PROCESS_RUNNING; + break; + case SSLEEP: + buf->state = GLIBTOP_PROCESS_INTERRUPTIBLE; + break; + case SSTOP: + buf->state = GLIBTOP_PROCESS_STOPPED; + break; + case SZOMB: + buf->state = GLIBTOP_PROCESS_ZOMBIE; + break; + default: + return; + } + + buf->flags |= (1 << GLIBTOP_PROC_STATE_STATE); } diff --git a/sysdeps/freebsd/proctime.c b/sysdeps/freebsd/proctime.c index bf6c38a0..0f4384b9 100644 --- a/sysdeps/freebsd/proctime.c +++ b/sysdeps/freebsd/proctime.c @@ -140,8 +140,10 @@ glibtop_get_proc_time_p (glibtop *server, glibtop_proc_time *buf, /* It does not work for the swapper task. */ if (pid == 0) return; - sprintf (filename, "/proc/%d/mem", pid); +#ifndef __bsdi__ + sprintf (filename, "/proc/%d/mem", (int) pid); if (stat (filename, &statb)) return; +#endif /* Get the process information */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); diff --git a/sysdeps/freebsd/sem_limits.c b/sysdeps/freebsd/sem_limits.c index 61eeda64..a52b82f9 100644 --- a/sysdeps/freebsd/sem_limits.c +++ b/sysdeps/freebsd/sem_limits.c @@ -27,9 +27,26 @@ #include +#if defined(__bsdi__) && (_BSDI_VERSION < 199700) +/* Older versions of BSDI don't seem to have this. */ + +void +glibtop_init_sem_limits_p (glibtop *server) +{ } + +void +glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf) +{ + glibtop_init_p (server, (1 << GLIBTOP_SYSDEPS_SEM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_sem_limits)); +} + +#else + /* #define KERNEL to get declaration of `struct seminfo'. */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) #define KERNEL 1 #else #define _KERNEL 1 @@ -98,3 +115,6 @@ glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf) buf->flags = _glibtop_sysdeps_sem_limits; } + +#endif /* either a newer BSDI or no BSDI at all. */ + diff --git a/sysdeps/freebsd/shm_limits.c b/sysdeps/freebsd/shm_limits.c index bab0d85f..0d049549 100644 --- a/sysdeps/freebsd/shm_limits.c +++ b/sysdeps/freebsd/shm_limits.c @@ -27,9 +27,26 @@ #include +#if defined(__bsdi__) && (_BSDI_VERSION < 199700) +/* Older versions of BSDI don't seem to have this. */ + +void +glibtop_init_shm_limits_p (glibtop *server) +{ } + +void +glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) +{ + glibtop_init_p (server, (1 << GLIBTOP_SYSDEPS_SHM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_shm_limits)); +} + +#else + /* #define KERNEL to get declaration of `struct shminfo'. */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) #define KERNEL 1 #else #define _KERNEL 1 @@ -93,3 +110,6 @@ glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) buf->flags = _glibtop_sysdeps_shm_limits; } + +#endif /* either a newer BSDI or no BSDI at all. */ + diff --git a/sysdeps/freebsd/swap.c b/sysdeps/freebsd/swap.c index 1b0f2ad2..b6980b3e 100644 --- a/sysdeps/freebsd/swap.c +++ b/sysdeps/freebsd/swap.c @@ -34,15 +34,24 @@ static const unsigned long _glibtop_sysdeps_swap = (1 << GLIBTOP_SWAP_FREE) + (1 << GLIBTOP_SWAP_PAGEIN) + (1 << GLIBTOP_SWAP_PAGEOUT); -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) #include +#ifdef __bsdi__ +#include +#else #include +#endif #include -#if __FreeBSD__ < 4 - /* nlist structure for kernel access */ + +#if defined(__bsdi__) +static struct nlist nlst [] = { + { "_swapstats" }, /* general swap info */ + { 0 } +}; +#elif __FreeBSD__ < 4 static struct nlist nlst [] = { #define VM_SWAPLIST 0 { "_swaplist" },/* list of free swap areas */ @@ -56,10 +65,9 @@ static struct nlist nlst [] = { { "_dmmax" }, /* maximum size of a swap block */ { 0 } }; - #endif -#elif (defined __NetBSD__) +#elif defined(__NetBSD__) #include @@ -76,8 +84,8 @@ static struct nlist nlst2 [] = { void glibtop_init_swap_p (glibtop *server) { -#ifdef __FreeBSD__ -#if __FreeBSD__ < 4 +#if defined(__FreeBSD__) || defined(__bsdi__) +#if __FreeBSD__ < 4 || defined(__bsdi__) if (kvm_nlist (server->machine.kd, nlst) != 0) { glibtop_warn_io_r (server, "kvm_nlist (swap)"); return; @@ -86,14 +94,14 @@ glibtop_init_swap_p (glibtop *server) struct kvm_swap dummy; if (kvm_getswapinfo (server->machine.kd, &dummy, 1, 0) != 0) { - glibtop_warn_io_r (server, "kvm_nlist (swap)"); + glibtop_warn_io_r (server, "kvm_swap (swap)"); return; } #endif #endif if (kvm_nlist (server->machine.kd, nlst2) != 0) { - glibtop_warn_io_r (server, "kvm_nlist (swap)"); + glibtop_warn_io_r (server, "kvm_nlist (cnt)"); return; } @@ -110,8 +118,9 @@ glibtop_init_swap_p (glibtop *server) void glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) { -#ifdef __FreeBSD__ -#if __FreeBSD__ < 4 +#if defined(__FreeBSD__) + +# if __FreeBSD__ < 4 char *header; int hlen, nswdev, dmmax; int div, nfree, npfree; @@ -122,11 +131,14 @@ glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) struct rlist *swapptr; size_t sw_size; u_long ptr; -#else +# else int nswdev; struct kvm_swap kvmsw[16]; -#endif -#elif (defined __NetBSD__) +# endif + +#elif defined(__bsdi__) + struct swapstats swap; +#elif defined(__NetBSD__) struct swapent *swaplist; #endif @@ -174,7 +186,7 @@ glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) swappgsout = vmm.v_swpout; #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) #if __FreeBSD__ < 4 @@ -214,7 +226,7 @@ glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) if (kvm_read (server->machine.kd, nlst[VM_SWDEVT].n_value, &ptr, sizeof (ptr)) != sizeof (ptr)) { - glibtop_warn_io_r (server, "kvm_read (swaplist)"); + glibtop_warn_io_r (server, "kvm_read (swdevt)"); return; } @@ -328,7 +340,24 @@ glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) #endif -#elif (defined __NetBSD__) +#elif defined(__bsdi__) + + /* General info about swap devices. */ + + if (kvm_read (server->machine.kd, nlst[0].n_value, + &swap, sizeof (swap)) != sizeof (swap)) { + glibtop_warn_io_r (server, "kvm_read (swap)"); + return; + } + + buf->flags = _glibtop_sysdeps_swap; + + buf->used = swap.swap_total - swap.swap_free; + buf->free = swap.swap_free; + + buf->total = swap.swap_total; + +#elif defined(__NetBSD__) nswap = swapctl (SWAP_NSWAP, NULL, 0); if (nswap < 0) { diff --git a/sysdeps/kernel/glibtop_private.h b/sysdeps/kernel/glibtop_private.h new file mode 100644 index 00000000..0396d864 --- /dev/null +++ b/sysdeps/kernel/glibtop_private.h @@ -0,0 +1,89 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , March 1999. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_PRIVATE_H__ +#define __GLIBTOP_PRIVATE_H__ + +#include +#include + +#include +#include +#include + +#undef LIBGTOP_VERSION +#include + +BEGIN_LIBGTOP_DECLS + +int +glibtop_get_proc_data_stat_s (glibtop *server, libgtop_stat_t *stat); + +int +glibtop_get_proc_data_mem_s (glibtop *server, libgtop_mem_t *mem); + +int +glibtop_get_proc_data_swap_s (glibtop *server, libgtop_swap_t *swap); + +int +glibtop_get_proc_data_proclist_s (glibtop *server, + libgtop_proclist_t *proclist, + u_int64_t which, u_int64_t arg); + +int +glibtop_get_proc_data_proc_state_s (glibtop *server, + libgtop_proc_state_t *proc_state, + pid_t pid); + +int +glibtop_get_proc_data_proc_mem_s (glibtop *server, + libgtop_proc_mem_t *proc_mem, + pid_t pid); + +int +glibtop_get_proc_data_proc_signal_s (glibtop *server, + libgtop_proc_signal_t *proc_signal, + pid_t pid); + +int +glibtop_get_proc_data_proc_kernel_s (glibtop *server, + libgtop_proc_kernel_t *proc_kernel, + pid_t pid); + +int +glibtop_get_proc_data_proc_args_s (glibtop *server, pid_t pid, + char *result, size_t max_len); + +int +glibtop_get_proc_data_proc_maps_s (glibtop *server, pid_t pid, + libgtop_proc_maps_t *result, + size_t max_len); + +int +glibtop_get_proc_data_netload_s (glibtop *server, + libgtop_netload_t *netload, + const char *device); + +END_LIBGTOP_DECLS + +#endif __GLIBTOP_PRIVATE_H__ diff --git a/sysdeps/kernel/sysinfo.c b/sysdeps/kernel/sysinfo.c new file mode 100644 index 00000000..49f374c4 --- /dev/null +++ b/sysdeps/kernel/sysinfo.c @@ -0,0 +1,94 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +static const unsigned long _glibtop_sysdeps_sysinfo = +(1 << GLIBTOP_SYSINFO_CPUINFO); + +static glibtop_sysinfo sysinfo; + +static void +init_sysinfo (glibtop *server) +{ + char buffer [BUFSIZ]; + static int init = 0; + glibtop_entry *cpuinfo = NULL; + FILE *f; + + if (init) return; + + init = TRUE; + + glibtop_init_s (&server, GLIBTOP_SYSDEPS_CPU, 0); + + memset (&sysinfo, 0, sizeof (glibtop_sysinfo)); + + g_return_if_fail (f = fopen ("/proc/cpuinfo", "r")); + + while (fgets (buffer, BUFSIZ, f)) { + char *p, *start, *key, *value; + + if (cpuinfo == NULL) { + cpuinfo = &sysinfo.cpuinfo [sysinfo.ncpu++]; + + cpuinfo->labels = g_ptr_array_new (); + + cpuinfo->values = g_hash_table_new (NULL, NULL); + + if (sysinfo.ncpu > GLIBTOP_NCPU) + sysinfo.ncpu = GLIBTOP_NCPU; + } + + p = strchr (buffer, ':'); + if (!p) continue; + + /* Remove leading spaces from `p'. */ + *p = '\0'; start = p; p++; + while (isspace (*p)) p++; + + /* Remove trailing spaces from `buffer'. */ + while ((start > buffer) && (*start) && isspace (*start)) + *start-- = '\0'; + + key = g_strdup (buffer); + value = g_strdup (p); + + g_ptr_array_add (cpuinfo->labels, key); + + g_hash_table_insert (cpuinfo->values, key, value); + } + + fclose (f); + + sysinfo.flags = _glibtop_sysdeps_sysinfo; +} + +glibtop_sysinfo * +glibtop_get_sysinfo_s (glibtop *server) +{ + init_sysinfo (server); + return &sysinfo; +} diff --git a/sysdeps/linux/sysinfo.c b/sysdeps/linux/sysinfo.c index 7112bd3e..49f374c4 100644 --- a/sysdeps/linux/sysinfo.c +++ b/sysdeps/linux/sysinfo.c @@ -64,11 +64,13 @@ init_sysinfo (glibtop *server) p = strchr (buffer, ':'); if (!p) continue; - + + /* Remove leading spaces from `p'. */ *p = '\0'; start = p; p++; while (isspace (*p)) p++; - while ((start > buffer) && isspace (*start)) + /* Remove trailing spaces from `buffer'. */ + while ((start > buffer) && (*start) && isspace (*start)) *start-- = '\0'; key = g_strdup (buffer); diff --git a/sysdeps/solaris/.cvsignore b/sysdeps/solaris/.cvsignore new file mode 100644 index 00000000..635816db --- /dev/null +++ b/sysdeps/solaris/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +libgtop_sysdeps.la +*.lo diff --git a/sysdeps/solaris/ChangeLog b/sysdeps/solaris/ChangeLog new file mode 100644 index 00000000..fb05754c --- /dev/null +++ b/sysdeps/solaris/ChangeLog @@ -0,0 +1,144 @@ +1999-05-03 Drazen Kacar + + * glibtop_private.h: Fixed typoo. + + * procmap.c (glibtop_get_proc_map_s): Implemented start, end, + offset and perm for mapped segments. File name and inode + should be accessible from bunyip kstat data. The only + obstacle is that the data format is undocumented and + possibly not the same accross releases. + +1999-05-03 Drazen Kacar + + * glibtop_private.h, procdata.c (glibtop_get_proc_status_s): + Read pstatus info from /proc + + * procsignal.c (glibtop_get_proc_signal_s): Implemented + set of pending and blocked signals. The rest should probably + be read from /proc//sigact, but I'm not sure it's + worth implementing before thread API comes into place. + + * siglist.c: Added Solaris 7 signals. Someone will gettextize + it eventually. Besides, signal list should become a pointer + instead of being fixed field. We need some run time initializations. + The code is written, but commented out. + +1999-05-03 Drazen Kacar + + * glibtop_private.h: Ups, forgot to put prototypes in. + +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 + boot time. These are constants. Also added three new kstats. + + * open.c (glibtop_get_kstats): Initialize kstats in *server. + We need to call this at init time (obviously) and each time + kstat_chain_update() says that kstat chain has changed. In this + case all kstat pointers and data are invalid, so we need to + reinitialize everything. + + (glibtop_open_s): Made it call glibtop_get_kstats(). Added + initialization for run time constants in struct machine. + + * cpu.c (glibtop_get_cpu_s): Call kstat_chain_update(). + See if processor is on-line and set bits in xcpu_flags. + Added frequency (bad name, should have been ticks). + + * swap.c (glibtop_get_swap_s): Call kstat_chain_update(). + I probably broke vminfo_snaptime consistency. Fix later. + + * uptime.c (glibtop_get_uptime_s): Implemented uptime and boot_time. + Still looking for a sane way to get idletime. + + * mem.c (glibtop_get_mem_s): Implemented. Will use bunyip + module if it's loaded. Or when it gets loaded. kstat_chain_update() + is our friend. And with a friends like that... + + * loadavg.c (glibtop_get_loadavg_s): Solaris 2.6 code brought + into sync with everything else. + + * msg_limits.c (glibtop_init_msg_limits_s): Implemented. + + * sem_limits.c (glibtop_get_sem_limits_s): Implemented. + + Solaris takes kernel modularity too seriously. We can't get + IPC configuration data if the kernel module is not loaded and + it won't be loaded until some process actually asks for a + particular IPC resource. There's no way to tell our applications + about this. Possible API additions? + + All three IPC functions should go into daemon, but I'm keeping + them in the normal library because I can't build daemon yet. All + praise 64 bits! + +1999-04-29 Drazen Kacar + + * glibtop_machine.h: added field for kvm descriptor. + + * open.c: added code for opening kernel name space. + + * shm_limits.c: implemented. + +1999-03-31 Drazen Kacar + + * loadavg.c: make it work with Solaris 2.6 and older. A part + of it should be moved to open.c. + +1999-03-19 Martin Baulig + + Added first kstat based implementation for Solaris 7. + + * open.c (glibtop_open_s): Walk kstat list and save interesting + kstats in the `server->machine'. + + * cpu.c: This can already provide `idle', `user' and `sys' with + full SMP support. + + * swap.c: This can already provide `total', `used' and `free'. + +1999-03-17 Martin Baulig + + Initial import of my Solaris 7 port. + + * loadavg.c: We use getloadavg () to get the `loadavg' field. + + * procdata.c: This file will handle all interaction with the + /proc filesystem. + (glibtop_get_proc_data_psinfo_s): Read `/proc//psinfo' and + return the resulting `struct psinfo'. + (glibtop_get_proc_data_usage_s): Read `/proc//usage' and + return the resulting `struct prusage'. + + * proclist.c: We use readdir () on /proc to get the list of + all pids. + + * procstate.c: Read `uid' and `gid' from the `struct psinfo'. + + * proctime.c: Read `start_time', `rtime', `utime' and `stime' + from the `struct prusage'. + + * procuid.c: Read `euid', `uid', `egid', `gid', `pid', `ppid', + `pgrp', `session' and `tty' from the `struct psinfo'. + diff --git a/sysdeps/solaris/Makefile.am b/sysdeps/solaris/Makefile.am new file mode 100644 index 00000000..ef7846b0 --- /dev/null +++ b/sysdeps/solaris/Makefile.am @@ -0,0 +1,18 @@ +LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@ + +INCLUDES = @INCLUDES@ + +lib_LTLIBRARIES = libgtop_sysdeps.la + +libgtop_sysdeps_la_SOURCES = open.c close.c siglist.c cpu.c mem.c swap.c \ + uptime.c loadavg.c shm_limits.c msg_limits.c \ + sem_limits.c proclist.c procstate.c procuid.c \ + proctime.c procmem.c procsignal.c prockernel.c \ + procsegment.c procargs.c procmap.c netload.c \ + ppp.c procdata.c + +libgtop_sysdeps_la_LDFLAGS = $(LT_VERSION_INFO) + +include_HEADERS = glibtop_server.h glibtop_machine.h +noinst_HEADERS = glibtop_private.h + diff --git a/sysdeps/solaris/close.c b/sysdeps/solaris/close.c new file mode 100644 index 00000000..4262d2f0 --- /dev/null +++ b/sysdeps/solaris/close.c @@ -0,0 +1,30 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +/* Closes pipe to gtop server. */ + +void +glibtop_close_s (glibtop *server) +{ } diff --git a/sysdeps/solaris/cpu.c b/sysdeps/solaris/cpu.c new file mode 100644 index 00000000..5b34e3b9 --- /dev/null +++ b/sysdeps/solaris/cpu.c @@ -0,0 +1,106 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +#include +#include + +#include + +static const unsigned long _glibtop_sysdeps_cpu = +(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) + +(1L << GLIBTOP_CPU_FREQUENCY) + (1L << GLIBTOP_XCPU_FLAGS); + +/* Init function. */ + +void +glibtop_init_cpu_s (glibtop *server) +{ + server->sysdeps.cpu = _glibtop_sysdeps_cpu; +} + +/* Provides information about cpu usage. */ + +void +glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf) +{ + kstat_ctl_t *kc = server->machine.kc; + cpu_stat_t cpu_stat; + processorid_t cpu; + int ncpu, found; + kid_t ret; + + memset (buf, 0, sizeof (glibtop_cpu)); + + if(!kc) + return; + switch(kstat_chain_update(kc)) + { + 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; + + for (cpu = 0, found = 0; cpu < GLIBTOP_NCPU && found != ncpu; cpu++) + { + kstat_t *ksp = server->machine.cpu_stat_kstat [cpu]; + if (!ksp) continue; + + ++found; + if(p_online(cpu, P_STATUS) == P_ONLINE) + buf->xcpu_flags |= (1L << cpu); + else + continue; + ret = kstat_read (kc, ksp, &cpu_stat); + + if (ret == -1) { + glibtop_warn_io_r (server, "kstat_read (cpu_stat%d)", cpu); + continue; + } + + 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]; + + buf->idle += cpu_stat.cpu_sysinfo.cpu [CPU_IDLE]; + buf->user += cpu_stat.cpu_sysinfo.cpu [CPU_USER]; + buf->sys += cpu_stat.cpu_sysinfo.cpu [CPU_KERNEL]; + } + + buf->total = buf->idle + buf->user + buf->sys; + buf->frequency = server->machine.ticks; + + buf->flags = _glibtop_sysdeps_cpu; +} diff --git a/sysdeps/solaris/glibtop_machine.h b/sysdeps/solaris/glibtop_machine.h new file mode 100644 index 00000000..2d77471b --- /dev/null +++ b/sysdeps/solaris/glibtop_machine.h @@ -0,0 +1,65 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , March 1999. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_MACHINE_H__ +#define __GLIBTOP_MACHINE_H__ + +#include +#include +#include + +#include +#include +#include + +BEGIN_LIBGTOP_DECLS + +typedef struct _glibtop_machine glibtop_machine; + +struct _glibtop_machine +{ + uid_t uid, euid; + gid_t gid, egid; + + kvm_t *kd; + + kstat_ctl_t *kc; + + kstat_t *vminfo_kstat; + hrtime_t vminfo_snaptime; + vminfo_t vminfo; + + kstat_t *cpu_stat_kstat [64]; + + kstat_t *system; /* boot_time & avenrun* where needed */ + kstat_t *syspages; /* memory usage */ + kstat_t *bunyip; /* more memory usage */ + + int pagesize; /* in kilobytes */ + int ticks; /* clock ticks, as returned by sysconf(_SC_CLK_TCK) */ + unsigned boot; /* boot time, it's ui32 in kstat */ +}; + +END_LIBGTOP_DECLS + +#endif __GLIBTOP_MACHINE_H__ diff --git a/sysdeps/solaris/glibtop_private.h b/sysdeps/solaris/glibtop_private.h new file mode 100644 index 00000000..d765c35a --- /dev/null +++ b/sysdeps/solaris/glibtop_private.h @@ -0,0 +1,54 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , March 1999. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_PRIVATE_H__ +#define __GLIBTOP_PRIVATE_H__ + +#include +#include + +#include +#include +#include +#include + +BEGIN_LIBGTOP_DECLS + +/* Read /proc//psinfo */ +int glibtop_get_proc_data_psinfo_s (glibtop *server, struct psinfo *psinfo, pid_t pid); + +/* Read /proc//usage */ +int glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t pid); + +/* Read /proc//cred */ +int glibtop_get_proc_credentials_s(glibtop *, struct prcred *, pid_t); + +/* Read /proc//status */ +int glibtop_get_proc_status_s(glibtop *, struct pstatus *, pid_t); + +/* Reread kstat chains */ +void glibtop_get_kstats(glibtop *); + +END_LIBGTOP_DECLS + +#endif __GLIBTOP_PRIVATE_H__ diff --git a/sysdeps/solaris/glibtop_server.h b/sysdeps/solaris/glibtop_server.h new file mode 100644 index 00000000..b3822d47 --- /dev/null +++ b/sysdeps/solaris/glibtop_server.h @@ -0,0 +1,52 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_SERVER_H__ +#define __GLIBTOP_SERVER_H__ + +BEGIN_LIBGTOP_DECLS + +#define GLIBTOP_SUID_CPU 0 +#define GLIBTOP_SUID_MEM 0 +#define GLIBTOP_SUID_SWAP 0 +#define GLIBTOP_SUID_UPTIME 0 +#define GLIBTOP_SUID_LOADAVG 0 +#define GLIBTOP_SUID_SHM_LIMITS 0 +#define GLIBTOP_SUID_MSG_LIMITS 0 +#define GLIBTOP_SUID_SEM_LIMITS 0 +#define GLIBTOP_SUID_PROCLIST 0 +#define GLIBTOP_SUID_PROC_STATE 0 +#define GLIBTOP_SUID_PROC_UID 0 +#define GLIBTOP_SUID_PROC_MEM 0 +#define GLIBTOP_SUID_PROC_TIME 0 +#define GLIBTOP_SUID_PROC_SIGNAL 0 +#define GLIBTOP_SUID_PROC_KERNEL 0 +#define GLIBTOP_SUID_PROC_SEGMENT 0 +#define GLIBTOP_SUID_PROC_ARGS 0 +#define GLIBTOP_SUID_PROC_MAP 0 +#define GLIBTOP_SUID_NETLOAD 0 +#define GLIBTOP_SUID_PPP 0 + +END_LIBGTOP_DECLS + +#endif diff --git a/sysdeps/solaris/loadavg.c b/sysdeps/solaris/loadavg.c new file mode 100644 index 00000000..9f4d4a37 --- /dev/null +++ b/sysdeps/solaris/loadavg.c @@ -0,0 +1,87 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , March 1999. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#ifdef HAVE_GETLOADAVG +#include +#else +#include +#include +#include +#endif + +static const unsigned long _glibtop_sysdeps_loadavg = +(1L << GLIBTOP_LOADAVG_LOADAVG); + +/* Init function. */ + +void +glibtop_init_loadavg_s (glibtop *server) +{ + server->sysdeps.loadavg = _glibtop_sysdeps_loadavg; +} + +/* Provides load average. */ + +void +glibtop_get_loadavg_s (glibtop *server, glibtop_loadavg *buf) +{ +#ifndef HAVE_GETLOADAVG + kstat_ctl_t *kc; + kstat_t *ksp; + int i; + static char *avestrings[] = { "avenrun_1min", + "avenrun_5min", + "avenrun_15min" }; +#endif + memset (buf, 0, sizeof (glibtop_loadavg)); + +#ifdef HAVE_GETLOADAVG + if (getloadavg (buf->loadavg, 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; + + kn = (kstat_named_t *)kstat_data_lookup(ksp, avestrings[i]); + if(kn) + buf->loadavg[i] = (double)kn->value.ul / FSCALE; + } +#endif + buf->flags = _glibtop_sysdeps_loadavg; +} diff --git a/sysdeps/solaris/mem.c b/sysdeps/solaris/mem.c new file mode 100644 index 00000000..ac21f0cb --- /dev/null +++ b/sysdeps/solaris/mem.c @@ -0,0 +1,123 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include +#include + +#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; +} + +/* Provides information about memory usage. */ + +void +glibtop_get_mem_s (glibtop *server, glibtop_mem *buf) +{ + kstat_ctl_t *kc = server->machine.kc; + kstat_t *ksp; + kstat_named_t *kn; + int pagesize = server->machine.pagesize; + + memset (buf, 0, sizeof (glibtop_mem)); + + buf->total = (u_int64_t)sysconf(_SC_PHYS_PAGES) * pagesize; + buf->flags = _glibtop_sysdeps_mem_os_sysconf; + + if(!kc) + return; + switch(kstat_chain_update(kc)) + { + 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"); + if(kn) + { +#ifdef _LP64 + buf->free = kn->value.ui64 * pagesize; +#else + buf->free = kn->value.ui32 * pagesize; +#endif + buf->used = buf->total - buf->free; + } + kn = (kstat_named_t *)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; + } + + /* 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"); + if(kn) +#ifdef _LP64 + buf->user = kn->value.ui64 * pagesize; +#else + buf->user = kn->value.ui32 * pagesize; +#endif + kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_exec"); + if(kn) +#ifdef _LP64 + buf->shared = kn->value.ui64 * pagesize; +#else + buf->shared = kn->value.ui32 * pagesize; +#endif + kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_vnode"); + if(kn) +#ifdef _LP64 + buf->buffer = kn->value.ui64 * pagesize; +#else + buf->buffer = kn->value.ui32 * pagesize; +#endif + buf->flags += _glibtop_sysdeps_mem_bunyip; + } +} diff --git a/sysdeps/solaris/msg_limits.c b/sysdeps/solaris/msg_limits.c new file mode 100644 index 00000000..2e4db207 --- /dev/null +++ b/sysdeps/solaris/msg_limits.c @@ -0,0 +1,74 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include +#include + +static struct nlist nlst[] = { {"msginfo"}, {NULL} }; +static const unsigned long _glibtop_sysdeps_msg_limits = +(1L << GLIBTOP_IPC_MSGPOOL) + (1L << GLIBTOP_IPC_MSGMAP) + +(1L << GLIBTOP_IPC_MSGMAX) + (1L << GLIBTOP_IPC_MSGMNB) + +(1L << GLIBTOP_IPC_MSGMNI) + (1L << GLIBTOP_IPC_MSGSSZ) + +(1L << GLIBTOP_IPC_MSGTQL); + +/* Init function. */ + +void +glibtop_init_msg_limits_s (glibtop *server) +{ + kvm_t *kd = server->machine.kd; + + if(kd && !kvm_nlist(kd, nlst)) + server->sysdeps.msg_limits = _glibtop_sysdeps_msg_limits; + else + server->sysdeps.msg_limits = 0; +} + +/* Provides information about sysv ipc limits. */ + +void +glibtop_get_msg_limits_s (glibtop *server, glibtop_msg_limits *buf) +{ + kvm_t *kd = server->machine.kd; + struct msginfo minfo; + + memset (buf, 0, sizeof (glibtop_msg_limits)); + + if(!(server->sysdeps.msg_limits)) + return; + if(kvm_read(kd, nlst[0].n_value, (void *)&minfo, + sizeof(struct msginfo)) != sizeof(struct msginfo)) + return; + + buf->msgmap = minfo.msgmap; + buf->msgmax = minfo.msgmax; + buf->msgmnb = minfo.msgmnb; + buf->msgmni = minfo.msgmni; + buf->msgssz = minfo.msgssz; + buf->msgtql = minfo.msgtql; + buf->msgpool = minfo.msgmni * minfo.msgmnb >> 10; + buf->flags = _glibtop_sysdeps_msg_limits; +} diff --git a/sysdeps/solaris/netload.c b/sysdeps/solaris/netload.c new file mode 100644 index 00000000..beebedba --- /dev/null +++ b/sysdeps/solaris/netload.c @@ -0,0 +1,45 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , October 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +static const unsigned long _glibtop_sysdeps_netload = 0; + +/* Init function. */ + +void +glibtop_init_netload_s (glibtop *server) +{ + server->sysdeps.netload = _glibtop_sysdeps_netload; +} + +/* Provides network statistics. */ + +void +glibtop_get_netload_s (glibtop *server, glibtop_netload *buf, + const char *interface) +{ + memset (buf, 0, sizeof (glibtop_netload)); +} diff --git a/sysdeps/solaris/open.c b/sysdeps/solaris/open.c new file mode 100644 index 00000000..845478fe --- /dev/null +++ b/sysdeps/solaris/open.c @@ -0,0 +1,183 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include + +#include + +/* We need to call this when kstat_chain_update() returns new KID. + * In that case all kstat pointers and data are invalid, so we + * need to reread everything. The condition shouldn't happen very + * often. + */ + +void +glibtop_get_kstats(glibtop *server) +{ + kstat_ctl_t *kc = server->machine.kc; + kstat_t *ksp; + int nproc_same, new_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; + } + + do { + 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) + { + 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 +glibtop_open_s (glibtop *server, const char *program_name, + const unsigned long features, const unsigned flags) +{ + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *kn; + + server->name = program_name; + + server->machine.pagesize = sysconf(_SC_PAGESIZE) >> 10; + server->machine.ticks = sysconf(_SC_CLK_TCK); + server->machine.kc = kc = kstat_open (); + +#if 0 + for (ksp = server->machine.kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) { + if (!strcmp (ksp->ks_class, "vm") && !strcmp (ksp->ks_name, "vminfo")) { + server->machine.vminfo_kstat = ksp; + kstat_read (server->machine.kc, ksp, &server->machine.vminfo); + server->machine.vminfo_snaptime = ksp->ks_snaptime; + continue; + } + + if (!strcmp (ksp->ks_class, "misc") && !strncmp (ksp->ks_name, "cpu_stat", 8)) { + int cpu; + + if ((sscanf (ksp->ks_name+8, "%d", &cpu) != 1) || (cpu > 63)) + continue; + + if (cpu >= server->ncpu) + server->ncpu = cpu+1; + + server->machine.cpu_stat_kstat [cpu] = ksp; + continue; + } + } + +#endif + + if (!kc) + glibtop_warn_io_r (server, "kstat_open ()"); + + server->ncpu = -1; /* Force processor detection */ + glibtop_get_kstats(server); + + server->machine.boot = 0; + if((ksp = server->machine.system) && kstat_read(kc, ksp, NULL) >= 0) + { + kn = (kstat_named_t *)kstat_data_lookup(ksp, "boot_time"); + if(kn) + server->machine.boot = kn->value.ui32; + } + + server->machine.kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL); + if(!server->machine.kd) + glibtop_warn_io_r(server, "kvm_open()"); + + fprintf (stderr, "Sleeping 2 seconds, please wait ...\n"); + sleep (2); +} diff --git a/sysdeps/solaris/ppp.c b/sysdeps/solaris/ppp.c new file mode 100644 index 00000000..6d0905d5 --- /dev/null +++ b/sysdeps/solaris/ppp.c @@ -0,0 +1,44 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , October 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +static const unsigned long _glibtop_sysdeps_ppp = 0; + +/* Init function. */ + +void +glibtop_init_ppp_s (glibtop *server) +{ + server->sysdeps.ppp = _glibtop_sysdeps_ppp; +} + +/* Provides PPP/ISDN information. */ + +void +glibtop_get_ppp_s (glibtop *server, glibtop_ppp *buf, unsigned short device) +{ + memset (buf, 0, sizeof (glibtop_ppp)); +} diff --git a/sysdeps/solaris/procargs.c b/sysdeps/solaris/procargs.c new file mode 100644 index 00000000..7d010d5e --- /dev/null +++ b/sysdeps/solaris/procargs.c @@ -0,0 +1,47 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include + +static const unsigned long _glibtop_sysdeps_proc_args = 0; + +/* Init function. */ + +void +glibtop_init_proc_args_s (glibtop *server) +{ + server->sysdeps.proc_args = _glibtop_sysdeps_proc_args; +} + +/* Provides detailed information about a process. */ + +char * +glibtop_get_proc_args_s (glibtop *server, glibtop_proc_args *buf, + pid_t pid, unsigned max_len) +{ + memset (buf, 0, sizeof (glibtop_proc_args)); + return NULL; +} diff --git a/sysdeps/solaris/procdata.c b/sysdeps/solaris/procdata.c new file mode 100644 index 00000000..0de27e0b --- /dev/null +++ b/sysdeps/solaris/procdata.c @@ -0,0 +1,121 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include + +/* Read /proc//psinfo. */ + +int +glibtop_get_proc_data_psinfo_s (glibtop *server, struct psinfo *psinfo, pid_t pid) +{ + int fd; + char buffer [BUFSIZ]; + + sprintf (buffer, "/proc/%d/psinfo", (int) pid); + fd = open (buffer, O_RDONLY); + if (fd < 0) { + glibtop_warn_io_r (server, "open (%s)", buffer); + return -1; + } + + if (pread (fd, psinfo, sizeof (struct psinfo), 0) != sizeof (struct psinfo)) { + close (fd); + glibtop_warn_io_r (server, "pread (%s)", buffer); + return -1; + } + + close (fd); + return 0; +} + +int +glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t pid) +{ + int fd; + char buffer [BUFSIZ]; + + sprintf (buffer, "/proc/%d/usage", (int) pid); + fd = open (buffer, O_RDONLY); + if (fd < 0) { + glibtop_warn_io_r (server, "open (%s)", buffer); + return -1; + } + + if (pread (fd, prusage, sizeof (struct prusage), 0) != sizeof (struct prusage)) { + close (fd); + glibtop_warn_io_r (server, "pread (%s)", buffer); + return -1; + } + + 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/cred", (int)pid); + if((fd = open(buffer, O_RDONLY)) < 0) + { + if(errno != EPERM && errno != EACCES) + 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, "pread (%s)", buffer); + return -1; + } + close(fd); + return 0; +} + +int +glibtop_get_proc_status_s(glibtop *server, struct pstatus *pstatus, pid_t pid) +{ + int fd; + char buffer[BUFSIZ]; + + sprintf(buffer, "/proc/%d/status", (int)pid); + if((fd = open(buffer, O_RDONLY)) < 0) + { + if(errno != EPERM && errno != EACCES) + glibtop_warn_io_r(server, "open (%s)", buffer); + return -1; + } + if(pread(fd, pstatus, sizeof(struct pstatus), 0) != sizeof(struct pstatus)) + { + close(fd); + glibtop_warn_io_r(server, "pread (%s)", buffer); + return -1; + } + close(fd); + return 0; +} diff --git a/sysdeps/solaris/prockernel.c b/sysdeps/solaris/prockernel.c new file mode 100644 index 00000000..d06f6cab --- /dev/null +++ b/sysdeps/solaris/prockernel.c @@ -0,0 +1,44 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +static const unsigned long _glibtop_sysdeps_proc_kernel = 0; + +/* Init function. */ + +void +glibtop_init_proc_kernel_s (glibtop *server) +{ + server->sysdeps.proc_kernel = _glibtop_sysdeps_proc_kernel; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_kernel_s (glibtop *server, glibtop_proc_kernel *buf, + pid_t pid) +{ + memset (buf, 0, sizeof (glibtop_proc_kernel)); +} diff --git a/sysdeps/solaris/proclist.c b/sysdeps/solaris/proclist.c new file mode 100644 index 00000000..a3451453 --- /dev/null +++ b/sysdeps/solaris/proclist.c @@ -0,0 +1,162 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +#include +#include +#include +#include + +#define GLIBTOP_PROCLIST_FLAGS 3 + +static const unsigned long _glibtop_sysdeps_proclist = +(1 << GLIBTOP_PROCLIST_TOTAL) + (1 << GLIBTOP_PROCLIST_NUMBER) + +(1 << GLIBTOP_PROCLIST_SIZE); + +/* Init function. */ + +void +glibtop_init_proclist_s (glibtop *server) +{ + server->sysdeps.proclist = _glibtop_sysdeps_proclist; +} + +#define BLOCK_COUNT 256 +#define BLOCK_SIZE (BLOCK_COUNT * sizeof (unsigned)) + +/* Fetch list of currently running processes. + * + * IMPORTANT NOTE: + * On error, this function MUST return NULL and set buf->flags to zero ! + * On success, it returnes a pointer to a list of buf->number elements + * each buf->size big. The total size is stored in buf->total. */ + +unsigned * +glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf, + int64_t which, int64_t arg) +{ + DIR *proc; + struct dirent *entry; + char buffer [BUFSIZ]; + unsigned count, total, pid; + unsigned pids [BLOCK_COUNT], *pids_chain = NULL; + unsigned pids_size = 0, pids_offset = 0, new_size; + struct stat statb; + int len, i, ok; + + memset (buf, 0, sizeof (glibtop_proclist)); + + proc = opendir ("/proc"); + if (!proc) return NULL; + + /* read every every entry in /proc */ + + for (count = total = 0, entry = readdir (proc); + entry; entry = readdir (proc)) { + ok = 1; len = strlen (entry->d_name); + + /* does it consist entirely of digits? */ + + for (i = 0; i < len; i++) + if (!isdigit (entry->d_name [i])) ok = 0; + if (!ok) continue; + + /* convert it in a number */ + + if (sscanf (entry->d_name, "%u", &pid) != 1) continue; + + /* is it really a directory? */ + + sprintf (buffer, "/proc/%d", pid); + + if (stat (buffer, &statb)) continue; + + if (!S_ISDIR (statb.st_mode)) continue; + + /* Fine. Now we first try to store it in pids. If this buffer is + * full, we copy it to the pids_chain. */ + + if (count >= BLOCK_COUNT) { + /* The following call to glibtop_realloc will be + * equivalent to glibtop_malloc () if `pids_chain' is + * NULL. We just calculate the new size and copy `pids' + * to the beginning of the newly allocated block. */ + + new_size = pids_size + BLOCK_SIZE; + + pids_chain = glibtop_realloc_r + (server, pids_chain, new_size); + + memcpy (pids_chain + pids_offset, pids, BLOCK_SIZE); + + pids_size = new_size; + + pids_offset += BLOCK_COUNT; + + count = 0; + } + + /* pids is now big enough to hold at least one single pid. */ + + pids [count++] = pid; + + total++; + } + + closedir (proc); + + /* count is only zero if an error occured (one a running Linux system, + * we have at least one single process). */ + + if (!count) return NULL; + + /* The following call to glibtop_realloc will be equivalent to + * glibtop_malloc if pids_chain is NULL. We just calculate the + * new size and copy pids to the beginning of the newly allocated + * block. */ + + new_size = pids_size + count * sizeof (unsigned); + + pids_chain = glibtop_realloc_r (server, pids_chain, new_size); + + memcpy (pids_chain + pids_offset, pids, count * sizeof (unsigned)); + + pids_size = new_size; + + pids_offset += BLOCK_COUNT; + + /* Since everything is ok now, we can set buf->flags, fill in the + * remaining fields and return the `pids_chain'. */ + + buf->flags = _glibtop_sysdeps_proclist; + + buf->size = sizeof (unsigned); + buf->number = total; + + buf->total = total * sizeof (unsigned); + + return pids_chain; +} diff --git a/sysdeps/solaris/procmap.c b/sysdeps/solaris/procmap.c new file mode 100644 index 00000000..772ee5c2 --- /dev/null +++ b/sysdeps/solaris/procmap.c @@ -0,0 +1,114 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + + +#include +#include +#include +#include + +#include +#include + +static const unsigned long _glibtop_sysdeps_proc_map = +(1L << GLIBTOP_PROC_MAP_NUMBER) + (1L << GLIBTOP_PROC_MAP_TOTAL) + +(1L << GLIBTOP_PROC_MAP_SIZE); +static const unsigned long _glibtop_sysdeps_map_entry = +(1L << GLIBTOP_MAP_ENTRY_START) + (1L << GLIBTOP_MAP_ENTRY_END) + +(1L << GLIBTOP_MAP_ENTRY_OFFSET) + (1L << GLIBTOP_MAP_ENTRY_PERM); + + +/* Init function. */ + +void +glibtop_init_proc_map_s (glibtop *server) +{ + server->sysdeps.proc_map = _glibtop_sysdeps_proc_map; +} + +/* Provides detailed information about a process. */ + +glibtop_map_entry * +glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) +{ + int fd, i, nmaps; + prmap_t *maps; + glibtop_map_entry *entry; + struct stat inode; + char buffer[BUFSIZ]; + + memset (buf, 0, sizeof (glibtop_proc_map)); + + sprintf(buffer, "/proc/%d/map", (int)pid); + if((fd = open(buffer, O_RDONLY)) < 0) + { + if(errno != EPERM && errno != EACCES) + glibtop_warn_io_r(server, "open (%s)", buffer); + return NULL; + } + if(fstat(fd, &inode) < 0) + { + if(errno != EOVERFLOW) + glibtop_warn_io_r(server, "fstat (%s)", buffer); + /* else call daemon for 64-bit support */ + close(fd); + return NULL; + } + maps = alloca(inode.st_size); + nmaps = inode.st_size / sizeof(prmap_t); + if(pread(fd, maps, inode.st_size, 0) != inode.st_size) + { + glibtop_warn_io_r(server, "pread (%s)", buffer); + close(fd); + return NULL; + } + close(fd); + if(!(entry = glibtop_malloc_r(server, nmaps * sizeof(glibtop_map_entry)))) + return NULL; + + buf->number = nmaps; + buf->size = sizeof(glibtop_map_entry); + buf->total = nmaps * sizeof(glibtop_map_entry); + + memset(entry, 0, nmaps * sizeof(glibtop_map_entry)); + for(i = 0; i < nmaps; ++i) + { + entry[i].start = maps[i].pr_vaddr; + entry[i].end = maps[i].pr_vaddr + maps[i].pr_size; + entry[i].offset = maps[i].pr_offset; + if(maps[i].pr_mflags & MA_READ) + entry[i].perm |= GLIBTOP_MAP_PERM_READ; + if(maps[i].pr_mflags & MA_WRITE) + entry[i].perm |= GLIBTOP_MAP_PERM_WRITE; + if(maps[i].pr_mflags & MA_EXEC) + entry[i].perm |= GLIBTOP_MAP_PERM_EXECUTE; + if(maps[i].pr_mflags & MA_SHARED) + entry[i].perm |= GLIBTOP_MAP_PERM_SHARED; + else + entry[i].perm |= GLIBTOP_MAP_PERM_PRIVATE; + entry[i].flags = _glibtop_sysdeps_map_entry; + } + + buf->flags = _glibtop_sysdeps_proc_map; + return entry; +} diff --git a/sysdeps/solaris/procmem.c b/sysdeps/solaris/procmem.c new file mode 100644 index 00000000..ab0c4170 --- /dev/null +++ b/sysdeps/solaris/procmem.c @@ -0,0 +1,44 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +static const unsigned long _glibtop_sysdeps_proc_mem = 0; + +/* Init function. */ + +void +glibtop_init_proc_mem_s (glibtop *server) +{ + server->sysdeps.proc_mem = _glibtop_sysdeps_proc_mem; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, + pid_t pid) +{ + memset (buf, 0, sizeof (glibtop_proc_mem)); +} diff --git a/sysdeps/solaris/procsegment.c b/sysdeps/solaris/procsegment.c new file mode 100644 index 00000000..b03709d4 --- /dev/null +++ b/sysdeps/solaris/procsegment.c @@ -0,0 +1,44 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +static const unsigned long _glibtop_sysdeps_proc_segment = 0; + +/* Init function. */ + +void +glibtop_init_proc_segment_s (glibtop *server) +{ + server->sysdeps.proc_segment = _glibtop_sysdeps_proc_segment; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_segment_s (glibtop *server, glibtop_proc_segment *buf, + pid_t pid) +{ + memset (buf, 0, sizeof (glibtop_proc_segment)); +} diff --git a/sysdeps/solaris/procsignal.c b/sysdeps/solaris/procsignal.c new file mode 100644 index 00000000..aa51ee25 --- /dev/null +++ b/sysdeps/solaris/procsignal.c @@ -0,0 +1,66 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include + +static const unsigned long _glibtop_sysdeps_proc_signal = +(1L << GLIBTOP_PROC_SIGNAL_SIGNAL) + (1L << GLIBTOP_PROC_SIGNAL_BLOCKED); + +/* Init function. */ + +void +glibtop_init_proc_signal_s (glibtop *server) +{ + server->sysdeps.proc_signal = _glibtop_sysdeps_proc_signal; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_signal_s (glibtop *server, glibtop_proc_signal *buf, + pid_t pid) +{ + struct pstatus pstatus; + int size; + + memset (buf, 0, sizeof (glibtop_proc_signal)); + + if(glibtop_get_proc_status_s(server, &pstatus, pid)) + return; + + if(sizeof(buf->signal) < sizeof(sigset_t)) + size = sizeof(buf->signal); + else + size = sizeof(sigset_t); + + memcpy(buf->signal, &pstatus.pr_sigpend, size); + memcpy(buf->blocked, &pstatus.pr_lwp.pr_lwphold, size); + + /* Technically, most of this is meaningless on a process level, + but this should be a good enough approximation. */ + + buf->flags = _glibtop_sysdeps_proc_signal; +} diff --git a/sysdeps/solaris/procstate.c b/sysdeps/solaris/procstate.c new file mode 100644 index 00000000..8e415879 --- /dev/null +++ b/sysdeps/solaris/procstate.c @@ -0,0 +1,79 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include + +static const unsigned long _glibtop_sysdeps_proc_state = +(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. */ + +void +glibtop_init_proc_state_s (glibtop *server) +{ + server->sysdeps.proc_state = _glibtop_sysdeps_proc_state; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid) +{ + struct psinfo psinfo; + + memset (buf, 0, sizeof (glibtop_proc_state)); + + if (glibtop_get_proc_data_psinfo_s (server, &psinfo, pid)) + return; + + 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); + + buf->flags = _glibtop_sysdeps_proc_state; +} diff --git a/sysdeps/solaris/proctime.c b/sysdeps/solaris/proctime.c new file mode 100644 index 00000000..88dfaf4f --- /dev/null +++ b/sysdeps/solaris/proctime.c @@ -0,0 +1,65 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include + +static const unsigned long _glibtop_sysdeps_proc_time = +(1 << GLIBTOP_PROC_TIME_START_TIME) + (1 << GLIBTOP_PROC_TIME_RTIME) + +(1 << GLIBTOP_PROC_TIME_UTIME) + (1 << GLIBTOP_PROC_TIME_STIME); + +/* Init function. */ + +void +glibtop_init_proc_time_s (glibtop *server) +{ + server->sysdeps.proc_time = _glibtop_sysdeps_proc_time; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_time_s (glibtop *server, glibtop_proc_time *buf, + pid_t pid) +{ + struct prusage prusage; + + memset (buf, 0, sizeof (glibtop_proc_time)); + + if (glibtop_get_proc_data_usage_s (server, &prusage, pid)) + return; + + buf->start_time = prusage.pr_create.tv_sec * 1E+6 + + prusage.pr_create.tv_nsec / 1E+3; + + buf->rtime = prusage.pr_rtime.tv_sec * 1E+6 + + prusage.pr_rtime.tv_nsec / 1E+3; + buf->utime = prusage.pr_utime.tv_sec * 1E+6 + + prusage.pr_utime.tv_nsec / 1E+3; + buf->stime = prusage.pr_stime.tv_sec * 1E+6 + + prusage.pr_stime.tv_nsec / 1E+3; + + buf->flags = _glibtop_sysdeps_proc_time; +} diff --git a/sysdeps/solaris/procuid.c b/sysdeps/solaris/procuid.c new file mode 100644 index 00000000..7695850e --- /dev/null +++ b/sysdeps/solaris/procuid.c @@ -0,0 +1,98 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include + +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_psinfo + + _glibtop_sysdeps_proc_uid_prcred; +} + +/* Provides detailed information about a process. */ + +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)); + + if (glibtop_get_proc_data_psinfo_s (server, &psinfo, pid)) + return; + + buf->euid = psinfo.pr_euid; + buf->uid = psinfo.pr_uid; + buf->egid = psinfo.pr_egid; + buf->gid = psinfo.pr_gid; + + buf->pid = psinfo.pr_pid; + buf->ppid = psinfo.pr_ppid; + buf->pgrp = psinfo.pr_pgid; + + buf->session = psinfo.pr_sid; + buf->tty = psinfo.pr_ttydev; + + 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; +} diff --git a/sysdeps/solaris/sem_limits.c b/sysdeps/solaris/sem_limits.c new file mode 100644 index 00000000..1a2af445 --- /dev/null +++ b/sysdeps/solaris/sem_limits.c @@ -0,0 +1,77 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include +#include + +static struct nlist nlst[] = { {"seminfo"}, {NULL} }; +static const unsigned long _glibtop_sysdeps_sem_limits = +(1L << GLIBTOP_IPC_SEMMAP) + (1L << GLIBTOP_IPC_SEMMNI) + +(1L << GLIBTOP_IPC_SEMMNS) + (1L << GLIBTOP_IPC_SEMMNU) + +(1L << GLIBTOP_IPC_SEMMSL) + (1L << GLIBTOP_IPC_SEMOPM) + +(1L << GLIBTOP_IPC_SEMUME) + (1L << GLIBTOP_IPC_SEMUSZ) + +(1L << GLIBTOP_IPC_SEMVMX) + (1L << GLIBTOP_IPC_SEMAEM); + +/* Init function. */ + +void +glibtop_init_sem_limits_s (glibtop *server) +{ + kvm_t *kd = server->machine.kd; + + if(kd && !kvm_nlist(kd, nlst)) + server->sysdeps.sem_limits = _glibtop_sysdeps_sem_limits; + else + server->sysdeps.sem_limits = 0; +} + +/* Provides information about sysv sem limits. */ + +void +glibtop_get_sem_limits_s (glibtop *server, glibtop_sem_limits *buf) +{ + kvm_t *kd = server->machine.kd; + struct seminfo sinfo; + + memset (buf, 0, sizeof (glibtop_sem_limits)); + + if(!(server->sysdeps.sem_limits)) + return; + if(kvm_read(kd, nlst[0].n_value, (void *)&sinfo, + sizeof(struct seminfo)) != sizeof(struct seminfo)) + return; + buf->semmap = sinfo.semmap; + buf->semmni = sinfo.semmni; + buf->semmns = sinfo.semmns; + buf->semmnu = sinfo.semmnu; + buf->semmsl = sinfo.semmsl; + buf->semopm = sinfo.semopm; + buf->semume = sinfo.semume; + buf->semusz = sinfo.semusz; + buf->semvmx = sinfo.semvmx; + buf->semaem = sinfo.semaem; + buf->flags = _glibtop_sysdeps_sem_limits; +} diff --git a/sysdeps/solaris/shm_limits.c b/sysdeps/solaris/shm_limits.c new file mode 100644 index 00000000..df11d948 --- /dev/null +++ b/sysdeps/solaris/shm_limits.c @@ -0,0 +1,68 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include +#include + +static struct nlist nlst[] = { {"shminfo"}, {NULL} }; +static const unsigned long _glibtop_sysdeps_shm_limits = +(1L << GLIBTOP_IPC_SHMMAX) + (1L << GLIBTOP_IPC_SHMMIN) + +(1L << GLIBTOP_IPC_SHMMNI) + (1L << GLIBTOP_IPC_SHMSEG); + +/* Init function. */ + +void +glibtop_init_shm_limits_s (glibtop *server) +{ + kvm_t *kd = server->machine.kd; + + if(kd && !kvm_nlist(kd, nlst)) + server->sysdeps.shm_limits = _glibtop_sysdeps_shm_limits; + else + server->sysdeps.shm_limits = 0; +} + +/* Provides information about sysv ipc limits. */ + +void +glibtop_get_shm_limits_s (glibtop *server, glibtop_shm_limits *buf) +{ + kvm_t *kd = server->machine.kd; + struct shminfo sinfo; + + memset (buf, 0, sizeof (glibtop_shm_limits)); + + if(!(server->sysdeps.shm_limits)) + return; + if(kvm_read(kd, nlst[0].n_value, (void *)&sinfo, + sizeof(struct shminfo)) != sizeof(struct shminfo)) + return; + buf->shmmax = sinfo.shmmax; + buf->shmmin = sinfo.shmmin; + buf->shmmni = sinfo.shmmni; + buf->shmseg = sinfo.shmseg; + buf->flags = _glibtop_sysdeps_shm_limits; +} diff --git a/sysdeps/solaris/siglist.c b/sysdeps/solaris/siglist.c new file mode 100644 index 00000000..b010013a --- /dev/null +++ b/sysdeps/solaris/siglist.c @@ -0,0 +1,127 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +static const glibtop_signame glibtop_sys_siglist [] = +{ { 1, "SIGHUP", "Hangup" }, + { 2, "SIGINT", "Interrupt" }, + { 3, "SIGQUIT", "Quit" }, + { 4, "SIGILL", "Illegal instruction" }, + { 5, "SIGTRAP", "Trace or breakpoint trap" }, + { 6, "SIGABRT", "Abort" }, + { 7, "SIGEMT", "Emulation trap" }, + { 8, "SIGFPE", "Arithmetic exception" }, + { 9, "SIGKILL", "Kill" }, + { 10, "SIGBUS", "Bus error" }, + { 11, "SIGSEGV", "Segmentation fault" }, + { 12, "SIGSYS", "Bad system call" }, + { 13, "SIGPIPE", "Broken pipe" }, + { 14, "SIGALRM", "Alarm clock" }, + { 15, "SIGTERM", "Terminate" }, + { 16, "SIGUSR1", "User signal 1" }, + { 17, "SIGUSR2", "User signal 2" }, + { 18, "SIGCHLD", "Child status changed" }, + { 19, "SIGPWR", "Power fail or restart" }, + { 20, "SIGWINCH","Window size change" }, + { 21, "SIGURG", "Urgent socket condition" }, + { 22, "SIGPOLL", "Pollable event" }, + { 23, "SIGSTOP", "Stop (cannot be ignored)" }, + { 24, "SIGTSTP", "User stop requested from tty" }, + { 25, "SIGCONT", "Continue" }, + { 26, "SIGTTIN", "Background tty read attempted" }, + { 27, "SIGTTOU", "Background tty write attempted" }, + { 28, "SIGVTALRM","Virtual timer expired" }, + { 29, "SIGPROF", "Profiling timer expired" }, + { 30, "SIGXCPU", "CPU time limit exceeded" }, + { 31, "SIGXFSZ", "File size limit exceeded" }, + { 32, "SIGWAITING","process' lwps are blocked" }, + { 33, "SIGLWP", "Inter-LWP signal reserved by threads library" }, + { 34, "SIGFREEZE","Check point freeze" }, + { 35, "SIGTHAW", "Check point thaw" }, + { 36, "SIGCANCEL","Cancelation signal reserved by threads library" }, + { 37, "SIGLOST", "Resource lost" }, + { 0, NULL, NULL } +}; + +/* + * Now, just for the fun of it, let's try to be forward and backward + * compatible. The above list is from Solaris 7. If later releases + * include new signals, binary from the earlier release won't be + * able to get the signal names, but it can get the correct numbers. + * So... + */ + +/* +#define MY_PRIVATE_COUNTOF(x) (sizeof(x)/sizeof(x[0])) + +glibtop_signame *glibtop_sys_siglist; + +static char *unknown = "Unknown"; +static glibtop_signame rt_min = + { 0, "SIGRTMIN", "First (highest-priority) realtime signal" }; +static glibtop_signame rt_max = + { 0, "SIGRTMIN", "Last (lowest-priority) realtime signal" }; +static char *rt_desc = "Real time signal %d"; + +void +glibtop_init_signals(void) +{ + int rtmin, rtmax, sigs, to, i; + char *bureq, p; + + rtmin = sysconf(_SC_SIGRT_MIN); + rtmax = sysconf(_SC_SIGRT_MAX); + sigs = MY_PRIVATE_COUNTOF(siglist); + + glibtop_sys_siglist = (glibtop_signame *) + malloc(rtmax * sizeof(glibtop_signame)); + bureq = malloc((rtmax - rtmin - 1) * (strlen(rt_desc) + 4)); + to = (sigs <= rtmin) ? sigs : rtmin; + memcpy(glibtop_sys_siglist, siglist, to * sizeof(glibtop_signame)); + for(i = sigs; i < rtmin; ++i) + { + glibtop_sys_siglist[i].number = i + 1; + glibtop_sys_siglist[i].name = glibtop_sys_siglist[i].label = unknown; + } + glibtop_sys_siglist[rtmin - 1].number = rtmin; + glibtop_sys_siglist[rtmin - 1].name = rt_min.name; + glibtop_sys_siglist[rtmin - 1].label = rt_min.label; + for(p = bureq, i = rtmin; i < rtmax; ++i) + { + glibtop_sys_siglist[i].number = i + 1; + to = sprintf(p, "%d", i + 1) + 1; + glibtop_sys_siglist[i].name = p; + p += to; + to = sprintf(p, rt_desc, i - rtmin + 2) + 1; + glibtop_sys_siglist[i].label = p; + p += to; + } + glibtop_sys_siglist[rtmax - 1].number = rtmax; + glibtop_sys_siglist[rtmax - 1].name = rt_max.name; + glibtop_sys_siglist[rtmax - 1].label = rt_max.label; + glibtop_sys_siglist[rtmax].number = 0; + glibtop_sys_siglist[rtmax].name = glibtop_sys_siglist[rtmax].label = NULL; +} +*/ diff --git a/sysdeps/solaris/swap.c b/sysdeps/solaris/swap.c new file mode 100644 index 00000000..b2e4721d --- /dev/null +++ b/sysdeps/solaris/swap.c @@ -0,0 +1,89 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +#include +#include + +#include + +static const unsigned long _glibtop_sysdeps_swap = +(1L << GLIBTOP_SWAP_TOTAL) + (1L << GLIBTOP_SWAP_USED) + +(1L << GLIBTOP_SWAP_FREE); + +/* Init function. */ + +void +glibtop_init_swap_s (glibtop *server) +{ + server->sysdeps.swap = _glibtop_sysdeps_swap; +} + +/* Provides information about swap usage. */ + +void +glibtop_get_swap_s (glibtop *server, glibtop_swap *buf) +{ + kstat_ctl_t *kc = server->machine.kc; + kstat_t *ksp = server->machine.vminfo_kstat; + u_int64_t swap_resv, swap_alloc, swap_avail, swap_free; + vminfo_t vminfo; + double rate; + kid_t ret; + + memset (buf, 0, sizeof (glibtop_swap)); + + if (!ksp) return; + + switch(kstat_chain_update(kc)) + { + 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)"); + return; + } + + rate = (ksp->ks_snaptime - server->machine.vminfo_snaptime) / 1E+9; + + 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; + + memcpy (&server->machine.vminfo, &vminfo, sizeof (vminfo_t)); + server->machine.vminfo_snaptime = ksp->ks_snaptime; + + buf->total = swap_resv + swap_avail; + buf->used = swap_alloc; + buf->free = buf->total - buf->used; + + buf->flags = _glibtop_sysdeps_swap; +} diff --git a/sysdeps/solaris/uptime.c b/sysdeps/solaris/uptime.c new file mode 100644 index 00000000..5c313e9e --- /dev/null +++ b/sysdeps/solaris/uptime.c @@ -0,0 +1,53 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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 LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include + +#include + +static const unsigned long _glibtop_sysdeps_uptime = +(1L << GLIBTOP_UPTIME_UPTIME) + (1L <sysdeps.uptime = _glibtop_sysdeps_uptime; +} + +/* Provides uptime and idle time. */ + +void +glibtop_get_uptime_s (glibtop *server, glibtop_uptime *buf) +{ + memset (buf, 0, sizeof (glibtop_uptime)); + + if(!(server->machine.boot)) + return; + buf->boot_time = server->machine.boot; + buf->uptime = time(NULL) - server->machine.boot; + + buf->flags = _glibtop_sysdeps_uptime; +}