[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