Liebe Leser,
Das Beilegen einer CD-ROM zu einem Buch verursacht nicht nur Kosten
von einigen Euro pro Buch, sondern geht vor allem zu Lasten der
Umwelt. Da außerdem alle Programme aus dem Buch in der Regel mit jeder
Linux-Distribution mitgeliefert werden, haben wir auf eine CD-ROM verzichtet.
Auf Wunsch einiger Leser gibt es hier die wenigen und kleinen im Buch
enthaltenden Programme und Skripten zum Download. Sie können diese
beliebig nutzen, ändern und weiterverbreiten. Jegliche Gewährleistung
ist aber ausgeschlossen. Die Benutzung ist auf eigene Gefahr.
Die genauen Einzelheiten hierzu regelt die
GNU General Public License von Version 2
oder später.
Startskript für Logsurfer
Das Startskript /etc/init.d/logsurfer auf Seite 40 (1. Auflage: Seite 38): ### BEGIN INIT INFO
# Provides: logsurfer
# Required-Start: $syslog
# Required-Stop: $syslog
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: logsurfer log analyser
### END INIT INFO
. /etc/rc.status
rc_reset
case "$1" in
start)
echo -n "Starting logsurfer "
startproc /usr/bin/logsurfer -f /var/logsurfer.fifo
rc_status -v
;;
stop)
echo -n "Shutting down logsurfer "
killproc -TERM /usr/bin/logsurfer
rc_status -v
;;
restart)
$0 stop
$0 start
rc_status
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
rc_exit
| |   |
|
Signaltestprogramm
Das Signaltestprogramm aus Abschnitt 7.3.3 (die kompilierte Version muss mit
chmod +x sigtest ausführbar gemacht werden):
#include <stdio.h>
/* Signalhandler: Gibt eine Zeile mit der Signalnummer aus. */
signal_handler(int signum)
{
printf("Signal %d empfangen.\n", signum);
}
/* Hauptfunktion: Installiert fuer alle Signale von 1 bis 31 den Handler,
geht danach in eine endlose Warteschleife */
main()
{
int i; /* deklariere Variable i */
for (i=1; i<32; i++) /* Schleife ueber alle 32 Signale */
signal(i, signal_handler); /* installiere Handler fuer Signal i */
while (1) sleep(1); /* Endlosschleife */
}
| |   |
|
Lese-Performance (nur 2. Auflage)
Das Programm readperf zum Testen der Platten-Lesegeschwindigkeit
aus Abschnitt 9.3 der 2. Auflage (die kompilierte Version muss mit
chmod +x readperf ausführbar gemacht werden)
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/timeb.h>
#include <sys/types.h>
#include <linux/fs.h>
#define BLOCKSIZE 512
#define NUMBLOCKS 2048 /* 1MB */
#define READSIZE (NUMBLOCKS * BLOCKSIZE)
#define READTIME 5 /* sec */
#define SEEKTIME 5 /* sec */
double timediff(struct timeb *before, struct timeb *after)
{
return (double)(after->time - before->time)
+ (double)(after->millitm - before->millitm) / 1000.0;
}
off64_t determine_filesize(int fd, long long blocksize)
{
off64_t endoffset;
unsigned long size_in_blocks;
if (0 == ioctl(fd, BLKGETSIZE, &size_in_blocks))
return (long long)size_in_blocks * blocksize;
else { // try seeking
lseek64(fd, 0, SEEK_SET);
endoffset = lseek64(fd, 0, SEEK_END);
if (endoffset == 0)
fprintf(stderr, "Cannot determine size of device: %s\n",
strerror(errno));
return endoffset;
}
}
void readperf(int fd, char *scratch, int readsize)
{
int readcount = 0;
struct timeb before, after;
double td;
double megabytes;
ftime(&before);
do {
size_t readbytes = read(fd, scratch, readsize);
if (readbytes != readsize) {
if (errno)
fprintf(stderr, "Error reading data: %s\n",
strerror(errno));
else
fprintf(stderr, "%ld bytes read instead of %ld.\n",
readbytes, readsize);
return;
}
readcount++;
ftime(&after);
} while (after.time - before.time < READTIME);
megabytes = (double)(readcount * readsize) / 1048576.0;
td = timediff(&before, &after);
printf("%6.2f MB/sec ", megabytes / td);
fflush(stdout);
}
void seekperf(int fd, char *scratch, long long blocksize)
{
int seekcount=0;
struct timeb before, after;
double td_ms;
off64_t endoffset;
long long numblocks;
endoffset = determine_filesize(fd, blocksize);
if (!endoffset) {
fprintf(stderr, "Cannot determine size of device/file.\n");
return;
}
numblocks = endoffset / blocksize;
ftime(&before);
srandom(before.time + before.millitm); /* avoid cache */
do {
long long blocknr = (long long)(random()) % numblocks;
lseek64(fd, blocknr * blocksize, SEEK_SET);
read(fd, scratch, blocksize);
seekcount++;
ftime(&after);
} while (after.time - before.time < SEEKTIME);
td_ms = timediff(&before, &after) * 1000.0;
printf("%5.1f ms/seek\n", td_ms / seekcount);
}
void perform_test(char *devname, char *scratch)
{
int fd;
printf("%-17s ", devname);
fflush(stdout);
/* Open raw device for reading */
fd = open(devname, O_RDONLY);
if (fd < 0) {
printf("Cannot open for reading: %s\n", strerror(errno));
return;
}
readperf(fd, scratch, READSIZE);
seekperf(fd, scratch, BLOCKSIZE);
close(fd);
}
main(int argc, char **argv)
{
char *scratch;
int dev;
if (argc < 2) {
fprintf(stderr, "Usage: %s DEVICE1 DEVICE2 ...\n", argv[0]);
exit(1);
}
/* allocate block-aligned memory for reading data into */
if (posix_memalign(&scratch, BLOCKSIZE, READSIZE)) {
fprintf(stderr, "Cannot allocate aligned memory: %s\n",
strerror(errno));
exit(3);
}
printf("IO performance test version 1.0.0 "
"-- Copyright Mathias Kettner\n"
"This software is licensed under GPL "
"- use at your own risk.\n"
"\n"
"DEVICE CONTINOUS RANDOM SEEK\n"
"---------------------------------------------------\n");
for (dev=1; dev<argc; dev++)
perform_test(argv[dev], scratch);
free(scratch);
}
| |   |
|
Dateisystem-Performance (nur 2. Auflage)
Das Programm fsperf zum Testen der Performance von verschiedenen
Dateisystemen, passend zu Abschnitt 9.4 der 2. Auflage:
#!/bin/bash
#
# fsperf - Performance measurement of filesystems
#
# Copyright Mathias Kettner 2004
#
# You can use this software under the terms of the GNU
# General Public License Version 2 or later. Please refer
# to http://mathias-kettner.de/diagnosebuch_downloads.html.
#
function pt_mkdir
{
time for i in 0 1 2 3 4 5 6 7 8 9
do
mkdir -p $i-{a,b,c}{,/}{1,2,3}{,/}{u,v,w}{,/}{g,h,i}{x,y,z}{3,4,5}
done
}
function pt_find
{
time find > /dev/null
}
function pt_touch
{
time for i in 0 1 2 3 4 5 6 7 8 9
do
touch $i-{a,b,c}{,/}{1,2,3}{,/}{u,v,w}{,/}{g,h,i}{x,y,z}{3,4,5}/HIRNI
done
}
function pt_write1gb
{
time dd if=/dev/zero of=1gb bs=1M count=1024
}
function pt_read1gb
{
time dd if=1gb of=/dev/null bs=1M count=1024
}
function performance_test
{
for pt in mkdir find touch write1gb read1gb
do
echo -n $pt:' '
TIME="$(pt_$pt 2>&1 | grep real | sed 's/^real[[:space:]]*//')"
printf "\033[1m%9s\033[m " "$TIME"
done
}
function usage
{
cat <<EOF >&2
Usage: fsperf BLOCK-DEVICE
WARNUNG: BLOCK-DEVICE will be deleted!
EOF
exit 5
}
[ "$#" == 1 ] || usage
DEVICE="$1"
[ -b "$DEVICE" ] || {
echo "$DEVICE is not a block special device" >&2
exit 5
}
mount | grep -q "^$DEVICE[[:space:]]" && {
echo "$DEVICE is already mounted! Please choose another device." >&2
exit 5
}
echo -n "Proceed using $DEVICE? All data will be lost! [N/y] "
read SURE
[ "$SURE" = y -o "$SURE" = Y ] || {
echo "Cancelled." >&2
exit 5
}
MOUNTPOINT=/tmp/fsperf.mp
mkdir -p $MOUNTPOINT || {
echo "Cannot create mount point $MOUNTPOINT" >&2
exit 5
}
trap "cd / ; umount $MOUNTPOINT ; echo Killed. ; exit 9" 2 3 15
for FS in ext2 ext3 reiserfs jfs ext3 ext2 jfs reiserfs jfs
do
printf "%-10s " $FS
yes | mkfs -t $FS $DEVICE > /dev/null 2>&1 || { echo " - failed" ; continue; }
mount -t $FS $DEVICE $MOUNTPOINT
cd $MOUNTPOINT
performance_test
cd -
umount $MOUNTPOINT
echo
done
| |   |
|
|