TDB on OpenBSD problem (log + code)

Jason Coene jason at dhnw.net
Tue May 1 19:47:12 GMT 2001


Jeremy,

I did what you suggested, here is a sample of the output (this goes on for
38mb, which was accumulated after
one occurence of the problem. It took about 10 seconds to log 38mb of this
before i killed the smbd process.

Notice the value of tdb->map_size jumping so sharply (seemingly doubling),
and lseek going along with it using
lseek_val = (tdb->map_size+size-1).

lseek (fd, 536952831, SEEK_SET) =  EEK!

Below are 1) near start of log, 2) near end of log, 3) new tdb_expand()
function.

Any idea why map size is doubling?

Regards,

Jason Coene

=======================================BEGIN
LOG===============================================
  jason (10.1.1.100) connect to service redist as user jason (uid=101,
gid=100) (pid 32280)
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(446)
  tdb: size was 103
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(448)
  tdb: size now 7496
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(453)
  tdb: lseek fd. map_size is 696, size is 7496, lseek value is 8191
(map_size+size-1)
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(455)
  tdb: lseek done
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(446)
  tdb: size was 103
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(448)
  tdb: size now 8192
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(453)
  tdb: lseek fd. map_size is 8192, size is 8192, lseek value is 16383
(map_size+size-1)
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(455)
  tdb: lseek done
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(446)
  tdb: size was 103
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(448)
  tdb: size now 8192
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(453)
  tdb: lseek fd. map_size is 16384, size is 8192, lseek value is 24575
(map_size+size-1)
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(455)
  tdb: lseek done
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(446)
  tdb: size was 103
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(448)
  tdb: size now 8192
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(453)
  tdb: lseek fd. map_size is 24576, size is 8192, lseek value is 32767
(map_size+size-1)
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(455)
  tdb: lseek done
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(446)
  tdb: size was 103
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(448)
  tdb: size now 8192
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(453)
  tdb: lseek fd. map_size is 32768, size is 8192, lseek value is 40959
(map_size+size-1)
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(455)
  tdb: lseek done
[2001/05/01 15:35:48, 0, pid=32280, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(446)
  tdb: size was 103
=======================================END
LOG===============================================


=======================================BEGIN
LOG===============================================
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(446)
  tdb: size was 103
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(448)
  tdb: size now 8192
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(453)
  tdb: lseek fd. map_size is 536928256, size is 8192, lseek value is
536936447 (map_size+size-1)
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(455)
  tdb: lseek done
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(446)
  tdb: size was 103
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(448)
  tdb: size now 8192
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(453)
  tdb: lseek fd. map_size is 536936448, size is 8192, lseek value is
536944639 (map_size+size-1)
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(455)
  tdb: lseek done
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(446)
  tdb: size was 103
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(448)
  tdb: size now 8192
[2001/05/01 15:36:20, 0, pid=18206, effective(101, 100), real(0, 0)]
tdb/tdb.c:tdb_expand(453)
  tdb: lseek fd. map_size is 536944640, size is 8192, lseek value is
536952831 (map_size+size-1)
=======================================END
LOG===============================================



=======================================BEGIN
CODE===============================================
static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size)
{
	struct list_struct rec;
	tdb_off offset;
	char b = 0;
	char *mybuf[512];

	bzero(&mybuf, 512);

	if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
		DEBUG(0,("tbd: tdb_lock returned -1\n"));
		return 0;
	}

	/* must know about any previous expansions by another process */
	tdb_oob(tdb, tdb->map_size + 1);

	/* always make room for at least 10 more records, and round
           the database up to a multiple of TDB_PAGE_SIZE */
	DEBUG(0, ("tdb: size was %d\n", size));
	size = TDB_ALIGN(tdb->map_size + size*10, TDB_PAGE_SIZE) - tdb->map_size;
	DEBUG(0, ("tdb: size now %d\n", size));


	/* expand the file itself */
        if (!(tdb->flags & TDB_INTERNAL)) {
			DEBUG(0, ("tdb: lseek fd. map_size is %d, size is %d, lseek value is %d
(map_size+size-1)\n", tdb->map_size, size, (tdb->map_size+size-1)));
			lseek(tdb->fd, tdb->map_size + size - 1, SEEK_SET);
			DEBUG(0, ("tdb: lseek done\n"));
			if (write(tdb->fd, &b, 1) != 1) {
				DEBUG(0, ("tdb: write failed\n"));
				goto fail;
			}
        }

	if (!(tdb->flags & TDB_INTERNAL) && tdb->map_ptr)
		tdb->map_ptr = tdb_munmap(tdb->map_ptr, tdb->map_size);

	tdb->map_size += size;

	if (tdb->flags & TDB_INTERNAL)
		tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size);

	/* form a new freelist record */
	memset(&rec,'\0',sizeof(rec));
	rec.rec_len = size - sizeof(rec);

	/* link it into the free list */
	offset = tdb->map_size - size;
	if (tdb_free(tdb, offset, &rec) == -1) goto fail;

	if (!(tdb->flags & TDB_NOMMAP))
		tdb->map_ptr = tdb_mmap(tdb->map_size, 0, tdb->fd);

	tdb_unlock(tdb, -1, F_WRLCK);
	return 0;
 fail:
	tdb_unlock(tdb, -1, F_WRLCK);
	return -1;
}
=======================================END
CODE===============================================





More information about the samba-technical mailing list