<?xml version="1.0"?>
<!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
<!-- $LastChangedRevision: 421174 $ -->

<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<modulesynopsis metafile="perchild.xml.meta">

<name>perchild</name>
<description>Multi-Processing Module allowing for daemon processes serving
requests to be assigned a variety of different userids</description>
<status>MPM</status>
<sourcefile>perchild.c</sourcefile>
<identifier>mpm_perchild_module</identifier>

<summary>
    <note type="warning">
      This module is not functional.  Development of this module is not
      complete and is not currently active.  Do not use
      <module>perchild</module> unless you are a programmer willing to
      help fix it.
    </note>

    <p>This Multi-Processing Module (MPM) implements a hybrid
    multi-process, multi-threaded web server. A fixed number of
    processes create threads to handle requests. Fluctuations in
    load are handled by increasing or decreasing the number of
    threads in each process.</p>
</summary>
<seealso><a href="../bind.html">Setting which addresses and ports Apache
uses</a></seealso>

<section id="how-it-works"><title>How it works</title>
    <p>A single control process launches the number of child processes
    indicated by the <directive module="perchild">NumServers</directive>
    directive at server startup. Each child process creates threads as
    specified in the <directive module="mpm_common">StartThreads</directive> directive.
    The individual threads then
    listen for connections and serve them when they arrive.</p>

    <p>Apache always tries to maintain a pool of <dfn>spare</dfn> or
    idle server threads, which stand ready to serve incoming
    requests. In this way, clients do not need to wait for new
    threads to be created. For each child process, Apache assesses
    the number of idle threads and creates or destroys threads to
    keep this number within the boundaries specified by
    <directive module="mpm_common">MinSpareThreads</directive>
    and <directive module="mpm_common">MaxSpareThreads</directive>.
    Since this process is very self-regulating, it is rarely
    necessary to modify these directives from their default values.
    The maximum number of clients that may be served simultaneously
    is determined by multiplying the number of server processes
    that will be created (<directive 
    module="perchild">NumServers</directive>) by the maximum
    number of threads created in each process
    (<directive module="mpm_common">MaxThreadsPerChild</directive>).</p>

    <p>While the parent process is usually started as root under
    Unix in order to bind to port 80, the child processes and
    threads are launched by Apache as a less-privileged user. The
    <directive module="mpm_common">User</directive> and <directive
    module="mpm_common">Group</directive> directives are used to
    set the privileges of the Apache child processes. The child
    processes must be able to read all the content that will be
    served, but should have as few privileges beyond that as
    possible. In addition, unless <program>suexec</program> is used,
    these directives also set the privileges which will be inherited
    by CGI scripts.</p>

    <p><directive module="mpm_common">MaxRequestsPerChild</directive>
    controls how frequently the
    server recycles processes by killing old ones and launching new
    ones.</p>

    <section id="user-ids"><title>Working with different user-IDs</title>
      <p>The <module>perchild</module> MPM adds the extra ability to
      specify that particular processes should serve requests under
      different user-IDs. These user-IDs can then be associated with
      specific virtual hosts. You have to use one <directive
      module="perchild">ChildPerUserID</directive> directive for
      every user/group combination you want to be run. Then you can tie
      particular virtual hosts to that user and group IDs.</p>

      <p>The following example runs 7 child processes. Two of them are run
      under <code>user1</code>/<code>group1</code>. The next four are run
      under <code>user2</code>/<code>group2</code> and the remaining
      process uses the <directive module="mpm_common"
      >User</directive> and <directive module="mpm_common">Group</directive>
      of the main server:</p>

      <example><title>Global config</title>
        NumServers 7<br />
        ChildPerUserID user1 group1 2<br />
        ChildPerUserID user2 group2 4
      </example>

      <p>Using unbalanced numbers of processes as above is useful, if the
      particular virtual hosts produce different load. The assignment to
      the virtual hosts is easily done as in the example below. In
      conclusion with the example above the following assumes, that
      <code>server2</code> has to serve about twice of the hits of
      <code>server1</code>.</p>

      <example><title>Example</title>
        NameVirtualHost *<br />
        <br />
        &lt;VirtualHost *&gt;<br />
        <indent>
          ServerName fallbackhost<br />
          # no assignment; use fallback<br />
        </indent>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost *&gt;<br />
        <indent>
          ServerName server1<br />
          AssignUserID user1 group1<br />
        </indent>
        &lt;/VirtualHost&gt;<br />
        <br />
        &lt;VirtualHost *&gt;<br />
        <indent>
          ServerName server2<br />
          AssignUserID user2 group2<br />
        </indent>
        &lt;/VirtualHost&gt;
      </example>
    </section>
</section>

<directivesynopsis location="mpm_common"><name>AcceptMutex</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>BS2000Account</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>CoreDumpDirectory</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>EnableExceptionHook</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>Group</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>PidFile</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>Listen</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>ListenBacklog</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>LockFile</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>MaxRequestsPerChild</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>MaxSpareThreads</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>MinSpareThreads</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>ScoreBoardFile</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>ReceiveBufferSize</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>SendBufferSize</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>ServerLimit</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>StartThreads</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>ThreadLimit</name>
</directivesynopsis>
<directivesynopsis location="mpm_common"><name>User</name>
</directivesynopsis>

<directivesynopsis>
<name>AssignUserID</name>
<description>Tie a virtual host to a user and group ID</description>
<syntax>AssignUserID <var>user-id</var> <var>group-id</var></syntax>
<contextlist><context>virtual host</context></contextlist>

<usage>
    <p>Tie a virtual host to a specific user/group combination. Requests
    addressed to the virtual host where this directive appears will be
    served by a process running with the specified user and group ID.</p>

    <p>The user and group ID has to be assigned to a number of children
    in the global server config using the <directive module="perchild"
    >ChildPerUserID</directive> directive. See the section above for a
    <a href="#user-ids">configuration example</a>.</p>
</usage>
</directivesynopsis>

<directivesynopsis>
<name>ChildPerUserID</name>
<description>Specify user ID and group ID for a number of child
processes</description>
<syntax>ChildPerUserID <var>user-id</var> <var>group-id</var>
<var>num-children</var></syntax>
<contextlist><context>server config</context></contextlist>

<usage>
    <p>Specify a user ID and group ID for a number of child processes.
    The third argument, <var>num-children</var>, is the number of child
    processes to start with the specified user and group. It does
    <em>not</em> represent a specific child number. In order to use this
    directive, the server must be run initially as <code>root</code>.
    If you start the server as a non-root user, it will fail to change
    to the lesser privileged user.</p>

    <p>If the total number of child processes, found by totaling all of the
    third arguments to all <directive>ChildPerUserID</directive> directives
    in the config file, is less than <directive module="perchild"
    >NumServers</directive>, then all remaining children will inherit the
    <directive module="mpm_common">User</directive> and <directive
    module="mpm_common">Group</directive> settings from the main server.
    See the section above for a <a href="#user-ids">configuration
    example</a>.</p>

    <note type="warning"><title>Security</title>
      <p>Don't set <var>user-id</var> (or <var>group-id</var>) to
      <code>root</code> unless you know exactly what you are doing, and
      what the dangers are.</p>
    </note>
</usage>
</directivesynopsis>

<directivesynopsis>
<name>MaxThreadsPerChild</name>
<description>Maximum number of threads per child process</description>
<syntax>MaxThreadsPerChild <var>number</var></syntax>
<default>MaxThreadsPerChild 64</default>
<contextlist><context>server config</context></contextlist>

<usage>
    <p>This directive sets the maximum number of threads that will be
    created in each child process. To increase this value beyond its
    default, it is necessary to change the value of the <directive
    module="mpm_common">ThreadLimit</directive> directive and stop and
    re-start the server.</p>
</usage>
</directivesynopsis>

<directivesynopsis>
<name>NumServers</name>
<description>Total number of children alive at the same time</description>
<syntax>NumServers <var>number</var></syntax>
<default>NumServers 2</default>
<contextlist><context>server config</context></contextlist>

<usage>
    <p>The <directive>NumServers</directive> directive determines the number
    of children alive at the same time. This number should be large enough to
    handle the requests for the entire site. To increase this value beyond the
    value of <code>8</code>, it is necessary to change the value of the
    <directive module="mpm_common">ServerLimit</directive> directive and stop
    and re-start the server. See the section above for a <a href="#user-ids"
    >configuration example</a>.</p>
</usage>
</directivesynopsis>

</modulesynopsis>
