4 Replies Latest reply: Mar 8, 2010 8:04 AM by 758592 RSS

    bug or feature? db->open with DB_CREATE|DB_TRUNCATE failures in db4.8

    754903
      Hi There,

      In the recent 4.8 release of libdb, a number of applications have experienced what at first glance appears to be a regression w.r.t. the behavior of libdb when calling db->open on an existing empty file with the flags DB_CREATE | DB_TRUNCATE. In previous versions this generated no errors and libdb happily "truncated" the empty file. however, this now appears to generate an error.

      For reference:

      sendmail bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=565242
      nvi bug (gento dev: "I don't know if this is a bug or a feature"): http://bugs.gentoo.org/286352
      php bug (reported by myself after finding the other two): http://bugs.php.net/bug.php?id=51086

      rangda[home/sean] dpkg -l libdb4.8-dev | grep ^ii
      ii libdb4.8-dev 4.8.26-1 Berkeley v4.8 Database Libraries [development]

      some simplified code to show the error:

      #include <db.h>

      void errcall_fcn(const DB_ENV dbenv, const char errpfx, const char *msg){
      fprintf(stderr, "caught error: %s%s\n", errpfx?errpfx:"", msg);
      }

      int main() {
      DB *dbp = NULL;
      /* create a temp file with size 0 */
      char tmpfn[] = "dbtest-XXXXXX";
      int tmpfd = mkstemp(tmpfn);
      close(tmpfd);
      db_create(&dbp, NULL, 0);
      dbp->set_errcall(dbp, errcall_fcn);
      dbp->open(dbp, 0, tmpfn, NULL, DB_BTREE, DB_CREATE|DB_TRUNCATE, 0600);
      unlink(tmpfn);
      }

      result:

      rangda[home/sean] gcc -g foo.c -ldb
      rangda[home/sean] ./a.out
      caught error: fop_read_meta: dbtest-TEKewC: unexpected file type or format
      caught error: dbtest-TEKewC: Invalid type 5 specified

      so my question is, is this intended behavior or an unintended regression? it causes some fairly severe headaches for some big applications/systems so i'd like to know what those more knowledgable have to say, specifically whether libdb4.8 could be fixed to restore the old behavior or whether these applications will have to be updated.


      thanks!
        • 1. Re: bug or feature? db->open with DB_CREATE|DB_TRUNCATE failures in db4.8
          cj
          I'm following this up. Use the PHP bug http://bugs.php.net/bug.php?id=51086 to track progress.
          • 2. Re: bug or feature? db->open with DB_CREATE|DB_TRUNCATE failures in db4.8
            Gmfeinberg-Oracle
            Hello,

            This seems to have been an inadvertent change in behavior. It's a bit odd that it worked in the first place and that so many products depend on this behavior but that's in the past. Would a patch for 4.8 be a reasonable solution to your problem as well as those of the other products that have run into this?

            Regards,
            George
            • 3. Re: bug or feature? db->open with DB_CREATE|DB_TRUNCATE failures in db4.8
              Gmfeinberg-Oracle
              If code change is reasonable a workaround would be to not create the empty file in the first place but instead create a temp name and use that.

              Regards,
              George
              • 4. Re: bug or feature? db->open with DB_CREATE|DB_TRUNCATE failures in db4.8
                758592
                gmfeinberg wrote:
                Hello,

                This seems to have been an inadvertent change in behavior. It's a bit odd that it worked in the first place and that so many products depend on this behavior but that's in the past. Would a patch for 4.8 be a reasonable solution to your problem as well as those of the other products that have run into this?
                Yes please. I spotted this comment in include/sm/bdb.h from the sendmail 8.14.4 distribution, suggesting that BerkeleyDB has been changed to work the way sendmail wants it work before:
                # if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
                
                #  define DBTXN NULL ,
                
                /*
                **  Always turn on DB_FCNTL_LOCKING for DB 4.1.x since its
                **  "workaround" for accepting an empty (locked) file depends on
                **  this flag. Notice: this requires 4.1.24 + patch (which should be
                **  part of 4.1.25).
                */
                
                #  define SM_DB_FLAG_ADD(flag)  (flag) |= DB_FCNTL_LOCKING
                
                # else /* DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 */
                
                #  define DBTXN
                #  if !HASFLOCK && defined(DB_FCNTL_LOCKING)
                #   define SM_DB_FLAG_ADD(flag) (flag) |= DB_FCNTL_LOCKING
                #  else /* !HASFLOCK && defined(DB_FCNTL_LOCKING) */
                #   define SM_DB_FLAG_ADD(flag) ((void) 0)
                #  endif /* !HASFLOCK && defined(DB_FCNTL_LOCKING) */
                
                # endif /* DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 */