s3:spoolssd Start spoolssd from printing_subsystem_init
authorSimo Sorce <idra@samba.org>
Wed, 18 May 2011 15:24:30 +0000 (11:24 -0400)
committerAndreas Schneider <asn@samba.org>
Wed, 10 Aug 2011 16:14:04 +0000 (18:14 +0200)
Use a child for the background updater process
Forward printer update messages from spoolss to background update process.

Signed-off-by: Andreas Schneider <asn@samba.org>
source3/printing/queue_process.c
source3/printing/queue_process.h
source3/printing/spoolssd.c
source3/smbd/server.c

index 2b15c3640487a771013410916d71147ae164eaf2..5d18a08d63e0585e3c2eae83422b40ca369a7dea 100644 (file)
 #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);
 
index 9401e00fb0a0e338d8ef481a930df41fc80cd412..f0da726058d1b6100e7deb3d128407bee109e25d 100644 (file)
@@ -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);
index 13f300d19a8e9c972663adb6b2f8c3dcdeb35c63..eb7b5e9b8302abb674a80472166d1a8d05c73554 100644 (file)
@@ -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 */
index 9e17e07a41eba6953f009fa7e4afc57c627b1a8b..ee406fdfafba2e91dc86658a1c3233fcbe8e4fe1 100644 (file)
@@ -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);