You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by cm...@collab.net on 2001/08/22 18:37:14 UTC

Berkeley DB Win32 problems.

Attached to this mail is a patch for one of the Sleepycat's C example
programs that, I think, demonstrates the problems we have with BDB
under Win98 (see Issue #384).  Can someone please apply the patch to
db-3.2.9/examples_c/ex_env.c and make sure I've not done anything
illegal with respect to how I'm using Berkeley's API?  If there are
no glaring errors in the code, I'd like to send it off to Sleepycat
with a kind "Whassup?" and see if we can nail this thing.

Note that in the patch, all I do differently is that I optionally pass
a DB_CREATE flag to db_env->open based on the non-zero-ness of the
'create' argument.  Their sample used to create a DB_ENV, close it,
then remove it.  With my patch, it is created, closed, and then an
attempt at re-opening it happens (which fails on my box with 'Resource
temporarily unavailable').  I'd love to hear how this behaves under
WinNT/2000, too.  See svn_fs_create_berkeley() and
svn_fs_open_berkeley() for our uses of BDB in this context.

Anybody with Win32 Memory Mapped I/O experience out there?  I have
none (but I'm learning).  It's really weird that I can see all this
data getting written to the __db.00x files through MMIO, but it never
seems to hit the disk.  Specifically, if I'm following the code right,
I'm seeing a DB_REGION In fact, I think that's the crux of the whole
problem.  If I recall correctly, when trying to re-open the
environment, BDB is looking for a 'magic number' in the __db.001 file
and not finding it.  I tried compiling a version of BDB with a call to
FlushViewOfFile() just before UnmapViewOfFile() but the behavior was
still the same.

Here is where the code is failing (os_win32/os_map.c:__os_map()) :

    if (is_region) {
        /*
         * XXX
         * Windows/95 zeroes anonymous memory regions at last close.
         * This means that the backing file can exist and reference
         * the region, but the region itself is no longer initialized.
         * If the caller is capable of creating the region, update
         * the REGINFO structure so that they do so.
         */
        renv = (REGENV *)pMemory;
        if (renv->magic == 0)
            if (F_ISSET(infop, REGION_CREATE_OK))
                F_SET(infop, REGION_CREATE);
            else {
                (void)UnmapViewOfFile(pMemory);
                pMemory = NULL;
                ret = EAGAIN;
            }
    }

We are trying to attach to a shared memory region, and renv->magic is
0 because the REGENV structure, which was the first thing written to
the region during the DB_ENV creation step, didn't persist (it was
never written to disk when db_env->close() was called after the
creation step).  However, because the REGION_CREATE_OK flag is not set
(which, I think is because the DB_CREATE flag wasn't passed in our
"re-open" call to db_env->open()), EAGAIN is returned up the stack,
which incidentally looks something like:

    __os_map()
    __os_r_sysattach()
    __os_r_attach()
    __db_e_attach()
    db_setup()
    main()

I'm pooped, so I won't be visiting this again until at least late
tonight, but perhaps much later.

Okay, here's the patch I mentioned waaaaaaaaay up there.

--------------------------------------------------------------------------

--- ex_env.c	Sat Oct 28 10:57:46 2000
+++ ex_env.c.new	Wed Aug 22 12:46:20 2001
@@ -37,7 +37,7 @@
 #endif
 #endif
 
-int	db_setup __P((char *, char *, FILE *, char *));
+int	db_setup __P((char *, char *, FILE *, char *, int));
 int	db_teardown __P((char *, char *, FILE *, char *));
 #ifdef HAVE_VXWORKS
 int	ex_env __P((void));
@@ -70,9 +70,13 @@
 	data_dir = CONFIG_DATA_DIR;
 
 	printf("Setup env\n");
-	if ((ret = db_setup(home, data_dir, stderr, progname)) != 0)
+	if ((ret = db_setup(home, data_dir, stderr, progname, 1)) != 0)
 		return (ret);
 
+	printf("Re-open env\n");
+	if ((ret = db_setup(home, data_dir, stderr, progname, 0)) != 0)
+		return (ret);
+
 	printf("Teardown env\n");
 	if ((ret = db_teardown(home, data_dir, stderr, progname)) != 0)
 		return (ret);
@@ -81,9 +85,10 @@
 }
 
 int
-db_setup(home, data_dir, errfp, progname)
+db_setup(home, data_dir, errfp, progname, create)
 	char *home, *data_dir, *progname;
 	FILE *errfp;
+    int create;
 {
 	DB_ENV *dbenv;
 	int ret;
@@ -122,7 +127,7 @@
 
 	/* Open the environment with full transactional support. */
 	if ((ret = dbenv->open(dbenv, home,
-	 DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN,
+	 (create ? DB_CREATE : 0) | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN,
 	    0)) != 0) {
 		dbenv->err(dbenv, ret, "environment open: %s", home);
 		dbenv->close(dbenv, 0);




---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Berkeley DB Win32 problems.

Posted by cm...@collab.net.
cmpilato@collab.net writes:

> Attached to this mail is a patch for one of the Sleepycat's C example
> programs that, I think, demonstrates the problems we have with BDB
> under Win98 (see Issue #384).

Actually, what was attached to that mail was a broken patch.  Let me
try this again:

--- ex_env.c	Sat Oct 28 09:57:46 2000
+++ ex_env.c.new	Thu Aug 23 11:10:07 2001
@@ -37,7 +37,7 @@
 #endif
 #endif
 
-int	db_setup __P((char *, char *, FILE *, char *));
+int	db_setup __P((char *, char *, FILE *, char *, int));
 int	db_teardown __P((char *, char *, FILE *, char *));
 #ifdef HAVE_VXWORKS
 int	ex_env __P((void));
@@ -70,7 +70,11 @@
 	data_dir = CONFIG_DATA_DIR;
 
 	printf("Setup env\n");
-	if ((ret = db_setup(home, data_dir, stderr, progname)) != 0)
+	if ((ret = db_setup(home, data_dir, stderr, progname, 1)) != 0)
+		return (ret);
+
+	printf("Re-open env\n");
+	if ((ret = db_setup(home, data_dir, stderr, progname, 0)) != 0)
 		return (ret);
 
 	printf("Teardown env\n");
@@ -81,9 +85,10 @@
 }
 
 int
-db_setup(home, data_dir, errfp, progname)
+db_setup(home, data_dir, errfp, progname, create)
 	char *home, *data_dir, *progname;
 	FILE *errfp;
+    int create;
 {
 	DB_ENV *dbenv;
 	int ret;
@@ -122,7 +127,7 @@
 
 	/* Open the environment with full transactional support. */
 	if ((ret = dbenv->open(dbenv, home,
-    DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN,
+	    (create ? DB_CREATE : 0) | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN,
 	    0)) != 0) {
 		dbenv->err(dbenv, ret, "environment open: %s", home);
 		dbenv->close(dbenv, 0);

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org