return tdb;
}
-static void make_conn_key(connection_struct *conn, const char *name, TDB_DATA *pkbuf, fstring tdb_key)
+static void make_conn_key(connection_struct *conn, const char *name, TDB_DATA *pkbuf, struct connections_key *pkey)
{
- snprintf(tdb_key, sizeof(fstring), "CONN/%lu/%ld", sys_getpid(), conn?conn->cnum:-1);
+ ZERO_STRUCTP(pkey);
+ pkey->pid = procid_self();
+ pkey->cnum = conn?conn->cnum:-1;
+ fstrcpy(pkey->name, name);
+#ifdef DEVELOPER
+ /* valgrind fixer... */
+ {
+ size_t sl = strlen(pkey->name);
+ if (sizeof(fstring)-sl)
+ memset(&pkey->name[sl], '\0', sizeof(fstring)-sl);
+ }
+#endif
- pkbuf->dptr = tdb_key;
- pkbuf->dsize = strlen(tdb_key)+1;
+ pkbuf->dptr = (char *)pkey;
+ pkbuf->dsize = sizeof(*pkey);
}
/****************************************************************************
BOOL yield_connection(connection_struct *conn, const char *name)
{
- fstring tdb_key;
+ struct connections_key key;
TDB_DATA kbuf;
if (!tdb)
DEBUG(3,("Yielding connection to %s\n",name));
- make_conn_key(conn, name, &kbuf, tdb_key);
+ make_conn_key(conn, name, &kbuf, &key);
if (tdb_delete(tdb, kbuf) != 0) {
int dbg_lvl = (!conn && (tdb_error(tdb) == TDB_ERR_NOEXIST)) ? 3 : 0;
struct count_stat {
pid_t mypid;
int curr_connections;
- char *name;
+ const char *name;
BOOL Clear;
};
/* 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));
+ DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n",
+ procid_str_static(&crec.pid), crec.cnum, crec.name));
if (tdb_delete(the_tdb, kbuf) != 0)
DEBUG(0,("count_fn: tdb_delete failed with error %s\n", tdb_errorstr(tdb) ));
return 0;
Claim an entry in the connections database.
****************************************************************************/
-BOOL claim_connection(connection_struct *conn, const char *name,int max_connections,BOOL Clear, uint32 msg_flags)
+int count_current_connections( const char *sharename, BOOL clear )
{
- struct connections_key key;
- struct connections_data crec;
- TDB_DATA kbuf, dbuf;
+ struct count_stat cs;
- if (!tdb)
- tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
- O_RDWR | O_CREAT, 0644);
-
- if (!tdb)
- return False;
+ cs.mypid = sys_getpid();
+ cs.curr_connections = 0;
+ cs.name = sharename;
+ cs.Clear = clear;
/*
- * Enforce the max connections parameter.
+ * This has a race condition, but locking the chain before hand is worse
+ * as it leads to deadlock.
*/
- if (max_connections > 0) {
- struct count_stat cs;
+ if (tdb_traverse(tdb, count_fn, &cs) == -1) {
+ DEBUG(0,("claim_connection: traverse of connections.tdb failed with error %s.\n",
+ tdb_errorstr(tdb) ));
+ return False;
+ }
+
+ return cs.curr_connections;
+}
- cs.mypid = sys_getpid();
- cs.curr_connections = 0;
- cs.name = lp_servicename(SNUM(conn));
- cs.Clear = Clear;
+/****************************************************************************
+ Claim an entry in the connections database.
+****************************************************************************/
- /*
- * This has a race condition, but locking the chain before hand is worse
- * as it leads to deadlock.
- */
+BOOL claim_connection(connection_struct *conn, const char *name,int max_connections,BOOL Clear, uint32 msg_flags)
+{
+ struct connections_key key;
+ struct connections_data crec;
+ TDB_DATA kbuf, dbuf;
- if (tdb_traverse(tdb, count_fn, &cs) == -1) {
- DEBUG(0,("claim_connection: traverse of connections.tdb failed with error %s.\n",
- tdb_errorstr(tdb) ));
+ if (!tdb) {
+ if ( (tdb =conn_tdb_ctx()) == NULL ) {
return False;
}
+ }
+
+ /*
+ * Enforce the max connections parameter.
+ */
- if (cs.curr_connections >= max_connections) {
+ if (max_connections > 0) {
+ int curr_connections;
+
+ curr_connections = count_current_connections( lp_servicename(SNUM(conn)), True );
+
+ if (curr_connections >= max_connections) {
DEBUG(1,("claim_connection: Max connections (%d) exceeded for %s\n",
max_connections, name ));
return False;
/* fill in the crec */
ZERO_STRUCT(crec);
crec.magic = 0x280267;
- crec.pid = sys_getpid();
+ crec.pid = procid_self();
crec.cnum = conn?conn->cnum:-1;
if (conn) {
crec.uid = conn->uid;
dbuf = tdb_fetch(tdb, kbuf);
if (!dbuf.dptr) {
- DEBUG(0,("register_message_flags: tdb_fetch failed\n"));
+ DEBUG(0,("register_message_flags: tdb_fetch failed: %s\n",
+ tdb_errorstr(tdb)));
return False;
}
pcrec = (struct connections_data *)dbuf.dptr;
- pcrec->bcast_msg_flags = msg_flags;
if (doreg)
pcrec->bcast_msg_flags |= msg_flags;
else
pcrec->bcast_msg_flags &= ~msg_flags;
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("register_message_flags: tdb_store failed with error %s.\n",
+ DEBUG(0,("register_message_flags: tdb_store failed: %s.\n",
tdb_errorstr(tdb) ));
SAFE_FREE(dbuf.dptr);
return False;
SAFE_FREE(dbuf.dptr);
return True;
}
+
+/*********************************************************************
+*********************************************************************/
+
+static TDB_DATA* make_pipe_rec_key( struct pipe_open_rec *prec )
+{
+ TDB_DATA *kbuf = NULL;
+ fstring key_string;
+
+ if ( !prec )
+ return NULL;
+
+ if ( (kbuf = TALLOC_P(prec, TDB_DATA)) == NULL ) {
+ return NULL;
+ }
+
+ snprintf( key_string, sizeof(key_string), "%s/%d/%d",
+ prec->name, procid_to_pid(&prec->pid), prec->pnum );
+
+ if ( (kbuf->dptr = talloc_strdup(prec, key_string)) == NULL )
+ return NULL;
+
+ kbuf->dsize = strlen(key_string)+1;
+
+ return kbuf;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static void fill_pipe_open_rec( struct pipe_open_rec *prec, smb_np_struct *p )
+{
+ prec->pid = pid_to_procid(sys_getpid());
+ prec->pnum = p->pnum;
+ prec->uid = geteuid();
+ fstrcpy( prec->name, p->name );
+
+ return;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+BOOL store_pipe_opendb( smb_np_struct *p )
+{
+ struct pipe_open_rec *prec;
+ TDB_DATA *key;
+ TDB_DATA data;
+ TDB_CONTEXT *pipe_tdb;
+ BOOL ret = False;
+
+ if ( (prec = TALLOC_P( NULL, struct pipe_open_rec)) == NULL ) {
+ DEBUG(0,("store_pipe_opendb: talloc failed!\n"));
+ return False;
+ }
+
+ fill_pipe_open_rec( prec, p );
+ if ( (key = make_pipe_rec_key( prec )) == NULL ) {
+ goto done;
+ }
+
+ data.dptr = (char*)prec;
+ data.dsize = sizeof(struct pipe_open_rec);
+
+ if ( (pipe_tdb = conn_tdb_ctx() ) == NULL ) {
+ goto done;
+ }
+
+ ret = (tdb_store( pipe_tdb, *key, data, TDB_REPLACE ) != -1);
+
+done:
+ TALLOC_FREE( prec );
+ return ret;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+BOOL delete_pipe_opendb( smb_np_struct *p )
+{
+ struct pipe_open_rec *prec;
+ TDB_DATA *key;
+ TDB_CONTEXT *pipe_tdb;
+ BOOL ret = False;
+
+ if ( (prec = TALLOC_P( NULL, struct pipe_open_rec)) == NULL ) {
+ DEBUG(0,("store_pipe_opendb: talloc failed!\n"));
+ return False;
+ }
+
+ fill_pipe_open_rec( prec, p );
+ if ( (key = make_pipe_rec_key( prec )) == NULL ) {
+ goto done;
+ }
+
+ if ( (pipe_tdb = conn_tdb_ctx() ) == NULL ) {
+ goto done;
+ }
+
+ ret = (tdb_delete( pipe_tdb, *key ) != -1 );
+
+done:
+ TALLOC_FREE( prec );
+ return ret;
+}