summaryrefslogtreecommitdiff
path: root/source3/smbd/process.c
diff options
context:
space:
mode:
authorDavid Disseldorp <ddiss@suse.de>2010-12-23 12:14:21 +0100
committerJeremy Allison <jra@samba.org>2011-01-07 15:37:39 -0800
commit0b188e7784a3f58810f871bf63d10d8a691ecbae (patch)
tree997ccf3bb3962549f814d82af4e54692880bcaee /source3/smbd/process.c
parent04248c2cfaa5a1728ef58fc8ca231fd1309ca694 (diff)
downloadsamba-0b188e7784a3f58810f871bf63d10d8a691ecbae.tar.gz
samba-0b188e7784a3f58810f871bf63d10d8a691ecbae.tar.bz2
samba-0b188e7784a3f58810f871bf63d10d8a691ecbae.zip
s3-printing: Initiate pcap reload from parent smbd
Since commit 7022554, smbds share a printcap cache (printer_list.tdb), therefore ordering of events between smbd processes is important when updating printcap cache information. Consider the following two process example: 1) smbd1 receives HUP or printcap cache time expiry 2) smbd1 checks whether pcap needs refresh, it does 3) smbd1 marks pcap as refreshed 4) smbd1 forks child1 to obtain cups printer info 5) smbd2 receives HUP or printcap cache time expiry 6) smbd2 checks whether pcap needs refresh, it does not (due to step 3) 7) smbd2 reloads printer shares prior to child1 completion (stale pcap) 8) child1 completion, pcap cache (printer_list.tdb) is updated by smbd1 9) smbd1 reloads printer shares based on new pcap information In this case both smbd1 and smbd2 are reliant on the pcap update performed on child1 completion. The prior commit "reload shares after pcap cache fill" ensures that smbd1 only reloads printer shares following pcap update, however smbd2 continues to present shares based on stale pcap data. This commit addresses the above problem by driving pcap cache and printer share updates from the parent smbd process. 1) smbd0 (parent) receives a HUP or printcap cache time expiry 2) smbd0 forks child0 to obtain cups printer info 3) child0 completion, pcap cache (printer_list.tdb) is updated by smbd0 4) smbd0 reloads printer shares 5) smbd0 notifies child smbds of pcap update via message_send_all() 6) child smbds read fresh pcap data and reload printer shares This architecture has the additional advantage that only a single process (the parent smbd) requests printer information from the printcap backend. Use time_mono in housekeeping functions As suggested by Björn Jacke.
Diffstat (limited to 'source3/smbd/process.c')
-rw-r--r--source3/smbd/process.c45
1 files changed, 9 insertions, 36 deletions
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 2992576702..e5b6f68199 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -943,6 +943,9 @@ static void smbd_sig_hup_handler(struct tevent_context *ev,
change_to_root_user();
DEBUG(1,("Reloading services after SIGHUP\n"));
reload_services(msg_ctx, smbd_server_conn->sock, False);
+ if (am_parent) {
+ pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
+ }
}
void smbd_setup_sig_hup_handler(struct tevent_context *ev,
@@ -2222,48 +2225,15 @@ void chain_reply(struct smb_request *req)
static void check_reload(struct smbd_server_connection *sconn, time_t t)
{
- time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
- if(last_smb_conf_reload_time == 0) {
+ if (last_smb_conf_reload_time == 0) {
last_smb_conf_reload_time = t;
- /* Our printing subsystem might not be ready at smbd start up.
- Then no printer is available till the first printers check
- is performed. A lower initial interval circumvents this. */
- if ( printcap_cache_time > 60 )
- last_printer_reload_time = t - printcap_cache_time + 60;
- else
- last_printer_reload_time = t;
- }
-
- if (mypid != getpid()) { /* First time or fork happened meanwhile */
- /* randomize over 60 second the printcap reload to avoid all
- * process hitting cupsd at the same time */
- int time_range = 60;
-
- last_printer_reload_time += random() % time_range;
- mypid = getpid();
}
if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
reload_services(sconn->msg_ctx, sconn->sock, True);
last_smb_conf_reload_time = t;
}
-
- /* 'printcap cache time = 0' disable the feature */
-
- if ( printcap_cache_time != 0 )
- {
- /* see if it's time to reload or if the clock has been set back */
-
- if ( (t >= last_printer_reload_time+printcap_cache_time)
- || (t-last_printer_reload_time < 0) )
- {
- DEBUG( 3,( "Printcap cache time expired.\n"));
- pcap_cache_reload(server_event_context(),
- sconn->msg_ctx, &reload_printers);
- last_printer_reload_time = t;
- }
- }
}
static bool fd_is_readable(int fd)
@@ -2493,13 +2463,16 @@ static bool housekeeping_fn(const struct timeval *now, void *private_data)
{
struct smbd_server_connection *sconn = talloc_get_type_abort(
private_data, struct smbd_server_connection);
+
+ DEBUG(5, ("housekeeping\n"));
+
change_to_root_user();
/* update printer queue caches if necessary */
update_monitored_printq_cache(sconn->msg_ctx);
/* check if we need to reload services */
- check_reload(sconn, time(NULL));
+ check_reload(sconn, time_mono(NULL));
/* Change machine password if neccessary. */
attempt_machine_password_change();
@@ -3106,7 +3079,7 @@ void smbd_process(struct smbd_server_connection *sconn)
}
if (!(event_add_idle(smbd_event_context(), NULL,
- timeval_set(SMBD_SELECT_TIMEOUT, 0),
+ timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
"housekeeping", housekeeping_fn, sconn))) {
DEBUG(0, ("Could not add housekeeping event\n"));
exit(1);