From d36a8dc896d2a814dd18f127593a8382e4004213 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 18 May 2011 11:24:30 -0400 Subject: s3:spoolssd Start spoolssd from printing_subsystem_init Use a child for the background updater process Forward printer update messages from spoolss to background update process. Signed-off-by: Andreas Schneider --- source3/printing/queue_process.c | 15 ++++++++-- source3/printing/queue_process.h | 1 + source3/printing/spoolssd.c | 65 +++++++++++++++++++++++++++++----------- source3/smbd/server.c | 30 +++++-------------- 4 files changed, 70 insertions(+), 41 deletions(-) (limited to 'source3') diff --git a/source3/printing/queue_process.c b/source3/printing/queue_process.c index 2b15c36404..5d18a08d63 100644 --- a/source3/printing/queue_process.c +++ b/source3/printing/queue_process.c @@ -29,6 +29,10 @@ #include "serverid.h" #include "locking/proto.h" #include "smbd/proto.h" +#include "rpc_server/rpc_service_setup.h" + +extern pid_t start_spoolssd(struct event_context *ev_ctx, + struct messaging_context *msg_ctx); /**************************************************************************** Notify smbds of new printcap data @@ -222,7 +226,6 @@ pid_t start_background_queue(struct tevent_context *ev, if (!locking_init()) { exit(1); } - messaging_register(msg_ctx, ev, MSG_SMB_CONF_UPDATED, bq_smb_conf_updated); messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE, @@ -252,15 +255,23 @@ pid_t start_background_queue(struct tevent_context *ev, /* Run before the parent forks */ bool printing_subsystem_init(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, + bool start_daemons, bool background_queue) { + enum rpc_service_mode_e spoolss_mode = rpc_spoolss_mode(); pid_t pid = -1; if (!print_backend_init(msg_ctx)) { return false; } - if (background_queue) { + /* start spoolss daemon */ + /* start as a separate daemon only if enabled */ + if (start_daemons && spoolss_mode == RPC_SERVICE_MODE_DAEMON) { + + pid = start_spoolssd(ev_ctx, msg_ctx); + + } else if (start_daemons && background_queue) { pid = start_background_queue(ev_ctx, msg_ctx); diff --git a/source3/printing/queue_process.h b/source3/printing/queue_process.h index 9401e00fb0..f0da726058 100644 --- a/source3/printing/queue_process.h +++ b/source3/printing/queue_process.h @@ -22,6 +22,7 @@ bool printing_subsystem_init(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, + bool start_daemons, bool background_queue); void printing_subsystem_update(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx); diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c index 13f300d19a..eb7b5e9b83 100644 --- a/source3/printing/spoolssd.c +++ b/source3/printing/spoolssd.c @@ -23,6 +23,7 @@ #include "messages.h" #include "include/printing.h" #include "printing/nt_printing_migrate_internal.h" +#include "printing/queue_process.h" #include "printing/pcap.h" #include "ntdomain.h" #include "librpc/gen_ndr/srv_winreg.h" @@ -93,9 +94,6 @@ static void spoolss_prefork_config(void) spoolss_spawn_rate = rate; } -void start_spoolssd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx); - static void spoolss_reopen_logs(void) { char *lfile = lp_logfile(); @@ -519,6 +517,26 @@ static void spoolss_handle_client(struct tevent_req *req) /* ==== Main Process Functions ==== */ +extern pid_t background_lpq_updater_pid; + +static void check_updater_child(void) +{ + int status; + pid_t pid; + + if (background_lpq_updater_pid == -1) { + return; + } + + pid = sys_waitpid(background_lpq_updater_pid, &status, WNOHANG); + if (pid > 0) { + DEBUG(2, ("The background queue child died... Restarting!\n")); + pid = start_background_queue(server_event_context(), + server_messaging_context()); + background_lpq_updater_pid = pid; + } +} + static void spoolssd_sig_chld_handler(struct tevent_context *ev_ctx, struct tevent_signal *se, int signum, int count, @@ -552,7 +570,8 @@ static void spoolssd_sig_chld_handler(struct tevent_context *ev_ctx, } } - + /* also check if the updater child is alive and well */ + check_updater_child(); } static bool spoolssd_setup_sig_chld_handler(struct tevent_context *ev_ctx, @@ -602,8 +621,8 @@ static bool spoolssd_schedule_check(struct tevent_context *ev_ctx, /* check situation again in 10 seconds */ next_event = tevent_timeval_current_ofs(10, 0); - /* check when the socket becomes readable, so that children - * are checked only when there is some activity */ + /* TODO: check when the socket becomes readable, so that children + * are checked only when there is some activity ? */ te = tevent_add_timer(ev_ctx, pfp, next_event, spoolssd_check_children, pfp); if (!te) { @@ -654,7 +673,17 @@ static void spoolssd_check_children(struct tevent_context *ev_ctx, ret = spoolssd_schedule_check(ev_ctx, pfp, current_time); } -void start_spoolssd(struct tevent_context *ev_ctx, +static void print_queue_forward(struct messaging_context *msg, + void *private_data, + uint32_t msg_type, + struct server_id server_id, + DATA_BLOB *data) +{ + messaging_send_buf(msg, pid_to_procid(background_lpq_updater_pid), + MSG_PRINTER_UPDATE, data->data, data->length); +} + +pid_t start_spoolssd(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx) { struct prefork_pool *pool; @@ -672,14 +701,12 @@ void start_spoolssd(struct tevent_context *ev_ctx, pid = sys_fork(); if (pid == -1) { - DEBUG(0, ("Failed to fork SPOOLSS [%s], aborting ...\n", + DEBUG(0, ("Failed to fork SPOOLSS [%s]\n", strerror(errno))); - exit(1); } - - if (pid) { - /* parent */ - return; + if (pid != 0) { + /* parent or error */ + return pid; } /* child */ @@ -699,6 +726,12 @@ void start_spoolssd(struct tevent_context *ev_ctx, /* Publish nt printers, this requires a working winreg pipe */ pcap_cache_reload(ev_ctx, msg_ctx, &reload_printers); + /* always start the backgroundqueue listner in spoolssd */ + pid = start_background_queue(ev_ctx, msg_ctx); + if (pid > 0) { + background_lpq_updater_pid = pid; + } + /* the listening fd must be created before the children are actually * forked out. */ listen_fd = create_named_pipe_socket(SPOOLSS_PIPE_NAME); @@ -734,10 +767,10 @@ void start_spoolssd(struct tevent_context *ev_ctx, exit(1); } - messaging_register(msg_ctx, NULL, - MSG_PRINTER_UPDATE, print_queue_receive); messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED, smb_conf_updated); + messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE, + print_queue_forward); mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { @@ -796,8 +829,6 @@ void start_spoolssd(struct tevent_context *ev_ctx, exit(1); } - reload_printers(ev_ctx, msg_ctx); - DEBUG(1, ("SPOOLSS Daemon Started (%d)\n", getpid())); /* loop forever */ diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 9e17e07a41..ee406fdfaf 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -42,9 +42,6 @@ extern void start_epmd(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx); -extern void start_spoolssd(struct event_context *ev_ctx, - struct messaging_context *msg_ctx); - #ifdef WITH_DFS extern int dcelogin_atmost_once; #endif /* WITH_DFS */ @@ -1212,32 +1209,21 @@ extern void build_options(bool screen); exit(1); } - /* only start the background queue daemon if we are - running as a daemon -- bad things will happen if - smbd is launched via inetd and we fork a copy of - ourselves here */ + /* only start other daemons if we are running as a daemon + * -- bad things will happen if smbd is launched via inetd + * and we fork a copy of ourselves here */ + if (is_daemon && !interactive && !_lp_disable_spoolss()) { + bool bgq = lp_parm_bool(-1, "smbd", "backgroundqueue", true); - if (is_daemon && !interactive - && lp_parm_bool(-1, "smbd", "backgroundqueue", true)) { - if (!printing_subsystem_init(ev_ctx, msg_ctx, true)) { + if (!printing_subsystem_init(ev_ctx, msg_ctx, true, bgq)) { exit(1); } - } else { - if (!printing_subsystem_init(ev_ctx, msg_ctx, false)) { + } else if (!_lp_disable_spoolss()) { + if (!printing_subsystem_init(ev_ctx, msg_ctx, false, false)) { exit(1); } } - if (is_daemon && !_lp_disable_spoolss()) { - enum rpc_service_mode_e spoolss_mode = rpc_spoolss_mode(); - - /* start spoolss daemon */ - /* start as a separate daemon only if enabled */ - if (spoolss_mode == RPC_SERVICE_MODE_DAEMON) { - start_spoolssd(ev_ctx, msg_ctx); - } - } - if (!is_daemon) { /* inetd mode */ TALLOC_FREE(frame); -- cgit