|
| Hi!
I am running a series of tests on a configuration with 2 nodes running
AIX 5.1 and GPFS 2.1.
When I try to run on both nodes of my system, multiple instances of a
program(LISTING-1) that sets a "blocking write lock", reads and
updates a specific region of a file, the processes on one node always
seem to hang without any error message.
Note that the same program runs perfectly well on JFS.
The problem in this case seems to be the fcntl() system call.
A modification of the program in which I use repeated non blocking
attempts works. But in this case I have to check for the (errno ==
EBUSY) after the fcntl() call.
This again is not the expected standard POSIX behavior!
I have observed problems with other applications as well that may be
related to the above bug(?). For one instance applications that use
C-ISAM that work well on a standard FS, hang when the ISAM file is on
GPFS and processes from both nodes try to concurrenty lock and update.
Does anyone has experience on the specific issue?
Thanks
---------------LISTING 1-----------------------------------------
#include <limits.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <errno.h>
#define BUFFSIZE 262144
#define ULONGSIZE sizeof(unsigned long)
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main(int argc, char ** argv){
int fd;
ssize_t rdBytes;
pid_t pid;
struct flock lock;
char progid[255];
struct utsname sysinfo;
off_t fd_offset;
unsigned long value;
char buff[BUFFSIZE]; /* 256K BUFFER */
/* Compose an identity string for the running process
nodename:progname:pid: */
pid = getpid();
uname(&sysinfo);
sprintf( progid,
"%s:%s:%d",
sysinfo.nodename,
argv[0],
pid);
/* OPEN-CREATE FILE */
if ((fd = open("master.dat",
O_RDWR | O_CREAT,
FILE_MODE)) == -1){
fprintf(stderr, "%s Error during open() %s\n",progid,
strerror(errno));
exit(1);
}
/* BLOCKING EXCLUSIVE WRITE LOCK BUFFSIZE bytes from offset 0 */
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = BUFFSIZE;
if (( fcntl(fd, F_SETLKW, &lock) ) == -1){
fprintf( stderr,
"%s Error during fcntl :1 %s\n",
progid,
strerror(errno));
exit(1);
}
/* READ */
if (( rdBytes = read(fd, (void *) buff, BUFFSIZE)) == -1){
fprintf(stderr, "%s Error during read %s\n",progid,
strerror(errno));
exit(1);
}
/* UPDATE */
if ( rdBytes == 0){ /* Empty file put all 0 */
memset(buff,0,BUFFSIZE);
if((write(fd,(void *) buff, BUFFSIZE)) != BUFFSIZE){
fprintf( stderr,
"%s Error during write :1 () %s\n",
progid,
strerror(errno));
exit(1);
}
} else { /* update the first 4bytes as a ulong Increment by 1
current value */
memcpy(&value,&buff[0],ULONGSIZE);
value++;
memcpy(&buff[0],&value,ULONGSIZE);
/* Reset fp */
lseek(fd, 0, SEEK_SET);
if((write(fd,(void *) buff, BUFFSIZE)) != BUFFSIZE){
fprintf(stderr, "%s Error during write :2 %s\n",progid,
strerror(errno));
exit(1);
}
}
/* UNLOCK */
lock.l_type = F_UNLCK;
if (( fcntl(fd, F_SETLKW, &lock) ) == -1){
fprintf( stderr,
"%s Error during fcntl() :2 %s\n",
progid,
strerror(errno));
exit(1);
}
fsync(fd);
close(fd);
exit(0);
}
|
|