summaryrefslogtreecommitdiff
path: root/source3/smbd/connection.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-05-17 00:24:34 +0000
committerJeremy Allison <jra@samba.org>2001-05-17 00:24:34 +0000
commit8c4d6548a91961ecc2a177f4f6f95fbea4035cd3 (patch)
treef199ea96bae5d12d29230fa6bc85901e1b6301e4 /source3/smbd/connection.c
parente307e9d814bbcf3bd0e85408d4f78279ebb1e1cf (diff)
downloadsamba-8c4d6548a91961ecc2a177f4f6f95fbea4035cd3.tar.gz
groupdb/mapping.c: Fix gcc compiler warning.
smbd/connection.c: Sync up with code in 2.2 Jeremy. (This used to be commit 87025c223dd33f2e02060c2a5cd45502946c87c6)
Diffstat (limited to 'source3/smbd/connection.c')
-rw-r--r--source3/smbd/connection.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index 5a3fcc2975d..edbc49777e6 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -84,18 +84,19 @@ static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *u
memcpy(&crec, dbuf.dptr, sizeof(crec));
- if (crec.cnum == -1)
+ if (crec.cnum == -1)
return 0;
- /* if the pid was not found delete the entry from connections.tdb */
- if (cs->Clear && !process_exists(crec.pid)) {
+ /* If the pid was not found delete the entry from connections.tdb */
+
+ if (cs->Clear && !process_exists(crec.pid) && (errno == ESRCH)) {
DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n",
(unsigned int)crec.pid, crec.cnum, crec.name));
tdb_delete(the_tdb, kbuf);
return 0;
}
- if (cs && strequal(crec.name, cs->name))
+ if (strequal(crec.name, cs->name))
cs->curr_connections++;
return 0;
@@ -109,7 +110,9 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
{
struct connections_key key;
struct connections_data crec;
- TDB_DATA kbuf, dbuf;
+ TDB_DATA kbuf, dbuf, lockkey;
+ BOOL rec_locked = False;
+ BOOL ret = True;
if (!tdb) {
tdb = tdb_open(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST,
@@ -130,18 +133,30 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
cs.name = lp_servicename(SNUM(conn));
cs.Clear = Clear;
+ lockkey.dptr = cs.name;
+ lockkey.dsize = strlen(cs.name)+1;
+
/*
- * Go through and count the connections
+ * Go through and count the connections with hash chain representing the service name
+ * locked. This is slow but removes race conditions. JRA.
*/
+
+ if (tdb_chainlock(tdb, lockkey))
+ return False;
+
+ rec_locked = True;
+
if (tdb_traverse(tdb, count_fn, &cs) == -1) {
DEBUG(0,("claim_connection: traverse of connections.tdb failed.\n"));
- return False;
+ ret = False;
+ goto out;
}
if (cs.curr_connections >= max_connections) {
DEBUG(1,("claim_connection: Max connections (%d) exceeded for %s\n",
max_connections, name ));
- return False;
+ ret = False;
+ goto out;
}
}
@@ -176,19 +191,12 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
dbuf.dsize = sizeof(crec);
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0)
- return False;
+ ret = False;
- return True;
-}
+ out:
-#if 0
-/****************************************************************************
- Use the count function to clean any dead records. Shouldn't be needed...
-****************************************************************************/
+ if (rec_locked)
+ tdb_chainunlock(tdb, lockkey);
-void clean_connection_db(void)
-{
- if (tdb_traverse(tdb, count_fn, NULL) == -1)
- DEBUG(0,("clean_connection_db: traverse of connections.tdb failed.\n"));
+ return ret;
}
-#endif