[SCM] Samba Shared Repository - branch master updated
Andreas Schneider
asn at samba.org
Wed Aug 10 11:30:03 MDT 2011
The branch, master has been updated
via d53e3ec selftest: Always test the spoolss deamon.
via 9eafbeb s3-spoolss: Fix prototypes warnings.
via c3cfa6b s3-printing: Do not try to force reload.
via 54aaa5a s3-spoolss: do not call pcap_cache_reload() directly
via dd4ff4b s3-printing: Add child handler to bq process
via befc539 s3-spoolss: Fix printers related messaging
via 7a07162 s3-prefork: Fix use of child id.
via f00681f s3-printing: make sure to block SIGHUP ...
via 6f682be s3-spoolss: Use a global variable for the pool
via b2f682a s3-printing: Allow bq process to have own logfile
via 339c106 s3-spoolssd: Use the child_id to open log files
via fa893e8 s3-prefork: Pass the child a child_id
via 0de0928 s3-printing: Force pcap reload when all ready
via 227551a s3-prefork: Return tsocket_address for client and server
via 2b33b43 s3-prefork: Pass messaging context around too
via 1155280 s3-prefork: Set up a SIGCHLD handler by default
via d36a8dc s3:spoolssd Start spoolssd from printing_subsystem_init
via 9ce6416 s3-printing: Rework how the background process is started
via 0a910c9 s3-prefork: Provide a cleanup function
via e0aa6ee s3-prefork: Inline Doxygen Documentation
via b58d446 s3-prefork: better timing out semantics
via f6ae58f s3-prefork: add support for multiple listning file descriptors
via afde4d8 s3-spoolssd: propagate SIGHUP to children
via 3339c9b s3-prefork: provide way to send a signal to all children
via de08cd9 s3-spoolssd: expand children pool when necessary
via 567ca03 s3-prefork: provide means to expand the pool size
via afc4dda s3-spoolssd: Use parametric option for prefork parameters
via 595cce8 s3-spoolss: make listening asynchronous
via 1dd93f4 s3-spoolssd: Use the prefork framework in spoolssd
via a1394fc s3-rpc_server: add termination function
via d67fc9c s3-rpc: Expose some internal functions
via 2056d06 s3-prefork: add way to manage number of clients per child
via b9354f7 s3-prefork: add asynchronous functions
via 4fef4fe s3-prefork: implement prefork framework
via 88b901b s3-printing: No need to register to smbd's children list
via 74f3e52 tevent: cleanup nesting counter when doing a full reinit.
via 09ad4d4 lib-util: Make create_unlink_tmp argument optional
via 05455b4 lib-util: Make useful function a common utility.
via 185cd4c libutil: use AI_ADDRCONFIG only when AI_NUMERIC is not defined
from e0dc3aa s3: Remove an unnecessary include
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit d53e3ecf085d432cb514c05fa55c137e4d9a8715
Author: Andreas Schneider <asn at samba.org>
Date: Wed Aug 10 18:05:07 2011 +0200
selftest: Always test the spoolss deamon.
Autobuild-User: Andreas Schneider <asn at cryptomilk.org>
Autobuild-Date: Wed Aug 10 19:29:14 CEST 2011 on sn-devel-104
commit 9eafbebf9c96f1f4c9a48239e025a1729cf697d8
Author: Andreas Schneider <asn at samba.org>
Date: Wed Aug 10 12:48:30 2011 +0200
s3-spoolss: Fix prototypes warnings.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit c3cfa6be4769be15de4278a72b1c73c763edb21f
Author: Simo Sorce <idra at samba.org>
Date: Wed Aug 10 09:27:24 2011 -0400
s3-printing: Do not try to force reload.
Be more correct in load printers at startup.
If async process have already started we do not need to force a reload, but we
just need to load the printers. If other process have not finished initializing
it makes no sense to try to force them as they are masking SIGHUP unitl init is
done anyway.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 54aaa5a58c91df4054c3cbaa238c6a83bbfb2eb7
Author: Simo Sorce <idra at samba.org>
Date: Wed Aug 10 09:20:24 2011 -0400
s3-spoolss: do not call pcap_cache_reload() directly
The background queue process is repsonsible for that.
Just reload printers if necessary or wait for a message from bq to do that.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit dd4ff4bfdd3338bc5102fdcdcfea75dc9cf0be8a
Author: Simo Sorce <idra at samba.org>
Date: Wed Aug 10 08:59:44 2011 -0400
s3-printing: Add child handler to bq process
The cups backend forks a child to do asynchronous work.
We need a sigchld handler in bq to properly wait for the chilod to finish and
reap it, otherwise it hangs the forever as a zombie process.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit befc53927363b6619ef306da56c4a5d15dfa8ed2
Author: Simo Sorce <idra at samba.org>
Date: Tue Aug 9 16:46:21 2011 -0400
s3-spoolss: Fix printers related messaging
Children were not properly receiving messages to reload printers when
the background queue process was dispatching them.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 7a071625581af876f8fd73b35a70eccd0d838208
Author: Simo Sorce <idra at samba.org>
Date: Tue Aug 9 16:44:52 2011 -0400
s3-prefork: Fix use of child id.
Children Ids must start at 1 as 0 represent the father.
Also fix callbacks that restart logs to use a procedd global variable that
holds the Id so that they work correctly both fot the parent process and the
children.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit f00681fe9a78e5c0b02daff2fd83a568f8d95eff
Author: Simo Sorce <idra at samba.org>
Date: Mon Aug 8 10:08:46 2011 -0400
s3-printing: make sure to block SIGHUP ...
... until we are ready to handle it.
Also make us ready as early as possible in spoolssd.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 6f682be2ae27d0f6b087a315a10f3c02cc385b66
Author: Simo Sorce <idra at samba.org>
Date: Mon Aug 8 14:15:14 2011 -0400
s3-spoolss: Use a global variable for the pool
This allows for setting up signal handlers earlier which is needed
for the following patch. It also simplify the code in a few places.
After all we never have more than pool active at any time during
spoolssd life span.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit b2f682a8e638433df7ae2b5afdd0a57f03d56ccb
Author: Simo Sorce <idra at samba.org>
Date: Fri Aug 5 15:14:26 2011 -0400
s3-printing: Allow bq process to have own logfile
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 339c106e51039ad045677835c2fc631026560ca8
Author: Simo Sorce <idra at samba.org>
Date: Fri Aug 5 10:08:23 2011 -0400
s3-spoolssd: Use the child_id to open log files
This way each child has its own log file and avoid mixing all logs form all
children in the same parent log file.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit fa893e815ba538e2a28302bfc17a75fac9e7aaa4
Author: Simo Sorce <idra at samba.org>
Date: Fri Aug 5 10:34:05 2011 -0400
s3-prefork: Pass the child a child_id
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 0de09289ae20040c7c535f18ed7146b1513c5b7d
Author: Simo Sorce <idra at samba.org>
Date: Thu Aug 4 08:56:01 2011 -0400
s3-printing: Force pcap reload when all ready
This way we are sure the cache is primed properly and messages can be sent to
processes if necessary as all messaging has been set up.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 227551a07bc1af29ff2e24d889ea7dd45d575773
Author: Simo Sorce <idra at samba.org>
Date: Tue Jul 19 15:07:42 2011 -0400
s3-prefork: Return tsocket_address for client and server
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 2b33b438ba8cc6f89bf91e5a63bf0168d48be670
Author: Simo Sorce <idra at samba.org>
Date: Mon Jul 18 10:39:50 2011 -0400
s3-prefork: Pass messaging context around too
Pair-Programmed-With: Andreas Schneider <asn at samba.org>
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 1155280a483e2a84e8baa27556c6ea066dbe6c8a
Author: Simo Sorce <idra at samba.org>
Date: Thu May 19 23:56:02 2011 -0400
s3-prefork: Set up a SIGCHLD handler by default
We need to properly handle preforked children so it is better to just do that
automatically.
If the parent needs/wants to intercept SIGCHLD events it can set a callback
that will be called by the prefork code once the internal cleanup function that
checks all prefork children has been executed.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit d36a8dc896d2a814dd18f127593a8382e4004213
Author: Simo Sorce <idra at samba.org>
Date: Wed May 18 11:24:30 2011 -0400
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 <asn at samba.org>
commit 9ce64166731dcacf7e2774380fe58ec780568d2e
Author: Simo Sorce <idra at samba.org>
Date: Wed Aug 3 17:04:50 2011 -0400
s3-printing: Rework how the background process is started
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 0a910c93472e1e4aff120219e09866d4a20ec2b2
Author: Simo Sorce <idra at samba.org>
Date: Mon May 16 10:46:35 2011 -0400
s3-prefork: Provide a cleanup function
This way the parent doesn't need to know how to handle dead children and
keeps all of that within the prefork abstraction.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit e0aa6eec0b498db345666df4b02d4917fa3e259a
Author: Simo Sorce <idra at samba.org>
Date: Mon May 16 10:23:59 2011 -0400
s3-prefork: Inline Doxygen Documentation
Signed-off-by: Andreas Schneider <asn at samba.org>
commit b58d446c03f55203486fe7bb14f08b428efec6f3
Author: Simo Sorce <idra at samba.org>
Date: Tue May 10 09:08:21 2011 -0400
s3-prefork: better timing out semantics
If this child has no clients, let the lock functions block for 1 second,
and then immediately reschedule the operation. This means we catch the lock
as soon as possible on a free child.
If, instead, we are already serving a client, we want to be non blocking,
so we timeout immediately on getting the lock, and then we sleep a 1/10th of
a second.
This means that a busy child will be slightly slower on picking up the lock,
but we won't block the existing client from communicating with us as we
immediately react to activity on the already opened file handler.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit f6ae58f24256a339eec3b17699b10ab11482e6c1
Author: Simo Sorce <idra at samba.org>
Date: Tue May 10 08:39:14 2011 -0400
s3-prefork: add support for multiple listning file descriptors
Signed-off-by: Andreas Schneider <asn at samba.org>
commit afde4d8d832529fdbb842a2acbf8e75f16333529
Author: Simo Sorce <idra at samba.org>
Date: Mon May 9 08:50:11 2011 -0400
s3-spoolssd: propagate SIGHUP to children
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 3339c9b9b43f4ee1b7f8fb61b3701364b8c81e03
Author: Simo Sorce <idra at samba.org>
Date: Mon May 9 08:49:50 2011 -0400
s3-prefork: provide way to send a signal to all children
Signed-off-by: Andreas Schneider <asn at samba.org>
commit de08cd99b2832aca319d81cd27c0c71838567f8d
Author: Simo Sorce <idra at samba.org>
Date: Mon May 9 05:37:29 2011 -0400
s3-spoolssd: expand children pool when necessary
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 567ca037866e188142ddc4533324e80080e93b81
Author: Simo Sorce <idra at samba.org>
Date: Mon May 9 04:51:47 2011 -0400
s3-prefork: provide means to expand the pool size
Signed-off-by: Andreas Schneider <asn at samba.org>
commit afc4dda7d078fb697ebfc36d021115007786c401
Author: Simo Sorce <idra at samba.org>
Date: Mon May 9 04:38:06 2011 -0400
s3-spoolssd: Use parametric option for prefork parameters
example:
spoolssd:prefork = 10:100:5
will configure spoolssd to start with a minimum of 10 preforked children,
a max set to 100 children and spawns/retires 5 children at a time when
ramping up/scaling down.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 595cce89fe88d0a93a2df00b9a8f880be56df0e8
Author: Simo Sorce <idra at samba.org>
Date: Thu May 5 17:59:00 2011 -0400
s3-spoolss: make listening asynchronous
This also allows to make each children serve more than one client at the same
time if necessary.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 1dd93f40c8ae22d4210e72df2bad60bf3e1da350
Author: Simo Sorce <idra at samba.org>
Date: Thu Apr 21 15:06:18 2011 -0400
s3-spoolssd: Use the prefork framework in spoolssd
This should make it more scalable and able to handle easily multiple clients at
the same time.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit a1394fc934e91e5db31853a89e3ae9b67e5c76f6
Author: Simo Sorce <idra at samba.org>
Date: Mon Apr 25 17:24:15 2011 -0400
s3-rpc_server: add termination function
This way we can act when a client disconnects.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit d67fc9c1ebd22dc275a790fc1e5e7a453b48ac7e
Author: Simo Sorce <idra at samba.org>
Date: Thu Apr 21 15:05:12 2011 -0400
s3-rpc: Expose some internal functions
This will allow to hook the prefork socket handlers to the rpc service.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 2056d06cae4937c12433d1247b02c346625f86a4
Author: Simo Sorce <idra at samba.org>
Date: Thu May 5 17:56:31 2011 -0400
s3-prefork: add way to manage number of clients per child
The allowed_clients var is a parent managed variable that tell children how
many clients they are allowed to handle at the same time. This way children
can overcommit but within parent controlled limits.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit b9354f72291836e155ed5af56ab98b6a8537ceef
Author: Simo Sorce <idra at samba.org>
Date: Tue May 3 18:55:25 2011 -0400
s3-prefork: add asynchronous functions
To get a client connection it is now possible to use asynchronous functions.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 4fef4fe4986245bfd0ac0c3a3d3a10d330bae09c
Author: Simo Sorce <idra at samba.org>
Date: Wed Apr 20 16:28:57 2011 -0400
s3-prefork: implement prefork framework
Primarily built for forked off rpc service daemons, but not tied to rpc
services and generic enough to be used elsewhere easily.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 88b901b6ee92ea5eb4420981625fb6a6b299e368
Author: Simo Sorce <idra at samba.org>
Date: Wed Aug 3 16:55:30 2011 -0400
s3-printing: No need to register to smbd's children list
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 74f3e52f009126aad7a039d02e42f5c60e6209a8
Author: Simo Sorce <idra at samba.org>
Date: Mon Apr 25 23:40:15 2011 -0400
tevent: cleanup nesting counter when doing a full reinit.
We may be forking from within a loop, so we need to clean-up to avoid
aborts when nesting is not allowed and we are in a new children.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 09ad4d47f875bb3b273902f78e9882e5c4ee259f
Author: Simo Sorce <idra at samba.org>
Date: Thu Apr 21 10:04:06 2011 -0400
lib-util: Make create_unlink_tmp argument optional
Use tmpdir() if no dir is provided.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 05455b459a93f620143d90fd34a28e4485fd606a
Author: Simo Sorce <idra at samba.org>
Date: Thu Apr 21 09:45:27 2011 -0400
lib-util: Make useful function a common utility.
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 185cd4c79492a7de5988f9407d764cdb3a0e2e10
Author: Simo Sorce <idra at samba.org>
Date: Wed May 11 17:50:07 2011 -0400
libutil: use AI_ADDRCONFIG only when AI_NUMERIC is not defined
This flag prevents startup w/o ip addresses assigned to any interface.
If AI_NUMERIC is passed it should be safe to avoid it.
Signed-off-by: Andreas Schneider <asn at samba.org>
-----------------------------------------------------------------------
Summary of changes:
lib/tevent/tevent.c | 7 +
lib/util/util.c | 39 ++-
lib/util/util.h | 5 +
lib/util/util_net.c | 16 +-
selftest/target/Samba3.pm | 1 +
source3/Makefile.in | 1 +
source3/lib/server_prefork.c | 934 ++++++++++++++++++++++++++++++++++++++
source3/lib/server_prefork.h | 268 +++++++++++
source3/printing/printing.c | 2 +
source3/printing/queue_process.c | 156 +++++--
source3/printing/queue_process.h | 9 +-
source3/printing/spoolssd.c | 717 ++++++++++++++++++++++++++++--
source3/rpc_server/rpc_server.c | 92 +++--
source3/rpc_server/rpc_server.h | 7 +
source3/smbd/globals.c | 1 +
source3/smbd/globals.h | 2 +
source3/smbd/process.c | 28 +--
source3/smbd/server.c | 36 +-
source3/wscript_build | 1 +
19 files changed, 2156 insertions(+), 166 deletions(-)
create mode 100644 source3/lib/server_prefork.c
create mode 100644 source3/lib/server_prefork.h
Changeset truncated at 500 lines:
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index 87e5aff..51555ba 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -185,6 +185,13 @@ int tevent_common_context_destructor(struct tevent_context *ev)
tevent_cleanup_pending_signal_handlers(se);
}
+ /* clean up nesting or we get an abort when nesting
+ * is not allowed. -- SSS */
+ ev->nesting.allowed = false;
+ ev->nesting.level = 0;
+ ev->nesting.hook_fn = NULL;
+ ev->nesting.hook_private = NULL;
+
return 0;
}
diff --git a/lib/util/util.c b/lib/util/util.c
index 7f30d43..2d1d830 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -3,9 +3,10 @@
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 2001-2002
- Copyright (C) Simo Sorce 2001
+ Copyright (C) Simo Sorce 2001-2011
Copyright (C) Jim McDonough (jmcd at us.ibm.com) 2003.
Copyright (C) James J Myers 2003
+ Copyright (C) Volker Lendecke 2010
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
@@ -61,6 +62,42 @@ _PUBLIC_ const char *tmpdir(void)
/**
+ Create a tmp file, open it and immediately unlink it.
+ If dir is NULL uses tmpdir()
+ Returns the file descriptor or -1 on error.
+**/
+int create_unlink_tmp(const char *dir)
+{
+ char *fname;
+ int fd;
+
+ if (!dir) {
+ dir = tmpdir();
+ }
+
+ fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
+ if (fname == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ fd = mkstemp(fname);
+ if (fd == -1) {
+ TALLOC_FREE(fname);
+ return -1;
+ }
+ if (unlink(fname) == -1) {
+ int sys_errno = errno;
+ close(fd);
+ TALLOC_FREE(fname);
+ errno = sys_errno;
+ return -1;
+ }
+ TALLOC_FREE(fname);
+ return fd;
+}
+
+
+/**
Check if a file exists - call vfs_file_exist for samba files.
**/
_PUBLIC_ bool file_exist(const char *fname)
diff --git a/lib/util/util.h b/lib/util/util.h
index b9734b0..7f0de26 100644
--- a/lib/util/util.h
+++ b/lib/util/util.h
@@ -623,6 +623,11 @@ bool file_compare(const char *path1, const char *path2);
_PUBLIC_ const char *tmpdir(void);
/**
+ * Creates and immediately unlinks a file. Returns open file descriptor.
+ **/
+_PUBLIC_ int create_unlink_tmp(const char *dir);
+
+/**
Check if a file exists - call vfs_file_exist for samba files.
**/
_PUBLIC_ bool file_exist(const char *fname);
diff --git a/lib/util/util_net.c b/lib/util/util_net.c
index 566bf56..23d25ac 100644
--- a/lib/util/util_net.c
+++ b/lib/util/util_net.c
@@ -73,10 +73,9 @@ bool interpret_string_addr_internal(struct addrinfo **ppres,
ppres);
if (ret) {
- DEBUG(3,("interpret_string_addr_internal: getaddrinfo failed "
- "for name %s [%s]\n",
- str,
- gai_strerror(ret) ));
+ DEBUG(3, ("interpret_string_addr_internal: "
+ "getaddrinfo failed for name %s (flags %d) [%s]\n",
+ str, flags, gai_strerror(ret)));
return false;
}
return true;
@@ -97,6 +96,7 @@ static bool interpret_string_addr_pref(struct sockaddr_storage *pss,
#if defined(HAVE_IPV6)
char addr[INET6_ADDRSTRLEN];
unsigned int scope_id = 0;
+ int int_flags;
if (strchr_m(str, ':')) {
char *p = strchr_m(str, '%');
@@ -117,7 +117,13 @@ static bool interpret_string_addr_pref(struct sockaddr_storage *pss,
zero_sockaddr(pss);
- if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) {
+ if (flags & AI_NUMERICHOST) {
+ int_flags = flags;
+ } else {
+ int_flags = flags|AI_ADDRCONFIG;
+ }
+
+ if (!interpret_string_addr_internal(&res, str, int_flags)) {
return false;
}
if (!res) {
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 183af5e..b767e53 100644
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -902,6 +902,7 @@ sub provision($$$$$$$)
ncalrpc dir = $prefix_abs/ncalrpc
rpc_server:epmapper = daemon
+ rpc_server:spoolss = daemon
rpc_server:tcpip = yes
resolv:host file = $dns_host_file
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 5fa848c..4a79f97 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -465,6 +465,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) $(LIBTSOCKET_OBJ) \
lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \
@CCAN_OBJ@ \
lib/server_contexts.o \
+ lib/server_prefork.o \
lib/ldap_escape.o @CHARSET_STATIC@ \
../libcli/security/secdesc.o ../libcli/security/access_check.o \
../libcli/security/secace.o ../libcli/security/object_tree.o \
diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c
new file mode 100644
index 0000000..501fbc1
--- /dev/null
+++ b/source3/lib/server_prefork.c
@@ -0,0 +1,934 @@
+/*
+ Unix SMB/CIFS implementation.
+ Common server globals
+
+ Copyright (C) Simo Sorce <idra at samba.org> 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 "system/time.h"
+#include "system/shmem.h"
+#include "system/filesys.h"
+#include "server_prefork.h"
+#include "../lib/util/util.h"
+#include "../lib/util/tevent_unix.h"
+
+struct prefork_pool {
+
+ int listen_fd_size;
+ int *listen_fds;
+
+ int lock_fd;
+
+ prefork_main_fn_t *main_fn;
+ void *private_data;
+
+ int pool_size;
+ struct pf_worker_data *pool;
+
+ int allowed_clients;
+
+ prefork_sigchld_fn_t *sigchld_fn;
+ void *sigchld_data;
+};
+
+static bool prefork_setup_sigchld_handler(struct tevent_context *ev_ctx,
+ struct prefork_pool *pfp);
+
+static int prefork_pool_destructor(struct prefork_pool *pfp)
+{
+ munmap(pfp->pool, pfp->pool_size * sizeof(struct pf_worker_data));
+ return 0;
+}
+
+bool prefork_create_pool(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx,
+ int listen_fd_size, int *listen_fds,
+ int min_children, int max_children,
+ prefork_main_fn_t *main_fn, void *private_data,
+ struct prefork_pool **pf_pool)
+{
+ struct prefork_pool *pfp;
+ pid_t pid;
+ time_t now = time(NULL);
+ size_t data_size;
+ int ret;
+ int i;
+ bool ok;
+
+ pfp = talloc_zero(mem_ctx, struct prefork_pool);
+ if (!pfp) {
+ DEBUG(1, ("Out of memory!\n"));
+ return false;
+ }
+ pfp->listen_fd_size = listen_fd_size;
+ pfp->listen_fds = talloc_array(pfp, int, listen_fd_size);
+ if (!pfp->listen_fds) {
+ DEBUG(1, ("Out of memory!\n"));
+ return false;
+ }
+ for (i = 0; i < listen_fd_size; i++) {
+ pfp->listen_fds[i] = listen_fds[i];
+ }
+ pfp->main_fn = main_fn;
+ pfp->private_data = private_data;
+
+ pfp->lock_fd = create_unlink_tmp(NULL);
+ if (pfp->lock_fd == -1) {
+ DEBUG(1, ("Failed to create prefork lock fd!\n"));
+ talloc_free(pfp);
+ return false;
+ }
+
+ pfp->pool_size = max_children;
+ data_size = sizeof(struct pf_worker_data) * max_children;
+
+ pfp->pool = mmap(NULL, data_size, PROT_READ|PROT_WRITE,
+ MAP_SHARED|MAP_ANONYMOUS, -1, 0);
+ if (pfp->pool == MAP_FAILED) {
+ DEBUG(1, ("Failed to mmap memory for prefork pool!\n"));
+ talloc_free(pfp);
+ return false;
+ }
+ talloc_set_destructor(pfp, prefork_pool_destructor);
+
+ for (i = 0; i < min_children; i++) {
+
+ pfp->pool[i].allowed_clients = 1;
+ pfp->pool[i].started = now;
+
+ pid = sys_fork();
+ switch (pid) {
+ case -1:
+ DEBUG(1, ("Failed to prefork child n. %d !\n", i));
+ break;
+
+ case 0: /* THE CHILD */
+
+ pfp->pool[i].status = PF_WORKER_IDLE;
+ ret = pfp->main_fn(ev_ctx, msg_ctx,
+ &pfp->pool[i], i + 1,
+ pfp->listen_fd_size,
+ pfp->listen_fds,
+ pfp->lock_fd,
+ pfp->private_data);
+ exit(ret);
+
+ default: /* THE PARENT */
+ pfp->pool[i].pid = pid;
+ break;
+ }
+ }
+
+ ok = prefork_setup_sigchld_handler(ev_ctx, pfp);
+ if (!ok) {
+ DEBUG(1, ("Failed to setup SIGCHLD Handler!\n"));
+ talloc_free(pfp);
+ return false;
+ }
+
+ *pf_pool = pfp;
+ return true;
+}
+
+/* Provide the new max children number in new_max
+ * (must be larger than current max).
+ * Returns: 0 if all fine
+ * ENOSPC if mremap fails to expand
+ * EINVAL if new_max is invalid
+ */
+int prefork_expand_pool(struct prefork_pool *pfp, int new_max)
+{
+ struct pf_worker_data *pool;
+ size_t old_size;
+ size_t new_size;
+
+ if (new_max <= pfp->pool_size) {
+ return EINVAL;
+ }
+
+ old_size = sizeof(struct pf_worker_data) * pfp->pool_size;
+ new_size = sizeof(struct pf_worker_data) * new_max;
+
+ pool = mremap(pfp->pool, old_size, new_size, 0);
+ if (pool == MAP_FAILED) {
+ DEBUG(3, ("Failed to mremap memory for prefork pool!\n"));
+ return ENOSPC;
+ }
+
+ memset(&pool[pfp->pool_size], 0, new_size - old_size);
+
+ pfp->pool_size = new_max;
+
+ return 0;
+}
+
+int prefork_add_children(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx,
+ struct prefork_pool *pfp,
+ int num_children)
+{
+ pid_t pid;
+ time_t now = time(NULL);
+ int ret;
+ int i, j;
+
+ for (i = 0, j = 0; i < pfp->pool_size && j < num_children; i++) {
+
+ if (pfp->pool[i].status != PF_WORKER_NONE) {
+ continue;
+ }
+
+ pfp->pool[i].allowed_clients = 1;
+ pfp->pool[i].started = now;
+
+ pid = sys_fork();
+ switch (pid) {
+ case -1:
+ DEBUG(1, ("Failed to prefork child n. %d !\n", j));
+ break;
+
+ case 0: /* THE CHILD */
+
+ pfp->pool[i].status = PF_WORKER_IDLE;
+ ret = pfp->main_fn(ev_ctx, msg_ctx,
+ &pfp->pool[i], i + 1,
+ pfp->listen_fd_size,
+ pfp->listen_fds,
+ pfp->lock_fd,
+ pfp->private_data);
+
+ pfp->pool[i].status = PF_WORKER_EXITING;
+ exit(ret);
+
+ default: /* THE PARENT */
+ pfp->pool[i].pid = pid;
+ j++;
+ break;
+ }
+ }
+
+ DEBUG(5, ("Added %d children!\n", j));
+
+ return j;
+}
+
+struct prefork_oldest {
+ int num;
+ time_t started;
+};
+
+/* sort in inverse order */
+static int prefork_sort_oldest(const void *ap, const void *bp)
+{
+ struct prefork_oldest *a = (struct prefork_oldest *)ap;
+ struct prefork_oldest *b = (struct prefork_oldest *)bp;
+
+ if (a->started == b->started) {
+ return 0;
+ }
+ if (a->started < b->started) {
+ return 1;
+ }
+ return -1;
+}
+
+int prefork_retire_children(struct prefork_pool *pfp,
+ int num_children, time_t age_limit)
+{
+ time_t now = time(NULL);
+ struct prefork_oldest *oldest;
+ int i, j;
+
+ oldest = talloc_array(pfp, struct prefork_oldest, pfp->pool_size);
+ if (!oldest) {
+ return -1;
+ }
+
+ for (i = 0; i < pfp->pool_size; i++) {
+ oldest[i].num = i;
+ if (pfp->pool[i].status == PF_WORKER_IDLE) {
+ oldest[i].started = pfp->pool[i].started;
+ } else {
+ oldest[i].started = now;
+ }
+ }
+
+ qsort(oldest, pfp->pool_size,
+ sizeof(struct prefork_oldest),
+ prefork_sort_oldest);
+
+ for (i = 0, j = 0; i < pfp->pool_size && j < num_children; i++) {
+ if (pfp->pool[i].status == PF_WORKER_IDLE &&
+ pfp->pool[i].started <= age_limit) {
+ /* tell the child it's time to give up */
+ DEBUG(5, ("Retiring pid %d!\n", pfp->pool[i].pid));
+ pfp->pool[i].cmds = PF_SRV_MSG_EXIT;
+ kill(pfp->pool[i].pid, SIGHUP);
+ j++;
+ }
+ }
+
+ return j;
+}
+
+int prefork_count_active_children(struct prefork_pool *pfp, int *total)
+{
+ int i, a, t;
+
+ a = 0;
+ t = 0;
+ for (i = 0; i < pfp->pool_size; i++) {
+ if (pfp->pool[i].status == PF_WORKER_NONE) {
+ continue;
+ }
+
+ t++;
+
+ if (pfp->pool[i].num_clients == 0) {
+ continue;
+ }
+
+ a++;
+ }
+
+ *total = t;
+ return a;
+}
+
+static void prefork_cleanup_loop(struct prefork_pool *pfp)
+{
+ int status;
+ pid_t pid;
+ int i;
+
+ /* TODO: should we use a process group id wait instead of looping ? */
+ for (i = 0; i < pfp->pool_size; i++) {
+ if (pfp->pool[i].status == PF_WORKER_NONE ||
+ pfp->pool[i].pid == 0) {
+ continue;
+ }
+
+ pid = sys_waitpid(pfp->pool[i].pid, &status, WNOHANG);
+ if (pid > 0) {
+
+ if (pfp->pool[i].status != PF_WORKER_EXITING) {
+ DEBUG(3, ("Child (%d) terminated abnormally:"
+ " %d\n", (int)pid, status));
+ } else {
+ DEBUG(10, ("Child (%d) terminated with status:"
+ " %d\n", (int)pid, status));
+ }
+
--
Samba Shared Repository
More information about the samba-cvs
mailing list