[SCM] Samba Shared Repository - branch v3-5-test updated

Karolin Seeger kseeger at samba.org
Sat Jan 15 09:19:15 MST 2011


The branch, v3-5-test has been updated
       via  5a2b2d4 s3-printing: update parent smbd pcap cache
       via  a8a01e4 s3-printing: reload shares after pcap cache fill
      from  b57378b s3-spoolss: Fix Bug #7641: handle win9x adddriver calls w/o config file.

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


- Log -----------------------------------------------------------------
commit 5a2b2d4aeb6fe4af13aa0c92d22ba5bc9b7f7e13
Author: David Disseldorp <ddiss at suse.de>
Date:   Mon Jan 10 14:08:07 2011 +0100

    s3-printing: update parent smbd pcap cache
    
    If a client connects to a samba share and while connected a printer is
    added, the client will see the new printer share after a maximum of
    'printcap cache time' seconds.
    
    smbd's forked for new client connections inherit printcap information
    from the parent (listener) smbd, which does not perform updates on
    printcap cache time expiry. Therefore newly connected clients may
    initially be presented with stale printer shares.
    
    Add a housekeeping function to the parent smbd to ensure newly connected
    clients see up to date printer shares.
    
    The last 2 patches address bug #7836 (A newly added printer isn't visbile to
    clients).

commit a8a01e4a3dcafd97372021d0d6f859fd3a69235f
Author: David Disseldorp <ddiss at suse.de>
Date:   Sun Dec 19 19:52:08 2010 +0100

    s3-printing: reload shares after pcap cache fill
    
    Since commit eada8f8a, updates to the cups pcap cache are performed
    asynchronously - cups_cache_reload() forks a child process to request
    cups printer information and notify the parent smbd on completion.
    
    Currently printer shares are reloaded immediately following the call to
    cups_cache_reload(), this occurs prior to smbd receiving new cups pcap
    information from the child process. Such behaviour can result in stale
    print shares as outlined in bug 7836.
    
    This fix ensures print shares are only reloaded after new pcap data has
    been received.
    
    Pair-Programmed-With: Lars Müller <lars at samba.org>

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

Summary of changes:
 source3/include/local.h       |    1 +
 source3/include/proto.h       |    4 ++--
 source3/printing/load.c       |    5 ++---
 source3/printing/pcap.c       |   18 ++++++++++++++----
 source3/printing/print_cups.c |   33 ++++++++++++++++++++++++---------
 source3/smbd/process.c        |    4 ++--
 source3/smbd/server.c         |   28 ++++++++++++++++++++++------
 source3/web/swat.c            |    4 ++--
 8 files changed, 69 insertions(+), 28 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/local.h b/source3/include/local.h
index a88b17b..d65cc00 100644
--- a/source3/include/local.h
+++ b/source3/include/local.h
@@ -148,6 +148,7 @@
 #define LPQ_LOCK_TIMEOUT (5)
 #define NMBD_INTERFACES_RELOAD (120)
 #define NMBD_UNEXPECTED_TIMEOUT (15)
+#define SMBD_HOUSEKEEPING_INTERVAL SMBD_SELECT_TIMEOUT
 
 /* the following are in milliseconds */
 #define LOCK_RETRY_TIMEOUT (100)
diff --git a/source3/include/proto.h b/source3/include/proto.h
index bfcd012..8250e54 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4897,7 +4897,7 @@ void pcap_cache_destroy_specific(struct pcap_cache **ppcache);
 bool pcap_cache_add(const char *name, const char *comment);
 bool pcap_cache_loaded(void);
 void pcap_cache_replace(const struct pcap_cache *cache);
-void pcap_cache_reload(void);
+void pcap_cache_reload(void (*post_cache_fill_fn)(void));
 bool pcap_printername_ok(const char *printername);
 void pcap_printer_fn_specific(const struct pcap_cache *, void (*fn)(const char *, const char *, void *), void *);
 void pcap_printer_fn(void (*fn)(const char *, const char *, void *), void *);
@@ -4908,7 +4908,7 @@ bool aix_cache_reload(void);
 
 /* The following definitions come from printing/print_cups.c  */
 
-bool cups_cache_reload(void);
+bool cups_cache_reload(void (*post_cache_fill_fn)(void));
 bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer);
 
 /* The following definitions come from printing/print_generic.c  */
diff --git a/source3/printing/load.c b/source3/printing/load.c
index 874f7f2..00da9cb 100644
--- a/source3/printing/load.c
+++ b/source3/printing/load.c
@@ -53,12 +53,11 @@ static void add_auto_printers(void)
 }
 
 /***************************************************************************
-load automatic printer services
+load automatic printer services from pre-populated pcap cache
 ***************************************************************************/
 void load_printers(void)
 {
-	if (!pcap_cache_loaded())
-		pcap_cache_reload();
+	SMB_ASSERT(pcap_cache_loaded());
 
 	add_auto_printers();
 
diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c
index a6bf52a..0d6480c 100644
--- a/source3/printing/pcap.c
+++ b/source3/printing/pcap.c
@@ -125,13 +125,14 @@ void pcap_cache_replace(const struct pcap_cache *pcache)
 	}
 }
 
-void pcap_cache_reload(void)
+void pcap_cache_reload(void (*post_cache_fill_fn)(void))
 {
 	const char *pcap_name = lp_printcapname();
 	bool pcap_reloaded = False;
 	struct pcap_cache *tmp_cache = NULL;
 	XFILE *pcap_file;
 	char *pcap_line;
+	bool post_cache_fill_fn_handled = false;
 
 	DEBUG(3, ("reloading printcap cache\n"));
 
@@ -146,7 +147,12 @@ void pcap_cache_reload(void)
 
 #ifdef HAVE_CUPS
 	if (strequal(pcap_name, "cups")) {
-		pcap_reloaded = cups_cache_reload();
+		pcap_reloaded = cups_cache_reload(post_cache_fill_fn);
+		/*
+		 * cups_cache_reload() is async and calls post_cache_fill_fn()
+		 * on successful completion
+		 */
+		post_cache_fill_fn_handled = true;
 		goto done;
 	}
 #endif
@@ -242,9 +248,13 @@ void pcap_cache_reload(void)
 done:
 	DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error"));
 
-	if (pcap_reloaded)
+	if (pcap_reloaded) {
 		pcap_cache_destroy_specific(&tmp_cache);
-	else {
+		if ((post_cache_fill_fn_handled == false)
+		 && (post_cache_fill_fn != NULL)) {
+			post_cache_fill_fn();
+		}
+	} else {
 		pcap_cache_destroy_specific(&pcap_cache);
 		pcap_cache = tmp_cache;
 	}
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index 4c24e44..82b4314 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -445,13 +445,19 @@ static bool cups_pcap_load_async(int *pfd)
 	_exit(0);
 }
 
+struct cups_async_cb_args {
+	int pipe_fd;
+	void (*post_cache_fill_fn)(void);
+};
+
 static void cups_async_callback(struct event_context *event_ctx,
 				struct fd_event *event,
 				uint16 flags,
 				void *p)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
-	int fd = *(int *)p;
+	struct cups_async_cb_args *cb_args = (struct cups_async_cb_args *)p;
+	int fd = cb_args->pipe_fd;
 	struct pcap_cache *tmp_pcap_cache = NULL;
 
 	DEBUG(5,("cups_async_callback: callback received for printer data. "
@@ -545,27 +551,36 @@ static void cups_async_callback(struct event_context *event_ctx,
 
 		/* And the systemwide pcap cache. */
 		pcap_cache_replace(local_pcap_copy);
+
+		/* Caller may have requested post cache fill callback */
+		if (cb_args->post_cache_fill_fn) {
+			cb_args->post_cache_fill_fn();
+		}
 	} else {
 		DEBUG(2,("cups_async_callback: failed to read a new "
 			"printer list\n"));
 	}
 	close(fd);
-	TALLOC_FREE(p);
+	TALLOC_FREE(cb_args);
 	TALLOC_FREE(cache_fd_event);
 }
 
-bool cups_cache_reload(void)
+bool cups_cache_reload(void (*post_cache_fill_fn)(void))
 {
-	int *p_pipe_fd = TALLOC_P(NULL, int);
+	struct cups_async_cb_args *cb_args;
+	int *p_pipe_fd;
 
-	if (!p_pipe_fd) {
+	cb_args = TALLOC_P(NULL, struct cups_async_cb_args);
+	if (!cb_args) {
 		return false;
 	}
-
+	cb_args->post_cache_fill_fn = post_cache_fill_fn;
+	p_pipe_fd = &cb_args->pipe_fd;
 	*p_pipe_fd = -1;
 
 	/* Set up an async refresh. */
 	if (!cups_pcap_load_async(p_pipe_fd)) {
+		talloc_free(cb_args);
 		return false;
 	}
 	if (!local_pcap_copy) {
@@ -578,7 +593,7 @@ bool cups_cache_reload(void)
 		cups_async_callback(smbd_event_context(),
 					NULL,
 					EVENT_FD_READ,
-					(void *)p_pipe_fd);
+					(void *)cb_args);
 		if (!local_pcap_copy) {
 			return false;
 		}
@@ -595,10 +610,10 @@ bool cups_cache_reload(void)
 					NULL, *p_pipe_fd,
 					EVENT_FD_READ,
 					cups_async_callback,
-					(void *)p_pipe_fd);
+					(void *)cb_args);
 		if (!cache_fd_event) {
 			close(*p_pipe_fd);
-			TALLOC_FREE(p_pipe_fd);
+			talloc_free(cb_args);
 			return false;
 		}
 	}
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 1596c0d..21b2c91 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -2079,7 +2079,7 @@ void check_reload(time_t t)
 			|| (t-last_printer_reload_time  < 0) ) 
 		{
 			DEBUG( 3,( "Printcap cache time expired.\n"));
-			reload_printers();
+			pcap_cache_reload(&reload_printers);
 			last_printer_reload_time = t;
 		}
 	}
@@ -2365,7 +2365,7 @@ void smbd_process(void)
 	}
 
 	if (!(event_add_idle(smbd_event_context(), NULL,
-			     timeval_set(SMBD_SELECT_TIMEOUT, 0),
+			     timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
 			     "housekeeping", housekeeping_fn, NULL))) {
 		DEBUG(0, ("Could not add housekeeping event\n"));
 		exit(1);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 0c59135..45d9270 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -541,6 +541,14 @@ static bool smbd_open_one_socket(struct smbd_parent_context *parent,
 	return true;
 }
 
+static bool parent_housekeeping_fn(const struct timeval *now, void *private_data)
+{
+	DEBUG(5, ("houskeeping\n"));
+	/* check if we need to reload services */
+	check_reload(time(NULL));
+	return true;
+}
+
 /****************************************************************************
  Open the socket communication.
 ****************************************************************************/
@@ -668,6 +676,14 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
 	claim_connection(NULL,"",
 			 FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_DBWRAP);
 
+	if (!(event_add_idle(smbd_event_context(), NULL,
+			     timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
+			     "parent_housekeeping", parent_housekeeping_fn,
+			     parent))) {
+		DEBUG(0, ("Could not add housekeeping event\n"));
+		exit(1);
+	}
+
         /* Listen to messages */
 
 	messaging_register(smbd_messaging_context(), NULL,
@@ -734,9 +750,9 @@ static void smbd_parent_loop(struct smbd_parent_context *parent)
 /* NOTREACHED	return True; */
 }
 
-/****************************************************************************
- Reload printers
-**************************************************************************/
+/***************************************************************************
+ purge stale printers and reload from pre-populated pcap cache
+***************************************************************************/
 void reload_printers(void)
 {
 	int snum;
@@ -744,9 +760,9 @@ void reload_printers(void)
 	int pnum = lp_servicenumber(PRINTERS_NAME);
 	const char *pname;
 
-	pcap_cache_reload();
+	SMB_ASSERT(pcap_cache_loaded());
 
-	/* remove stale printers */
+	DEBUG(10, ("reloading printer services from pcap cache\n"));
 	for (snum = 0; snum < n_services; snum++) {
 		/* avoid removing PRINTERS_NAME or non-autoloaded printers */
 		if (snum == pnum || !(lp_snum_ok(snum) && lp_print_ok(snum) &&
@@ -793,7 +809,7 @@ bool reload_services(bool test)
 
 	ret = lp_load(get_dyn_CONFIGFILE(), False, False, True, True);
 
-	reload_printers();
+	pcap_cache_reload(&reload_printers);
 
 	/* perhaps the config filename is now set */
 	if (!test)
diff --git a/source3/web/swat.c b/source3/web/swat.c
index 230b161..baffa44 100644
--- a/source3/web/swat.c
+++ b/source3/web/swat.c
@@ -490,7 +490,7 @@ static int save_reload(int snum)
                 return 0;
         }
 	iNumNonAutoPrintServices = lp_numservices();
-	load_printers();
+	pcap_cache_reload(&load_printers);
 
 	return 1;
 }
@@ -1434,7 +1434,7 @@ const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
 	load_config(True);
 	load_interfaces();
 	iNumNonAutoPrintServices = lp_numservices();
-	load_printers();
+	pcap_cache_reload(&load_printers);
 
 	cgi_setup(get_dyn_SWATDIR(), !demo_mode);
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list