Article View: dnet.comp.pcs
Article #7Was ist so los im Rechner?
From: Mike Schroeder
Date: Mon, 19 Jun 1989 07:43
Date: Mon, 19 Jun 1989 07:43
1257 lines
35111 bytes
35111 bytes
Hallo,
eine ganze Reihe von Euch haben Interesse an den neulich von mir
erwaehnten script und Programm angemeldet. Also poste ich es hier
- sonst muesste ich mittlerweile ca. 20 mails verschicken.
Bevor ich es vergesse - dank fuer 'sys' an Ralf Moritz und Torsten
Homeyer!
msch
----------- cut here ------------- cut here -------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 1 (of 1)."
# Contents: Makefile README pss.rcu pssV.2 pssV.3 sys.1 sys.c
# Wrapped by mike@cochise on Mon Jun 19 09:21:44 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(2058 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Configurate your Makefile is all you have to do.
X# Follow the explanations and unkomment the matching lines.
X#
X# Global definitions:
X#
X# Name of group which has readpermissions on /dev/kmem
XGROUP=sys
X
X# Directory where the binary should go
XBINDIR=/usr/local/bin
X
X# Directory where the manualpage should go
XMANDIR=/usr/man/man1
X
X
X# The following lines are for SCO-XENIX systems. Don't know the version
X# anymore.
X#CC= cc
X#CFLAGS= -O -DM_XENIX
X#LIBS= -lcurses -ltermcap -lffp
X
X# The following lines are for SINIX systems. It' tested on SINIX 1.0C for
X# the PC-MX.
X# no optimization, because optimizer gets out of space (Sigh)
X# torsten@homeyer.uucp in jun.88
X#CC= cc
X#CFLAGS= -DSINIX
X#LIBS= -lcurses -ltermcap -lffp
X
X#
X# Now the options for the various PCS versions of U*IX
X# The special devices mounted for MunixNet are handeld automatically.
X#
X# First for 16-Bit mashines. Tested on Munix V.2/07
X# Apply needed float library -f Option. We need -fT for 68881.
X# There are various floatingpoint libraries on 16-Bit and the compiler has to
X# generate different code, so you have to specify it as cc-flag
X#CC= cc
X#CFLAGS= -O -fT -DPCS_16
X#LIBS= -lcurses
X#
X# Now for 32-Bit V.2. Tested on Munix V.2/32-1.2
X#CC= cc
X#CFLAGS= -O -DPCS_V.2
X#LIBS= -lcurses
X#
X# Now for the V.3 type of munix. Tested on Munix V.3-3.1.
XCC= cc
XCFLAGS= -O -DPCS_V3
X# Or if you have NFS-filesystems mounted
X#CFLAGS= -O -DPCS_V3 -DNFS
XLIBS= -lcurses -lbsd
X#
X# Now for the V.3 sytem running on RISC-CPU. Tested on Munix V.3/R-p_1/2
X#CC= cc
X#CFLAGS= -O -DPCS_V3 -DPCS_RCU
X# Or if you have NFS-filesystems mounted
X#CFLAGS= -O3 -Olimit 512 -DPCS_V3 -DPCS_RCU -DNFS
X#LIBS= -lcurses -lmld -lbsd
X#
X
Xsys: sys.c
X $(CC) $(CFLAGS) $@.c -o $@ $(LIBS)
X
Xall: install sys man
X
Xinstall: sys
X -mkdir $(BINDIR)
X -mkdir $(MANDIR)
X chmod 0755 $(MANDIR) $(BINDIR)
X -rm $(BINDIR)/sys
X -rm $(MANDIR)/sys.1
X cp sys.1 $(MANDIR)
X chmod 0644 $(MANDIR)/sys.1
X cp sys $(BINDIR)
X chgrp $(GROUP) $(BINDIR)/sys
X chmod 2755 $(BINDIR)/sys
Xclean:
X rm -f core *.o *.u a.out sys
END_OF_FILE
if test 2058 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(661 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X Sys is tested on Munix V.2/32-1.2, V.3-3.1, V.2/07 and SCO-XENIX
X as well as PCS RCU under Munix V.3-3.1-p2 until now.
X But it should also run on any other SysV-Machine.
X I have made some changes and bugfixes to the original Sources.
X Look into the sources for more information.
X
X The programm pss shows a bit whats going on with Ram and Swap.
X It is a Shellscript so feel free to modify for own needs.
X This script has a major problem:
X If cols of ps -el output grow together you will get
X strange results.
X
X mfg Torsten Homeyer.
X
X
X E-mail: ....uunet!unido!pcsbst!torsten
X privat ....uunet!unido!homeyer!torsten
X
X torsten@{homeyer, pcsbst}.UUCP
X
END_OF_FILE
if test 661 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'pss.rcu' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'pss.rcu'\"
else
echo shar: Extracting \"'pss.rcu'\" \(1151 characters\)
sed "s/^X//" >'pss.rcu' <<'END_OF_FILE'
X: !/bin/sh
X# invented by Thomas Bagli --13.8.87--
X
Xcase $# in
X 0) no_of_req_processes=10 ;;
X *) no_of_req_processes=$1 ;;
Xesac
X
Xps -el | sort -r +9 -10 | \
Xoawk '
X BEGIN {
X req_count = 0
X total_procs = 0
X size_of_req_processes = 0
X size_of_all_processes = 0
X print " F S UID PID PPID C PRI NI " \
X "ADDR SZ WCHAN TTY TIME COMD"
X }
X {
X if ($10 != "SZ") {
X if (req_count == no_of_req_processes) {
X total_procs++
X size_of_all_processes += $10
X } else {
X req_count++
X total_procs++
X size_of_req_processes += $10
X size_of_all_processes += $10
X printf "%3d)%s\n", req_count, $0
X }
X }
X }
X END {
X print " SIZE OF REQ PROCESSES = " \
X size_of_req_processes " MemPages, " \
X size_of_req_processes * 4 / 1000 " Mbytes"
X print " SIZE OF ALL PROCESSES = " \
X size_of_all_processes " MemPages, " \
X size_of_all_processes * 4 / 1000 " Mbytes"
X print " TOTAL NO OF PROCESSES = " \
X total_procs
X }
X' no_of_req_processes=$no_of_req_processes -
X
X/etc/crash << EOFF 2> /dev/null \
X| sed "s/[0-9,a-f]*: 0*/ 4K SWAP BLOCKS = /"
Xod availsmem 1 D
Xquit
XEOFF
END_OF_FILE
if test 1151 -ne `wc -c <'pss.rcu'`; then
echo shar: \"'pss.rcu'\" unpacked with wrong size!
fi
# end of 'pss.rcu'
fi
if test -f 'pssV.2' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'pssV.2'\"
else
echo shar: Extracting \"'pssV.2'\" \(1258 characters\)
sed "s/^X//" >'pssV.2' <<'END_OF_FILE'
X: !/bin/sh
X# invented by Thomas Bagli, Richard Cole --13.8.87--
X
Xcase $# in
X 0) no_of_req_processes=10 ;;
X *) no_of_req_processes=$1 ;;
Xesac
X
Xps -el | sort -r +9 -10 | \
Xawk '
X BEGIN {
X req_count = 0
X total_procs = 0
X size_of_req_processes = 0
X size_of_all_processes = 0
X print " F S UID PID PPID C PRI NI " \
X "ADDR SZ WCHAN TTY TIME COMD"
X }
X {
X if ($10 != "SZ") {
X if (req_count == no_of_req_processes) {
X total_procs++
X size_of_all_processes += $10
X } else {
X req_count++
X total_procs++
X size_of_req_processes += $10
X size_of_all_processes += $10
X if (req_count < 10) print req_count ") " $0
X else if (req_count < 100) print req_count ") " $0
X else print req_count ")" $0
X }
X }
X }
X END {
X print " SIZE OF REQ PROCESSES = " \
X size_of_req_processes " MemPages, " \
X size_of_req_processes * 4 / 1000 " Mbytes"
X print " SIZE OF ALL PROCESSES = " \
X size_of_all_processes " MemPages, " \
X size_of_all_processes * 4 / 1000 " Mbytes"
X print " TOTAL NO OF PROCESSES = " \
X total_procs
X }
X' no_of_req_processes=$no_of_req_processes -
X
X/etc/crash << EOFF 2> /dev/null \
X| sed "s/[0-9,a-f]*: 0*/ 4K SWAP BLOCKS = /"
Xod availsmem 1 D
Xquit
XEOFF
END_OF_FILE
if test 1258 -ne `wc -c <'pssV.2'`; then
echo shar: \"'pssV.2'\" unpacked with wrong size!
fi
# end of 'pssV.2'
fi
if test -f 'pssV.3' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'pssV.3'\"
else
echo shar: Extracting \"'pssV.3'\" \(1267 characters\)
sed "s/^X//" >'pssV.3' <<'END_OF_FILE'
X: !/bin/sh
X# invented by Thomas Bagli, Richard Cole --13.8.87--
X
Xcase $# in
X 0) no_of_req_processes=10 ;;
X *) no_of_req_processes=$1 ;;
Xesac
X
Xps -el | sort -r +9 -10 | \
Xoawk '
X BEGIN {
X req_count = 0
X total_procs = 0
X size_of_req_processes = 0
X size_of_all_processes = 0
X print " F S UID PID PPID C PRI NI " \
X "ADDR SZ WCHAN TTY TIME COMD"
X }
X {
X if ($10 != "SZ") {
X if (req_count == no_of_req_processes) {
X total_procs++
X size_of_all_processes += $10
X } else {
X req_count++
X total_procs++
X size_of_req_processes += $10
X size_of_all_processes += $10
X if (req_count < 10) print req_count ") " $0
X else if (req_count < 100) print req_count ") " $0
X else print req_count ")" $0
X }
X }
X }
X END {
X print " SIZE OF REQ PROCESSES = " \
X size_of_req_processes " MemPages, " \
X size_of_req_processes * 4 / 1000 " Mbytes"
X print " SIZE OF ALL PROCESSES = " \
X size_of_all_processes " MemPages, " \
X size_of_all_processes * 4 / 1000 " Mbytes"
X print " TOTAL NO OF PROCESSES = " \
X total_procs
X }
X' no_of_req_processes=$no_of_req_processes -
X
X/etc/crash << EOFF 2> /dev/null \
X| sed "s/[0-9,a-f]*: 0*/ 4K SWAP BLOCKS = /"
Xod availsmem 1 D
Xquit
XEOFF
Xswap -l
END_OF_FILE
if test 1267 -ne `wc -c <'pssV.3'`; then
echo shar: \"'pssV.3'\" unpacked with wrong size!
fi
# end of 'pssV.3'
fi
if test -f 'sys.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sys.1'\"
else
echo shar: Extracting \"'sys.1'\" \(2614 characters\)
sed "s/^X//" >'sys.1' <<'END_OF_FILE'
X.TH SYS 1
X.SH NAME
Xsys \- display system statics
X.SH SYNOPSIS
X.B sys
X[time in seconds]
X.PP
XThis program displays various system statistics periodical via curses on
Xstdout (which should be a screen not used for anything else). The default
Xintervall is 60 seconds.
X.br
XThe values in brackets represent the average over the last 10 intervals\
X resp\. since \fBsys\fR was called.
X.sp
X.nf
XThe abbreviations mean:
X.br
Xidle CPU idle time in percent
X.br
Xuser CPU in user mode
X.br
Xkernel CPU in kernel mode
X.br
Xsxbrk CPU waiting for physical memory (no pages available
X anymore)
X.br
Xwait CPU waiting, splits into the following:
X.br
X w_io CPU waiting for block I/O
X.br
X w_swap CPU waiting for swapping/paging
X.br
X w_pio CPU waiting for physical I/O
X (streamer, etc)
X
X.br
X.fi
XDepending on your system you may not see some of the above mentioned
Xabbreviations.
X.sp
Xswapin, swapout swaps per minute
X.br
Xreadch, writech characters read/written in KB per minute
X.br
Xpswitch number of processor switches per minute
X.br
Xsyscall number of systemcalls per minute
X.br
Xmaxproc maximum number of running processes
X.br
Xcurproc currently running processes
X.br
Xnewproc new processes during the intervall
X.sp
XFor all mounted filesystems the free disk space is shown
Xin physical blocks or Kbyte, depending on your system.
X.br
XThe change of this value is displayed (one bar for each 2 KB).
X.SH FILES
X/unix or /xenix
X.br
X/etc/mnttab
X.br
X/dev/kmem
X.PP
X.SH AUTHOR
X.PP
XRalf Moritz, Technische Universitaet Berlin
X.sp
X BITNET: moritz@db0tui6 or
X.br
X UUCP: moritz@netmbx or
X.br
X ...!pyramid!tub!tmpmbx!moritz
X.SH MODIFICATIONS
X.PP
XTorsten Homeyer, PCS GmbH, Munich West-Germany
X.sp
X.nf
X UUCP:
X torsten@pcsbst.UUCP, ....uunet!unido!pcsbst!sws4!torsten
X.sp
X torsten@homeyer.UUCP, ....uunet!unido!homeyer!torsten
X.fi
X.sp
XMichael Schroeder, PCS GmbH, Munich West-Germany
X.sp
X UUCP:
X.br
X msc@pcsbst.UUCP
X ....uunet!unido!pcsbst!cochise!mike
X.br
X.SH BUGS
XNo other process should output anything to the screen where the program
Xis running (curses problem).
X.br
XIf a filesystem is unmounted while sys is running sys will abort with
Xan error message. New mounted filesystems are not recognized while sys
Xis running.
X.br
XThe number of new procs may be wrong (higher) after the pids begin
Xagain from 2.
X.br
XDue to rounding/truncating errors, the averages may not add up to
Xexactly 100.
END_OF_FILE
if test 2614 -ne `wc -c <'sys.1'`; then
echo shar: \"'sys.1'\" unpacked with wrong size!
fi
# end of 'sys.1'
fi
if test -f 'sys.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sys.c'\"
else
echo shar: Extracting \"'sys.c'\" \(19378 characters\)
sed "s/^X//" >'sys.c' <<'END_OF_FILE'
X/*
X * sys.c - Version 1.0 vom 2.4.88
X * - Version 1.2 vom 29.09.88
X * - Version 1.3 vom 25.02.89
X *
X * Dieses Programm sollte unter XENIX und Unix System V ohne
X * Modifikation lauffaehig sein (sofern die Permission stimmen).
X *
X * Besondere Gruesse an stocki@tub und jeden@netmbx / alle@tmpmbx
X *
X * Kommentare, Fragen, Verbesserungsvorschlaege etc. sind jederzeit
X * gerne gesehen.
X *
X * Ralf Moritz
X *
X * BITNET: moritz@db0tui6
X * UUCP: moritz@netmbx
X *
X * Modified by T. Homeyer, PCS Munich, torsten@{homeyer, pcsbst}.UUCP
X * till Spring 1988.
X * till now testet on MUNIX V.2/32-1.2., V.3/3.1, V.3/R-p_1/2 and V.2/07,
X * SCO-Xenix.
X * Added monitoring of CPU_SXBRK (thanks for idea to jum@cosmo).
X * Waiting for MMU to free physical Ram; Line 'sxbrk'.
X * Added monitoring of CPU_WAIT, based on diffs from jum@cosmo.
X * Line "wio" splits in following wait times:
X * Waiting for Block-IO; Line 'w_io ='.
X * Waiting for Swap- Paging Line 'w_swap ='.
X * Waiting for Phys-IO; Line 'w_pio ='.
X * Made following Bugfixes:
X * - detect LAN-Special-Files (you can't get the Filesystem-Size
X on such a device :-).
X - detect NFS-filesystems mounted (they have no entry in /dev)
X - take the last five chars of the mounted filesystems
X (otherwise it looks pretty bad on the screen).
X - declare *stdscr external, just for clearness.
X - unit of diskfree and diskused is physical Blocks or Bytes.
X it's mashine dependent.
X - added endwin() on every program exit.
X*
X* Added W_IO, W_PIO, W_SWAP and a few fixes for XENIX.
X* Added monitoring of syscalls, line syscall.
X* Special thanks to arne@oldman.uucp for his equipment :-)
X*
X* Modified (a little) by M. Schroeder, PCS GmbH, msc@pcsbst.uucp
X* in Sept. 88 - included total average of idle, user, kernel,
X* sxbrk and wio.
X*
X*
X* developt a version for Siemens Sinix 1.0C (PC-MX),
X* 1.0 (PC-X) and upper, which should run without modifications on
X* 2.0 and upper (MX2, MX300, MX500). but i have no equipment to test it.
X*/
X
X#define MAX_PID 29999 /* groesste Moegliche PID */
X#define C100 100L /* 100 % Multiplikator */
X#define TIME 60 /* default Intervall (60 Sekunden) */
X#ifdef M_XENIX
X#define UNIX "/xenix"
X#else
X#define UNIX "/unix"
X#define PNMNTTAB "/etc/mnttab"
X#endif
X
X#ifdef SINIX
X#undef UNIX
X#define UNIX "/sinix"
X#undef PNMNTTAB
X#define PNMNTTAB "/etc/mtab"
X#endif /* SINIX */
X
X#ifdef PCS_16
X#define CPU_KERNEL CPU_KERNAL
X#endif
X
X#define KMEM "/dev/kmem"
X
X#define BALKEN '=' /* fuer ASCII 'Graphic' */
X#define SOME_MORE 10 /* Mittelwerte ueber 10 Intervalle */
X#define MAX_PROC 300 /* sollte die reale maximale Prozess- */
X /* Zahl groesser sein bitte aendern */
X#define MAX_DISK 60 /* maximale Anzahl gemounteter Filesys. */
X
X#include <stdio.h>
X#include <curses.h>
X#ifndef SINIX
X#include <sys/types.h>
X#endif
X#ifdef PCS_16
X#undef FALSE
X#undef TRUE
X#endif
X#ifdef PCS_RCU
X#undef SYSV
X#endif
X#ifdef PCS_V.2
X#undef NULL
X#endif
X#include <sys/param.h>
X#include <sys/sysinfo.h>
X#include <fcntl.h>
X#include <sys/var.h>
X#include <sys/proc.h>
X#ifdef SINIX
X#include <signal.h>
X#else
X#include <sys/signal.h>
X#endif
X#include <a.out.h>
X#include <sys/utsname.h>
X#ifdef SINIX
X#include <mtab.h>
X#else
X#include <mnttab.h>
X#endif
X#include <sys/stat.h>
X#ifdef SINIX /* no ustat() and no ustat.h Grrrr! (Sigh) */
X#include<sys/filsys.h>
X#else
X#include <ustat.h>
X#endif
X
X
X/* Y values for various lines */
X#define IDLE 3
X#define USER 4
X#define KERN 5
X#define WIO 7
X#define SX_BRK 6
X#define WIO_ 8
X#define WSWAP_ 9
X#define WPIO_ 10
X#define SWAPIN 11
X#define READCH 12
X#define PSWITCH 13
X#define PROCN 14
X#define DISKS 15
X#define PROZENT 9
X
Xstatic struct nlist Nl[] = {
X#ifndef PCS_RCU
X { "_sysinfo" },
X { "_v" },
X { "_proc" },
X { 0 } };
X#else
X { "sysinfo" },
X { "v" },
X { "proc" },
X { 0 } };
X#endif
X
Xstatic struct var _v;
X
X/* will cause memory faults if not defined external */
Xextern WINDOW *initscr();
Xextern WINDOW *stdscr;
Xextern long lseek();
Xstatic int run_procs[MAX_PROC]; /* enthaelt Pid des laufenden Procs oder 0 */
Xstatic int last_proc = 0; /* letzter gestarteter Prozess */
X
X/* Die momentane Anzahl laufender Prozesse und die Anzahl der seit dem
X letzten Aufruf der Routine neu hinzugekommenen Prozesse wird berechnet.
X run_procs[] und last_proc werden als globale Variablen verwendet
X und geaendert.
X*/
Xcount_procs(kmem, count, new_procs)
Xint kmem, *count, *new_procs;
X{
X struct proc process;
X int i, min, max;
X
X max = last_proc; /* groesste PID erstmal letzte PID */
X min = -1; /* groesste PID kleiner als 10000 - keine */
X
X
X if ((lseek(kmem, (long)Nl[2].n_value, 0)) == -1L) {
X perror(KMEM);
X terminate();
X }
X
X *count = 0;
X for (i = 1; i <= _v.v_proc; i++) {
X if (read(kmem, &process, sizeof(process)) != sizeof(process)) {
X perror(KMEM);
X terminate();
X }
X if (process.p_stat) {
X (*count)++;
X if (run_procs[i] != process.p_pid) {
X if (process.p_pid > max) {
X max = process.p_pid;
X }
X if ((process.p_pid < 10000) &&
X (process.p_pid > min)) {
X min = process.p_pid;
X }
X }
X run_procs[i] = process.p_pid;
X }
X else {
X run_procs[i] = 0;
X } /* if */
X } /* for */
X if ((last_proc > 20000) && (min != -1)) {
X *new_procs = MAX_PID - last_proc + min;
X last_proc = min;
X }
X else {
X *new_procs = max - last_proc;
X if (*new_procs > 999) fprintf(stderr,
X "\n\rlp = %d, max = %d", last_proc, max);
X last_proc = max;
X }
X}
X
X/* Abbruch des Programms, loeschen des Bildschirms */
Xterminate()
X{
X clear();
X refresh();
X endwin();
X exit(0);
X}
X
X/* ab der aktuellen Cursor-Position anzahl Zeichen loeschen (curses) */
X/* keine Ueberpruefeung ob Zeilensprung vorkam/vorkommt !!! */
XDelchars(anzahl)
Xint anzahl;
X{
X int i, x ,y;
X getyx(stdscr, y, x);
X for(i = 1; i <= anzahl; i++)
X addch(' ');
X move(y,x);
X}
X
X/* pseudo graphische Darstellung eins Wertes von 0-100 */
X/* es werden 2+50 Zeichen rechts vom Cursor benoetigt */
Xgraph(percent)
Xint percent;
X{
X int i;
X int x ,y;
X
X getyx(stdscr, y, x);
X move(y,x+5);
X Delchars(50);
X for(i = 2; i <= percent; i +=2)
X addch(BALKEN);
X}
X
X/* pseudo graphische Darstellung eins vorzeichenbehafteten Wertes.
X Es werden 43 Zeichen rechts vom Cursor benoetigt.
X 2 Einheiten sind ein BALKEN. Mitte (0) ist ein sekrechter Strich.
X sollte ein Wert von mehr als abs(l_value) uebergeben werden, gibt
X es ein ">" oder "<" Zeichen zusaetzlich.
X*/
Xplus_minus(l_value)
Xlong l_value;
X{
X int l, i, x ,y;
X
X l = (int)l_value;
X l += l % 2;
X
X getyx(stdscr, y, x);
X move(y,x+5);
X
X Delchars(43);
X if (l < -40L) {
X addch('<');
X l = -40L;
X }
X else
X addch(' ');
X for (i = -40; (i < (int)l) && (i < 0); i += 2)
X addch(' ');
X for (i = (int)l; i < 0; i += 2)
X addch(BALKEN);
X addch('|');
X for (i = 0; (i < (int)l) && (i < 40); i += 2)
X addch(BALKEN);
X if (l >= 40L)
X addch('>');
X}
X
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X struct sysinfo s1, s0, s2;
X struct utsname name;
X#ifndef SINIX
X struct mnttab mnt_buf;
X struct ustat ustat_buf;
X#else
X struct mtab mnt_buf;
X struct filsys root_bl;
X#endif
X struct stat stat_buf;
X dev_t disk_dev[MAX_DISK];
X long disk_free[MAX_DISK];
X int i, fd, cur_disks = 0;
X long time(), total, w_total, zeit;
X int Time = TIME;
X int kmem, tmpint, count = 0;
X char *ctime(), strchr(), string[80];
X int anzahl, new_procs;
X double s_avg[8]; /* store the averages, make it double */
X /* in C math is going in double, so no */
X /* conversion has to appear **TH** */
X#ifdef SINIX /* grrrrr */
X unsigned avg_count; /* hey, something has to count */
X#else
X unsigned long avg_count; /* hey, something has to count */
X /* the averages ;-) */
X#endif
X
X if (argc == 2)
X Time = atoi(argv[1]);
X if (Time <= 0) {
X fprintf(stderr, "%s: illegal time (%s) - should be > 0\n",
X argv[0], argv[1]);
X endwin();
X exit(1);
X }
X
X signal(SIGINT, terminate);
X
X if (nlist(UNIX, Nl) == -1)
X {
X perror(UNIX);
X endwin();
X exit(1);
X }
X
X if ((fd = open(PNMNTTAB, O_RDONLY)) < 0) {
X perror(PNMNTTAB);
X endwin();
X exit(1);
X }
X
X if ((kmem = open(KMEM, O_RDONLY)) < 0)
X {
X perror(KMEM);
X endwin();
X exit(1);
X }
X
X if ((lseek(kmem, (long)Nl[1].n_value, 0)) == -1L)
X {
X /* _v */
X perror("NLIST__ _v");
X endwin();
X exit(1);
X }
X
X if (read(kmem, &_v, sizeof(_v)) != sizeof(_v)) {
X perror(KMEM);
X endwin();
X exit(1);
X }
X
X if ((lseek(kmem, (long)Nl[2].n_value, 0)) == -1L)
X /* _proc */
X {
X perror("NLIST__ _proc");
X endwin();
X exit(1);
X }
X
X for (tmpint = 0; tmpint < MAX_PROC; tmpint++)
X run_procs[tmpint] = 0;
X for (tmpint = 0; tmpint < 8; tmpint++)
X s_avg[tmpint] = 0.;
X avg_count = 0;
X /* get all currently active procs */
X count_procs(kmem, &anzahl, &new_procs);
X /* but the highest is not the last recently started */
X last_proc = getpid();
X initscr();
X clear();
X uname(&name);
X sprintf(string, "Sysname: %-9s Nodename: %-9s Version: %-9s Time =",
X name.sysname, name.nodename, name.version);
X mvaddstr(0,2, string);
X mvaddstr(1,3, "System-Load");
X mvaddstr(1,68,"last total");
X mvaddstr(2,3, "-----------");
X mvaddstr(2,68," avg avg");
X mvaddstr(IDLE,3, "idle = %"); mvaddstr(IDLE,68, "( ) ( )");
X mvaddstr(USER,3, "user = %"); mvaddstr(USER,68, "( ) ( )");
X mvaddstr(KERN,3, "kern = %"); mvaddstr(KERN,68, "( ) ( )");
X#ifdef CPU_WAIT
X mvaddstr(WIO,3, "wait = %"); mvaddstr(WIO,68, "( ) ( )");
X#endif
X#ifdef CPU_SXBRK
X mvaddstr(SX_BRK,3, "sxbrk= %"); mvaddstr(SX_BRK,68, "( ) ( )");
X#endif
X#ifdef W_IO
X mvaddstr(WIO_,3, "w_io = %"); mvaddstr(WIO_,68, "( )");
X#endif
X#ifdef W_SWAP
X mvaddstr(WSWAP_,3, "w_swp= %"); mvaddstr(WSWAP_,68, "( )");
X#endif
X#ifdef W_PIO
X mvaddstr(WPIO_,3, "w_pio= %"); mvaddstr(WPIO_,68, "( )");
X#endif
X mvaddstr(SWAPIN, 3,"swapin ="); mvaddstr(SWAPIN, 43,"swapout =");
X mvaddstr(READCH,3,"readch ="); mvaddstr(READCH,43,"writech =");
X mvaddstr(PSWITCH,3,"pswitch ="); mvaddstr(PSWITCH,43,"syscall =");
X
X sprintf(string, "maxproc = %3d", _v.v_proc);
X mvaddstr(PROCN,3, string);
X mvaddstr(PROCN, 28, "curproc =");
X mvaddstr(PROCN, 53, "newproc =");
X
X#ifndef SINIX
X while (read(fd, &mnt_buf, sizeof(mnt_buf)) == sizeof(mnt_buf)) {
X/* you are out of luck if you try an stat on a NFS-Specaial entry,
X** so only prozess the real ones */
X if ((mnt_buf.mt_filsys[0] == '\0')
X#ifdef NFS
X || !(strchr(mnt_buf.mt_dev,':') == NULL)
X#endif
X ) continue;
X#ifndef PCS_V3
X sprintf(string, "/dev/%s", mnt_buf.mt_dev);
X#else
X sprintf(string, "%s", mnt_buf.mt_dev);
X#endif
X#else
X cur_disks = 1; /* root not in /etc/mtab, let first entry for it */
X while (read(fd, &mnt_buf, sizeof(mnt_buf)) == sizeof(mnt_buf)) {
X if (mnt_buf.mt_file[0] == '\0')
X continue;
X sprintf(string, "/dev/%s", mnt_buf.mt_spec);
X#endif /* SINIX */
X if (stat(string, &stat_buf) == -1) {
X perror(string);
X endwin();
X exit(1);
X }
X/* you are out of luck if you try an stat on a LAN-Specaial entry,
X** so only prozess the real ones */
X#ifdef S_IFLAN
X if((stat_buf.st_mode & S_IFLAN) == S_IFLAN)
X continue;
X#endif
X/* the unit is physical Blocks not byte or Kbyte in SYS_V */
X#if defined(M_XENIX) || defined(SINIX)
X sprintf(string, "%-5s : free = Bl",
X#else
X sprintf(string, "%-5s : free = KB",
X#endif
X/* only get the last five chars of the mountet Filesystem */
X#ifndef SINIX
X (strlen(mnt_buf.mt_dev) < 6) ? mnt_buf.mt_dev :
X &mnt_buf.mt_dev[strlen(mnt_buf.mt_dev) - 5]);
X
X mvaddstr(DISKS+cur_disks, 3, string);
X sprintf(string, "/dev/%s", mnt_buf.mt_dev);
X disk_dev[cur_disks++] = stat_buf.st_rdev;
X#else
X (strlen(mnt_buf.mt_spec) < 6) ? mnt_buf.mt_spec :
X &mnt_buf.mt_spec[strlen(mnt_buf.mt_spec) - 5]);
X mvaddstr(DISKS+cur_disks, 3, string);
X sprintf(string, "/dev/%s", mnt_buf.mt_spec);
X if((disk_dev[cur_disks++] = open(string,O_RDONLY)) == -1)
X {
X perror(mnt_buf.mt_spec);
X sleep(3);
X terminate();
X }
X#endif
X if (cur_disks > MAX_DISK) {
X fprintf(stderr,
X "\nTo many mounted filesystems...\n");
X sleep(3);
X terminate();
X }
X }
X
X#ifdef SINIX /* root not in /etc/mtab */
X sprintf(string, "%-5s : free = KB","/");
X mvaddstr(DISKS, 3, string);
X if((disk_dev[0] = open("/dev/root",O_RDONLY)) == -1)
X {
X perror("/");
X sleep(3);
X terminate();
X }
X#endif
X close(fd);
X#ifndef SINIX
X for (i = 0; i < cur_disks; i++) {
X if (ustat(disk_dev[i], &ustat_buf) == -1) {
X perror("");
X fprintf(stderr, "ustat(%d, ?)\n\r", disk_dev[i]);
X sleep(5);
X endwin();
X exit(1);
X }
X disk_free[i] = ustat_buf.f_tfree;
X }
X#else
X for(i = 0; i < cur_disks; i++)
X {
X if(lseek(disk_dev[i],(long)BUFSIZ,0) == -1L)
X {
X perror("can't seek on device");
X endwin();
X exit(1);
X }
X if(read(disk_dev[i],&root_bl,sizeof(struct filsys)) == -1)
X {
X perror("can't read device");
X endwin();
X exit(1);
X }
X disk_free[i] = root_bl.s_tfree;
X }
X#endif
X
X refresh();
X
X
X if ((lseek(kmem, (long)Nl[0].n_value, 0)) == -1L)
X /* _sysinfo */
X {
X perror("NLIST__ _sysinfo");
X endwin();
X exit(1);
X }
X
X if (read(kmem, &s0, sizeof(s0)) != sizeof(s0))
X {
X perror(KMEM);
X endwin();
X exit(1);
X }
X
X sleep(Time);
X s2 = s0;
X
X
X/* Hauptroutine - wird nie (ausser bei Fehlern) beendet. Abbruch durch
X externe Ereignisse (kill etc.).
X*/
X for(;;count++) {
X if ((lseek(kmem, (long)Nl[0].n_value, 0)) == -1L)
X {
X perror(KMEM);
X endwin();
X exit(1);
X }
X
X s1 = s0;
X
X if (read(kmem, &s0, sizeof(s0)) != sizeof(s0))
X {
X perror(KMEM);
X endwin();
X exit(1);
X }
X
X total = (s0.cpu[CPU_IDLE] - s1.cpu[CPU_IDLE]) +
X (s0.cpu[CPU_USER] - s1.cpu[CPU_USER]) +
X#ifdef CPU_WAIT
X (s0.cpu[CPU_WAIT] - s1.cpu[CPU_WAIT]) +
X#endif
X#ifdef CPU_SXBRK
X (s0.cpu[CPU_SXBRK] - s1.cpu[CPU_SXBRK]) +
X#endif
X (s0.cpu[CPU_KERNEL] - s1.cpu[CPU_KERNEL]);
X
X#if defined(W_IO) || defined(W_SWAP) || defined(W_PIO)
X w_total =
X#ifdef W_IO
X (s0.wait[W_IO] - s1.wait[W_IO])
X#endif
X#ifdef W_SWAP
X + (s0.wait[W_SWAP] - s1.wait[W_SWAP])
X#endif
X#ifdef W_PIO
X + (s0.wait[W_PIO] - s1.wait[W_PIO])
X#endif
X + 0L; /* only for ";" */
X#endif
X
X
X zeit = time(NULL);
X strcpy(string, ctime(&zeit)+11);
X string[9] = '\0';
X mvaddstr(0, 69, string);
X tmpint = (int)(C100 * (s0.cpu[CPU_IDLE] - s1.cpu[CPU_IDLE]) / total);
X s_avg[0] = (s_avg[0]*avg_count + tmpint) / (avg_count + 1);
X sprintf(string, "%3d", tmpint);
X mvaddstr(IDLE,PROZENT, string);
X graph(tmpint);
X tmpint = (int)(C100 * (s0.cpu[CPU_USER] - s1.cpu[CPU_USER]) / total);
X s_avg[1] = (s_avg[1]*avg_count + tmpint) / (avg_count + 1);
X sprintf(string, "%3d", tmpint);
X mvaddstr(USER,PROZENT, string);
X graph(tmpint);
X tmpint = (int)(C100 *(s0.cpu[CPU_KERNEL] - s1.cpu[CPU_KERNEL]) / total);
X s_avg[2] = (s_avg[2]*avg_count + tmpint) / (avg_count + 1);
X sprintf(string, "%3d", tmpint);
X mvaddstr(KERN,PROZENT, string);
X graph(tmpint);
X#ifdef CPU_WAIT
X tmpint = (int)(C100 * (s0.cpu[CPU_WAIT] - s1.cpu[CPU_WAIT]) / total);
X s_avg[3] = (s_avg[3]*avg_count + tmpint) / (avg_count + 1);
X sprintf(string, "%3d", tmpint);
X mvaddstr(WIO,PROZENT, string);
X graph(tmpint);
X#endif
X#ifdef CPU_SXBRK
X tmpint = (int)(C100 * (s0.cpu[CPU_SXBRK] - s1.cpu[CPU_SXBRK]) / total);
X s_avg[4] = (s_avg[4]*avg_count + tmpint) / (avg_count + 1);
X sprintf(string, "%3d", tmpint);
X mvaddstr(SX_BRK,PROZENT, string);
X graph(tmpint);
X#endif
X#ifdef W_IO
X tmpint = (w_total == 0 ? 0 : (int)(C100 * (s0.wait[W_IO] -
X s1.wait[W_IO]) / w_total));
X sprintf(string, "%3d", tmpint);
X mvaddstr(WIO_,PROZENT, string);
X graph(tmpint);
X#endif
X#ifdef W_SWAP
X tmpint = (w_total == 0 ? 0 : (int)(C100 * (s0.wait[W_SWAP] -
X s1.wait[W_SWAP]) / w_total));
X sprintf(string, "%3d", tmpint);
X mvaddstr(WSWAP_,PROZENT, string);
X graph(tmpint);
X#endif
X#ifdef W_PIO
X tmpint = (w_total == 0 ? 0 : (int)(C100 * (s0.wait[W_PIO] -
X s1.wait[W_PIO]) / w_total));
X sprintf(string, "%3d", tmpint);
X mvaddstr(WPIO_,PROZENT, string);
X graph(tmpint);
X#endif
X
X sprintf(string, "%5ld /min", (s0.swapin - s1.swapin)*60L/Time);
X mvaddstr( SWAPIN, 13, string);
X sprintf(string, "%5ld /min", (s0.swapout - s1.swapout)*60L/Time);
X mvaddstr( SWAPIN, 53, string);
X
X sprintf(string, "%5ld K/min", (s0.readch - s1.readch)*60L/Time/1024L);
X mvaddstr(READCH, 13, string);
X sprintf(string, "%5ld K/min", (s0.writech - s1.writech)*60L/Time/1024L);
X mvaddstr(READCH, 53, string);
X
X sprintf(string, "%5ld /min", (s0.pswitch - s1.pswitch)*60L/Time);
X mvaddstr(PSWITCH, 13, string);
X sprintf(string, "%5ld /min", (s0.syscall - s1.syscall)*60L/Time);
X mvaddstr(PSWITCH, 53, string);
X
X count_procs(kmem, &anzahl, &new_procs);
X sprintf(string, "%3d", anzahl);
X mvaddstr(PROCN, 38, string);
X sprintf(string, "%3d ", new_procs);
X mvaddstr(PROCN, 63, string);
X
X if (count == SOME_MORE) { /* mal wieder ein Mittelwert ? */
X total = (s0.cpu[CPU_IDLE] - s2.cpu[CPU_IDLE]) +
X (s0.cpu[CPU_USER] - s2.cpu[CPU_USER]) +
X#ifdef CPU_WAIT
X (s0.cpu[CPU_WAIT] - s2.cpu[CPU_WAIT]) +
X#endif
X#ifdef CPU_SXBRK
X (s0.cpu[CPU_SXBRK] - s2.cpu[CPU_SXBRK]) +
X#endif
X (s0.cpu[CPU_KERNEL] - s2.cpu[CPU_KERNEL]);
X tmpint = (int)(C100 * (s0.cpu[CPU_IDLE] -
X s2.cpu[CPU_IDLE]) / total);
X sprintf(string, "%3d) (%3d", tmpint, (int)s_avg[0]);
X mvaddstr(IDLE,69, string);
X tmpint = (int)(C100 * (s0.cpu[CPU_USER] -
X s2.cpu[CPU_USER]) / total);
X sprintf(string, "%3d) (%3d", tmpint, (int)s_avg[1]);
X mvaddstr(USER,69, string);
X tmpint = (int)(C100 * (s0.cpu[CPU_KERNEL] -
X s2.cpu[CPU_KERNEL]) / total);
X sprintf(string, "%3d) (%3d", tmpint, (int)s_avg[2]);
X mvaddstr(KERN,69, string);
X#ifdef CPU_WAIT
X tmpint = (int)(C100 * (s0.cpu[CPU_WAIT] -
X s2.cpu[CPU_WAIT]) / total);
X sprintf(string, "%3d) (%3d", tmpint, (int)s_avg[3]);
X mvaddstr(WIO,69, string);
X#endif
X#ifdef CPU_SXBRK
X tmpint = (int)(C100 * (s0.cpu[CPU_SXBRK] -
X s2.cpu[CPU_SXBRK]) / total);
X sprintf(string, "%3d) (%3d", tmpint, (int)s_avg[4]);
X mvaddstr(SX_BRK,69, string);
X#endif
X
X#if defined(W_IO) || defined(W_SWAP) || defined(W_PIO)
X w_total =
X#ifdef W_IO
X (s0.wait[W_IO] - s2.wait[W_IO])
X#endif
X#ifdef W_SWAP
X + (s0.wait[W_SWAP] - s2.wait[W_SWAP])
X#endif
X#ifdef W_PIO
X + (s0.wait[W_PIO] - s2.wait[W_PIO])
X#endif
X + 0L; /* only for ";" */
X#endif
X#ifdef W_IO
X tmpint = (w_total == 0 ? 0 : (int)(C100 * (s0.wait[W_IO] -
X s2.wait[W_IO]) / w_total));
X sprintf(string, "%3d", tmpint);
X mvaddstr(WIO_,69, string);
X#endif
X#ifdef W_SWAP
X tmpint = (w_total == 0 ? 0 : (int)(C100 * (s0.wait[W_SWAP] -
X s2.wait[W_SWAP]) / w_total));
X sprintf(string, "%3d", tmpint);
X mvaddstr(WSWAP_,69, string);
X#endif
X#ifdef W_PIO
X tmpint = (w_total == 0 ? 0 : (int)(C100 * (s0.wait[W_PIO] -
X s2.wait[W_PIO]) / w_total));
X sprintf(string, "%3d", tmpint);
X mvaddstr(WPIO_,69, string);
X#endif
X
X s2 = s0;
X count = 0;
X }
X
X#ifndef SINIX
X for (i = 0; i < cur_disks; i++) {
X if (ustat(disk_dev[i], &ustat_buf) < 0) {
X fprintf(stderr, "\nustat(%d, ?) ", disk_dev[i]);
X perror("");
X endwin();
X exit(1);
X }
X/****/ sprintf(string, "%-6ld", ustat_buf.f_tfree);
X mvaddstr(DISKS +i, 18, string);
X plus_minus(ustat_buf.f_tfree - disk_free[i]);
X disk_free[i] = ustat_buf.f_tfree;
X }
X#else
X for(i = 0; i < cur_disks; ++i)
X {
X if(lseek(disk_dev[i],(long)BUFSIZ,0) == -1)
X {
X perror("can't seek on device");
X endwin();
X exit(1);
X }
X if(read(disk_dev[i],&root_bl,sizeof(struct filsys)) == -1)
X {
X perror("can't read device");
X endwin();
X exit(1);
X }
X sprintf(string, "%-6ld", root_bl.s_tfree);
X mvaddstr(DISKS +i, 18, string);
X plus_minus(root_bl.s_tfree - disk_free[i]);
X disk_free[i] = root_bl.s_tfree;
X }
X#endif
X avg_count = avg_count + 1;
X
X refresh();
X
X sleep(Time);
X }
X}
X
END_OF_FILE
if test 19378 -ne `wc -c <'sys.c'`; then
echo shar: \"'sys.c'\" unpacked with wrong size!
fi
# end of 'sys.c'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have the archive.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Mike Schroeder PCS-Mail: msc
DOMAIN: msc@cochise.pcs.de (EUR) or msc@cochise.pcs.com (US)
BANG: ..unido!pcsbst!msc (EUR) or ..pyramid!pcsbst!msc (US)
Technical Details
Message-ID:
<859@pcsbst.UUCP>Path:
arc1-ca.pugleaf.net!gmdzi!unido!pcsbst!mikeShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 1354df,78443784b15f64ec,start X-Google-Attributes: gid1354df,public X-Google-ArrivalTime: 1989-06-19 05:19:22 PST Path: arc1-ca.pugleaf.net!gmdzi!unido!pcsbst!mike From: mike@pcsbst.UUCP (Mike Schroeder) Newsgroups: dnet.comp.pcs Subject: Was ist so los im Rechner? Message-ID: <859@pcsbst.UUCP> Date: 19 Jun 89 07:43:14 GMT Reply-To: msc@cochise.pcs.de (Mike Schroeder) Distribution: dnet Organization: PCS GmbH, Pfaelzer-Wald-Str. 36, 8000 Muenchen; West-Germany Lines: 1257 Posted: Mon Jun 19 08:43:14 1989