summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in1
-rw-r--r--source3/include/printing.h2
-rw-r--r--source3/printing/printing.c114
-rw-r--r--source3/printing/queue_process.c294
-rw-r--r--source3/printing/queue_process.h29
-rw-r--r--source3/smbd/globals.c1
-rw-r--r--source3/smbd/process.c4
-rw-r--r--source3/smbd/proto.h2
-rw-r--r--source3/smbd/server.c46
-rw-r--r--source3/smbd/server_reload.c9
-rwxr-xr-xsource3/wscript_build3
11 files changed, 339 insertions, 166 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index f1fe0dd061..9bf3bc0399 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -972,6 +972,7 @@ PRINTBACKEND_OBJ = printing/printing.o \
printing/nt_printing_ads.o \
librpc/gen_ndr/ndr_ntprinting.o \
../librpc/ndr/ndr_ntprinting.o \
+ printing/queue_process.o \
$(PRINTBASE_OBJ)
SMBD_OBJ = $(SMBD_OBJ_BASE) $(SMBD_OBJ_MAIN)
diff --git a/source3/include/printing.h b/source3/include/printing.h
index 0c81d07fbe..debf63f5e0 100644
--- a/source3/include/printing.h
+++ b/source3/include/printing.h
@@ -234,8 +234,6 @@ uint16 pjobid_to_rap(const char* sharename, uint32 jobid);
bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid);
void rap_jobid_delete(const char* sharename, uint32 jobid);
bool print_backend_init(struct messaging_context *msg_ctx);
-void start_background_queue(struct tevent_context *ev,
- struct messaging_context *msg);
void printing_end(void);
/* The following definitions come from printing/lpq_parse.c */
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 9dbd516940..f1e2aeb265 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -28,6 +28,7 @@
#include "../librpc/gen_ndr/netlogon.h"
#include "printing/notify.h"
#include "printing/pcap.h"
+#include "printing/queue_process.h"
#include "serverid.h"
#include "smbd/smbd.h"
#include "auth.h"
@@ -1599,119 +1600,6 @@ void print_queue_receive(struct messaging_context *msg,
return;
}
-static void printing_pause_fd_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags,
- void *private_data)
-{
- /*
- * If pause_pipe[1] is closed it means the parent smbd
- * and children exited or aborted.
- */
- exit_server_cleanly(NULL);
-}
-
-extern struct child_pid *children;
-extern int num_children;
-
-static void add_child_pid(pid_t pid)
-{
- struct child_pid *child;
-
- child = SMB_MALLOC_P(struct child_pid);
- if (child == NULL) {
- DEBUG(0, ("Could not add child struct -- malloc failed\n"));
- return;
- }
- child->pid = pid;
- DLIST_ADD(children, child);
- num_children += 1;
-}
-
-static pid_t background_lpq_updater_pid = -1;
-
-/****************************************************************************
-main thread of the background lpq updater
-****************************************************************************/
-void start_background_queue(struct tevent_context *ev,
- struct messaging_context *msg_ctx)
-{
- /* Use local variables for this as we don't
- * need to save the parent side of this, just
- * ensure it closes when the process exits.
- */
- int pause_pipe[2];
-
- DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
-
- if (pipe(pause_pipe) == -1) {
- DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
- exit(1);
- }
-
- background_lpq_updater_pid = sys_fork();
-
- if (background_lpq_updater_pid == -1) {
- DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
- exit(1);
- }
-
- /* Track the printing pid along with other smbd children */
- add_child_pid(background_lpq_updater_pid);
-
- if(background_lpq_updater_pid == 0) {
- struct tevent_fd *fde;
- int ret;
- NTSTATUS status;
-
- /* Child. */
- DEBUG(5,("start_background_queue: background LPQ thread started\n"));
-
- close(pause_pipe[0]);
- pause_pipe[0] = -1;
-
- status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("reinit_after_fork() failed\n"));
- smb_panic("reinit_after_fork() failed");
- }
-
- smbd_setup_sig_term_handler();
- smbd_setup_sig_hup_handler(ev, msg_ctx);
-
- if (!serverid_register(procid_self(),
- FLAG_MSG_GENERAL|FLAG_MSG_SMBD
- |FLAG_MSG_PRINT_GENERAL)) {
- exit(1);
- }
-
- if (!locking_init()) {
- exit(1);
- }
-
- messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
- print_queue_receive);
-
- fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
- printing_pause_fd_handler,
- NULL);
- if (!fde) {
- DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
- smb_panic("tevent_add_fd() failed for pause_pipe");
- }
-
- DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
- ret = tevent_loop_wait(ev);
- /* should not be reached */
- DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
- ret, (ret == 0) ? "out of events" : strerror(errno)));
- exit(1);
- }
-
- close(pause_pipe[1]);
-}
-
/****************************************************************************
update the internal database from the system print queue for a queue
****************************************************************************/
diff --git a/source3/printing/queue_process.c b/source3/printing/queue_process.c
new file mode 100644
index 0000000000..9fbdd811ab
--- /dev/null
+++ b/source3/printing/queue_process.c
@@ -0,0 +1,294 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ printing backend routines
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Jeremy Allison 2002
+ Copyright (C) Simo Sorce 2011
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/globals.h"
+#include "include/messages.h"
+#include "printing.h"
+#include "printing/pcap.h"
+#include "serverid.h"
+#include "locking/proto.h"
+#include "smbd/proto.h"
+
+/****************************************************************************
+ Notify smbds of new printcap data
+**************************************************************************/
+static void reload_pcap_change_notify(struct tevent_context *ev,
+ struct messaging_context *msg_ctx)
+{
+ message_send_all(msg_ctx, MSG_PRINTER_PCAP, NULL, 0, NULL);
+}
+
+static bool print_queue_housekeeping(const struct timeval *now, void *pvt)
+{
+ struct messaging_context *msg_ctx =
+ talloc_get_type_abort(pvt, struct messaging_context);
+ time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
+ time_t t = time_mono(NULL);
+
+ DEBUG(5, ("print queue housekeeping\n"));
+
+ /* if periodic printcap rescan is enabled,
+ * see if it's time to reload */
+ if ((printcap_cache_time != 0) &&
+ (t >= (last_printer_reload_time + printcap_cache_time))) {
+ DEBUG( 3,( "Printcap cache time expired.\n"));
+ pcap_cache_reload(messaging_event_context(msg_ctx),
+ msg_ctx,
+ &reload_pcap_change_notify);
+ last_printer_reload_time = t;
+ }
+
+ return true;
+}
+
+static bool printing_subsystem_queue_tasks(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx)
+{
+ if (!(event_add_idle(ev_ctx, NULL,
+ timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
+ "print_queue_housekeeping",
+ print_queue_housekeeping,
+ msg_ctx))) {
+ DEBUG(0, ("Could not add print_queue_housekeeping event\n"));
+ return false;
+ }
+
+ return true;
+}
+
+static void bq_sig_term_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ exit_server_cleanly("termination signal");
+}
+
+void bq_setup_sig_term_handler(void)
+{
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(server_event_context(),
+ server_event_context(),
+ SIGTERM, 0,
+ bq_sig_term_handler,
+ NULL);
+ if (!se) {
+ exit_server("failed to setup SIGTERM handler");
+ }
+}
+
+static void bq_sig_hup_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *pvt)
+{
+ struct messaging_context *msg_ctx;
+
+ msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
+ change_to_root_user();
+
+ DEBUG(1, ("Reloading pcap cache after SIGHUP\n"));
+ pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
+}
+
+static void bq_setup_sig_hup_handler(struct tevent_context *ev,
+ struct messaging_context *msg_ctx)
+{
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(ev, ev, SIGHUP, 0, bq_sig_hup_handler,
+ msg_ctx);
+ if (!se) {
+ exit_server("failed to setup SIGHUP handler");
+ }
+}
+
+static void bq_smb_conf_updated(struct messaging_context *msg_ctx,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ struct tevent_context *ev_ctx =
+ talloc_get_type_abort(private_data, struct tevent_context);
+
+ DEBUG(10,("smb_conf_updated: Got message saying smb.conf was "
+ "updated. Reloading.\n"));
+ change_to_root_user();
+ pcap_cache_reload(ev_ctx, msg_ctx, &reload_pcap_change_notify);
+}
+
+static void printing_pause_fd_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
+{
+ /*
+ * If pause_pipe[1] is closed it means the parent smbd
+ * and children exited or aborted.
+ */
+ exit_server_cleanly(NULL);
+}
+
+extern struct child_pid *children;
+extern int num_children;
+
+static void add_child_pid(pid_t pid)
+{
+ struct child_pid *child;
+
+ child = SMB_MALLOC_P(struct child_pid);
+ if (child == NULL) {
+ DEBUG(0, ("Could not add child struct -- malloc failed\n"));
+ return;
+ }
+ child->pid = pid;
+ DLIST_ADD(children, child);
+ num_children += 1;
+}
+
+pid_t background_lpq_updater_pid = -1;
+
+/****************************************************************************
+main thread of the background lpq updater
+****************************************************************************/
+static void start_background_queue(struct tevent_context *ev,
+ struct messaging_context *msg_ctx)
+{
+ /* Use local variables for this as we don't
+ * need to save the parent side of this, just
+ * ensure it closes when the process exits.
+ */
+ int pause_pipe[2];
+
+ DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
+
+ if (pipe(pause_pipe) == -1) {
+ DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
+ exit(1);
+ }
+
+ background_lpq_updater_pid = sys_fork();
+
+ if (background_lpq_updater_pid == -1) {
+ DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
+ exit(1);
+ }
+
+ /* Track the printing pid along with other smbd children */
+ add_child_pid(background_lpq_updater_pid);
+
+ if(background_lpq_updater_pid == 0) {
+ struct tevent_fd *fde;
+ int ret;
+ NTSTATUS status;
+
+ /* Child. */
+ DEBUG(5,("start_background_queue: background LPQ thread started\n"));
+
+ close(pause_pipe[0]);
+ pause_pipe[0] = -1;
+
+ status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("reinit_after_fork() failed\n"));
+ smb_panic("reinit_after_fork() failed");
+ }
+
+ bq_setup_sig_term_handler();
+ bq_setup_sig_hup_handler(ev, msg_ctx);
+
+ if (!printing_subsystem_queue_tasks(ev, msg_ctx)) {
+ exit(1);
+ }
+
+ if (!serverid_register(procid_self(),
+ FLAG_MSG_GENERAL|FLAG_MSG_SMBD
+ |FLAG_MSG_PRINT_GENERAL)) {
+ exit(1);
+ }
+
+ 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,
+ print_queue_receive);
+
+ fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
+ printing_pause_fd_handler,
+ NULL);
+ if (!fde) {
+ DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
+ smb_panic("tevent_add_fd() failed for pause_pipe");
+ }
+
+ DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
+ ret = tevent_loop_wait(ev);
+ /* should not be reached */
+ DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
+ ret, (ret == 0) ? "out of events" : strerror(errno)));
+ exit(1);
+ }
+
+ close(pause_pipe[1]);
+}
+
+static bool use_background_queue;
+
+/* Run before the parent forks */
+bool printing_subsystem_init(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx,
+ bool background_queue)
+{
+ bool ret = true;
+
+ use_background_queue = background_queue;
+
+ /* Publish nt printers, this requires a working winreg pipe */
+ pcap_cache_reload(ev_ctx, msg_ctx, &reload_printers);
+
+ if (background_queue) {
+ start_background_queue(ev_ctx, msg_ctx);
+ } else {
+ ret = printing_subsystem_queue_tasks(ev_ctx, msg_ctx);
+ }
+
+ return ret;
+}
+
+void printing_subsystem_update(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx)
+{
+ if (use_background_queue) return;
+
+ pcap_cache_reload(ev_ctx, msg_ctx, &reload_pcap_change_notify);
+}
diff --git a/source3/printing/queue_process.h b/source3/printing/queue_process.h
new file mode 100644
index 0000000000..41305d85ab
--- /dev/null
+++ b/source3/printing/queue_process.h
@@ -0,0 +1,29 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ printing backend routines
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Jeremy Allison 2002
+ Copyright (C) Simo Sorce 2011
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+extern pid_t background_lpq_updater_pid;
+
+bool printing_subsystem_init(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx,
+ bool background_queue);
+void printing_subsystem_update(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx);
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index fe743a6965..bf36dcb71f 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -60,6 +60,7 @@ bool logged_ioctl_message = false;
time_t last_smb_conf_reload_time = 0;
time_t last_printer_reload_time = 0;
+
/****************************************************************************
structure to hold a linked list of queued messages.
for processing.
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 9df95a8d9d..86e834789f 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -27,7 +27,7 @@
#include "../lib/async_req/async_sock.h"
#include "ctdbd_conn.h"
#include "../lib/util/select.h"
-#include "printing/pcap.h"
+#include "printing/queue_process.h"
#include "system/select.h"
#include "passdb.h"
#include "auth.h"
@@ -882,7 +882,7 @@ static void smbd_sig_hup_handler(struct tevent_context *ev,
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);
+ printing_subsystem_update(ev, msg_ctx);
}
}
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index b2acaa0ee7..2b24f70930 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -966,8 +966,6 @@ void reload_printers(struct tevent_context *ev,
struct messaging_context *msg_ctx);
bool reload_services(struct messaging_context *msg_ctx, int smb_sock,
bool test);
-void reload_pcap_change_notify(struct tevent_context *ev,
- struct messaging_context *msg_ctx);
void exit_server(const char *const explanation);
void exit_server_cleanly(const char *const explanation);
void exit_server_fault(void);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 18e51a2e42..16395ee3dd 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -32,8 +32,8 @@
#include "memcache.h"
#include "ctdbd_conn.h"
#include "printing/printer_list.h"
+#include "printing/queue_process.h"
#include "rpc_server/rpc_service_setup.h"
-#include "printing/pcap.h"
#include "printing.h"
#include "serverid.h"
#include "passdb.h"
@@ -69,8 +69,7 @@ static void smb_conf_updated(struct messaging_context *msg,
change_to_root_user();
reload_services(msg, smbd_server_conn->sock, False);
if (am_parent) {
- pcap_cache_reload(ev_ctx, msg,
- &reload_pcap_change_notify);
+ printing_subsystem_update(ev_ctx, msg);
}
}
@@ -585,28 +584,6 @@ static bool smbd_open_one_socket(struct smbd_parent_context *parent,
return true;
}
-static bool smbd_parent_housekeeping(const struct timeval *now, void *private_data)
-{
- struct messaging_context *msg_ctx =
- talloc_get_type_abort(private_data, struct messaging_context);
- time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
- time_t t = time_mono(NULL);
-
- DEBUG(5, ("parent housekeeping\n"));
-
- /* if periodic printcap rescan is enabled, see if it's time to reload */
- if ((printcap_cache_time != 0)
- && (t >= (last_printer_reload_time + printcap_cache_time))) {
- DEBUG( 3,( "Printcap cache time expired.\n"));
- pcap_cache_reload(messaging_event_context(msg_ctx),
- msg_ctx,
- &reload_pcap_change_notify);
- last_printer_reload_time = t;
- }
-
- return true;
-}
-
/****************************************************************************
Open the socket communication.
****************************************************************************/
@@ -757,14 +734,6 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
return false;
}
- if (!(event_add_idle(ev_ctx, NULL,
- timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
- "parent_housekeeping", smbd_parent_housekeeping,
- msg_ctx))) {
- DEBUG(0, ("Could not add parent_housekeeping event\n"));
- return false;
- }
-
/* Listen to messages */
messaging_register(msg_ctx, NULL, MSG_SMB_SAM_SYNC, msg_sam_sync);
@@ -1252,9 +1221,6 @@ extern void build_options(bool screen);
exit(1);
}
- /* Publish nt printers, this requires a working winreg pipe */
- pcap_cache_reload(ev_ctx, msg_ctx, &reload_printers);
-
/* 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
@@ -1262,7 +1228,13 @@ extern void build_options(bool screen);
if (is_daemon && !interactive
&& lp_parm_bool(-1, "smbd", "backgroundqueue", true)) {
- start_background_queue(ev_ctx, msg_ctx);
+ if (!printing_subsystem_init(ev_ctx, msg_ctx, true)) {
+ exit(1);
+ }
+ } else {
+ if (!printing_subsystem_init(ev_ctx, msg_ctx, false)) {
+ exit(1);
+ }
}
if (is_daemon && !_lp_disable_spoolss()) {
diff --git a/source3/smbd/server_reload.c b/source3/smbd/server_reload.c
index db81aadab1..6639c4a8f6 100644
--- a/source3/smbd/server_reload.c
+++ b/source3/smbd/server_reload.c
@@ -143,12 +143,3 @@ bool reload_services(struct messaging_context *msg_ctx, int smb_sock,
return(ret);
}
-
-/****************************************************************************
- Notify smbds of new printcap data
-**************************************************************************/
-void reload_pcap_change_notify(struct tevent_context *ev,
- struct messaging_context *msg_ctx)
-{
- message_send_all(msg_ctx, MSG_PRINTER_PCAP, NULL, 0, NULL);
-}
diff --git a/source3/wscript_build b/source3/wscript_build
index 3be15ea02c..266a0e3fad 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -408,7 +408,8 @@ PRINTBACKEND_SRC = '''printing/printing.c
printing/nt_printing.c
printing/nt_printing_tdb.c
printing/nt_printing_migrate_internal.c
- printing/nt_printing_ads.c'''
+ printing/nt_printing_ads.c
+ printing/queue_process.c'''
NMBD_SRC1 = '''nmbd/asyncdns.c nmbd/nmbd.c nmbd/nmbd_become_dmb.c
nmbd/nmbd_become_lmb.c nmbd/nmbd_browserdb.c