Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Apr 1999 09:10:02 -0700 (PDT)
From:      David G Andersen <danderse@cs.utah.edu>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/10971: ypserv segfaults regularly (really: Race condition in the Berkeley db library).
Message-ID:  <199904301610.JAA64925@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/10971; it has been noted by GNATS.

From: David G Andersen <danderse@cs.utah.edu>
To: freebsd-gnats-submit@freebsd.org
Cc: danderse@cs.utah.edu
Subject: Re: bin/10971: ypserv segfaults regularly (really: Race condition in the Berkeley db library).
Date: Fri, 30 Apr 1999 10:02:43 -0600 (MDT)

 As I mentioned in email to -hackers, this is the ugly,
 don't-commit-because-it-changes-the-DB-semantics fix we use to
 make ypserv work for us.  To apply it, compile a *separate* libc with the
 patched hash_page.c (that's lib/libc/db/hash/hash_page.c if you're keeping
 track), and then patch your yp_dblookup.c so it opens the database
 readwrite, so it can obtain an exclusive (read) lock on the database.
 Recompile ypserv and link it statically against the separate libc, and
 voila, life is good.
 
 Alternately, change hash_page.c (and the equivalent functions in the other
 DB routines) to use pread with an absolute offset, instead of doing the
 lseek()/read() race condition combo.  This only works for people in
 -current, but it's a better and faster fix.
 
    -Dave
 
 *** yp_dblookup.c       1998/02/11 19:15:32     1.15
 --- yp_dblookup.c       1999/04/13 23:51:44
 ***************
 *** 414,420 ****
   #ifdef DB_CACHE
   again:
   #endif
 !       dbp = dbopen(buf,O_RDONLY, PERM_SECURE, DB_HASH, NULL);
   
         if (dbp == NULL) {
                 switch(errno) {
 --- 414,420 ----
   #ifdef DB_CACHE
   again:
   #endif
 !       dbp = dbopen(buf, O_RDWR, PERM_SECURE, DB_HASH, NULL);
   
         if (dbp == NULL) {
                 switch(errno) {
 
 
 *** hash_page.c Fri Apr  2 15:36:00 1999
 --- hash_page.c.locking Thu Apr  1 22:01:49 1999
 ***************
 *** 524,529 ****
 --- 524,530 ----
         register int fd, page, size;
         int rsize;
         u_int16_t *bp;
 +       struct flock fl;
   
         fd = hashp->fp;
         size = hashp->BSIZE;
 ***************
 *** 536,544 ****
 --- 537,556 ----
                 page = BUCKET_TO_PAGE(bucket);
         else
                 page = OADDR_TO_PAGE(bucket);
 + 
 +       fl.l_start = fl.l_len = fl.l_pid = 0;
 +       fl.l_type = F_WRLCK;
 +       fl.l_whence = SEEK_SET;
 + 
 +       fcntl(fd, F_SETLKW, &fl);
 + 
         if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
             ((rsize = read(fd, p, size)) == -1))
                 return (-1);
 + 
 +       fl.l_type = F_UNLCK;
 +       fcntl(fd, F_SETLK, &fl);
 + 
         bp = (u_int16_t *)p;
         if (!rsize)
                 bp[0] = 0;      /* We hit the EOF, so initialize a new
 page */
 
 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199904301610.JAA64925>