*BSD News Article 7559


Return to BSD News archive

Xref: sserve comp.unix.sys5.r4:433 comp.bugs.sys5:1498 comp.unix.sysv386:25396 comp.unix.solaris:443 comp.unix.bsd:7609
Newsgroups: comp.unix.sys5.r4,comp.bugs.sys5,comp.unix.sysv386,comp.unix.solaris,comp.unix.bsd
Path: sserve!manuel.anu.edu.au!munnari.oz.au!sgiblab!sdd.hp.com!usc!zaphod.mps.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!agate!ames!kronos.arc.nasa.gov!iscnvx!netcomsv!dsndata!dsndata!randy
From: randy@dsndata.dsndata.com (Randy Terbush)
Subject: Bug in SysVr4 'lockd'
Message-ID: <RANDY.92Nov6125246@dsndata.dsndata.com>
Sender: randy@dsndata.uucp (Randy Terbush)
Organization: Design Data
Date: Fri, 6 Nov 1992 18:52:52 GMT
Lines: 392

The following shar file contains a program that will test the 'lockd'
program for a nasty little bug that virtually cripples any application
that uses 'rpc' calls to the 'lockd' to do file locking.

The symptoms are ~30% cpu usage by 'lockd' and severe slowing of the
machines on the network.  This program demonstates that it takes ~20
seconds to obtain locks from an ailing 'lockd'.  We have verified that
this bug does not exist in HPUX 8.0x.

The reason for this post is due to USL's lack of action towards fixing
the bug.  Documentation in the 'Makefile' get's into more detail
regarding the USL's response to the problem.  I would be interested in
knowing what other UNIX lockd's have this bug.

Katherine Woods at Dell Computer Corp. has been gracious enough to
accept mail regarding this problem, with the plan of forwarding the
responses to the USL.  As the accompanying documentation indicates,
she can be contacted at kwoods@eutopia.dell.com.

Test code is authored by Jeff Minnig, netcomsv!dsndata!jeff.

I have knowingly cross-posted this to other groups to communicate the
seemingly growing difficulties in working with an OS whose source
originates from the USL.  No flames please....

Randy Terbush ------------------------------------- Design Data, Inc.
UUCP: netcomsv!dsndata!randy ---------------------- 1033 'O' st. Suite 324
INET: randy%dsndata@netcomsv.netcom.com ----------- Lincoln, NE  68508
--------------------------------------------------- 402-476-8278

#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 11/06/1992 18:40 UTC by dsndata!randy
# Source directory /users/randy/src/lockd/locking
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   3010 -rw-rw---- Makefile
#    596 -rwxr-xr-x ltest
#   2744 -rw-r----- main.c
#    823 -rw-r----- time.c
#
# ============= Makefile ==============
if test -f 'Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping Makefile (File already exists)'
else
echo 'x - extracting Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
# Copyright Design Data, Inc.  1992, 1993
# 1033 'O' Street - Suite 324
# Lincoln, NE  68508
# 402-476-8278
X
# INTRODUCTION
#
# This Makefile will build a 'lockd' testing program that will display a
# bug in 'lockd' which exists in Dell Issue 2.2 SVR4 (and possibly others).
# Dell Computer UNIX Development personnel have made every attempt to get
# the USL to fix this problem, but have had no success.
# USL has admitted to the existance of this bug in version 4.0, 4.1,
# and 4.2 of their distributed and yet to be released sources.  This is
# a network crippling problem that they have refused to fix until
# release 4.3, which will be OVER 1 YEAR from today. (29 Oct 1992)
# If your version of 'lockd' exhibits this same problem, I would
# strongly urge you to contact your vendor and ask them to put some
# pressure on USL to fix this problem.  SVR4 is virtually useless in a
# network of shared resources while this problem exists.
X
# WHO DO I CONTACT?
#
# If you would like to send mail to kwoods@eutopia.dell.com and
# express your interest in getting this fixed, please do.  Katherine
# Woods is not the source of this posting or source and is involved only
# to help expedite these responses to USL.
X
# WHAT DO THE NUMBERS MEAN?
#
# The timings that this program displays to screen are the times
# required to lock a file on an NFS mounted filesystem.  This program has
# also been run on HPUX 8.0.  The time to lock a file using a working 'lockd'
# will be less than 1 second. (0.x)  The same test run on SVR4 takes
# ~20.0 seconds.  If you watch the system load while running
# this test, you will see that 'lockd' uses a whopping 30%! of cpu to
# handle lock requests with the brain dead version.
X
# HOW DO I TEST LOCKD?
#
# To run this test, first type 'make' in this directory to build 'lockd_test'.
# Then type 'ltest hostname' to start the test.  'ltest'
# remoteshells out to the named host and creates /tmp/locktest.  The
# script then returns to the local machine, mounts the directory on the
# host, and creates the necessary files to run the test.  'lockd_test'
# is then executed and begins displaying the times required to lock the
# files on the mounted filesystem.
# This may not work on your network due to permissions for execution
# of /etc/mount, uid mapping, filesystem sharing, etc..  If you have
# problems, take a look at ltest to see the necessary steps.
# IMPORTANT: The files you are locking must exist on the remote
# filesystem.  Not the local filesystem.
X
# CODE AUTHOR
#
# Jeff Minnig - dsndata!jeff
X
# MYSELF - (Head Problem Causer)
#
# Randy Terbush - dsndata!randy
X
X
# CHOOSE YOUR COMPILER
CC= gcc
#CC=cc
X
# Uncomment the appropriate define flags
CFLAGS= -O -DSYSV386
# Uncommenting the following will work for BSD type (HPUX in our case) systems.
#CFLAGS=	-O
X
all : lockd_test
X
main.o : main.c
X	$(CC) $(CFLAGS) -c main.c
X
time.o : time.c
X	$(CC) $(CFLAGS) -c time.c
X
lockd_test : main.o time.o
X	$(CC) $(CFLAGS) -o lockd_test main.c time.c
X
clean :
X	rm -rf *~ *.o
X
SHAR_EOF
chmod 0660 Makefile ||
echo 'restore of Makefile failed'
Wc_c="`wc -c < 'Makefile'`"
test 3010 -eq "$Wc_c" ||
	echo 'Makefile: original size 3010, current size' "$Wc_c"
fi
# ============= ltest ==============
if test -f 'ltest' -a X"$1" != X"-c"; then
	echo 'x - skipping ltest (File already exists)'
else
echo 'x - extracting ltest (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ltest' &&
#! /bin/sh
X
if [ $# -lt 1 ]
then
X	echo "ltest: Usage is 'ltest hostname'\n"
X	exit 1
fi
X
mkdir /tmp/locktest
X
filelist="0 1 2 3 4 5 6 7 8 9 A B C D E F"
X
rsh $1 mkdir /tmp/locktest
X
# The following mount command works on HPUX 8.0
# mount $1:/tmp/locktest /tmp/locktest -t nfs
X
# The following mount command works on Dell Issue 2.2
mount -F nfs $1:/tmp/locktest /tmp/locktest
X
# IMPORTANT
# The mounts must be in place before creating the following files.
# The files you are locking, must exist on the remote machine.
X
for i in $filelist
do
X        cp /dev/null /tmp/locktest/$i
done
X
../lockd_test
SHAR_EOF
chmod 0755 ltest ||
echo 'restore of ltest failed'
Wc_c="`wc -c < 'ltest'`"
test 596 -eq "$Wc_c" ||
	echo 'ltest: original size 596, current size' "$Wc_c"
fi
# ============= main.c ==============
if test -f 'main.c' -a X"$1" != X"-c"; then
	echo 'x - skipping main.c (File already exists)'
else
echo 'x - extracting main.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'main.c' &&
/* Copyright Design Data, Inc.  1992, 1993 */
/* 1033 'O' Street - Suite 324 */
/* Lincoln, NE  68508 */
/* Author - Jeff Minnig - dsndata!jeff */
X
#include	<stdio.h>
#include	<sys/types.h>
#include	<unistd.h>
#include	<stdlib.h>
#include	<fcntl.h>
#include	<sys/stat.h>
#include	<errno.h>
X
#define TOTAL_ITERATIONS	10
X
#define NF 16
X
X
static char	*lock_names[ NF ] = 
{
X    "/tmp/locktest/0",
X    "/tmp/locktest/1",
X    "/tmp/locktest/2",
X    "/tmp/locktest/3",
X    "/tmp/locktest/4",
X    "/tmp/locktest/5",
X    "/tmp/locktest/6",
X    "/tmp/locktest/7",
X    "/tmp/locktest/8",
X    "/tmp/locktest/9",
X    "/tmp/locktest/A",
X    "/tmp/locktest/B",
X    "/tmp/locktest/C",
X    "/tmp/locktest/D",
X    "/tmp/locktest/E",
X    "/tmp/locktest/F"
X    };
X
X
X
static int	lock_fds[ NF ];
static int	lock_flag[ NF ];
X
extern unsigned long elapsed( void );
X
int main( int argc, char **argv )
{
X    int	ret;
X    int	cnt;
X    int sub_cnt;
X    unsigned long	cycle_elapsed = (unsigned long) 0;
X    unsigned long	total_elapsed = (unsigned long) 0;
X
X
/************************************************************************/
/*									*/
/* open the files							*/
/*									*/
/************************************************************************/
X
X    for( cnt = 0; cnt < NF; cnt++ )
X    {
X	lock_fds[ cnt ] = open( lock_names[ cnt ], O_RDWR );
X	if( lock_fds[ cnt ] < 0 )
X	{
X	    perror( lock_names[ cnt ] );
X	}
X    }
X
X
/************************************************************************/
/*									*/
/* loop, lock, unlock							*/
/*									*/
/************************************************************************/
X
X    for( cnt = 0; cnt < TOTAL_ITERATIONS; cnt++ )
X    {
X	fprintf( stderr, "Iteration %d\n", cnt );
X
X	(void) elapsed();
X	for( sub_cnt = 0; sub_cnt < NF; sub_cnt++ )
X	{
X	    lock_flag[ sub_cnt ] = 0;
X
X	    ret = lockf( lock_fds[ sub_cnt ], F_TLOCK, 0 );
X	    if( ret < 0 )
X	    {
X		fprintf( stderr, "Error locking: sub(%03d,%02d) - errno = %d\n", cnt, sub_cnt, errno );
X		continue;
X	    }
X
X	    lock_flag[ sub_cnt ] = 1;
X	    
X
X	}
X
X	for( sub_cnt = 0; sub_cnt < NF; sub_cnt++ )
X	{
X	    if( lock_flag[ sub_cnt ] )
X	    {
X
X		ret = lockf( lock_fds[ sub_cnt ], F_ULOCK, 0 );
X		if( ret < 0 )
X		{
X		    fprintf( stderr, "Error unlocking: sub(%03d,%02d) - errno = %d\n", cnt, sub_cnt, errno );
X		    continue;
X		}
X
X		lock_flag[ sub_cnt ] = 0;
X	    }
X	}
X	
X	cycle_elapsed = elapsed();
X	total_elapsed += cycle_elapsed;
X
X	fprintf( stderr, "%3d: elapsed time: %3d.%2d seconds\n", cnt, cycle_elapsed / 100, cycle_elapsed % 100 );
X	(void) elapsed();
X	
X    }
X
X    
X    fprintf( stderr, "Total elapsed: %d.%d seconds\n", total_elapsed / 100, total_elapsed % 100 );
X
X    for( cnt = 0; cnt < NF; cnt++ )
X	close( lock_fds[ cnt ] );
X
X    return 0;
}
SHAR_EOF
chmod 0640 main.c ||
echo 'restore of main.c failed'
Wc_c="`wc -c < 'main.c'`"
test 2744 -eq "$Wc_c" ||
	echo 'main.c: original size 2744, current size' "$Wc_c"
fi
# ============= time.c ==============
if test -f 'time.c' -a X"$1" != X"-c"; then
	echo 'x - skipping time.c (File already exists)'
else
echo 'x - extracting time.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'time.c' &&
/* Copyright Design Data, Inc.  1992, 1993 */
/* 1033 'O' Street - Suite 324 */
/* Lincoln, NE  68508 */
/* Author - Jeff Minnig - dsndata!jeff */
X
#include	<stdio.h>
#include	<sys/time.h>
#include	<sys/times.h>
#include	<stdlib.h>
#include	<unistd.h>
X
int	gettimeofday ();
X
static struct timeval	start = { 0, 0 };
X
unsigned long elapsed (void)
{
X    struct timeval stop;
X    struct timeval e;
X    struct timezone tz;
X    
X    gettimeofday( &stop, &tz );
X    
X    if ( ! timerisset( &start ) )
X    {
X	start = stop;
X	return( 0 );
X    }
X    
X    if (start.tv_usec > stop.tv_usec)
X    {
X	stop.tv_usec += 1000000;
X	stop.tv_sec -= 1;
X    }
X    
X    e.tv_usec = stop.tv_usec - start.tv_usec;
X    e.tv_sec = stop.tv_sec - start.tv_sec;
X
X    start = stop;
X
X    return (e.tv_sec * 100) + (e.tv_usec / 10000); /* return 100ths	*/
}
X
SHAR_EOF
chmod 0640 time.c ||
echo 'restore of time.c failed'
Wc_c="`wc -c < 'time.c'`"
test 823 -eq "$Wc_c" ||
	echo 'time.c: original size 823, current size' "$Wc_c"
fi
exit 0