kern/107109: [nfs] Netbeans/Eclipse/Java provoke deadlocks when used with NFS

Joerg Lehners Joerg.Lehners at Informatik.Uni-Oldenburg.DE
Fri Feb 2 16:00:37 UTC 2007


The following reply was made to PR kern/107109; it has been noted by GNATS.

From: "Joerg Lehners" <Joerg.Lehners at Informatik.Uni-Oldenburg.DE>
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: kern/107109: [nfs] Netbeans/Eclipse/Java provoke deadlocks when
 used with NFS
Date: Fri, 2 Feb 2007 16:52:15 +0100 (MET)

 On Tue, 30 Jan 2007, Joerg Lehners wrote:
 > [...]
 > I'll try to write a threaded C program to try to show that
 > this issue is not specific to Java. Perhaps someone ele is faster? :)
 
 Done, see attached file.
 
 While writing this short program and trying to reproduce the problem
 more easily I discovered that it is NOT neccessary to do stat() on
 files/directories that are on a NFS volume. It is neccessary for the
 test program to have its CURRENT WORKING DIRECTORY on a NFS volume
 that is mounted with 'intr'.
 For the I/O part I decided have the program do a opendir()/readdir()/stat()
 loop over the root-directory.
 
 So to provoke to lockup: compile and run the program with a working directory
 on a NFS volume mounted with 'intr'.
 I got lockups within milliseconds of runtime.
 
 So the subject of this PR is now wrong: the issue is not Netbeans/Eclipse/
 Java specific at all. Someone might want to change the subject of this PR.
 
 Suggestion: NFS volumes with 'intr' may cause deadlocks when used with
 threaded programs
 
 --- c.c begins here ---
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <errno.h>
 #include <time.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <dirent.h>
 
 void 	*forker(void *);
 void	*looper(void *);
 
 int main (int argc, char **argv)
 {
    pthread_t	forker_thrid1;
    pthread_t	forker_thrid2;
    pthread_t	looper_thrid1;
    pthread_t	looper_thrid2;
    pthread_t	looper_thrid3;
 
    fprintf (stderr, "started!\n");
 
    pthread_create (&forker_thrid1, NULL, forker, NULL);
    fprintf (stderr, "forker1 created!\n");
 
    pthread_create (&forker_thrid2, NULL, forker, NULL);
    fprintf (stderr, "forker2 created!\n");
 
    pthread_create (&looper_thrid1, NULL, looper, NULL);
    fprintf (stderr, "looper1 created!\n");
 
    pthread_create (&looper_thrid2, NULL, looper, NULL);
    fprintf (stderr, "looper2 created!\n");
 
    pthread_create (&looper_thrid3, NULL, looper, NULL);
    fprintf (stderr, "looper3 created!\n");
 
    pause();
 
    exit (0);
 }
 
 void	*forker(void *arg)
 {
    pid_t	child_pid;
    int child_status;
    struct timespec sleep_time;
 
    fprintf (stderr, "forker started\n");
    while (1) {
      child_pid = fork();
      if (child_pid < 0) {
        fprintf (stderr, "fork failed, errno: %d\n", errno);
      }
      else if (child_pid == 0) {
        /* child */
        exit (0);
      }
      else {
        /* parent */
        wait (&child_status);
        /* fprintf (stderr, "forked and waited for the child\n"); */
        fprintf (stderr, "f");
      }
 
      sleep_time.tv_sec = 0;
      sleep_time.tv_nsec = 10 * 1000 * 1000;
      nanosleep (&sleep_time, NULL);
    }
 
    return (NULL);
 }
 
 void	*looper(void *arg)
 {
    char	*dirname;
    DIR* dir;
    struct dirent dir_entry;
    struct dirent *dir_entry_p;
    struct stat stat_buf;
    int count;
    struct timespec sleep_time;
 
    fprintf (stderr, "looper started\n");
 
    dirname = "/";
 
    dir = opendir (dirname);
    if (dir == NULL) {
      fprintf (stderr, "opendir of %s failed\n", dirname);
      return (NULL);
    }
    fprintf (stderr, "opened directory %s\n", dirname);
 
    while (1) {
 
      count = 0;
      rewinddir (dir);
 
      while (1) {
        if (readdir_r (dir, &dir_entry, &dir_entry_p) < 0) {
          fprintf (stderr, "error reading directory\n");
          break;
        }
        if (dir_entry_p == NULL)
          break;
        /* fprintf (stderr, "filename: %s\n", dir_entry.d_name); */
        count++;
        if (stat (dir_entry.d_name, &stat_buf) < 0) {
          /* fprintf (stderr, "error stat()ing %s\n", dir_entry.d_name); */
        }
      }
 
      /* fprintf (stderr, "looper looped, %d entries\n", count); */
      fprintf (stderr, "l");
 
      sleep_time.tv_sec = 0;
      sleep_time.tv_nsec = 100 * 1000 * 1000;
      nanosleep (&sleep_time, NULL);
    }
 
    return (NULL);
 }
 --- c.c ends here ---
 
 --- Makefile begins here ---
 
 CFLAGS=-Wall
 LDFLAGS=-lpthread
 
 c:	c.o
  	cc -o c c.o ${LDFLAGS}
 
 c.o: 	c.c
 --- Makefile ends here ---
 
 
 -- 
 Mail: Joerg.Lehners at Informatik.Uni-Oldenburg.DE    Tel: 2198
 Real: Joerg Lehners, Informatik ARBI, Uni Oldenburg, D-26111 Oldenburg
 Unwoerter: Kostensenkung - Gewinnmaximierung - billig, billig, billig


More information about the freebsd-bugs mailing list