home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / unix / aix / 13575 < prev    next >
Encoding:
Text File  |  1993-01-21  |  5.3 KB  |  159 lines

  1. Newsgroups: comp.unix.aix
  2. Path: sparky!uunet!psinntp!stiatl!jer
  3. From: jer@stiatl.salestech.com (John Ramspott)
  4. Subject: NFS File locking in AIX (bug)
  5. Message-ID: <1993Jan20.223356.2353@stiatl.salestech.com>
  6. Organization: Sales Technologies, Inc.
  7. Date: Wed, 20 Jan 1993 22:33:56 GMT
  8. Lines: 149
  9.  
  10. Hello AIX developers,
  11.  
  12.  
  13. We cannot
  14. get file-locking working when two different processes are trying to
  15. append to the file from two DIFFERENT machines via NFS. The Info
  16. Explorer says that the NFS file lock manager supports the SVID
  17. advisory locking, namely fcntl() and lockf(). We use fcntl() because
  18. it is a part of POSIX and XPG3. The bottom line is we have tried lots
  19. of different things, and the resulting data file contains errors. Typically,
  20. a record from one process will overwrite a partial record, an entire record,
  21. or even multiple records of the other process. The locking does work if
  22. all processes are on the same machine.
  23.  
  24. We have spent over two days trying to get this to work, throwing me off
  25. schedule quite a bit. This was suppose to just work :-). I give it a
  26. very high priority. Running one of the processes on the NFS Server machine
  27. (Barney in our case) seems to make very little difference. If two different
  28. machines are used, you usually get errors.
  29.  
  30. The program will open a file called trylock.dat in the current directory,
  31. and will append 500 records to it. It also opens trylock.dat.lock, but
  32. never writes to it. The code as I am sending it does not use the lock file
  33. (it locks the file being written to), but changing the second fd parameter
  34. in writeline() call to fdl will have the program lock the lock file instead.
  35. This did not help; in fact, the resulting data file had garbage in it (same
  36. as if you had no locking at all).
  37.  
  38. The current program locks the entire file. We have tried variations
  39. of just locking from the end-of-file the size of the message to be
  40. written. This also failed the multi-node test. We would prefer to
  41. just do record locking.
  42.  
  43. The program writes out what it believes to be the end-of-file position
  44. and iteration number (loop position). If multiple processes are running,
  45. no value for file_ptr for one process should EVER match one from the
  46. other. This however does happen, causing one to overwrite the others data.
  47.  
  48. Sample Program usage:
  49.  
  50. trylock aaaaa > out1  (on machine 1)
  51. trylock BBBBBBB > out2 (on machine 2)
  52.  
  53. Whatever you pass trylock, that is the buffer it appends to the trylock.dat
  54. file. We have noticed that using different sized buffers for each
  55. invocation makes errors in the file more obvious.
  56.  
  57. Thank you,
  58. John E. Ramspott
  59. Software Engineer
  60. Sales Technologies, Inc.
  61. jer@salestech.com
  62. (404) 841-4986
  63.  
  64. Compile with: c89 -o trylock trylock.c -D_ALL_SOURCE
  65. -------------------  trylock.c ---------------------------
  66. #include <unistd.h>
  67. #include <stdlib.h>
  68. #include <string.h>
  69. #include <stdio.h>
  70. #include <fcntl.h>
  71. #include <sys/types.h>
  72. #include <sys/stat.h>
  73.  
  74. short count;
  75.  
  76. short writeline( int fd, int fdl, char *message )
  77. {
  78.    int status;
  79.    int msg_length;
  80.    off_t file_ptr;
  81.    struct flock alock;
  82.  
  83.    msg_length = strlen( message );
  84.  
  85.    /* Note that this locks the entire file. We initially were using */
  86.    /* whence = SEEK_END, start = 0, and len = msg_length, to only */
  87.    /* lock the record we want to write to. This seems to produce the */
  88.    /* same affect as locking the whole file -- overlapping records from */
  89.    /* different nodes. We would prefer to just lock the area we are adding */
  90.    /* to the end of file. */
  91.    alock.l_type = F_WRLCK;
  92.    alock.l_whence = SEEK_SET;
  93.    alock.l_start = 0;
  94.    alock.l_len = 0;
  95.    status = fcntl( fdl, F_SETLKW, &alock );
  96.    if (status == -1)
  97.       return( -3 );
  98.  
  99.    file_ptr = lseek( fd, 0, SEEK_END );
  100.    printf( "file_ptr = %ld  iteration = %d\n", file_ptr, count );
  101.  
  102.    status = write( fd, message, msg_length );
  103.    if (status == -1)
  104.       return( -4 );
  105.  
  106.    alock.l_type = F_UNLCK;
  107.    alock.l_whence = SEEK_SET;
  108.    alock.l_start = 0;
  109.    alock.l_len = 0;
  110.    status = fcntl( fdl, F_SETLKW, &alock );
  111.    if (status == -1)
  112.       return( -1 );
  113.  
  114.    return( 0 );
  115. }
  116.  
  117.  
  118. main( int argc, char *argv[] )
  119. {
  120.    int fd, fdl;
  121.    char writeBuff[ BUFSIZ ];
  122.    short status;
  123.  
  124.    strcpy( writeBuff, argv[1] );
  125.    strcat( writeBuff, "\n" );
  126.  
  127.    /* We have experimented with not using O_APPEND and using */
  128.    /* lseek(), and doing both. We have also experimented with */
  129.    /* the O_SYNC flag, with no noticeable affect */
  130.    fd = open( "trylock.dat", O_CREAT | O_RDWR | O_APPEND,
  131.               S_IRUSR | S_IWUSR );
  132.  
  133.    fdl = open( "trylock.dat.lock", O_CREAT | O_RDWR,
  134.               S_IRUSR | S_IWUSR );
  135.  
  136.    for (count = 0; count < 500; count++ )
  137.    {
  138.       /* The second fd parameter below is the fd to use for file */
  139.       /* locking. Using fdl for the second parameter will cause it */
  140.       /* to use a separate lock file instead of the one we are writing */
  141.       /* to. Using a separate file for locking actually made the resulting */
  142.       /* data contain more garbage and errors for us */
  143.       status = writeline( fd, fd, writeBuff );
  144.       if (status != 0)
  145.          printf( "status = %d  writeBuff = %s", status, writeBuff );
  146. /*      usleep( 400000 );  Sleeping increases interleaving, but does */
  147. /* not solve the problem of overlapping records. */
  148.    }
  149.  
  150.    close( fd );
  151.    close ( fdl );
  152. }
  153. ------------------- end of trylock.c ------------------------
  154.  
  155. -- 
  156. John E. Ramspott
  157. Amiga Fanatic at Large
  158. ..!uupsi!stiatl!jer   (uupsi is a direct internet connection)
  159.