Well, I'm happy to report that the bug we reported a couple weeks
ago (Subject: weird open() bug with O_CREAT|O_WRONLY|O_APPEND) has
been fixed with the latest release of PVFS2.

Unfortunately, the same person who uncovered that bug has reported
another one.

Background:  UNIX files are deleted (in the sense that an inode gets
freed up) only if _both_ the following are true: (1) the link count
is zero; (2) no process has the file open.

It's therefore a rather common idiom to do something like ...

        fd = open(file,args);
        unlink(file);
        read(fd);

The file itself gets deleted when the "close(fd)" is done.  Sorry
to report that the current release of PVFS2 doesn't work this way.
If an unlink() is done to an open file, a subsequent read() on the
file descriptor returned by the open() (done prior to the unlink())
will return zero.

A simple test program is appended below.  To demonstrate the problem,
compile both without and with "-DBAD" (the unlink() gets done if and
only if "-DBAD" is used), then run the program both on a file in some
locally-mounted filesystem and on a PVFS2 filesystem.  First, we do it
in /tmp ...

shc> pwd
/tmp
shc> 
shc> cc -o good bug.c
shc> cc -DBAD -o bad bug.c
shc> 
shc> echo foo bar spam >file
shc> echo bozo snarf! >>file
shc> 
shc> /tmp/good file
OLD CONTENTS:
foo bar spam
bozo snarf!
shc> 
shc> /tmp/bad file
OLD CONTENTS:
foo bar spam
bozo snarf!
shc> 

But when run on a PVFS2 filesystem ...

shc> pwd
/pvfs/scratch/test/mark
shc> 
shc> echo foo bar spam >file
shc> echo bozo snarf! >>file
shc> 
shc> /tmp/good file
OLD CONTENTS:
foo bar spam
bozo snarf!
shc> 
shc> /tmp/bad file
OLD CONTENTS:
shc> 

It turns out that many programs depend on being able to read() after
doing an unlink().  For example, the person who first stumbled across
this problem had done something like "perl -pi -e 's/foo/bar/' file",
only to find the file had been truncated to zero length!  A quick bit
of playing around with "strace" revealed what "perl" was doing:  It's
opening the input file and then unlinking it; then creating a new file
with the same name to receive the output.  But when it starts to read
its input, it gets an immediate EOF.

Is this a bug, or do design constraints preclude PVFS2 from observing
standard UNIX filesystem semantics for this sort of thing?  And if the
latter, where is this documented?  A copy of bug.c is appended below.

=============================================

/*
 *  Short test program to demonstrate PVFS2
 *  open() + unlink() + read() problem ...
 *
 *  A read() on an open file descriptor for
 *  which an unlink() has been done on the
 *  file associated with the fd will return
 *  EOF instead of the file's contents.
 *
 *  Bug, misfeature, or ... ?
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <libgen.h>

char    buf[4096];

main(ac,av)
int     ac;
char ** av;
{
        int     fd, nb;

        if ( ac != 2 ) {
                fprintf(stderr,"Usage: %s filename\n",basename(av[0]));
                exit(1);
        }
        if ( (fd=open(av[1],O_RDONLY)) < 0 ) {
                fprintf(stderr,"Can't open %s\n",av[1]);
                exit(1);
        }
#ifdef BAD
        unlink(av[1]);
#endif
        fprintf(stdout,"OLD CONTENTS:\n");
        while ( (nb=read(fd,buf,sizeof(buf)-1)) > 0 ) {
                buf[nb] = 0;
                fprintf(stdout,"%s",buf);
        }
        close(fd);
        exit(0);
}
_______________________________________________
Pvfs2-users mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-users

Reply via email to