s3-spoolssd: Check if we were able to create the prefork pool.
[Samba/gebeck_regimport.git] / source3 / printing / spoolssd.c
blobc5c30ab104d57ec3d045dcdfd194d1f85ea7bcf2
1 /*
2 Unix SMB/Netbios implementation.
3 SPOOLSS Daemon
4 Copyright (C) Simo Sorce 2010
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "includes.h"
20 #include "serverid.h"
21 #include "smbd/smbd.h"
23 #include "messages.h"
24 #include "include/printing.h"
25 #include "printing/nt_printing_migrate_internal.h"
26 #include "printing/queue_process.h"
27 #include "printing/pcap.h"
28 #include "printing/load.h"
29 #include "ntdomain.h"
30 #include "librpc/gen_ndr/srv_winreg.h"
31 #include "librpc/gen_ndr/srv_spoolss.h"
32 #include "rpc_server/rpc_server.h"
33 #include "rpc_server/rpc_ep_register.h"
34 #include "rpc_server/spoolss/srv_spoolss_nt.h"
35 #include "librpc/rpc/dcerpc_ep.h"
36 #include "lib/server_prefork.h"
38 #define SPOOLSS_PIPE_NAME "spoolss"
39 #define DAEMON_NAME "spoolssd"
41 #define SPOOLSS_MIN_CHILDREN 5
42 #define SPOOLSS_MAX_CHILDREN 25
43 #define SPOOLSS_SPAWN_RATE 5
44 #define SPOOLSS_MIN_LIFE 60 /* 1 minute minimum life time */
46 #define SPOOLSS_INIT 0x00
47 #define SPOOLSS_NEW_MAX 0x01
48 #define SPOLLSS_ENOSPC 0x02
50 static struct prefork_pool *spoolss_pool;
51 static int spoolss_min_children;
52 static int spoolss_max_children;
53 static int spoolss_spawn_rate;
54 static int spoolss_prefork_status;
55 static int spoolss_child_id = 0;
57 pid_t start_spoolssd(struct tevent_context *ev_ctx,
58 struct messaging_context *msg_ctx);
60 static void spoolss_prefork_config(void)
62 static int spoolss_prefork_config_init = false;
63 const char *prefork_str;
64 int min, max, rate;
65 bool use_defaults = false;
66 int ret;
68 if (!spoolss_prefork_config_init) {
69 spoolss_pool = NULL;
70 spoolss_prefork_status = SPOOLSS_INIT;
71 spoolss_min_children = 0;
72 spoolss_max_children = 0;
73 spoolss_spawn_rate = 0;
74 spoolss_prefork_config_init = true;
77 prefork_str = lp_parm_const_string(GLOBAL_SECTION_SNUM,
78 "spoolssd", "prefork", "none");
79 if (strcmp(prefork_str, "none") == 0) {
80 use_defaults = true;
81 } else {
82 ret = sscanf(prefork_str, "%d:%d:%d", &min, &max, &rate);
83 if (ret != 3) {
84 DEBUG(0, ("invalid format for spoolssd:prefork!\n"));
85 use_defaults = true;
89 if (use_defaults) {
90 min = SPOOLSS_MIN_CHILDREN;
91 max = SPOOLSS_MAX_CHILDREN;
92 rate = SPOOLSS_SPAWN_RATE;
95 if (max > spoolss_max_children && spoolss_max_children != 0) {
96 spoolss_prefork_status |= SPOOLSS_NEW_MAX;
99 spoolss_min_children = min;
100 spoolss_max_children = max;
101 spoolss_spawn_rate = rate;
104 static void spoolss_reopen_logs(int child_id)
106 char *lfile = lp_logfile();
107 char *ext;
108 int rc;
110 if (child_id) {
111 rc = asprintf(&ext, ".%s.%d", DAEMON_NAME, child_id);
112 } else {
113 rc = asprintf(&ext, ".%s", DAEMON_NAME);
116 if (rc == -1) {
117 /* if we can't allocate, set it to NULL
118 * and logging will flow in the original file */
119 ext = NULL;
122 rc = 0;
123 if (lfile == NULL || lfile[0] == '\0') {
124 rc = asprintf(&lfile, "%s/log%s",
125 get_dyn_LOGFILEBASE(), ext?ext:"");
126 } else {
127 if (ext && strstr(lfile, ext) == NULL) {
128 if (strstr(lfile, DAEMON_NAME) == NULL) {
129 rc = asprintf(&lfile, "%s%s",
130 lp_logfile(), ext?ext:"");
131 } else {
132 rc = asprintf(&lfile, "%s.%d",
133 lp_logfile(), child_id);
138 if (rc > 0) {
139 lp_set_logfile(lfile);
140 SAFE_FREE(lfile);
143 SAFE_FREE(ext);
145 reopen_logs();
148 static void update_conf(struct tevent_context *ev,
149 struct messaging_context *msg)
151 change_to_root_user();
152 lp_load(get_dyn_CONFIGFILE(), true, false, false, true);
153 reload_printers(ev, msg);
155 spoolss_reopen_logs(spoolss_child_id);
156 if (spoolss_child_id == 0) {
157 spoolss_prefork_config();
161 static void smb_conf_updated(struct messaging_context *msg,
162 void *private_data,
163 uint32_t msg_type,
164 struct server_id server_id,
165 DATA_BLOB *data)
167 struct tevent_context *ev_ctx = talloc_get_type_abort(private_data,
168 struct tevent_context);
170 DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n"));
171 update_conf(ev_ctx, msg);
174 static void update_pcap(struct tevent_context *ev_ctx,
175 struct messaging_context *msg_ctx)
177 change_to_root_user();
178 reload_printers(ev_ctx, msg_ctx);
181 static void pcap_updated(struct messaging_context *msg,
182 void *private_data,
183 uint32_t msg_type,
184 struct server_id server_id,
185 DATA_BLOB *data)
187 struct tevent_context *ev_ctx;
189 ev_ctx = talloc_get_type_abort(private_data, struct tevent_context);
191 DEBUG(10, ("Got message that pcap updated. Reloading.\n"));
192 update_pcap(ev_ctx, msg);
195 static void spoolss_sig_term_handler(struct tevent_context *ev,
196 struct tevent_signal *se,
197 int signum,
198 int count,
199 void *siginfo,
200 void *private_data)
202 exit_server_cleanly("termination signal");
205 static void spoolss_setup_sig_term_handler(struct tevent_context *ev_ctx)
207 struct tevent_signal *se;
209 se = tevent_add_signal(ev_ctx,
210 ev_ctx,
211 SIGTERM, 0,
212 spoolss_sig_term_handler,
213 NULL);
214 if (!se) {
215 exit_server("failed to setup SIGTERM handler");
219 static void spoolss_sig_hup_handler(struct tevent_context *ev,
220 struct tevent_signal *se,
221 int signum,
222 int count,
223 void *siginfo,
224 void *pvt)
226 struct messaging_context *msg_ctx;
228 msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
230 DEBUG(1,("Reloading printers after SIGHUP\n"));
231 update_conf(ev, msg_ctx);
233 /* relay to all children */
234 if (spoolss_pool) {
235 prefork_send_signal_to_all(spoolss_pool, SIGHUP);
239 static void spoolss_setup_sig_hup_handler(struct tevent_context *ev_ctx,
240 struct messaging_context *msg_ctx)
242 struct tevent_signal *se;
244 se = tevent_add_signal(ev_ctx,
245 ev_ctx,
246 SIGHUP, 0,
247 spoolss_sig_hup_handler,
248 msg_ctx);
249 if (!se) {
250 exit_server("failed to setup SIGHUP handler");
254 static bool spoolss_init_cb(void *ptr)
256 struct messaging_context *msg_ctx = talloc_get_type_abort(
257 ptr, struct messaging_context);
259 return nt_printing_tdb_migrate(msg_ctx);
262 static bool spoolss_shutdown_cb(void *ptr)
264 srv_spoolss_cleanup();
266 return true;
269 /* Children */
271 struct spoolss_chld_sig_hup_ctx {
272 struct messaging_context *msg_ctx;
273 struct pf_worker_data *pf;
276 static void spoolss_chld_sig_hup_handler(struct tevent_context *ev,
277 struct tevent_signal *se,
278 int signum,
279 int count,
280 void *siginfo,
281 void *pvt)
283 struct spoolss_chld_sig_hup_ctx *shc;
285 shc = talloc_get_type_abort(pvt, struct spoolss_chld_sig_hup_ctx);
287 /* avoid wasting CPU cycles if we are going to exit soon anyways */
288 if (shc->pf != NULL &&
289 shc->pf->cmds == PF_SRV_MSG_EXIT) {
290 return;
293 change_to_root_user();
294 DEBUG(1,("Reloading printers after SIGHUP\n"));
295 reload_printers(ev, shc->msg_ctx);
296 spoolss_reopen_logs(spoolss_child_id);
299 static bool spoolss_setup_chld_hup_handler(struct tevent_context *ev_ctx,
300 struct messaging_context *msg_ctx,
301 struct pf_worker_data *pf)
303 struct spoolss_chld_sig_hup_ctx *shc;
304 struct tevent_signal *se;
306 shc = talloc(ev_ctx, struct spoolss_chld_sig_hup_ctx);
307 if (!shc) {
308 DEBUG(1, ("failed to setup SIGHUP handler"));
309 return false;
311 shc->pf = pf;
312 shc->msg_ctx = msg_ctx;
314 se = tevent_add_signal(ev_ctx,
315 ev_ctx,
316 SIGHUP, 0,
317 spoolss_chld_sig_hup_handler,
318 shc);
319 if (!se) {
320 DEBUG(1, ("failed to setup SIGHUP handler"));
321 return false;
324 return true;
327 static bool spoolss_child_init(struct tevent_context *ev_ctx,
328 int child_id, struct pf_worker_data *pf)
330 NTSTATUS status;
331 struct rpc_srv_callbacks spoolss_cb;
332 struct messaging_context *msg_ctx = server_messaging_context();
333 bool ok;
335 status = reinit_after_fork(msg_ctx, ev_ctx,
336 procid_self(), true);
337 if (!NT_STATUS_IS_OK(status)) {
338 DEBUG(0,("reinit_after_fork() failed\n"));
339 smb_panic("reinit_after_fork() failed");
342 spoolss_child_id = child_id;
343 spoolss_reopen_logs(child_id);
345 ok = spoolss_setup_chld_hup_handler(ev_ctx, msg_ctx, pf);
346 if (!ok) {
347 return false;
350 if (!serverid_register(procid_self(),
351 FLAG_MSG_GENERAL |
352 FLAG_MSG_PRINT_GENERAL)) {
353 return false;
356 if (!locking_init()) {
357 return false;
360 messaging_register(msg_ctx, ev_ctx,
361 MSG_SMB_CONF_UPDATED, smb_conf_updated);
362 messaging_register(msg_ctx, ev_ctx, MSG_PRINTER_PCAP,
363 pcap_updated);
365 /* As soon as messaging is up check if pcap has been loaded already.
366 * If so then we probably missed a message and should load_printers()
367 * ourselves. If pcap has not been loaded yet, then ignore, we will get
368 * a message as soon as the bq process completes the reload. */
369 if (pcap_cache_loaded()) {
370 load_printers(ev_ctx, msg_ctx);
373 /* try to reinit rpc queues */
374 spoolss_cb.init = spoolss_init_cb;
375 spoolss_cb.shutdown = spoolss_shutdown_cb;
376 spoolss_cb.private_data = msg_ctx;
378 status = rpc_winreg_init(NULL);
379 if (!NT_STATUS_IS_OK(status)) {
380 DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n",
381 nt_errstr(status)));
382 return false;
385 status = rpc_spoolss_init(&spoolss_cb);
386 if (!NT_STATUS_IS_OK(status)) {
387 DEBUG(0, ("Failed to register spoolss rpc inteface! (%s)\n",
388 nt_errstr(status)));
389 return false;
392 return true;
395 struct spoolss_children_data {
396 struct tevent_context *ev_ctx;
397 struct messaging_context *msg_ctx;
398 struct pf_worker_data *pf;
399 int listen_fd_size;
400 int *listen_fds;
401 int lock_fd;
403 bool listening;
406 static void spoolss_next_client(void *pvt);
408 static int spoolss_children_main(struct tevent_context *ev_ctx,
409 struct messaging_context *msg_ctx,
410 struct pf_worker_data *pf,
411 int child_id,
412 int listen_fd_size,
413 int *listen_fds,
414 int lock_fd,
415 void *private_data)
417 struct spoolss_children_data *data;
418 bool ok;
419 int ret;
421 ok = spoolss_child_init(ev_ctx, child_id, pf);
422 if (!ok) {
423 return 1;
426 data = talloc(ev_ctx, struct spoolss_children_data);
427 if (!data) {
428 return 1;
430 data->pf = pf;
431 data->ev_ctx = ev_ctx;
432 data->msg_ctx = msg_ctx;
433 data->lock_fd = lock_fd;
434 data->listen_fd_size = listen_fd_size;
435 data->listen_fds = listen_fds;
436 data->listening = false;
438 /* loop until it is time to exit */
439 while (pf->status != PF_WORKER_EXITING) {
440 /* try to see if it is time to schedule the next client */
441 spoolss_next_client(data);
443 ret = tevent_loop_once(ev_ctx);
444 if (ret != 0) {
445 DEBUG(0, ("tevent_loop_once() exited with %d: %s\n",
446 ret, strerror(errno)));
447 pf->status = PF_WORKER_EXITING;
451 return ret;
454 static void spoolss_client_terminated(void *pvt)
456 struct spoolss_children_data *data;
458 data = talloc_get_type_abort(pvt, struct spoolss_children_data);
460 if (data->pf->num_clients) {
461 data->pf->num_clients--;
462 } else {
463 DEBUG(2, ("Invalid num clients, aborting!\n"));
464 data->pf->status = PF_WORKER_EXITING;
465 return;
468 spoolss_next_client(pvt);
471 struct spoolss_new_client {
472 struct spoolss_children_data *data;
473 struct tsocket_address *srv_addr;
474 struct tsocket_address *cli_addr;
477 static void spoolss_handle_client(struct tevent_req *req);
479 static void spoolss_next_client(void *pvt)
481 struct tevent_req *req;
482 struct spoolss_children_data *data;
483 struct spoolss_new_client *next;
485 data = talloc_get_type_abort(pvt, struct spoolss_children_data);
487 if (data->pf->num_clients == 0) {
488 data->pf->status = PF_WORKER_IDLE;
491 if (data->pf->cmds == PF_SRV_MSG_EXIT) {
492 DEBUG(2, ("Parent process commands we terminate!\n"));
493 return;
496 if (data->listening ||
497 data->pf->num_clients >= data->pf->allowed_clients) {
498 /* nothing to do for now we are already listening
499 * or reached the number of clients we are allowed
500 * to handle in parallel */
501 return;
504 next = talloc_zero(data, struct spoolss_new_client);
505 if (!next) {
506 DEBUG(1, ("Out of memory!?\n"));
507 return;
509 next->data = data;
511 req = prefork_listen_send(next, data->ev_ctx, data->pf,
512 data->listen_fd_size,
513 data->listen_fds,
514 data->lock_fd);
515 if (!req) {
516 DEBUG(1, ("Failed to make listening request!?\n"));
517 talloc_free(next);
518 return;
520 tevent_req_set_callback(req, spoolss_handle_client, next);
522 data->listening = true;
525 static void spoolss_handle_client(struct tevent_req *req)
527 struct spoolss_children_data *data;
528 struct spoolss_new_client *client;
529 int ret;
530 int sd;
532 client = tevent_req_callback_data(req, struct spoolss_new_client);
533 data = client->data;
535 ret = prefork_listen_recv(req, client, &sd,
536 &client->srv_addr, &client->cli_addr);
538 /* this will free the request too */
539 talloc_free(client);
540 /* we are done listening */
541 data->listening = false;
543 if (ret > 0) {
544 DEBUG(1, ("Failed to accept client connection!\n"));
545 /* bail out if we are not serving any other client */
546 if (data->pf->num_clients == 0) {
547 data->pf->status = PF_WORKER_EXITING;
549 return;
552 if (ret == -2) {
553 DEBUG(1, ("Server asks us to die!\n"));
554 data->pf->status = PF_WORKER_EXITING;
555 return;
558 DEBUG(2, ("Spoolss preforked child %d got client connection!\n",
559 (int)(data->pf->pid)));
561 named_pipe_accept_function(data->ev_ctx, data->msg_ctx,
562 SPOOLSS_PIPE_NAME, sd,
563 spoolss_client_terminated, data);
566 /* ==== Main Process Functions ==== */
568 extern pid_t background_lpq_updater_pid;
569 static char *bq_logfile;
571 static void check_updater_child(void)
573 int status;
574 pid_t pid;
576 if (background_lpq_updater_pid == -1) {
577 return;
580 pid = sys_waitpid(background_lpq_updater_pid, &status, WNOHANG);
581 if (pid > 0) {
582 DEBUG(2, ("The background queue child died... Restarting!\n"));
583 pid = start_background_queue(server_event_context(),
584 server_messaging_context(),
585 bq_logfile);
586 background_lpq_updater_pid = pid;
590 static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
591 struct messaging_context *msg_ctx,
592 struct timeval current_time);
593 static void spoolssd_check_children(struct tevent_context *ev_ctx,
594 struct tevent_timer *te,
595 struct timeval current_time,
596 void *pvt);
598 static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx,
599 struct prefork_pool *pfp,
600 void *pvt)
602 struct messaging_context *msg_ctx;
603 int active, total;
604 int n, r;
606 msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
608 /* now check we do not descend below the minimum */
609 active = prefork_count_active_children(pfp, &total);
611 n = 0;
612 if (total < spoolss_min_children) {
613 n = total - spoolss_min_children;
614 } else if (total - active < (total / 4)) {
615 n = spoolss_min_children;
618 if (n > 0) {
619 r = prefork_add_children(ev_ctx, msg_ctx, pfp, n);
620 if (r < n) {
621 DEBUG(10, ("Tried to start %d children but only,"
622 "%d were actually started.!\n", n, r));
626 /* also check if the updater child is alive and well */
627 check_updater_child();
630 static bool spoolssd_setup_children_monitor(struct tevent_context *ev_ctx,
631 struct messaging_context *msg_ctx)
633 bool ok;
635 /* add our oun sigchld callback */
636 prefork_set_sigchld_callback(spoolss_pool,
637 spoolssd_sigchld_handler, msg_ctx);
639 ok = spoolssd_schedule_check(ev_ctx, msg_ctx,
640 tevent_timeval_current());
641 return ok;
644 static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
645 struct messaging_context *msg_ctx,
646 struct timeval current_time)
648 struct tevent_timer *te;
649 struct timeval next_event;
651 /* check situation again in 10 seconds */
652 next_event = tevent_timeval_current_ofs(10, 0);
654 /* TODO: check when the socket becomes readable, so that children
655 * are checked only when there is some activity ? */
656 te = tevent_add_timer(ev_ctx, spoolss_pool, next_event,
657 spoolssd_check_children, msg_ctx);
658 if (!te) {
659 DEBUG(2, ("Failed to set up children monitoring!\n"));
660 return false;
663 return true;
666 static void spoolssd_check_children(struct tevent_context *ev_ctx,
667 struct tevent_timer *te,
668 struct timeval current_time,
669 void *pvt)
671 struct messaging_context *msg_ctx;
672 time_t now = time(NULL);
673 int active, total;
674 int ret, n;
676 msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
678 if ((spoolss_prefork_status & SPOOLSS_NEW_MAX) &&
679 !(spoolss_prefork_status & SPOLLSS_ENOSPC)) {
680 ret = prefork_expand_pool(spoolss_pool, spoolss_max_children);
681 if (ret == ENOSPC) {
682 spoolss_prefork_status |= SPOLLSS_ENOSPC;
684 spoolss_prefork_status &= ~SPOOLSS_NEW_MAX;
687 active = prefork_count_active_children(spoolss_pool, &total);
689 if (total - active < spoolss_spawn_rate) {
690 n = prefork_add_children(ev_ctx, msg_ctx,
691 spoolss_pool, spoolss_spawn_rate);
692 if (n < spoolss_spawn_rate) {
693 DEBUG(10, ("Tried to start 5 children but only,"
694 "%d were actually started.!\n", n));
698 if (total - active > spoolss_min_children) {
699 if ((total - spoolss_min_children) >= spoolss_spawn_rate) {
700 prefork_retire_children(spoolss_pool,
701 spoolss_spawn_rate,
702 now - SPOOLSS_MIN_LIFE);
706 ret = spoolssd_schedule_check(ev_ctx, msg_ctx, current_time);
709 static void print_queue_forward(struct messaging_context *msg,
710 void *private_data,
711 uint32_t msg_type,
712 struct server_id server_id,
713 DATA_BLOB *data)
715 messaging_send_buf(msg, pid_to_procid(background_lpq_updater_pid),
716 MSG_PRINTER_UPDATE, data->data, data->length);
719 static char *get_bq_logfile(void)
721 char *lfile = lp_logfile();
722 int rc;
724 if (lfile == NULL || lfile[0] == '\0') {
725 rc = asprintf(&lfile, "%s/log.%s.bq",
726 get_dyn_LOGFILEBASE(), DAEMON_NAME);
727 } else {
728 rc = asprintf(&lfile, "%s.bq", lp_logfile());
730 if (rc == -1) {
731 lfile = NULL;
733 return lfile;
736 pid_t start_spoolssd(struct tevent_context *ev_ctx,
737 struct messaging_context *msg_ctx)
739 struct rpc_srv_callbacks spoolss_cb;
740 struct dcerpc_binding_vector *v;
741 TALLOC_CTX *mem_ctx;
742 pid_t pid;
743 NTSTATUS status;
744 int listen_fd;
745 int ret;
746 bool ok;
748 DEBUG(1, ("Forking SPOOLSS Daemon\n"));
751 * Block signals before forking child as it will have to
752 * set its own handlers. Child will re-enable SIGHUP as
753 * soon as the handlers are set up.
755 BlockSignals(true, SIGTERM);
756 BlockSignals(true, SIGHUP);
758 pid = sys_fork();
760 if (pid == -1) {
761 DEBUG(0, ("Failed to fork SPOOLSS [%s]\n",
762 strerror(errno)));
765 /* parent or error */
766 if (pid != 0) {
768 /* Re-enable SIGHUP before returnig */
769 BlockSignals(false, SIGTERM);
770 BlockSignals(false, SIGHUP);
771 return pid;
774 /* child */
775 close_low_fds(false);
777 status = reinit_after_fork(msg_ctx,
778 ev_ctx,
779 procid_self(), true);
780 if (!NT_STATUS_IS_OK(status)) {
781 DEBUG(0,("reinit_after_fork() failed\n"));
782 smb_panic("reinit_after_fork() failed");
785 spoolss_reopen_logs(0);
786 spoolss_prefork_config();
788 spoolss_setup_sig_term_handler(ev_ctx);
789 spoolss_setup_sig_hup_handler(ev_ctx, msg_ctx);
791 BlockSignals(false, SIGTERM);
792 BlockSignals(false, SIGHUP);
794 /* always start the backgroundqueue listner in spoolssd */
795 bq_logfile = get_bq_logfile();
796 pid = start_background_queue(ev_ctx, msg_ctx, bq_logfile);
797 if (pid > 0) {
798 background_lpq_updater_pid = pid;
801 /* the listening fd must be created before the children are actually
802 * forked out. */
803 listen_fd = create_named_pipe_socket(SPOOLSS_PIPE_NAME);
804 if (listen_fd == -1) {
805 exit(1);
808 ret = listen(listen_fd, spoolss_max_children);
809 if (ret == -1) {
810 DEBUG(0, ("Failed to listen on spoolss pipe - %s\n",
811 strerror(errno)));
812 exit(1);
815 /* start children before any more initialization is done */
816 ok = prefork_create_pool(ev_ctx, /* mem_ctx */
817 ev_ctx, msg_ctx,
818 1, &listen_fd,
819 spoolss_min_children,
820 spoolss_max_children,
821 &spoolss_children_main, NULL,
822 &spoolss_pool);
823 if (!ok) {
824 exit(1);
827 if (!serverid_register(procid_self(),
828 FLAG_MSG_GENERAL |
829 FLAG_MSG_PRINT_GENERAL)) {
830 exit(1);
833 if (!locking_init()) {
834 exit(1);
837 messaging_register(msg_ctx, ev_ctx,
838 MSG_SMB_CONF_UPDATED, smb_conf_updated);
839 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
840 print_queue_forward);
841 messaging_register(msg_ctx, ev_ctx, MSG_PRINTER_PCAP,
842 pcap_updated);
844 /* As soon as messaging is up check if pcap has been loaded already.
845 * If so then we probably missed a message and should load_printers()
846 * ourselves. If pcap has not been loaded yet, then ignore, we will get
847 * a message as soon as the bq process completes the reload. */
848 if (pcap_cache_loaded()) {
849 load_printers(ev_ctx, msg_ctx);
852 mem_ctx = talloc_new(NULL);
853 if (mem_ctx == NULL) {
854 exit(1);
858 * Initialize spoolss with an init function to convert printers first.
859 * static_init_rpc will try to initialize the spoolss server too but you
860 * can't register it twice.
862 spoolss_cb.init = spoolss_init_cb;
863 spoolss_cb.shutdown = spoolss_shutdown_cb;
864 spoolss_cb.private_data = msg_ctx;
866 status = rpc_winreg_init(NULL);
867 if (!NT_STATUS_IS_OK(status)) {
868 DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n",
869 nt_errstr(status)));
870 exit(1);
873 status = rpc_spoolss_init(&spoolss_cb);
874 if (!NT_STATUS_IS_OK(status)) {
875 DEBUG(0, ("Failed to register spoolss rpc inteface! (%s)\n",
876 nt_errstr(status)));
877 exit(1);
880 status = dcerpc_binding_vector_new(mem_ctx, &v);
881 if (!NT_STATUS_IS_OK(status)) {
882 DEBUG(0, ("Failed to create binding vector (%s)\n",
883 nt_errstr(status)));
884 exit(1);
887 status = dcerpc_binding_vector_add_np_default(&ndr_table_spoolss, v);
888 if (!NT_STATUS_IS_OK(status)) {
889 DEBUG(0, ("Failed to add np to binding vector (%s)\n",
890 nt_errstr(status)));
891 exit(1);
894 status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_spoolss, v);
895 if (!NT_STATUS_IS_OK(status)) {
896 DEBUG(0, ("Failed to register spoolss endpoint! (%s)\n",
897 nt_errstr(status)));
898 exit(1);
901 talloc_free(mem_ctx);
903 ok = spoolssd_setup_children_monitor(ev_ctx, msg_ctx);
904 if (!ok) {
905 DEBUG(0, ("Failed to setup children monitoring!\n"));
906 exit(1);
909 DEBUG(1, ("SPOOLSS Daemon Started (%d)\n", getpid()));
911 /* loop forever */
912 ret = tevent_loop_wait(ev_ctx);
914 /* should not be reached */
915 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
916 ret, (ret == 0) ? "out of events" : strerror(errno)));
917 exit(1);