[PATCHES] Cleanup dead records in messages.tdb
Jeremy Allison
jra at samba.org
Thu Apr 3 15:56:39 MDT 2014
On Thu, Apr 03, 2014 at 02:32:25PM -0700, Jeremy Allison wrote:
> On Thu, Apr 03, 2014 at 02:26:29PM -0700, Christof Schmitt wrote:
> >
> > Actually, there is an issue with the locking here: tdb_delete fails,
> > because it tries to get a lock for the delete, but the chain is already
> > locked. Either we have to live with the race here, or add a call to tdb
> > that allows deletion without acquiring the lock.
>
> Are you sure here ? That same bug would then exist
> in the function :
>
> tatic NTSTATUS retrieve_all_messages(TDB_CONTEXT *msg_tdb,
> struct server_id id,
> TALLOC_CTX *mem_ctx,
> struct messaging_array **presult)
> {
> struct messaging_array *result;
> TDB_DATA key = message_key_pid(mem_ctx, id);
> NTSTATUS status;
>
> if (tdb_chainlock(msg_tdb, key) != 0) {
> TALLOC_FREE(key.dptr);
> return NT_STATUS_LOCK_NOT_GRANTED;
> }
>
> status = messaging_tdb_fetch(msg_tdb, key, mem_ctx, &result);
>
> /*
> * We delete the record here, tdb_set_max_dead keeps it around
> */
> tdb_delete(msg_tdb, key);
> tdb_chainunlock(msg_tdb, key);
>
> if (NT_STATUS_IS_OK(status)) {
> *presult = result;
> }
>
> TALLOC_FREE(key.dptr);
>
> return status;
> }
>
> which is called regularly in the messaging
> code...
Just wrote a quick standalone test:
+static void jratest(TDB_CONTEXT *db)
+{
+ TDB_DATA key, data;
+
+ key.dptr = "keyname";
+ key.dsize = 8;
+ data.dptr = "data";
+ data.dsize = 5;
+
+ if (tdb_store(db, key, data, 0) != 0) {
+ abort();
+ }
+
+ if (tdb_chainlock(db, key) != 0) {
+ abort();
+ }
+
+ if (tdb_delete(db, key) != 0) {
+ abort();
+ }
+ if (tdb_chainunlock(db, key) != 0) {
+ abort();
+ }
+}
seems to work fine. So I don't think there's
a problem with deleting a record under a chainlock...
(I'm pretty sure those locks are recursive).
Jeremy.
More information about the samba-technical
mailing list