Problems with file locking (Ultrix and HP-UX)

Fletcher Kittredge fkittred at bbn.com
Tue Jul 10 04:02:02 AEST 1990


I have been testing Posix style file locking on Ultrix 4.0(FT 2)
and 3.1 on both RISC and VAX in preparation for using it in a
product.  I have had strange results.  And was hoping someone could
enlighten me.  

Problem description:

On all 4 systems, advisory file locking works correctly on local files.
However, on Ultrix 3.1 systems, locking a NFS mounted file is extremely
slow (200 times slower than locking a local file).  This seems to be
the case whether the Ultrix 3.1 system is the locking client or the
NFS server.  I tested this with the following systems being both
client and server:

Sun-3 running Sun O/S 4.0.3
Sun-4 running Sun O/S 4.0.3

HP9000 Series 800 running HP-UX 7.0
HP9000 Series 300 running HP-UX 7.0

VAX Ultrix 3.1
VAX Ultrix 4.0

RISC Ultrix 3.1
RISC Ultrix 4.0

In addition, when Ultrix 4.0(FT 2) is the client platform, and HP-UX is
the server platform, I am unable to get a lock at all.  Calling fnctl()
to lock the first time returns -1 and perror() prints the following
message on Ultrix:

No locks available

The debugger shows errno set to 75 which, according to the header
file errno.h, corresponds to the Posix error condition ENOLCK.

My test code follows.

Questions:

1) It appears that the slowness of Ultrix 3.1 locking is a known
problem which will be fixed in 4.0.  In the meantime is there a
work-around for 3.1?

2) Is the problem with locking between Ultrix 4.0 and HP-UX a known
problem, whose problem is it, and when will it be fixed?  (I am
reporting it to Ultrix Field Test).

many grateful thanks for any information,

regards,
fletcher
Fletcher E. Kittredge  fkittred at bbn.com
Lead Programmer
Platforms and Tools Group
BBN Software Products Company
10 Fawcett St.
Cambridge, MA. 02138

%%%%%%%%%%%%%Cut here %%%%%%%%%%%%%%%%

/*
 *  Program to test file locking using Posix fnctl() based file locking.
 *
 *
 *  Usage:
 *
 *     locktst [ -v level -c count ] files
 *
 * where level is the amount of verbose status information and c is the
 * number of times to lock/write/read the data.  Foreach file supplied on
 * the command line, this program opens the file, locks the file for
 * read+write, writes and reads data, and unlocks the file.
 *
 */

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/file.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>

    char *progname;

#ifdef __STDC__
main(int argc, char *argv[])
#else
main(argc, argv)
      int argc;
      char *argv[];
#endif      
{
    extern int optind, opterr;
    extern char *optarg;
    extern int errno;
    struct flock lock;	/* Posix fcntl() lock structure */
    int c;
    int fd;			/* File Des for table */
    int outbuf[1024];		/* garbage out */
    int inbuf[1024];		/* garbage in */
    int times = 100;
    int i;
    int verbose_level = 0;
    progname = argv[0];
    /* process options */
    while ((c = getopt (argc, argv, "c:v:")) != EOF)
	switch (c)
	    {
	case 'c':
	    times = atoi(optarg);
	    break;
	case 'v':
	    verbose_level = atoi(optarg);
	    break;
	default:
	    usage(1);
	    }
    /* Set values to lock whole file */
    lock.l_whence = 0;
    lock.l_start = 0;
    lock.l_len = 0;
    /*
     * For each file
     *     open the file
     * 	 for times
     * 	     lock the file
     * 	     write garbage
     * 	     read garbage
     * 	     compare garbage
     * 	     unlock file
     *     close the file
     *
     */
    for(; optind < argc; optind++)
	{
	if((fd = open(argv[optind], O_RDWR | O_CREAT, 0664)) < 0)
	    {
	    fprintf(stderr, "Failed to open file %s for read+write\n",
		    argv[optind]);
	    perror("");
	    exit(1);
	    }
	if(verbose_level > 0)
	    fprintf(stdout, "Opened file %s\n", argv[optind]);
	
	for(i=0; i < times;i++)
	    {
	    /* lock the file */
	    lock.l_type = F_WRLCK;
	    if(fcntl(fd, F_SETLK, &lock) < 0)
		switch(errno)
		    {
		    /*
		     * These three error conditions mean we can retry lock.
		     */
		case EACCES :
		case EAGAIN :
		case ETIMEDOUT :
		    fprintf(stderr, "couldn't lock file %s, retrying\n",
			    argv[optind]);
		    perror("");
		    exit(3);
		default:
		    fprintf(stderr, "couldn't lock file %s, aborting\n",
			    argv[optind]);
		    perror("");
		    exit(4);
		    }
	    if(verbose_level > 1)
		fprintf(stdout, "Locked file %s\n", argv[optind]);

	    /* write junk, read junk, compare junk */
	    if(write(fd, outbuf, sizeof(outbuf)) < 0)
		{
		fprintf(stderr, "Write on file %s failed\n",
			argv[optind]);
		perror("");
		}
	    (void)lseek(fd, SEEK_SET, 0L);
	    if(read(fd, inbuf, sizeof(inbuf)) < 0)
		{
		fprintf(stderr, "Read on file %s failed\n",
			argv[optind]);
		perror("");
		}
	    if(bcmp(outbuf, inbuf, sizeof(inbuf)) != 0)
		fprintf(stderr,
			"Data written and read do not compare.\n");
		
	    /* Unlock the file */
	    lock.l_type = F_UNLCK;
	    if(fcntl(fd, F_SETLK, &lock) < 0)
		switch(errno)
		    {
		    /*
		     * These three error conditions mean we can retry lock.
		     */
		case EACCES :
		case EAGAIN :
		case ETIMEDOUT :
		    fprintf(stderr, "couldn't unlock file %s, retrying\n",
			    argv[optind]);
		    perror("");
		    exit(3);
		default:
		    fprintf(stderr, "couldn't lock file %s, aborting\n",
			    argv[optind]);
		    perror("");
		    exit(4);
		    }
	    if(verbose_level > 1)
		fprintf(stdout, "Unlocked file %s\n", argv[optind]);
	    } /* for times */
	(void)close(fd);
	(void)unlink(argv[optind]);
	
	}
    }    

#ifdef __STDC__
usage(int status)
#else
usage(status)
      int status;
#endif      
{
    
    fprintf(stderr, "usage: %s [-v level -c count] files ...\n", progname);
    exit(1);
    }



Fletcher E. Kittredge  fkittred at bbn.com
Lead Programmer
Platforms and Tools Group
BBN Software Products Company
10 Fawcett St.
Cambridge, MA. 02138



More information about the Comp.unix.ultrix mailing list