On Wed, Jan 17, 2007 at 11:04:29AM -0500, Josh Kelley
wrote:> When using Samba 3.0.23b (slightly old, I know) on CentOS 4.4,
> smbstatus -B fails with a segmentation fault. smbstatus works, and
> tdbdump is able to dump brlock.tdb and locking.tdb without any errors
> (which is not what I expected).
>
> Here's the backtrace (non-ASCII characters replaced with 'X'):
> #0 0x0017fa2c in memcpy () from /lib/tls/libc.so.6
> #1 0x0029b19f in tdb_write (tdb=0x89b8608, off=3083693360, buf=0x89b8608,
> len=144) at tdb/tdb.c:404
> #2 0x0029d578 in tdb_store (tdb=0x89b7078, key> {dptr = 0x89b8128
"\005X", dsize = 16}, dbuf> {dptr = 0x89b8608
"XX\002", dsize = 144}, flag=1) at tdb/tdb.c:1101
> #3 0x002611a2 in traverse_fn (ttdb=0x89b7078, kbuf> {dptr =
0x89b8128 "\005X", dsize = 16}, dbuf> {dptr = 0x89b8608
"XX\002", dsize = 612}, state=0x25b622)
> at locking/brlock.c:1352
> #4 0x0029ccd4 in tdb_traverse (tdb=0x89b7078, fn=0x2610f8
<traverse_fn>,
> private_val=0x25b622) at tdb/tdb.c:1403
> #5 0x002612b6 in brl_forall (fn=0x9d30) at locking/brlock.c:1381
> #6 0x0025bdd8 in main (argc=2, argv=0xbffa9064) at utils/status.c:733
>
> Any suggestions?
This is a bug in tdb_write that it's not checking for the
tdb being read-only. Here's a patch. This has been fixed
differently in the svn code (tdb_write is fixed).
Jeremy.
-------------- next part --------------
Index: locking/brlock.c
==================================================================---
locking/brlock.c (revision 20619)
+++ locking/brlock.c (working copy)
@@ -1337,21 +1337,23 @@
key = (struct lock_key *)kbuf.dptr;
orig_num_locks = num_locks = dbuf.dsize/sizeof(*locks);
- /* Ensure the lock db is clean of entries from invalid processes. */
+ if (!ttdb->read_only) {
+ /* Ensure the lock db is clean of entries from invalid processes. */
- if (!validate_lock_entries(&num_locks, &locks)) {
- SAFE_FREE(locks);
- return -1; /* Terminate traversal */
- }
+ if (!validate_lock_entries(&num_locks, &locks)) {
+ SAFE_FREE(locks);
+ return -1; /* Terminate traversal */
+ }
- if (orig_num_locks != num_locks) {
- dbuf.dptr = (void *)locks;
- dbuf.dsize = num_locks * sizeof(*locks);
+ if (orig_num_locks != num_locks) {
+ dbuf.dptr = (void *)locks;
+ dbuf.dsize = num_locks * sizeof(*locks);
- if (dbuf.dsize) {
- tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE);
- } else {
- tdb_delete(ttdb, kbuf);
+ if (dbuf.dsize) {
+ tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE);
+ } else {
+ tdb_delete(ttdb, kbuf);
+ }
}
}