[SCM] Samba Shared Repository - branch v3-3-test updated - release-3-2-0pre2-4213-g8674c68

Jeremy Allison jra at samba.org
Fri Oct 3 21:20:24 GMT 2008


The branch, v3-3-test has been updated
       via  8674c683e37b13554b6f0f121198bd4746c78796 (commit)
      from  3e5662bfda7856af5d6607c23397da0b18c9827a (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test


- Log -----------------------------------------------------------------
commit 8674c683e37b13554b6f0f121198bd4746c78796
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Oct 3 14:19:44 2008 -0700

    Simply our main loop processing. A lot :-). Correctly use events for all the previous "special" cases.
    A step on the way to adding signals to the events and being able to merge the S3 event system with
    the S4 one.
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source/auth/auth_domain.c |   65 +++++++++++++++
 source/include/proto.h    |    3 +-
 source/lib/dummysmbd.c    |   15 ++++
 source/printing/notify.c  |   26 ++++++
 source/smbd/process.c     |  193 ++------------------------------------------
 source/smbd/reply.c       |    3 -
 source/smbd/server.c      |   31 +++++++
 7 files changed, 148 insertions(+), 188 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/auth/auth_domain.c b/source/auth/auth_domain.c
index c25e62a..f11dbe6 100644
--- a/source/auth/auth_domain.c
+++ b/source/auth/auth_domain.c
@@ -26,6 +26,71 @@
 extern bool global_machine_password_needs_changing;
 static struct named_mutex *mutex;
 
+/*
+ * Change machine password (called from main loop
+ * idle timeout. Must be done as root.
+ */
+
+void attempt_machine_password_change(void)
+{
+	unsigned char trust_passwd_hash[16];
+	time_t lct;
+	void *lock;
+
+	if (!global_machine_password_needs_changing) {
+		return;
+	}
+
+	if (lp_security() != SEC_DOMAIN) {
+		return;
+	}
+
+	/*
+	 * We're in domain level security, and the code that
+	 * read the machine password flagged that the machine
+	 * password needs changing.
+	 */
+
+	/*
+	 * First, open the machine password file with an exclusive lock.
+	 */
+
+	lock = secrets_get_trust_account_lock(NULL, lp_workgroup());
+
+	if (lock == NULL) {
+		DEBUG(0,("attempt_machine_password_change: unable to lock "
+			"the machine account password for machine %s in "
+			"domain %s.\n",
+			global_myname(), lp_workgroup() ));
+		return;
+	}
+
+	if(!secrets_fetch_trust_account_password(lp_workgroup(),
+			trust_passwd_hash, &lct, NULL)) {
+		DEBUG(0,("attempt_machine_password_change: unable to read the "
+			"machine account password for %s in domain %s.\n",
+			global_myname(), lp_workgroup()));
+		TALLOC_FREE(lock);
+		return;
+	}
+
+	/*
+	 * Make sure someone else hasn't already done this.
+	 */
+
+	if(time(NULL) < lct + lp_machine_password_timeout()) {
+		global_machine_password_needs_changing = false;
+		TALLOC_FREE(lock);
+		return;
+	}
+
+	/* always just contact the PDC here */
+
+	change_trust_account_password( lp_workgroup(), NULL);
+	global_machine_password_needs_changing = false;
+	TALLOC_FREE(lock);
+}
+
 /**
  * Connect to a remote server for (inter)domain security authenticaion.
  *
diff --git a/source/include/proto.h b/source/include/proto.h
index 950d2b5..6066ce2 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -43,7 +43,8 @@ bool password_ok(const char *smb_name, DATA_BLOB password_blob);
 
 /* The following definitions come from auth/auth_domain.c  */
 
-NTSTATUS auth_domain_init(void) ;
+void attempt_machine_password_change(void);
+NTSTATUS auth_domain_init(void);
 
 /* The following definitions come from auth/auth_ntlmssp.c  */
 
diff --git a/source/lib/dummysmbd.c b/source/lib/dummysmbd.c
index dbe886e..5c624bd 100644
--- a/source/lib/dummysmbd.c
+++ b/source/lib/dummysmbd.c
@@ -51,3 +51,18 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
 {
 	return NT_STATUS_OK;
 }
+
+bool change_to_root_user(void)
+{
+	return false;
+}
+
+struct event_context *smbd_event_context(void)
+{
+	return NULL;
+}
+
+struct messaging_context *smbd_messaging_context(void)
+{
+	return NULL;
+}
diff --git a/source/printing/notify.c b/source/printing/notify.c
index 23df17c..f6599c4 100644
--- a/source/printing/notify.c
+++ b/source/printing/notify.c
@@ -34,6 +34,7 @@ static struct notify_queue {
 	size_t buflen;
 } *notify_queue_head = NULL;
 
+static struct timed_event *notify_event;
 
 static bool create_send_ctx(void)
 {
@@ -214,6 +215,22 @@ void print_notify_send_messages(struct messaging_context *msg_ctx,
 	num_messages = 0;
 }
 
+/*******************************************************************
+ Event handler to send the messages.
+*******************************************************************/
+
+static void print_notify_event_send_messages(struct event_context *event_ctx,
+					struct timed_event *te,
+					const struct timeval *now,
+					void *private_data)
+{
+	/* Remove this timed event handler. */
+	TALLOC_FREE(notify_event);
+
+	change_to_root_user();
+	print_notify_send_messages(smbd_messaging_context(), 0);
+}
+
 /**********************************************************************
  deep copy a SPOOLSS_NOTIFY_MSG structure using a TALLOC_CTX
  *********************************************************************/
@@ -304,6 +321,15 @@ to notify_queue_head\n", msg->type, msg->field, msg->printer));
 
 	DLIST_ADD_END(notify_queue_head, pnqueue, struct notify_queue *);
 	num_messages++;
+
+	if (smbd_event_context()) {
+		/* Add an event for 1 second's time to send this queue. */
+		notify_event = event_add_timed(smbd_event_context(), NULL,
+					timeval_current_ofs(1,0),
+					"print_notify",
+					print_notify_event_send_messages, NULL);
+	}
+
 }
 
 static void send_notify_field_values(const char *sharename, uint32 type,
diff --git a/source/smbd/process.c b/source/smbd/process.c
index c7e5c4c..0b8ff4f 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -706,7 +706,7 @@ The timeout is in milliseconds
 ****************************************************************************/
 
 static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer,
-				       size_t *buffer_len, int timeout,
+				       size_t *buffer_len,
 				       size_t *p_unread, bool *p_encrypted)
 {
 	fd_set r_fds, w_fds;
@@ -720,13 +720,8 @@ static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer,
 
  again:
 
-	if (timeout >= 0) {
-		to.tv_sec = timeout / 1000;
-		to.tv_usec = (timeout % 1000) * 1000;
-	} else {
-		to.tv_sec = SMBD_SELECT_TIMEOUT;
-		to.tv_usec = 0;
-	}
+	to.tv_sec = SMBD_SELECT_TIMEOUT;
+	to.tv_usec = 0;
 
 	/*
 	 * Note that this call must be before processing any SMB
@@ -869,7 +864,7 @@ static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer,
 
 	/* Did we timeout ? */
 	if (selrtn == 0) {
-		return NT_STATUS_IO_TIMEOUT;
+		goto again;
 	}
 
 	/*
@@ -1837,23 +1832,6 @@ void chain_reply(struct smb_request *req)
 }
 
 /****************************************************************************
- Setup the needed select timeout in milliseconds.
-****************************************************************************/
-
-static int setup_select_timeout(void)
-{
-	int select_timeout;
-
-	select_timeout = SMBD_SELECT_TIMEOUT*1000;
-
-	if (print_notify_messages_pending()) {
-		select_timeout = MIN(select_timeout, 1000);
-	}
-
-	return select_timeout;
-}
-
-/****************************************************************************
  Check if services need reloading.
 ****************************************************************************/
 
@@ -1907,113 +1885,18 @@ void check_reload(time_t t)
 }
 
 /****************************************************************************
- Process any timeout housekeeping. Return False if the caller should exit.
-****************************************************************************/
-
-static void timeout_processing(int *select_timeout,
-			       time_t *last_timeout_processing_time)
-{
-	time_t t;
-
-	*last_timeout_processing_time = t = time(NULL);
-
-	/* become root again if waiting */
-	change_to_root_user();
-
-	/* check if we need to reload services */
-	check_reload(t);
-
-	if(global_machine_password_needs_changing && 
-			/* for ADS we need to do a regular ADS password change, not a domain
-					password change */
-			lp_security() == SEC_DOMAIN) {
-
-		unsigned char trust_passwd_hash[16];
-		time_t lct;
-		void *lock;
-
-		/*
-		 * We're in domain level security, and the code that
-		 * read the machine password flagged that the machine
-		 * password needs changing.
-		 */
-
-		/*
-		 * First, open the machine password file with an exclusive lock.
-		 */
-
-		lock = secrets_get_trust_account_lock(NULL, lp_workgroup());
-
-		if (lock == NULL) {
-			DEBUG(0,("process: unable to lock the machine account password for \
-machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
-			return;
-		}
-
-		if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {
-			DEBUG(0,("process: unable to read the machine account password for \
-machine %s in domain %s.\n", global_myname(), lp_workgroup()));
-			TALLOC_FREE(lock);
-			return;
-		}
-
-		/*
-		 * Make sure someone else hasn't already done this.
-		 */
-
-		if(t < lct + lp_machine_password_timeout()) {
-			global_machine_password_needs_changing = False;
-			TALLOC_FREE(lock);
-			return;
-		}
-
-		/* always just contact the PDC here */
-    
-		change_trust_account_password( lp_workgroup(), NULL);
-		global_machine_password_needs_changing = False;
-		TALLOC_FREE(lock);
-	}
-
-	/* update printer queue caches if necessary */
-  
-	update_monitored_printq_cache();
-  
-	/*
-	 * Now we are root, check if the log files need pruning.
-	 * Force a log file check.
-	 */
-	force_check_log_size();
-	check_log_size();
-
-	/* Send any queued printer notify message to interested smbd's. */
-
-	print_notify_send_messages(smbd_messaging_context(), 0);
-
-	/*
-	 * Modify the select timeout depending upon
-	 * what we have remaining in our queues.
-	 */
-
-	*select_timeout = setup_select_timeout();
-
-	return;
-}
-
-/****************************************************************************
  Process commands from the client
 ****************************************************************************/
 
 void smbd_process(void)
 {
-	time_t last_timeout_processing_time = time(NULL);
 	unsigned int num_smbs = 0;
 	size_t unread_bytes = 0;
 
 	max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
 
 	while (True) {
-		int select_timeout = setup_select_timeout();
-		int num_echos;
+		NTSTATUS status;
 		char *inbuf = NULL;
 		size_t inbuf_len = 0;
 		bool encrypted = false;
@@ -2021,82 +1904,24 @@ void smbd_process(void)
 
 		errno = 0;
 
-		/* Did someone ask for immediate checks on things like blocking locks ? */
-		if (select_timeout == 0) {
-			timeout_processing(&select_timeout,
-					   &last_timeout_processing_time);
-			num_smbs = 0; /* Reset smb counter. */
-		}
-
 		run_events(smbd_event_context(), 0, NULL, NULL);
 
-		while (True) {
-			NTSTATUS status;
-
-			status = receive_message_or_smb(
-				talloc_tos(), &inbuf, &inbuf_len,
-				select_timeout,	&unread_bytes, &encrypted);
-
-			if (NT_STATUS_IS_OK(status)) {
-				break;
-			}
-
-			if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
-				timeout_processing(
-					&select_timeout,
-					&last_timeout_processing_time);
-				continue;
-			}
+		status = receive_message_or_smb(
+			talloc_tos(), &inbuf, &inbuf_len,
+			&unread_bytes, &encrypted);
 
+		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(3, ("receive_message_or_smb failed: %s, "
 				  "exiting\n", nt_errstr(status)));
 			return;
-
-			num_smbs = 0; /* Reset smb counter. */
 		}
 
-
-		/*
-		 * Ensure we do timeout processing if the SMB we just got was
-		 * only an echo request. This allows us to set the select
-		 * timeout in 'receive_message_or_smb()' to any value we like
-		 * without worrying that the client will send echo requests
-		 * faster than the select timeout, thus starving out the
-		 * essential processing (change notify, blocking locks) that
-		 * the timeout code does. JRA.
-		 */
-		num_echos = smb_echo_count;
-
 		process_smb(inbuf, inbuf_len, unread_bytes, encrypted);
 
 		TALLOC_FREE(inbuf);
 
-		if (smb_echo_count != num_echos) {
-			timeout_processing(&select_timeout,
-					   &last_timeout_processing_time);
-			num_smbs = 0; /* Reset smb counter. */
-		}
-
 		num_smbs++;
 
-		/*
-		 * If we are getting smb requests in a constant stream
-		 * with no echos, make sure we attempt timeout processing
-		 * every select_timeout milliseconds - but only check for this
-		 * every 200 smb requests.
-		 */
-		
-		if ((num_smbs % 200) == 0) {
-			time_t new_check_time = time(NULL);
-			if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {
-				timeout_processing(
-					&select_timeout,
-					&last_timeout_processing_time);
-				num_smbs = 0; /* Reset smb counter. */
-				last_timeout_processing_time = new_check_time; /* Reset time. */
-			}
-		}
-
 		/* The timeout_processing function isn't run nearly
 		   often enough to implement 'max log size' without
 		   overrunning the size of the file by many megabytes.
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index fbda57d..ae8e769 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -29,7 +29,6 @@
 /* look in server.c for some explanation of these variables */
 extern enum protocol_types Protocol;
 extern int max_recv;
-unsigned int smb_echo_count = 0;
 extern uint32 global_client_caps;
 
 extern bool global_encrypted_passwords_negotiated;
@@ -4614,8 +4613,6 @@ void reply_echo(struct smb_request *req)
 
 	TALLOC_FREE(req->outbuf);
 
-	smb_echo_count++;
-
 	END_PROFILE(SMBecho);
 	return;
 }
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 53116f3..69a483e 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -1067,6 +1067,30 @@ static bool deadtime_fn(const struct timeval *now, void *private_data)
 	return True;
 }
 
+/*
+ * Do the recurring log file and smb.conf reload checks.
+ */
+
+static bool housekeeping_fn(const struct timeval *now, void *private_data)
+{
+	change_to_root_user();
+
+	/* update printer queue caches if necessary */
+	update_monitored_printq_cache();
+
+	/* check if we need to reload services */
+	check_reload(time(NULL));
+
+	/* Change machine password if neccessary. */
+	attempt_machine_password_change();
+
+        /*
+	 * Force a log file check.
+	 */
+        force_check_log_size();
+        check_log_size();
+	return true;
+}
 
 /****************************************************************************
  main program.
@@ -1426,6 +1450,13 @@ extern void build_options(bool screen);
 		exit(1);
 	}
 
+	if (!(event_add_idle(smbd_event_context(), NULL,
+			     timeval_set(SMBD_SELECT_TIMEOUT, 0),
+			     "housekeeping", housekeeping_fn, NULL))) {
+		DEBUG(0, ("Could not add housekeeping event\n"));
+		exit(1);
+	}
+
 #ifdef CLUSTER_SUPPORT
 
 	if (lp_clustering()) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list