| <?xml version="1.0" encoding="UTF-8" ?> | |
| <!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd"> | |
| <?xml-stylesheet type="text/xsl" href="./style/manual.en.xsl"?> | |
| <!-- $LastChangedRevision$ --> | |
| <!-- | |
| 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. | |
| --> | |
| <manualpage metafile="dso.xml.meta"> | |
| <title>Dynamic Shared Object (DSO) Support</title> | |
| <summary> | |
| <p>The Apache HTTP Server is a modular program where the | |
| administrator can choose the functionality to include in the | |
| server by selecting a set of modules. | |
| Modules will be compiled as Dynamic Shared Objects (DSOs) | |
| that exist separately from the main <program>httpd</program> | |
| binary file. DSO modules may be compiled at the time the server | |
| is built, or they may be compiled and added at a later time | |
| using the Apache Extension Tool (<program>apxs</program>).</p> | |
| <p>Alternatively, the modules can be statically compiled into | |
| the <program>httpd</program> binary when the server is built.</p> | |
| <p>This document describes how to use DSO modules as well as | |
| the theory behind their use.</p> | |
| </summary> | |
| <section id="implementation"><title>Implementation</title> | |
| <related> | |
| <modulelist> | |
| <module>mod_so</module> | |
| </modulelist> | |
| <directivelist> | |
| <directive module="mod_so">LoadModule</directive> | |
| </directivelist> | |
| </related> | |
| <p>The DSO support for loading individual Apache httpd modules is based | |
| on a module named <module>mod_so</module> which must be statically | |
| compiled into the Apache httpd core. It is the only module besides | |
| <module>core</module> which cannot be put into a DSO | |
| itself. Practically all other distributed Apache httpd modules will then | |
| be placed into a DSO. After a module is compiled into a DSO named | |
| <code>mod_foo.so</code> you can use <module>mod_so</module>'s <directive | |
| module="mod_so">LoadModule</directive> directive in your | |
| <code>httpd.conf</code> file to load this module at server startup | |
| or restart.</p> | |
| <p>The DSO builds for individual modules can be disabled via | |
| <program>configure</program>'s <code>--enable-mods-static</code> | |
| option as discussed in the <a href="install.html">install | |
| documentation</a>.</p> | |
| <p>To simplify this creation of DSO files for Apache httpd modules | |
| (especially for third-party modules) a support program | |
| named <program>apxs</program> (<dfn>APache | |
| eXtenSion</dfn>) is available. It can be used to build DSO based | |
| modules <em>outside of</em> the Apache httpd source tree. The idea is | |
| simple: When installing Apache HTTP Server the <program>configure</program>'s | |
| <code>make install</code> procedure installs the Apache httpd C | |
| header files and puts the platform-dependent compiler and | |
| linker flags for building DSO files into the <program>apxs</program> | |
| program. This way the user can use <program>apxs</program> to compile | |
| his Apache httpd module sources without the Apache httpd distribution | |
| source tree and without having to fiddle with the | |
| platform-dependent compiler and linker flags for DSO | |
| support.</p> | |
| </section> | |
| <section id="usage"><title>Usage Summary</title> | |
| <p>To give you an overview of the DSO features of Apache HTTP Server 2.x, | |
| here is a short and concise summary:</p> | |
| <ol> | |
| <li> | |
| <p>Build and install a <em>distributed</em> Apache httpd module, say | |
| <code>mod_foo.c</code>, into its own DSO | |
| <code>mod_foo.so</code>:</p> | |
| <example> | |
| <highlight language="sh"> | |
| $ ./configure --prefix=/path/to/install --enable-foo | |
| $ make install | |
| </highlight> | |
| </example> | |
| </li> | |
| <li> | |
| <p>Configure Apache HTTP Server with all modules enabled. Only a basic | |
| set will be loaded during server startup. You can change the set of loaded | |
| modules by activating or deactivating the <directive | |
| module="mod_so">LoadModule</directive> directives in | |
| <code>httpd.conf</code>.</p> | |
| <example> | |
| <highlight language="sh"> | |
| $ ./configure --enable-mods-shared=all | |
| $ make install | |
| </highlight> | |
| </example> | |
| </li> | |
| <li> | |
| <p>Some modules are only useful for developers and will not be build. | |
| when using the module set <em>all</em>. To build all available modules | |
| including developer modules use <em>reallyall</em>. In addition the | |
| <directive module="mod_so">LoadModule</directive> directives for all | |
| built modules can be activated via the configure option | |
| <code>--enable-load-all-modules</code>.</p> | |
| <example> | |
| <highlight language="sh"> | |
| $ ./configure --enable-mods-shared=reallyall --enable-load-all-modules | |
| $ make install | |
| </highlight> | |
| </example> | |
| </li> | |
| <li> | |
| Build and install a <em>third-party</em> Apache httpd module, say | |
| <code>mod_foo.c</code>, into its own DSO | |
| <code>mod_foo.so</code> <em>outside of</em> the Apache httpd | |
| source tree using <program>apxs</program>: | |
| <example> | |
| <highlight language="sh"> | |
| $ cd /path/to/3rdparty | |
| $ apxs -cia mod_foo.c | |
| </highlight> | |
| </example> | |
| </li> | |
| </ol> | |
| <p>In all cases, once the shared module is compiled, you must | |
| use a <directive module="mod_so">LoadModule</directive> | |
| directive in <code>httpd.conf</code> to tell Apache httpd to activate | |
| the module.</p> | |
| <p>See the <a href="programs/apxs.html">apxs documentation</a> for more details.</p> | |
| </section> | |
| <section id="background"><title>Background</title> | |
| <p>On modern Unix derivatives there exists a mechanism | |
| called dynamic linking/loading of <em>Dynamic Shared | |
| Objects</em> (DSO) which provides a way to build a piece of | |
| program code in a special format for loading it at run-time | |
| into the address space of an executable program.</p> | |
| <p>This loading can usually be done in two ways: automatically | |
| by a system program called <code>ld.so</code> when an | |
| executable program is started or manually from within the | |
| executing program via a programmatic system interface to the | |
| Unix loader through the system calls | |
| <code>dlopen()/dlsym()</code>.</p> | |
| <p>In the first way the DSO's are usually called <em>shared | |
| libraries</em> or <em>DSO libraries</em> and named | |
| <code>libfoo.so</code> or <code>libfoo.so.1.2</code>. They | |
| reside in a system directory (usually <code>/usr/lib</code>) | |
| and the link to the executable program is established at | |
| build-time by specifying <code>-lfoo</code> to the linker | |
| command. This hard-codes library references into the executable | |
| program file so that at start-time the Unix loader is able to | |
| locate <code>libfoo.so</code> in <code>/usr/lib</code>, in | |
| paths hard-coded via linker-options like <code>-R</code> or in | |
| paths configured via the environment variable | |
| <code>LD_LIBRARY_PATH</code>. It then resolves any (yet | |
| unresolved) symbols in the executable program which are | |
| available in the DSO.</p> | |
| <p>Symbols in the executable program are usually not referenced | |
| by the DSO (because it's a reusable library of general code) | |
| and hence no further resolving has to be done. The executable | |
| program has no need to do anything on its own to use the | |
| symbols from the DSO because the complete resolving is done by | |
| the Unix loader. (In fact, the code to invoke | |
| <code>ld.so</code> is part of the run-time startup code which | |
| is linked into every executable program which has been bound | |
| non-static). The advantage of dynamic loading of common library | |
| code is obvious: the library code needs to be stored only once, | |
| in a system library like <code>libc.so</code>, saving disk | |
| space for every program.</p> | |
| <p>In the second way the DSO's are usually called <em>shared | |
| objects</em> or <em>DSO files</em> and can be named with an | |
| arbitrary extension (although the canonical name is | |
| <code>foo.so</code>). These files usually stay inside a | |
| program-specific directory and there is no automatically | |
| established link to the executable program where they are used. | |
| Instead the executable program manually loads the DSO at | |
| run-time into its address space via <code>dlopen()</code>. At | |
| this time no resolving of symbols from the DSO for the | |
| executable program is done. But instead the Unix loader | |
| automatically resolves any (yet unresolved) symbols in the DSO | |
| from the set of symbols exported by the executable program and | |
| its already loaded DSO libraries (especially all symbols from | |
| the ubiquitous <code>libc.so</code>). This way the DSO gets | |
| knowledge of the executable program's symbol set as if it had | |
| been statically linked with it in the first place.</p> | |
| <p>Finally, to take advantage of the DSO's API the executable | |
| program has to resolve particular symbols from the DSO via | |
| <code>dlsym()</code> for later use inside dispatch tables | |
| <em>etc.</em> In other words: The executable program has to | |
| manually resolve every symbol it needs to be able to use it. | |
| The advantage of such a mechanism is that optional program | |
| parts need not be loaded (and thus do not spend memory) until | |
| they are needed by the program in question. When required, | |
| these program parts can be loaded dynamically to extend the | |
| base program's functionality.</p> | |
| <p>Although this DSO mechanism sounds straightforward there is | |
| at least one difficult step here: The resolving of symbols from | |
| the executable program for the DSO when using a DSO to extend a | |
| program (the second way). Why? Because "reverse resolving" DSO | |
| symbols from the executable program's symbol set is against the | |
| library design (where the library has no knowledge about the | |
| programs it is used by) and is neither available under all | |
| platforms nor standardized. In practice the executable | |
| program's global symbols are often not re-exported and thus not | |
| available for use in a DSO. Finding a way to force the linker | |
| to export all global symbols is the main problem one has to | |
| solve when using DSO for extending a program at run-time.</p> | |
| <p>The shared library approach is the typical one, because it | |
| is what the DSO mechanism was designed for, hence it is used | |
| for nearly all types of libraries the operating system | |
| provides.</p> | |
| </section> | |
| <section id="advantages"><title>Advantages and Disadvantages</title> | |
| <p>The above DSO based features have the following | |
| advantages:</p> | |
| <ul> | |
| <li>The server package is more flexible at run-time because | |
| the server process can be assembled at run-time via | |
| <directive module="mod_so">LoadModule</directive> | |
| <code>httpd.conf</code> configuration directives instead of | |
| <program>configure</program> options at build-time. For instance, | |
| this way one is able to run different server instances | |
| (standard & SSL version, minimalistic & dynamic | |
| version [mod_perl, mod_php], <em>etc.</em>) with only one Apache httpd | |
| installation.</li> | |
| <li>The server package can be easily extended with | |
| third-party modules even after installation. This is | |
| a great benefit for vendor package maintainers, who can create | |
| an Apache httpd core package and additional packages containing | |
| extensions like PHP, mod_perl, mod_security, <em>etc.</em></li> | |
| <li>Easier Apache httpd module prototyping, because with the | |
| DSO/<program>apxs</program> pair you can both work outside the | |
| Apache httpd source tree and only need an <code>apxs -i</code> | |
| command followed by an <code>apachectl restart</code> to | |
| bring a new version of your currently developed module into | |
| the running Apache HTTP Server.</li> | |
| </ul> | |
| <p>DSO has the following disadvantages:</p> | |
| <ul> | |
| <li>The server is approximately 20% slower at startup time | |
| because of the symbol resolving overhead the Unix loader now | |
| has to do.</li> | |
| <li>The server is approximately 5% slower at execution time | |
| under some platforms, because position independent code (PIC) | |
| sometimes needs complicated assembler tricks for relative | |
| addressing, which are not necessarily as fast as absolute | |
| addressing.</li> | |
| <li>Because DSO modules cannot be linked against other | |
| DSO-based libraries (<code>ld -lfoo</code>) on all platforms | |
| (for instance a.out-based platforms usually don't provide | |
| this functionality while ELF-based platforms do) you cannot | |
| use the DSO mechanism for all types of modules. Or in other | |
| words, modules compiled as DSO files are restricted to only | |
| use symbols from the Apache httpd core, from the C library | |
| (<code>libc</code>) and all other dynamic or static libraries | |
| used by the Apache httpd core, or from static library archives | |
| (<code>libfoo.a</code>) containing position independent code. | |
| The only chances to use other code is to either make sure the | |
| httpd core itself already contains a reference to it or | |
| loading the code yourself via <code>dlopen()</code>.</li> | |
| </ul> | |
| </section> | |
| </manualpage> |