summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/printing/queue_process.c15
-rw-r--r--source3/printing/queue_process.h1
-rw-r--r--source3/printing/spoolssd.c65
-rw-r--r--source3/smbd/server.c30
4 files changed, 70 insertions, 41 deletions
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);