summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2010-10-19 11:11:56 -0700
committerJeremy Allison <jra@samba.org>2010-10-19 15:13:17 -0700
commite7d0f478ee529500461f80f2fd51987c9255d345 (patch)
tree84b120159293ec5c4d3fa51464312157d6c6fb28 /source3/smbd
parentd7f4bea39455c5d0a9b36cfa731d10c96a1c1405 (diff)
downloadsamba-e7d0f478ee529500461f80f2fd51987c9255d345.tar.gz
samba-e7d0f478ee529500461f80f2fd51987c9255d345.tar.bz2
samba-e7d0f478ee529500461f80f2fd51987c9255d345.zip
Add deadtime detection for SMB2. Correctly update lastused timestamp across all active tcons. Should fix dfree cache not updating bug.
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/conn.c92
-rw-r--r--source3/smbd/process.c14
2 files changed, 76 insertions, 30 deletions
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index e8f14fd918..8de8ce2e11 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -245,34 +245,92 @@ bool conn_close_all(struct smbd_server_connection *sconn)
}
/****************************************************************************
+ Update last used timestamps.
+****************************************************************************/
+
+static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t)
+{
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *ptcon;
+
+ for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+ connection_struct *conn = ptcon->compat_conn;
+ /* Update if connection wasn't idle. */
+ if (conn && conn->lastused != conn->lastused_count) {
+ conn->lastused = t;
+ conn->lastused_count = t;
+ }
+ }
+ }
+ } else {
+ /* SMB1 */
+ connection_struct *conn;
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+ /* Update if connection wasn't idle. */
+ if (conn->lastused != conn->lastused_count) {
+ conn->lastused = t;
+ conn->lastused_count = t;
+ }
+ }
+ }
+}
+
+/****************************************************************************
Idle inactive connections.
****************************************************************************/
-bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
+bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
{
int deadtime = lp_deadtime()*60;
- connection_struct *conn;
- if (deadtime <= 0)
+ conn_lastused_update(sconn, t);
+
+ if (deadtime <= 0) {
deadtime = DEFAULT_SMBD_TIMEOUT;
+ }
- for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *ptcon;
- time_t age = t - conn->lastused;
+ for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+ time_t age;
+ connection_struct *conn = ptcon->compat_conn;
- /* Update if connection wasn't idle. */
- if (conn->lastused != conn->lastused_count) {
- conn->lastused = t;
- conn->lastused_count = t;
- }
+ if (conn == NULL) {
+ continue;
+ }
- /* close dirptrs on connections that are idle */
- if (age > DPTR_IDLE_TIMEOUT) {
- dptr_idlecnum(conn);
+ age = t - conn->lastused;
+ /* close dirptrs on connections that are idle */
+ if (age > DPTR_IDLE_TIMEOUT) {
+ dptr_idlecnum(conn);
+ }
+
+ if (conn->num_files_open > 0 || age < deadtime) {
+ return false;
+ }
+ }
}
+ } else {
+ /* SMB1 */
+ connection_struct *conn;
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+ time_t age = t - conn->lastused;
- if (conn->num_files_open > 0 || age < deadtime) {
- return False;
+ /* close dirptrs on connections that are idle */
+ if (age > DPTR_IDLE_TIMEOUT) {
+ dptr_idlecnum(conn);
+ }
+
+ if (conn->num_files_open > 0 || age < deadtime) {
+ return false;
+ }
}
}
@@ -281,10 +339,10 @@ bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
* idle with a handle open.
*/
if (check_open_pipes()) {
- return False;
+ return false;
}
- return True;
+ return true;
}
/****************************************************************************
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index ff2b8fc67d..f2aa23e3e0 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -2467,21 +2467,9 @@ static bool deadtime_fn(const struct timeval *now, void *private_data)
struct smbd_server_connection *sconn =
(struct smbd_server_connection *)private_data;
- if (sconn->using_smb2) {
- /* TODO: implement real idle check */
- if (sconn->smb2.sessions.list) {
- return true;
- }
- DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
- messaging_send(sconn->msg_ctx,
- messaging_server_id(sconn->msg_ctx),
- MSG_SHUTDOWN, &data_blob_null);
- return false;
- }
-
if ((conn_num_open(sconn) == 0)
|| (conn_idle_all(sconn, now->tv_sec))) {
- DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
+ DEBUG( 2, ( "Closing idle connection\n" ) );
messaging_send(sconn->msg_ctx,
messaging_server_id(sconn->msg_ctx),
MSG_SHUTDOWN, &data_blob_null);