1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-08 05:57:51 +03:00

Implemented max connections in a similar way to 2.0.x (scan of connection db).

This needs testing !
Tidied up tabs in tdb.c.
Jeremy.
This commit is contained in:
Jeremy Allison -
parent 858290d63b
commit 0852465053
2 changed files with 91 additions and 11 deletions

View File

@ -37,8 +37,9 @@ TDB_CONTEXT *conn_tdb_ctx(void)
}
/****************************************************************************
delete a connection record
Delete a connection record.
****************************************************************************/
BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
{
struct connections_key key;
@ -62,21 +63,92 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
return(True);
}
struct count_stat {
pid_t mypid;
int curr_connections;
char *name;
};
/****************************************************************************
claim an entry in the connections database
Count the entries belonging to a service in the connection db.
****************************************************************************/
static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *udp)
{
struct connections_data crec;
struct count_stat *cs = (struct count_stat *)udp;
memcpy(&crec, dbuf.dptr, sizeof(crec));
if (crec.cnum == -1)
return 0;
/* if the pid was not found delete the entry from connections.tdb */
if (!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 (strequal(crec.name, cs->name))
cs->curr_connections++;
return 0;
}
/****************************************************************************
Claim an entry in the connections database.
****************************************************************************/
BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear)
{
struct connections_key key;
struct connections_data crec;
TDB_DATA kbuf, dbuf;
BOOL db_locked = False;
BOOL ret = True;
if (!tdb) {
tdb = tdb_open(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST,
O_RDWR | O_CREAT, 0644);
}
if (!tdb) return False;
if (!tdb)
return False;
/*
* Enforce the max connections parameter.
*/
if (max_connections > 0) {
struct count_stat cs;
cs.mypid = sys_getpid();
cs.curr_connections = 0;
cs.name = lp_servicename(SNUM(conn));
/*
* Go through and count the connections with the db locked. This is
* slow but essentially what 2.0.x did. JRA.
*/
if (tdb_lockall(tdb))
return False;
db_locked = True;
if (tdb_traverse(tdb, count_fn, &cs)) {
ret = False;
goto out;
}
if (cs.curr_connections >= max_connections) {
DEBUG(1,("claim_connection: Max connections (%d) exceeded for %s\n",
max_connections, name ));
ret = False;
goto out;
}
}
DEBUG(5,("claiming %s %d\n",name,max_connections));
@ -108,8 +180,14 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
dbuf.dptr = (char *)&crec;
dbuf.dsize = sizeof(crec);
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) return False;
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0)
ret = False;
return True;
out:
if (db_locked)
tdb_unlockall(tdb);
return ret;
}

View File

@ -872,10 +872,10 @@ int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state)
struct tdb_traverse_lock tl = { NULL, 0, 0 };
int ret, count = 0;
/* This was in the initializaton, above, but the IRIX compiler
* did not like it. crh
*/
tl.next = tdb->travlocks.next;
/* This was in the initializaton, above, but the IRIX compiler
* did not like it. crh
*/
tl.next = tdb->travlocks.next;
/* fcntl locks don't stack: beware traverse inside traverse */
tdb->travlocks.next = &tl;
@ -908,8 +908,10 @@ int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state)
free(key.dptr);
}
tdb->travlocks.next = tl.next;
if (ret < 0) return -1;
else return count;
if (ret < 0)
return -1;
else
return count;
}
/* find the first entry in the database and return its key */