*BSD News Article 24282


Return to BSD News archive

Newsgroups: comp.os.386bsd.apps
Path: sserve!csadfa.cs.adfa.oz.au!wkt
From: wkt@csadfa.cs.adfa.oz.au (Warren Toomey)
Subject: [src] Disk seek stats program
Message-ID: <1993Nov21.221632.2247@sserve.cc.adfa.oz.au>
Keywords: disk arm motion seek stats collector
Sender: news@sserve.cc.adfa.oz.au
Organization: Australian Defence Force Academy, Canberra, Australia
Date: Sun, 21 Nov 1993 22:16:32 GMT

Shar file below!

#	Readme
#	seekstat.c
#	seekstat.h
#	ufs_disksubr.c.diff
#
echo x - Readme
sed 's/^X//' >Readme << 'END-of-Readme'
XHere is a little stats program I wrote after reading the Nutshell book on
XSystem Performance Tuning. It makes the kernel gather stats on the disk seek
Xmotion, which can be accessed by the program.
X
XInstallation
X------------
X
XPatch /sys/ufs/ufs_disksubr.c with the included patch. There are only
Xadditions, so if the patch fails you can do it manually.
X
XInstall seekstat.h in /sys/sys.
X
XAdd the option SEEKSTAT to your kernel config file.
X
XRecompile your kernel. BEFORE you install the new kernel, make sure you
Xsave your old kernel and can reboot using it, either by hard disk or floppy.
XJust in case!
X
XInstall the new kernel and reboot.
X
XCompile the seekstat program:
X	cc -o seekstat seekstat.c
X	
X
XMan Page
X--------
X
XFirst run seekstat with no arguments:
X	seekstat | less
X	
XThe columns are:
X	+ The device number (I haven't bothered mapping these to names).
X	+ The cylinder of a read/write request.
X	+ The seek to get the head there.
X
XNow, rerun seekstat with two arguments, a `clump' of cylinders and a device
Xnumber from above, e.g
X	seekstat 10 8 | less
X
XWe bucketize the raw data into clumps, and print out stats per clump. You
Xwill get the number of requests per clump, and in a second table the number
Xof seeks, broken into the same sized clumps. For example:
X
X
X607 Seeks			Total # of seeks for device 8
X
XCylgrp	Use
X0	0
X20	0
X   ...
X400	0
X420	0
X440	103			These cylinders are the ones
X460	169			being accessed most
X480	21
X500	2
X520	1
X540	14
X560	11
X580	16
X600	51
X620	4
X640	2
X660	2
X680	9
X
XSeek	Count
X0	289			Most seeks are for <20 cylinders
X20	33
X40	28
X60	13
X80	26
X100	16
X120	25
X140	35
X160	18
X180	4
X200	0
X   ...
X
XSystem Requirements
X-------------------
X
XThe extra code in the kernel is negligible. However, 2048 seekstat
Xbuffers are added, increasing the kernel's data size by 12,288 bytes.
XThe performance penalty to collect the statistics should also be
Xnegligible.
END-of-Readme
echo x - seekstat.c
sed 's/^X//' >seekstat.c << 'END-of-seekstat.c'
X/*
X * Seekstat: Print out statistics about the disk arm motion
X *
X * Written 11/93 by Warren wkt@csadfa.cs.adfa.oz.au
X */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <fcntl.h>
X#include <nlist.h>
X#include <sys/seekstat.h>
X
Xchar	*fcore	= "/dev/kmem";		/* Device to read from */
Xchar	*fnlist	= "/386bsd";		/* File to nlist thru */
Xint	fc;				/* File desc of fcore */
X
X					/* List of kernel names we desire */
Xstruct nlist nl[] = {
X
X	{ "_seekst" },
X	{ "" }
X};
X
Xstruct seekstat seekst[NUMSEEKSTATS];
X
Xusage()
X { fprintf(stderr,"Usage: seekstat [cyls device#]\n"); exit(1); }
X
Xmain(argc,argv)
X int argc;
X char *argv[];
X{
X int i,cnt,got,device;
X int seeks, cyls, maxcyl=0, maxseek=0;
X int *cylbox, *seekbox;
X
X						/* Check and get the args */
X if (argc!=1 && argc!=3) usage();
X if (argc==3)
X  { cyls=atoi(argv[1]);
X    if (cyls<1) { fprintf(stderr,"Cyls cannot be <1\n"); exit(1); }
X    device=atoi(argv[2]);
X  }
X						/* Find the data structures */
X						/* in the kernel */
X i=nlist(fnlist, nl);
X if (i==-1) { perror("nlist"); exit(1); }
X
X for (i=0;nl[i].n_name;i++)
X   if (nl[0].n_type == 0)
X     { fprintf(stderr,"%s not found in namelist\n",nl[0].n_name); exit(1); }
X
X						/* Open up the kernel memory */
X fc= open(fcore,O_RDONLY);
X if (fc==-1) { perror("opening /dev/kmem"); exit(1); }
X
X
X						/* Get the stat info */
X  i=lseek(fc, nl[0].n_value, SEEK_SET);
X  if (i==-1) { perror("lseeking /dev/kmem"); exit(1); }
X  if (argc==1) printf("Dev\tCyl\tSeek\n");
X
X  for (got=NUMSEEKSTATS,cnt=i=0;i<NUMSEEKSTATS;i++)
X   { read(fc, &seekst[cnt], sizeof(struct seekstat));
X     if (seekst[cnt].b_dev==0 && seekst[cnt].b_cyl==0 && seekst[cnt].b_seek==0)
X	break;
X     if (argc==3 && seekst[cnt].b_dev!=device) continue;
X     if (seekst[cnt].b_seek<0) seekst[cnt].b_seek=-seekst[cnt].b_seek;
X     if (argc==1) printf("%x\t%d\t%d\n",
X			seekst[cnt].b_dev,seekst[cnt].b_cyl,seekst[cnt].b_seek);
X     if (seekst[cnt].b_cyl> maxcyl) maxcyl=seekst[cnt].b_cyl;
X     if (seekst[cnt].b_seek> maxseek) maxseek=seekst[cnt].b_seek;
X     cnt++;
X   }
X  got=cnt;
X
X  if (argc==1) exit(0);
X  printf("%d Seeks\n\n",got);
X						/* Now get buckets for stats */
X  cylbox=(int *)calloc(1+(maxcyl/cyls), sizeof(int));
X  if (cylbox==NULL) { fprintf(stderr,"Can't malloc cylbox\n"); exit(1); }
X  seekbox=(int *)calloc(1+(maxseek/cyls), sizeof(int));
X  if (seekbox==NULL) { fprintf(stderr,"Can't malloc seekbox\n"); exit(1); }
X
X						/* Drop seek, cyl into bucket */
X  for (cnt=0;cnt<got;cnt++)
X   { i=seekst[cnt].b_cyl/cyls; cylbox[i]++;
X     i=seekst[cnt].b_seek/cyls; seekbox[i]++;
X   }
X
X  printf("Cylgrp\tUse\n");
X  for (i=0;i<(maxcyl/cyls);i++) printf("%d\t%d\n", i * cyls, cylbox[i]);
X
X						/* Find highest !0 seek */
X  for (i=maxseek/cyls;i>=0;i--) if (seekbox[i]) { seeks=i+1; break; }
X
X  printf("\nSeek\tCount\n");
X  for (i=0;i<seeks;i++) printf("%d\t%d\n", i * cyls, seekbox[i]);
X }
END-of-seekstat.c
echo x - seekstat.h
sed 's/^X//' >seekstat.h << 'END-of-seekstat.h'
X#ifndef _SEEKSTAT_H
X#define _SEEKSTAT_H
X
X/* Structure to gather statistics about disk seek patterns.
X * Author: Warren Toomey, wkt@csadfa.cs.adfa.oz.au
X *
X * This is only used in ufs_disksubr.c, with SEEKSTAT defined.
X */
X
X#define NUMSEEKSTATS	2048		/* We record up to 2048 statistics */
X
Xstruct seekstat {
X	short b_dev;			/* The device that is seeking */
X	short b_cyl;			/* A seek to this cylinder */
X	short b_seek;			/* With this seek movement */
X};
X#endif	/* _SEEKSTAT_H */
END-of-seekstat.h
echo x - ufs_disksubr.c.diff
sed 's/^X//' >ufs_disksubr.c.diff << 'END-of-ufs_disksubr.c.diff'
X*** z	Sat Nov 20 13:30:59 1993
X--- ufs_disksubr.c	Sat Nov 20 09:05:34 1993
X***************
X*** 37,48 ****
X--- 37,54 ----
X  #include "systm.h"
X  #include "buf.h"
X  #include "dkbad.h"
X  #include "disklabel.h"
X  #include "syslog.h"
X  
X+ #ifdef SEEKSTAT
X+ #include "seekstat.h"
X+ struct seekstat seekst[NUMSEEKSTATS];
X+ int sscount=0;
X+ #endif
X+ 
X  /*
X   * Seek sort for disks.  We depend on the driver
X   * which calls us using b_resid as the current cylinder number.
X   *
X   * The argument dp structure holds a b_actf activity chain pointer
X   * on which we keep two queues, sorted in ascending cylinder order.
X***************
X*** 134,145 ****
X--- 140,157 ----
X  	/*
X  	 * Neither a second list nor a larger
X  	 * request... we go at the end of the first list,
X  	 * which is the same as the end of the whole schebang.
X  	 */
X  insert:
X+ #ifdef SEEKSTAT
X+ 	seekst[sscount].b_dev= ap->b_dev;
X+ 	seekst[sscount].b_cyl= ap->b_cylin;
X+ 	seekst[sscount].b_seek= ap->b_cylin - bp->b_cylin;
X+ 	sscount++; sscount%= NUMSEEKSTATS;
X+ #endif
X  	bp->av_forw = ap->av_forw;
X  	ap->av_forw = bp;
X  	if (ap == dp->b_actl)
X  		dp->b_actl = bp;
X  }
X  
END-of-ufs_disksubr.c.diff
exit

#! rnews 7949 sserve.cc.adfa.oz.au
Xref: sserve comp.os.386bsd.questions:7059 comp.windows.x.i386unix:5103 comp.os.386bsd.apps:716
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!agate!howland.reston.ans.net!xlink.net!rz.uni-karlsruhe.de!uni-mannheim!andrew
From: andrew@wipux2.wifo.uni-mannheim.de (Andrew Wheadon)
Newsgroups: comp.os.386bsd.questions,comp.windows.x.i386unix,comp.os.386bsd.apps
Subject: Re: XFree86-2.0, NetBSD-current, shared libs
Date: 21 Nov 1993 19:16:05 GMT
Organization: Rechenzentrum Uni-Mannheim
Lines: 247
Message-ID: <2coepl$7qj@darum.uni-mannheim.de>
References: <2clt2o$gpu@news.rhrz.uni-bonn.de>
NNTP-Posting-Host: wipux2.wifo.uni-mannheim.de

In article <2clt2o$gpu@news.rhrz.uni-bonn.de>,
Henry G. Juengst <juengst@saph2.physik.uni-bonn.de> wrote:
>questions. Later when the following problems are sovled I could publish
>the new files + patches.
a patch which solves all the problems except that libphigs is still
built statically, was posted a short time ago to 
netbsd-current-users@sun-lamp.cs.berkeley.edu
(The fact that libphigs is not built as a shared-libs is due to
 the fact that it is not built the same way as the others, and it's
 to much trouble to create a new patch just for 1 library.

>  available). Initialize.c from the libXt reports an "Unresolved inheritance
>  ...
>  isn't it ? Does anybody have a good idea how to solve this problem ?

You should do:
COPTS=-DEXPERIMENTAL ; export COPTS
and recompile /usr/src/gnu/usr.bin/ld

following is the patch for XFree86-2.0:

To: xfree86-beta@physics.su.oz.au
Cc: current-users@sun-lamp.cs.berkeley.edu
Subject: Yet another patch for XFree-2.0 for shared libraries
Date: Mon, 15 Nov 1993 15:07:53 -0500
From: John Brezak <brezak@ch.hp.com>

Since I haven't seen what should be the *right* patch for XFree-2.0 NetBSD shared
libraries, I'll add this one to the maze. All of the others are *flawed* IMHO 'cause
they fell back to the Sun shlib behavior or were plain broken.

Features of this patch:

- No source code changes - Just config/x386.cf and lib/Xmu/Imakefile
- Add new shlib type - config/netbsdLib.{tmpl,rules}
- No libxx.sa's needed
- libXt based apps work
- libXmu only apps work
- Tested with netbsd-current 11/14/93
- Started verison numbers at 5.0 (for most things)
- Added a -DBSDSHLIB (not used) for just in case...

*** config/x386.cf.orig	Mon Nov 15 14:56:02 1993
--- config/x386.cf	Mon Nov 15 14:56:05 1993
***************
*** 978,983 ****
--- 978,988 ----
  # define CppCmd			/usr/libexec/cpp
  #endif
  
+ #ifdef i386NetBsd
+ # define ForceNormalLib YES
+ # include <netbsdLib.rules>
+ #endif
+ 
  #if HasGcc
  # define AnsiCCOptions		/**/
  # if HasGcc2
*** /dev/null	Mon Nov 15 02:34:33 1993
--- config/netbsdLib.rules	Fri Nov 12 07:43:50 1993
***************
*** 0 ****
--- 1,72 ----
+ XCOMM $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
+ 
+ /*
+  * NetBSD shared library rules
+  */
+ 
+ #ifndef HasSharedLibraries
+ #define HasSharedLibraries YES
+ #endif
+ #ifndef SharedDataSeparation
+ #define SharedDataSeparation NO
+ #endif
+ #ifndef SharedCodeDef
+ #define SharedCodeDef
+ #endif
+ #ifndef SharedLibraryDef
+ #define SharedLibraryDef -DBSDSHLIB
+ #endif
+ #ifndef ShLibIncludeFile
+ #define ShLibIncludeFile <netbsdLib.tmpl>
+ #endif
+ #ifndef SharedLibraryLoadFlags
+ #define SharedLibraryLoadFlags -Bshareable -assert pure-text
+ #endif
+ #ifndef PositionIndependentCFlags
+ #define PositionIndependentCFlags -fpic
+ #endif
+ 
+ /*
+  * InstallSharedLibrary - generate rules to install the shared library.
+  */
+ #ifndef InstallSharedLibrary
+ #define	InstallSharedLibrary(libname,rev,dest)				@@\
+ install:: Concat(lib,libname.so.rev) 					@@\
+ 	MakeDir($(DESTDIR)dest)						@@\
+ 	$(INSTALL) -c $(INSTLIBFLAGS) Concat(lib,libname.so.rev) $(DESTDIR)dest @@\
+ 
+ #endif /* InstallSharedLibrary */
+ 
+ /*
+  * InstallSharedLibraryData - generate rules to install the shared library data
+  */
+ #ifndef InstallSharedLibraryData
+ #define	InstallSharedLibraryData(libname,rev,dest)
+ #endif /* InstallSharedLibraryData */
+ 
+ /*
+  * NormalSharedLibraryTarget - generate rules to create a shared library;
+  * build it into a different name so that the we do not hose people by having
+  * the library gone for long periods.
+  */
+ #ifndef SharedLibraryTarget
+ #define SharedLibraryTarget(libname,rev,solist,down,up)			@@\
+ AllTarget(Concat(lib,libname.so.rev))					@@\
+ 									@@\
+ Concat(lib,libname.so.rev):  solist					@@\
+ 	$(RM) $@~							@@\
+ 	(cd down; $(LD) -o up/$@~ $(SHLIBLDFLAGS) solist $(REQUIREDLIBS)) @@\
+ 	$(RM) $@ 							@@\
+ 	$(MV) $@~ $@							@@\
+ 									@@\
+ clean::									@@\
+ 	$(RM) Concat(lib,libname.so.rev)
+ 
+ #endif /* SharedLibraryTarget */
+ 
+ /*
+  * SharedLibraryDataTarget - generate rules to create shlib data file;
+  */
+ #ifndef SharedLibraryDataTarget
+ #define SharedLibraryDataTarget(libname,rev,salist)
+ #endif /* SharedLibraryDataTarget */
*** /dev/null	Mon Nov 15 02:34:33 1993
--- config/netbsdLib.tmpl	Mon Nov 15 15:00:37 1993
***************
*** 0 ****
--- 1,81 ----
+ XCOMM $XConsortium: sunLib.tmpl,v 1.14.1.2 92/11/11 09:55:02 rws Exp $
+ 
+ /*
+  * NetBSD shared library template
+  */
+ 
+ #ifndef SharedXlibRev
+ #define SharedXlibRev 5.0
+ #endif
+ #ifndef SharedOldXRev
+ #define SharedOldXRev 5.0
+ #endif
+ #ifndef SharedXtRev
+ #define SharedXtRev 5.0
+ #endif
+ #ifndef SharedXawRev
+ #define SharedXawRev 5.0
+ #endif
+ #ifndef SharedXmuRev
+ #define SharedXmuRev 5.0
+ #endif
+ #ifndef SharedXextRev
+ #define SharedXextRev 5.0
+ #endif
+ #ifndef SharedXinputRev
+ #define SharedXinputRev 5.0
+ #endif
+ #ifndef SharedXTrapRev
+ #define SharedXTrapRev 1.0
+ #endif
+ #ifndef SharedPexRev
+ #define SharedPexRev 1.0
+ #endif
+ 
+ SHLIBLDFLAGS = SharedLibraryLoadFlags
+ PICFLAGS = PositionIndependentCFlags
+ 
+ /*
+  * and now a little bit of magic for using imake without source tree; if we
+  * are using shared libraries, we really do not need to depend on anything
+  */
+ #if SharedLibXpm
+         DEPXPMLIB = 
+            XPMLIB = _Use(-lXpm,-L$(XPMSRC)/lib -lXpm)
+ #endif
+ #if SharedLibXext
+   DEPEXTENSIONLIB = 
+      EXTENSIONLIB = _Use(-lXext,-L$(EXTENSIONSRC)/lib -lXext)
+ #endif
+ #if SharedLibX
+           DEPXLIB = $(DEPEXTENSIONLIB)
+              XLIB = $(EXTENSIONLIB) _Use(-lX11,-L$(XLIBSRC) -lX11)
+ #endif
+ #if SharedLibXmu
+         DEPXMULIB = 
+        XMULIBONLY = _Use(-lXmu,-L$(XMUSRC) -lXmu)
+            XMULIB = _Use(-lXmu,-L$(XMUSRC) -lXmu -L$(TOOLKITSRC) -L$(EXTENSIONSRC)/lib -L$(XLIBSRC))
+ #if !defined(UseInstalled) && !defined(XawClientLibs)
+ #define XawClientLibs $(XAWLIB) $(XMULIBONLY) $(XTOOLLIB) $(XLIB)
+ #endif
+ #endif
+ #if SharedOldLibX
+        DEPOLDXLIB = 
+           OLDXLIB = _Use(-loldX,-L$(OLDXLIBSRC) -loldX)
+ #endif
+ #if SharedLibXt
+       DEPXTOOLLIB = 
+          XTOOLLIB = _Use(-lXt,-L$(TOOLKITSRC) -lXt)
+ #endif
+ #if SharedLibXaw
+         DEPXAWLIB = 
+            XAWLIB = _Use(-lXaw,-L$(AWIDGETSRC) -lXaw)
+ #endif
+ #if SharedLibXinput
+         DEPXILIB = 
+            XILIB = _Use(-lXi,-L$(XILIBSRC) -lXi)
+ #endif
+ #if SharedLibPex
+         DEPPEXLIB = 
+            PEXLIB = _Use(-lPEX5,-L$(PEXLIBSRC) -lPEX5)
+ #endif
*** lib/Xmu/Imakefile.orig	Mon Nov 15 14:56:35 1993
--- lib/Xmu/Imakefile	Sun Nov 14 16:11:03 1993
***************
*** 11,17 ****
  #define DoProfileLib ProfileLibXmu
  #include <Library.tmpl>
  
! #if defined(RsArchitecture) || SunPost411FCSLd
  #if DoNormalLib
  REQUIREDLIBS = -L../$(TOOLKITSRC) -lXt -L../$(EXTENSIONSRC)/lib -lXext -L../$(XLIBSRC) -lX11
  #else
--- 11,17 ----
  #define DoProfileLib ProfileLibXmu
  #include <Library.tmpl>
  
! #if defined(RsArchitecture) || SunPost411FCSLd || defined(i386NetBsd)
  #if DoNormalLib
  REQUIREDLIBS = -L../$(TOOLKITSRC) -lXt -L../$(EXTENSIONSRC)/lib -lXext -L../$(XLIBSRC) -lX11
  #else


--- end of the patch

Enjoy
-- 
Eat the rich -- the poor are tough and stringy.