<?xml version="1.0" encoding="EUC-KR"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="ko" xml:lang="ko">
<!-- 용어 같이 기제 -->
  <head>
    <meta name="generator" content="HTML Tidy, see www.w3.org" />

    <title>동적공유객체 (DSO) 지원</title>
  </head>
  <!-- Background white, links blue (unvisited), navy (visited), red (active) -->

  <body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
  vlink="#000080" alink="#FF0000">
        <div align="center">
      <img src="images/sub.gif" alt="[APACHE DOCUMENTATION]" /> 

      <h3>Apache HTTP Server Version 2.0</h3>
    </div>




    <h1 align="center">동적공유객체 (DSO) 지원</h1>

    <p>아파치 웹서버는 관리자가 모듈들을 선택하여 서버에 포함할
    기능을 결정할 수 있는 모듈화된 프로그램이다. 모듈은 서버가 컴파일될때
    <code>httpd</code> 실행파일에 정적으로 컴파일될 수 있다.
    아니면 모듈은 중심이 되는 <code>httpd</code> 실행파일과 별도로
    동적공유객체(Dynamic Shared Objects, DSOs)로 컴파일될 수 있다.
    DSO 모듈은 서버가 컴파일될때 컴파일하거나 Apache Extension
    Tool (<a href="programs/apxs.html">apxs</a>)을 사용하여 나중에
    컴파일하고 추가할 수 있다.</p>

    <p>이 문서는 DSO 모듈 사용법과 관련된 이론을 설명한다.</p>

    <ul>
      <li><a href="#implementation">구현</a></li>

      <li><a href="#usage">사용법 요약</a></li>

      <li><a href="#background">배경지식</a></li>

      <li><a href="#advantages">장점과 단점</a></li>
    </ul>
    <hr />

    <table border="1">
      <tr>
        <td valign="top"><strong>관련된 모듈</strong><br />
         <br />
         <a href="mod/mod_so.html">mod_so</a><br />
         </td>

        <td valign="top"><strong>관련된 지시어</strong><br />
         <br />
         <a href="mod/mod_so.html#loadmodule">LoadModule</a><br />
         </td>
      </tr>
    </table>

    <h2><a id="implementation"
    name="implementation">구현</a></h2>

    <p>아파치 모듈을 읽어들이기위한 DSO 지원은 아파치 핵심에
    정적으로 컴파일되야할
    <a href="mod/mod_so.html"><code>mod_so.c</code></a>라는
    모듈이 제공한다. 이는 <code>core.c</code>를 제외하고
    DSO가 될 수 없는 유일한 모듈이다. 실제로 다른 모든 아파치 모듈은
    각각 <a href="install.html">설치 문서</a>에서 설명한
    <code>configure</code>의 <code>--enable-<i>module</i>=shared</code>
    옵션을 사용하여 DSO로 컴파일할 수 있다. 모듈이
    <code>mod_foo.so</code>와 같이 DSO로 컴파일된후 <code>httpd.conf</code>
    파일에 <a href="mod/mod_so.html"><code>mod_so</code></a>의
    <a href="mod/mod_so.html#loadmodule"><code>LoadModule</code></a>
    명령어를 사용하여 서버 시작시 혹은 재시작시 그 모듈을 읽어들일
    수 있다.</p>

    <p>아파치 모듈(특히 제삼의 모듈)로 사용할 DSO 파일을 쉽게
    만들기위해 <a href="programs/apxs.html">apxs</a> (<em>APache
    eXtenSion</em>)라는 새로운 지원 프로그램이 있다.
    이는 아파치 소스 트리 <em>밖에서</em> DSO로 사용할 모듈을
    컴파일할때 사용한다. 개념은 쉽다. 아파치를 설치할때
    <code>configure</code>와 <code>make install</code>이
    아파치 C 헤더파일을 설치하고, DSO 파일을 컴파일하기위한
    플래폼 특유의 컴파일러 옵션과 링커 옵션을 <code>apxs</code>
    프로그램에 쓴다. 그래서 사용자는 <code>apxs</code>를
    사용하여 아파치 배포본 소스 트리없이, 또 DSO 지원을 위한 플래폼
    특유의 컴파일러 옵션와 링커 옵션에 신경을 쓰지않고 자신의
    아파치 모듈 소스를 컴파일할 수 있다.</p>

    <h2><a id="usage" name="usage">사용법 요약</a></h2>

    <p>Apache 2.0의 DSO 기능에 대한 짧고 간략한 요약이다:</p>

    <ol>
      <li>
        <em>배포본에 있는</em> 아파치 모듈을 컴파일하고 설치하는 경우.
        예를 들어 <code>mod_foo.c</code>를 DSO <code>mod_foo.so</code>로:

        <table bgcolor="#f0f0f0" cellpadding="10">
          <tr>
            <td>
<pre>
$ ./configure --prefix=/path/to/install
        --enable-foo=shared
$ make install
</pre>
            </td>
          </tr>
        </table>
      </li>

      <li>
        <em>제삼의</em> 아파치 모듈을 컴파일하고 설치하는 경우. 예를 들어
        <code>mod_foo.c</code>를 DSO <code>mod_foo.so</code>로:

        <table bgcolor="#f0f0f0" cellpadding="10">
          <tr>
            <td>
<pre>
$ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c 
        --enable-foo=shared
$ make install
</pre>
            </td>
          </tr>
        </table>
      </li>

      <li>
        공유 모듈을 <em>다음에 설치하기위해</em> 아파치를 구성하는 경우:

        <table bgcolor="#f0f0f0" cellpadding="10">
          <tr>
            <td>
<pre>
$ ./configure --enable-so
$ make install
</pre>
            </td>
          </tr>
        </table>
      </li>

      <li>
        <em>제삼의</em> 아파치 모듈을 컴파일하고 설치하는 경우.
        <code>mod_foo.c</code>를 <a href="programs/apxs.html">apxs</a>를
        사용하여 아파치 소스 트리 <em>밖에서</em> DSO
        <code>mod_foo.so</code>로:

        <table bgcolor="#f0f0f0" cellpadding="10">
          <tr>
            <td>
<pre>
$ cd /path/to/3rdparty
$ apxs -c mod_foo.c
$ apxs -i -a -n foo mod_foo.la
</pre>
            </td>
          </tr>
        </table>
      </li>
    </ol>

    <p>모든 경우 일단 공유 모듈이 컴파일되면, <code>httpd.conf</code>에
    <a href="mod/mod_so.html#loadmodule"><code>LoadModule</code></a>
    지시어를 사용하여 아파치가 그 모듈을 활성화하게 해야한다.</p>

    <h2><a id="background" name="background">배경지식</a></h2>

    <p>현대적인 유닉스류에는 <em>동적공유객체</em> (DSO)의
    동적 링킹/로딩이라고 하여, 특별한 형식의 실행코드 조각을 만들어
    실행중 실행프로그램의 주소공간에 읽어들이는 멋진 기능이 있다.</p>

    <p>이 로딩은 보통 두가지 방법으로 가능하다. 하나는 실행프로그램이
    시작할때 <code>ld.so</code>라는 시스템 프로그램이 로딩을
    자동으로 하는 경우고, 다른 하나는 실행중인 프로그램에서
    <code>dlopen()/dlsym()</code> 시스템콜로 유닉스 로더의
    시스템 인터페이스을 사용하여 직접 로딩하는 경우다.</p>

    <p>첫번째 경우 DSO는 보통 <em>공유라이브러리(shared libraries)</em> 혹은
    <em>DSO 라이브러리</em>라고 부르며, 파일은 <code>libfoo.so</code>나
    <code>libfoo.so.1.2</code> 같은 이름을 가진다. 이들은
    시스템 디렉토리(보통 <code>/usr/lib</code>)에 있고,
    컴파일시 링커 명령어에 <code>-lfoo</code>를 주어 실행파일과
    연결된다. 이렇게 직접 써준 라이브러리는 실행파일에 참조되여서,
    링커 옵션 <code>-R</code>로 직접 지정하였거나 환경변수
    <code>LD_LIBRARY_PATH</code>로 지정한 경로인 <code>/usr/lib</code>에서
    유닉스 로더가 프로그램이 시작할때 <code>libfoo.so</code>를
    찾을(resolve) 수 있다. 그러면 실행프로그램의 (아직 못찾은)
    심볼(symbol)을 DSO에서 찾게된다.</p>

    <p>DSO는 보통 실행프로그램의 심볼을 찾지않기 때문에 (DSO가
    재사용가능한 일반적인 코드의 라이브러리이므로) 찾기는 여기서 끝난다.
    유닉스 로더가 심볼 찾기를 완전히 담당하므로 실행프로그램이 직접
    DSO에서 심볼을 찾을 필요가 없다. (사실 <code>ld.so</code>를
    부르는 코드는 정적이 아닌 모든 실행프로그램에 링크되는 실행시
    시작코드의 일부다.) 공통된 라이브러리 코드를 동적으로 읽어들이는
    장점은 명확하다. 라이브러리 코드가 모든 프로그램에 저장되는 대신
    <code>libc.so</code>와 같은 시스템 라이브러리에 한번만 저장되기
    때문에 디스크 공간이 절약된다.</p>

    <p>두번째 경우 DSO는 보통 <em>공유객체(shared objects)</em> 혹은
    <em>DSO 파일</em>이라고 부르고, (규칙상 이름은 <code>foo.so</code>이지만)
    파일의 확장자는 자유롭다. 이 파일들은 보통 프로그램 자체 디렉토리에
    위치하고 실행프로그램에 자동으로 연결되지 않는다. 대신 실행프로그램은
    <code>dlopen()</code>을 사용하여 DSO를 실행시 주소공간에 직접
    읽어들여야 한다. 이때 실행프로그램은 DSO에서 심볼을 찾지 않는다.
    대신 유닉스 로더가 자동으로 실행파일과 실행파일이 이미 읽어들인 DSO
    라이브러리(특히 항상있는 <code>libc.so</code>의 모든 심볼)에서
    DSO의 (아직 못찾은) 심볼을 찾는다. 그래서 DSO는 마치 처음부터
    실행프로그램에 정적으로 링크된것과 같이 실행파일의 심볼을
    알게된다.</p>

    <p>DSO의 API를 이용하기위해서 마지막으로 실행프로그램은
    <code>dlsym()</code>로 DSO에서 특정 심볼을 찾아서,
    앞으로 사용하기위해 디스패치(dispatch) 표 <em>등</em>에
    저장한다. 다른 말로 실행프로그램은 사용할 모든 실볼을 직접
    찾아야한다. 이런 구조의 장점은 프로그램의 선택적인 일부을
    프로그램이 필요할때까지 읽어들이지 않아도 (그래서
    메모리를 낭비하지 않게) 된다는 점이다. 기본 프로그램의 기능을
    확장하기위해 필요할때 이 부분을 동적으로 읽어들일 수 있다.</p>

    <p>이런 DSO 구조가 자연스럽게 보이지만, 최소한 어려운 점이
    하나있다. 이는 프로그램을 확장하기위해 DSO를 사용할때
    DSO가 실행프로그램의 심볼을 찾는 일이다. 왜? DSO가 실행프로그램의
    심볼을 "역으로 찾는 것"은 (라이브러리는 사용되는 프로그램에 대해
    모른다는) 라이브러리 설계에 반하며, 모든 플래폼에서 지원되지
    않고 표준화되지도 않았기 때문이다. 실제로 실행파일의
    전역심볼(global symbol)은 자주 익스포트(export)되지 않기때문에
    DSO가 사용할 수 없다. DSO를 사용하여 실행중 프로그램을 확장하려면
    링커에게 모든 전역심볼을 익스포트하도록 강제하는 것이 주요한
    해결책이다.</p>

    <p>공유라이브러리는 DSO 구조를 위해 설계되었기때문에 전형적이고,
    운영체제가 제공하는 거의 모든 종류의 라이브러리에 사용된다.
    반대로 많은 프로그램은 프로그램을 확장하기위해 공유객체를
    사용하지 않는다.</p>

    <p>1998년 실행중 실제로 기능을 확장하기위해
    DSO 구조를 사용한 소프트웨어 패키지는 (XS 구조와 DynaLoader 모듈을
    사용한) Perl 5, Netscape Server <em>등</em>으로 드물었다.
    아파치는 이미 기능을 확장하기위해 모듈 개념을 사용했고 외부
    모듈을 아파치 핵심기능에 연결하기위해 내부적으로 디스패치목록을 이용한
    접근방법을 사용했기때문에 1.3 버전부터 여기에 합류했다. 그래서
    아파치는 실행중 모듈을 읽어들이는데 DSO를 사용하도록 운명지워졌다.</p>

    <h2><a id="advantages" name="advantages">장단점</a></h2>

    <p>앞에서 말한 DSO를 사용하면 다음과 같은 장점이 있다:</p>

    <ul>
      <li>실제 서버 프로세스가 컴파일시 <code>configure</code>
      옵션대신 <code>httpd.conf</code>의 <a
      href="mod/mod_so.html#loadmodule"><code>LoadModule</code></a>로
      실행중에 결합되므로 서버 패키지가 실행시 더 유연하다. 예를 들어 
      한번의 아파치 설치만으로 다른 서버(표준 버전과 SSL 버전, 최소화 버전과
      기능추가 버전 [mod_perl, PHP3] <em>등</em>)를 실행할 수 있다.</li>

      <li>서버는 설치후에도 제삼의 모듈로 쉽게 확장이 가능하다.
      최소한 기업의 패키지 제작자는 아파치 핵심 패키지와 별도로 PHP3, mod_perl,
      mod_fastcgi 등을 추가 패키지로 만들 수 있어서 큰 이득이 된다.</li>

      <li>DSO와 <code>apxs</code>를 가지고 아파치 소스 트리
      밖에서 작업하고 <code>apxs -i</code>와
      <code>apachectl restart</code> 명령어만으로 현재 개발한
      모듈의 새 버전을 실행중인 아파치 서버에 반영할 수 있어서 더 쉽게
      아파치 모듈을 개발할 수 있다.</li>
    </ul>

    <p>DSO는 다음과 같은 단점이 있다:</p>

    <ul>
      <li>프로그램의 주소공간에 코드를 동적으로 읽어들이는 기능을
      지원하지않는 운영체제가 있기 때문에 모든 플래폼에서 DSO를
      사용할 수 없다.</li>

      <li>서버는 시작시 약 20% 정도 늦다.
      because of the symbol resolving overhead the Unix loader now
      has to do.</li>

      <li>서버는 위치독립코드(position independent code, PIC)때문에
      절대주소지정(absolute addressing)만큼 빠르지 않는 상대주소지정(relative
      addressing)의 복잡한 어셈블러 기법이 필요하므로 어떤 플래폼에서
      실행시 약 5% 정도 늦다.</li>

      <li>DSO 모듈이 다른 DSO기반 라이브러리(<code>ld -lfoo</code>)에
      링크할 수 없는 플래폼이 있기때문에 (예를 들어 ELF기반 플래폼은
      지원하지만 a.out기반 플래폼은 보통 이 기능을 지원하지 않는다)
      모든 종류의 모듈에 DSO를 사용할 수 없다. 다른 말로
      DSO 파일로 컴파일되는 모듈은 아파치 핵심과 아파치 핵심이
      사용하는 C 라이브러리(<code>libc</code>)와 다른 동적/정적
      라이브러리, 위치독립코드를 담고 있는 정적 라이브러리
      아카이브(<code>libfoo.a</code>)의 심볼만을 사용할 수 있다.
      다른 코드를 사용하는 방법은 아파치 핵심이 그것을 참조하던지,
      <code>dlopen()</code>으로 직접 코드를 읽어들이는 것이다.</li>
    </ul>
        <hr />

    <h3 align="center">Apache HTTP Server Version 2.0</h3>
    <a href="./"><img src="images/index.gif" alt="Index" /></a>



  </body>
</html>

