레이블이 아. 리눅스 어려워인 게시물을 표시합니다. 모든 게시물 표시
레이블이 아. 리눅스 어려워인 게시물을 표시합니다. 모든 게시물 표시

2009년 4월 1일 수요일

MSSQL에서 limit(mysql의 from, to) 기능 사용방법

mysql

"select * from t_name limit 0, 1000"

MSSQL

"select row_number() as rownum, * from t_name  where rownum BETWEEN 0 and 1000"


mysql

"select * from t_name limit 3, 1000"

MSSQL

"select row_number() as rownum, * from t_name where rownum BETWEEN 3 and 3+1000"

2008년 1월 5일 토요일

Tomcat5 + Mysql + Apache + PHP 한글 신경 안쓰고 설치하기(대박)

Apache의 Tomcat ... 젠장
완전 깡패(Apache)에 양아치(Tomcat:여자뒤를 졸졸 따라다니는 남자)같은 놈들이다.
이놈들과 씨름한지 사흘째... 결국 결론을 찾았다.

첫째날..
Tomcat5를 Fedora6에 설치했다. Manager까지 띄우고 나서 설치할려고 하는 Web Application이 컴파일이 안되서 하루를 잡아먹었다.... 결국 컴파일 성공

둘째날
설치한 Web Applicaion과 MySQL 사이에 한글 에러가 나서 하루를 잡아먹었다.... 결국 GG...

셋째날
한글문제를 해결할 방법을 찾아내다... 여러분 더 이상 고민하지 마라... 간단한 길이 있다...
정답은 바로... Redhat... 그것도 9..   Enterprise Edition 아니다.  Redhat9.. kernel 2.4

지금 부터 설명하는건 회사 웹서버 설치 방법이 아니다....
그냥 개인적인 서버 돌릴때나 써먹어라..
그리고 redhat9 쓴다고 비웃는 사람들... 다시는 내 블로그 오지마라.

그럼 시작해볼까..

Step1. Redhat9 을 설치한다. kaist 서버에 가면 있다. 속도도 빠르고... CD 3장 밖에 않한다.
설치 옵션은 webserver + ftpserver + 편집기 + 개발용도구(gnu-java 제외) + mysql
그렇다... 기본적인 mysql 쓴다. 3.x 버전인데 쓸만하다. 서브쿼리는 안되지만...
위에도 말했듯이 개인적인 서버 꾸밀때 쓰는 방법이다. 물론 노력하면 4.x 버전으로 설치 할 수 있다. 그건 다른 사람이 쓴 글 보고 연구하기 바란다.

Step2. 세팅 시작
-- 리눅스의 한글 설정 확인 vi /etc/sysconfig/i18n
-- 첫번재 줄에 LANG="ko_KR.eucKR" 로 설정되어 있다면 pass 그렇지 않다면 설정하고 저장
-- setup에 가서 mysqld, vsftpd, httpd 을 시스템 서비스 자동시작으로 바꿔준다

Step3. JAVA SDK 설치
-- java.sun.com 으로 가서 jdk-6u3-linux-i586.bin을 다운로드 받는다. 버전에 따라 파일명이 약간 다를 수 있다.
--  /usr/local/src 로 jdk-6u3-linux-i586.bin을 복사한다.
-- %cd /usr/local/src
-- sh jdk-6u3-linux-i586.bin
-- 압축이 다 풀리면  %cp -R jdk1.6.0_03 ../jdk

Step4. ant 설치
-- www.apache.org 로 가서 apache-ant-1.7.0-bin.tar.gz 다운로드
-- Ant가 뭔지 궁금한 사람은 따로 찾아보도록 하고 java에서 쓰는 make 라고 생각하면 된다.
-- /usr/local/src로 복사
-- %cd /usr/local/src
-- %tar xfz apache-ant-1.7.0-bin.tar.gz
-- cp -R apache-ant-1.7.0 ../ant

Step5. tomcat 설치
-- www.apache.org로 가서 /apache-tomcat-5.5.25.tar.gz 다운로드
-- /usr/local/src로 복사
-- %tar xfz apache-tomcat-5.5.25.tar.gz
-- %cp -R apache-tomcat-5.5.25 ../tomcat

Step6. 환경변수 설정
자 여기까지 왔으면 벌써 5개 설치됐다. httpd, mysqld, jdk, ant, tomcat....
명령 몇개 쳤는데 벌써 다 됐다. 이제 환경변수 설정해줘야 한다.
우리가 하는건 편한 윈도가 아니고 리눅스이기 때문에 이런거 다 해줘야 한다.
귀찮으면 윈도 써라... 처음부터 끝까지 마우스로만 설치해도 되는거 많다.
% vi /etc/profile
가장 아랫 줄로 가서
JAVA_HOME=/usr/local/jdk
export JAVA_HOME
ANT_HOME=/usr/local/ant
export ANT_HOME
CATALINA_HOME=/usr/local/tomcat
export CATALINA_HOME
PATH=$PATH:$JAVA_HOME/bin:$ANT_HOME/bin
export PATH
CLASSPATH=$CLASSPATH:$JAVA_PATH/lib:$CATALINA_HOME/common/lib
export CLASSPATH
추가 한 다음 저장하고 나온다.
환경변수 적용 : % source /etc/profile

Step7. Tomcat 설정
cd /usr/local/tomcat/conf
vi tomcat-user.xml
<tomcat-users> 태그 안에  
<user name="admin"  password="admin"  roles="admin, manager" /> 추가
이렇게 추가하면 tomcat manager 에 admin//admin 으로 로그인 가능하다.
저장하고 나와서 톰켓을 실행한다.
$CATALINA_HOME/bin/startup.sh
경로들이 제대로 나오면서
http://server_ip:8080 으로 접속해서 tomcat manager 화면이 나오면 성공
----------------------------------------------------------------------------------
정리하면서...
Tomcat 자체가 너무 생소했고... 아파치 http 와는 차원이 다른 한글문제 등으로 오랜동안
좌절했다... redhat9 의 경우 설치부터 eucKR 로 설치 하기 때문에 unicode -> eucKR 에서 생기는 문제점을 해결 가능하다. 하지만 커널 버전이 낮기 때문에 사람들이 선호하지 않는다.
근본적으로 한글 문제를 해결하기 위해서는 모든 페이지를 unicode로 만드는 것이다.

지금 설정으로는 80포트로는 php, 8080 포트로는 jsp 서비스가 가능하다. 80 포트로 php와 jsp 동시에 서비스 하기 위해서는 jakarta-connection 설정을 하면 된다. 이부분에 대해서는 각자 찾아보길 바란다. 내 생각으로는 방문자가 많지 않은 홈페이지에서는 아파치 서버와 꼭 연결할 필요없이 tomcat을 80으로 세팅해서 쓰는 방법도 괜찮을것 같다. 사람들이 말하길 아파치가 성능이 좀 좋다고 하는데 그거야 엄청난 방문자들이 들어올때 이야기고 아파치가 jsp를 처리한다고 해서 tomcat이 돌지 않아도 된다는 얘긴 아니다. 그리고 한 서버에서 php와 jsp를 동시에 돌리는 것은 별로 좋은 방법이 아니라고 본다.

2008년 1월 4일 금요일

javax.servlet.jsp does not exist 문제해결

톰캣을 설치하고 나서

몇날 몇일을 고생하게 만들었다.

다음과 같이 해결

JAVA_HOME=/usr/local/jdk1.6.0
ANT_HOME=/opt/SDK/lib/ant
CATALINA_HOME=/usr/local/apache-tomcat-5.5.25
export CATALINA_HOME
export ANT_HOME
export JAVA_HOME
PATH=$PATH:$JAVA_HOME/bin:$ANT_HOME/bin
CLASSPATH=$CLASSPATH:$JAVA_HOME/lib/tools.jar:
                  $CATALINA_HOME/common/lib/servlet-api.jar:
                  $CATALINA_HOME/common/lib/jsp-api.jar:
                  $CATALINA_HOME/webapps/ROOT/WEB-INF/classes

Set Default JAVA with SUN JAVA in Fedora 5,6,7

Fedora Core developers make it rather hard to install and properly configure Sun’s JVM. All said and done Sun’s JVM (comes with JDK) is the best JVM implementation out there; not to mention that it is the reference implementation. Here is how you can easily install JDK 6 / Java SE 6 in 5 minutes or less. Here are the steps:

1. Login as root

2. First you need to download it from here. This works fine from GUI browsers like Firefox, Internet Explorer or Safari. However Sun makes it very hard (from java.sun.com) to download it for Linux console users (like those trying to install on their dedicated web server). You cannot access the download link from text based lynx browser. Fortunately there is a way. I found a secret location for you to easily download JDK 6 using wget or curl (console apps). This is also very useful if you are planning to use any download accelerators. The current binary (32 bit version) is here. This link will surely change with time so it is better to browse to the link above and then access this link from that page.

Download it using wget or curl. The command, for example, today will be:
wget http://www.java.net/…/jdk-6u2-ea-bin-b02-linux-i586-12_apr_2007-rpm.bin

Note: The link has been truncated for brevity, however it is hyperlinked to the actual link.

3. Now change the permission of the downloaded file to 755 like this:
chmod 755 jdk-6u2-ea-bin-b02-linux-i586-12_apr_2007-rpm.bin

4. Then run it:
./jdk-6u2-ea-bin-b02-linux-i586-12_apr_2007-rpm.bin

You will need to type yes to indicate your acceptance to their agreement and the installation will complete on its own. Unfortunately you are not yet done. Type java -version on the command line and you will see that it still points to the crappy old JVM from gcj.

5. Now you need to find the actual location of your JDK installation and indicate to Fedora to accept your choice.

Type the following:
updatedb;locate javac |grep bin

You will see an entry like this:
/usr/java/jdk1.6.0_02/bin/javac

Here /usr/java/jdk1.6.0_02 is the actual JAVA_HOME for your machine. Note this as you will need it to run the future commands.

Now you need to run the alternatives command to instruct Fedora to recognize Sun’s JVM.
alternatives --install /usr/bin/java java /usr/java/jdk1.6.0_02/bin/java 100
alternatives --install /usr/bin/jar jar /usr/java/jdk1.6.0_02/bin/jar 100
alternatives --install /usr/bin/javac javac /usr/java/jdk1.6.0_02/bin/javac 100

You can do this for other Java executables too, should you need them, following the same pattern.

Note: If alternatives is not in your path then use locate alternatives to locate it.

Finally you should configure alternative to use Sun’s JVM as the default JVM. To do this type:
/usr/sbin/alternatives --config java

This will present you with at least 2 options. Choose the one for Sun’s JVM. Similarly repeat the process for other commands.

Now you are done configuring Fedora for the most part. Type java -version and you should see something like this:

java version “1.6.0_02-ea”
Java(TM) SE Runtime Environment (build 1.6.0_02-ea-b02)
Java HotSpot(TM) Client VM (build 1.6.0_02-ea-b02, mixed mode, sharing)

Note: This works for most part, except Tomcat. The default installation of Tomcat has been hardwired to use GCJ. I changed the configuration file and it didn’t help. My solution for Tomcat is to ditch Fedora’s version and install directly from site. It works like a charm. Set JAVA_HOME to the value we found above and you are done.

FC6에 APM+Oracle+Tomcat+Resin 설치

어제 하나로 IDC 가서 페도라6 으로 갈아 치웠다.
대략 14시간의 삽질 끝에 모든 설치를 성공하고 이렇게 글을 남겨 본다.
Apache2.2 + PHP5 + MySQL5 + Tomcat6 + Resin3.1 + Oracle10g + JDK1.6 설치 가이드.
아마 가장 최신의 패키지들을 설치한것이 아닐까 하는 생각이 든다.
거두 절미하고 본격적으로 시작하니 잘 따라해보자.

모든 설치는 putty, realvnc를 이용하여 설치했다.
realvnc 설정 가이드도 있으니 무시하지 끝까지 보고 따라해보자.


1. APM 설치
Apache2.2 + PHP5 + MySQL5 는 RPM 패키지로 설치한다.
아마 대부분 설치가 됐을것이므로 자세한 가이드는 패스한다.

2. 페도라6 처음 설치시 해주면 좋은것들..
bash$> updatedb

mlocate를 사용할때 캐쉬를 이용한다.
페도라6 처음 설치 시 이 캐쉬파일이 없어 locate가 동작하지 않을것이니 앞으로의 편의를 위해 캐쉬를 만들어주자.


3. 필요없는 자바, 톰캣 관련 패키지 삭제
우리는 현재 최신버전의 JDK 1.6 을 설치할 것이다.
하지만, 페도라6 는 GNU 버전의 JDK1.4.2 를 기본 패키지로써 제공하고 있다.
구버전은 안키운다. 삭제해주자.
또한, 페도라6에서 기본적으로 설치되는 톰캣은 5.5 다.
구버전은 안키운다. 삭제해주자. (-_-)

bash$> yum -y remove tomcat\*
bash$> yum -y remove \*java\*

톰캣을 삭제하면 종속성에 의해 이클립스가 삭제된다.
뭐 필요없다 페도라6 에서 제공하는 이클립스는 3.1 이다.
이클립스 3.2 는 나중에 따로 가이드를 올리겠다.
앞에 \ 는 역슬러시다 java 라는 단어가 들어간 패키지명은 모두 삭제한다.
조금 시간이 걸릴것이므로 느긋하게 기다린다.


4. 필수 패키지 설치
앞으로 진행을 편히하기 위해 필요한 모든 패키지를 설치하고 가자.

bash$> yum -y install httpd-devel php-mysql libXp-devel libXp perl

httpd-devel: apxs mod_jk의 동적 모듈 컴파일을 위해
php-mysql: php에서 mysql에 연결하기 위해
libXp, LibXp-devle: 오라클 설치 때 필요한 openmotif 패키지 때문에..
perl: 펄은 대부분 설치 되었겠지만 없으면 설치해야한다.

-y 옵션은 모두건 yes 한다는거다.
뭐뭐 설치되는지 구경하고 싶으면 -y 옵션을 빼자

우선 필요한 패키지들을 설치해준다.
이젠 openmotif21-2.1.30-14.i386.rpm 를 설치해야 한다.
첨부된 파일을 다운로드 받고 압축을 풀면 openmotif21-2.1.30-14.i386.rpm 파일이 나온다.
적당히 서버에 업로드하고

bash$> rpm -Uvh openmotif21-2.1.30-14.i386.rpm

이젠 오라클 설치에 필요한 패키지를 설치해야한다.
아래 패키지는 꼭 설치해 주도록 하자.

bash$> yum -y install setarch-\* tcl-\* libXau-devel-\* libXp-\* compat-db-\* compat-db-\* compat-libstdc++-33\* compat-libf2c-34-\* compat-gcc-34-\* libaio-* compat-gcc-34-c++-\* compat-libstdc++-296\* compat-libgcc-296\*

여기서 중요한건 띄어쓰기다. 잘보고 한줄에 모두 입력하도록 한다.
너무 길어서 쓰기 힘들면 긁어다 입력하자. 다시한번 말하지만 \ 는 역슬러시다.

필수 패키지 설치가 끝났다.
이제 본격적으로 설치에 들어간다.


5. JDK 1.6 설치
첨부된 파일 중에 jdk-6-linux-i586.bin 이 있다.
이상한 사이비 사이트에서 받은것이 아닌, sun사 홈페이지에 직접 다운로드한 jdk 1.6 이므로 안심하고 설치하자. 뭐 못믿겠으면 직접 sun사 홈페이지가서 받아도 된다.

적당히 업로드하고 실행시켜서 설치해준다.
중요한건 설치할때 해당 경로에서 jdk1.6.0 이란 디렉토리를 만들면서 설치 된다.
그러니 반드시 내가 설치를 원하는곳으로 파일을 이동시켜서 설치하자
본인은 /usr/local 로 이동시켜서 아래 명령을 실행했다.
본인의 jdk 경로 (JAVA_HOME)은 /usr/local/jdk1.6.0 이 되겠다.

bash$> sh jdk-6-linux-i586.bin

요래요래 해주면 일단 jdk 가 설치 된다.
이제 각종 환경 변수들을 쌔려 줘야 한다.
글로벌하게 적용되야 하니 /etc/profile 맨 마지막에 적당히 추가해주자.

bash$> vi /etc/profile

JAVA_HOME=/usr/local/jdk1.6.0
export JAVA_HOME
PATH=$PATH:$JAVA_HOME/bin
CLASSPATH=$CLASSPATH:$JAVA_HOME/lib
export PATH

여기서 JAVA_HOME, CLASSPATH 를 자신이 JDK를 설치한 경로로 적어줘야한다.
먼말인지 모르겠다면 앞으로 이 가이드를 따라올 수 없는것이니 일찌감치 포기하자.

추가해 줬으면 이제 putty 를 종료하고 다시 서버로 접속한다.
그래야만 위 환경변수가 적용된다.



5. Resin 3.1 설치
이제 레진을 설치해보자.
레진 또한 첨부 파일에 보면 resin-3.1.0.tar.gz 파일이 있다.
참고로 레진이랑 톰캣은 소스가 아니라 바이너리다.
즉, 압축만 풀면 바로 쓸 수 있는것이다.
하지만 약간의 설정이 필요하니 잘 따라오도록 하자.
본인은 /usr/local/etc 로 resin-3.1.0.tar.gz 파일을 이동시키고 압축을 풀었다.

bash$> tar xvzf resin-3.1.0.tar.gz

뭐 압축풀면 끝이다.
하지만 아파치와의 연동을 위해 환경설정과 컴파일을 한번 때려줘야 한다.
레진 디렉토리로 이동 후..

bash$> cd resin-3.1.0
bash$> ./configure --with-apache=/usr/include/httpd

요로코롬 해준다.
이게 뭐냐면 레진이 아파치랑 연동하기 위해 아파치 라이브러리를 참조하기 때문이다.
완료가 되면 아래 명령을 바로 때려주자.

bash$> make all
bash$> make install


요래 해주면 caucho_module.so 동적 라이브러리 모듈이 생성되고 자동으로 httpd.conf 에 넣어준다. 레진이 이래서 조낸 좋은거다.

이제 httpd.conf 파일을 열어서 추가가 됐는지 확인해보자

bash$> vi /etc/httpd/conf/httpd.conf

파일 맨 마지막에

LoadModule caucho_module /usr/lib/httpd/modules/mod_caucho.so
ResinConfigServer localhost 6802
CauchoConfigCacheDirectory /tmp
CauchoStatus yes

요렇게 추가가 된게 보일것이다.
하지만 바로 지워준다.

왜? 아래 따로 include 해서 쓸것이기 때문이다.
싫으면 걍쓰도록한다. 하지만 나중에 다른 버철호스트에도 레진이 영향을 받아 웹페이지가 안열리는 현상이 발생할 수도 있다.
그러니 왠만하면 본 가이드를 그대로 따라하자
본인은 다 나중에 편하고, 좋자고 하는것이지 막 각종 편법들을 남발해가면서 일단 설치만 되면 땡이지 하는건 딱 질색이기 때문이다.

이걸로 바로 사용할 수 있지만.. 간단하게 버철호스트랑 레진의 호스트와 차후 톰캣 설치 시 mod_jk 와 손쉽게 바꿔가며 사용할 수 있게 하기 위해 별도의 conf 파일로 만들어 준다.
아래처럼 따라해보자.

bash$> cd /etc/httpd
bash$> mkdir conf.custom
bash$> vi resin.conf


따로 include 해서 레진과 톰캣을 손쉽게 바꿔가면 쓰기 위한것이다.
vi resin.conf 한다음 아까 위에 지웠던 내용을 입력해준다. (-_-) (방금 욕하는 소리가 들렸다.)

LoadModule caucho_module /usr/lib/httpd/modules/mod_caucho.so
ResinConfigServer localhost 6802
CauchoConfigCacheDirectory /tmp
CauchoStatus yes

요래 하고 저장해주자.
설마 저장하는 법을 모르는 사람이 있을까봐 알려준다.
vi 편집기 상태에서  :wq! 라고 입력하고 엔터치면 된다.

참고로 아래 버철호스트는 newal.net 의 예제 이다.
자신에게 맞게 적당히 수정해주는 센스가 필요하다.
newal.net 이 돌아가는 DocumentRoot 는 /home/newal/www 이다
이 디렉토리 안에 index 파일이 존재한다. (에이 보안상 안좋은데.. 그래도 다 알려준다.)

NameVirtualHost 222.237.78.65

<VirtualHost 222.237.78.65>
   ServerAdmin newal@newal.net
   DocumentRoot /home/newal/www
   ServerName newal.net
   ServerAlias www.newal.net
   DirectoryIndex index.jsp index.php index.html index.htm
   ErrorLog logs/error_newal.net
   CustomLog logs/access_newal.net common

  # 레진을 사용하기 위해..
   Include conf.custom/resin.conf

  # 테터툴즈 사용을 위해..
   <Directory /home/newal/www>
       Options FollowSymLinks
       AllowOverride FileInfo
   </Directory>
</VirtualHost>

자 Include conf.custom/resin.conf 보이지 않는거 바로 이 버철호스트에서만 레진을 쓰겠다는것이다.

다른 버철호스트에도 레진을 적용하고 싶으면 그냥 Include conf.custom/resin.conf 요 문구만 갔다 붙여넣기 해주면 된다. 조낸 좋지 않은가?

자 이제 레진의 호스트를 잡아줘야 한다.

bash$> cd /usr/local/etc/resin-3.1.0/conf
bash$> vi resin.conf


아래 부분을 추가해줘야하는데 어디다 하는지 모를것이다.
자세하게 알려주겠다.
대략 250번째 라인을 보면 Configuration for the web-tier/load-balancer 주석이 보인다.
뭐 약간 틀릴 수도 있으니 +- 20줄 내에서 잘 찾아보자.

이 주석 바로 위에 </cluster> 가 보일것이다.
</cluster> 위에다가 추가해주면 된다.
아래가 아니라 위에다 추가하는것이다. 잘보고 추가 하자.

    <host id="newal.net" root-directory=".">
      <web-app id="/" root-directory="/home/newal/www"/>
      <web-app id="/resin-admin" root-directory="${resin.home}/php/admin">
        <prologue>
          <resin:set var="resin_admin_password"  default=""/>
          <resin:set var="resin_admin_localhost" default="true"/>
        </prologue>
      </web-app>
    </host>

잘 보면 root-directory 가 아파치에서 적은 DocumentRoot 와 일치하는것을 볼 수 있다.
당연하지만 레진이 도메인이 newal.net 일때 /home/newal/www/index.jsp 파일을 읽을 것이다.

자 이제 끝났다.
레진을 시작시켜 보자.

bash$> cd /usr/local/etc/resin-3.1.0/bin
bash$> sh httpd.sh start


요래 해주면 레진이 시작 된다. 뭐 한줄 나오고 끝이다.
이제 바로 아파치를 재시작 해준다.

bash$> /etc/init.d/httpd restart


이제 /home/newal/www 디렉토리에 index.php 파일을 만들고 파일 내용은 아래처럼 한다.

<?
phpinfo();
?>

또하나 index.jsp 파일을 만들고 내용은 아래처럼 한다.

<%
out.println("Hello World");
%>


위와 같이 대충 만들어놓고 브라우저에서 접근해보자

http://newal.net/index.php
http://newal.net/index.jsp

php정보가 나오고, Hello World 가 뜨면 성공한것이다.



더 쓰고 싶은데 귀찮아서 여기까지 쓰고 나머지는 다음에 쓰겠다..



출처 : http://newal.net/

2007년 12월 14일 금요일

Linux Tomcat 설치

다음은 생전 처음으로 리눅스에 톰캣을 설치한 내용을 적은 메모이다.



톰캣 다운로드

다운로드 URL : http://tomcat.apache.org/

위의 URL에서 톰캣을 다운받는다.

이 문서에서는 apache-tomcat-5.5.17.tar.gz 를 다운받았다.



톰캣 설치

다운 받은 apache-tomcat-5.5.17.tar.gz를 /usr/local/src 로 옮겼다.

#tar xvfz apache-tomcat-5.5.17.tar.gz [enter]

/usr/local/src/apache-tomcat-5.5.17 디렉토리가 생기고 그 안에 톰캣이 깔린다.

이 디렉토리를 /usr/local 로 옮겼다.

#mv apache-tomcat-5.5.17 /usr/local [enter]



톰캣 실행

# cd /usr/local/apache-tomcat-5.5.17/bin [enter]
# ./startup.sh [enter]



톰캣 실행 확인

브라우저에서 http://192.168.0.2:8080 를 넣어 고양이가 나오는지 확인




톰캣 관리화면 활성화 시키기

다음 파일을 편집한다.
# vi /usr/local/apache-tomcat-5.5.17/tomcat-users.xml [enter]

다음 내용을 추가시킨다.
<role rolename="manager"/>
<user username="admin" password="admin" roles="manager"/>

톰캣을 다시 재실행한다.

#/usr/local/apache-tomcat-5.5.17/bin/shutdown.sh [enter]
#/usr/local/apache-tomcat-5.5.17/bin/startup.sh [enter]


톰캣 관리화면을 열어본다.

브라우저에서 http://192.168.0.2:8080/manager/html
ID : admin
Password : admin



톰캣 클래스패스 설정하기

#vi /etc/profile [enter]

다음 내용을 넣는다.(주로 가장 마지막에...)
CATALINA_HOME="/usr/local/apache-tomcat-5.5.17"
export CATALINA_HOME
CLASSPATH=".:$CATALINA_HOME/lib/servlet.jar"
export CLASSPATH


* 위에서 CLASSPATH의 경우는 이미 CLASSPATH가 정해져 있다면
  처음에 $CLASSPATH를 넣어주거나
  기존의 CLASSPATH 정의부분의 뒤쪽에 이어서 입력해 준다.

저장하고 나온 후
#source /etc/profile [enter]


---- 참고 ----
http://cafe.naver.com/bestreal.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=221

2007년 12월 12일 수요일

Fedora 4 YUM 설정

출처 : http://iparid.egloos.com/1709753

yum.repo.d 설정 (FC4)
/etc/yum.conf 설정은 레뎃9 시절 등등 예전 자료가 많았지만, FC3부터 /etc/yum.repos.d/* 여섯개의 파일로 분산되면서 새로운 설정 방법을 설명한 곳을 한참 뒤져보았다. 인터넷에서는 한 군데 FC3 기준으로 설명해 놓았다. 요걸 보고 조금 고쳐서 FC4에 맞게 설정하는 법, 또 원리 등등을 조금 적어 보겠다.

원래 들어있는 파일은 6개다.

fedora.repo
fedora-devel.repo
fedora-extras-devel.repo
fedora-extras.repo
fedora-updates.repo
fedora-updates-testing.repo

여기에서 인스톨에 fedora.repo, 업데이트에 fedora-updates.repo를 쓴다. 일단 요것만 고쳐보자.

<원본 fedora.repo>
name=Fedora Core $releasever - $basearch - Base한글
#baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/$releasever/$basearch/os/
mirrorlist=http://fedora.redhat.com/download/mirrors/fedora-core-$releasever
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora


baseurl에 주석 처리가 되어있으니 결국 mirrorlist 행이 관건인 셈이다. $releasever는 자기 페도라 버전에 따라 현재까지 1~5로 나타난다. 그럼 주소에 나와 있는 fedora-core-4 파일을 열어보자.

http://download.fedoraproject.org/pub/fedora/linux/core/4/$ARCH/os/
http://mirror.linux.duke.edu/pub/fedora/linux/core/4/$ARCH/os/
http://fedora.mirrors.tds.net/pub/fedora-core/4/$ARCH/os/
...
...


가능한 미러가 66개 나와있다. 그런데 제일 느린 서버가 1순위이므로 접속은 되지만 느려터져 답답하다. 따라서 커스텀 미러 리스트 파일을 작성하자. Updates가 들어있는 디렉토리 주소가 조금 다르다. 한국 서버가 가장 빠르기는 하지만 이 포스트를 작성하는 시점에서 404 에러를 토했기 때문에 속도는 조금 떨어져도(200-500kB/s 정도) 믿음직스러운 kernel.org를 1순위로 잡았다.

<custom-BASE>
http://mirrors.kernel.org/fedora/core/4/$ARCH/os
ftp://ftp.kreonet.re.kr/pub/Linux/fedora/core/4/$ARCH/os
ftp://mirror.hostway.co.kr/pub/fedora/4/$ARCH/os
ftp://ftp.kaist.ac.kr/pub/fedora/linux/core/4/$ARCH/os


<custom-UPDATES>
http://mirrors.kernel.org/fedora/core/updates/4/$ARCH
ftp://ftp.kreonet.re.kr/pub/Linux/fedora/core/updates/4/$ARCH
ftp://mirror.hostway.co.kr/pub/fedora/updates/4/$ARCH
ftp://ftp.kaist.ac.kr/pub/fedora/linux/core/updates/4/$ARCH


그럼 fedora.repo, fedora-updates.repo 기존의 mirrorlist를 주석처리하고, 새로운 주소로 설정하자.
gpgcheck도 꺼놓으면 성가시지 않다.

<고친 fedora.repo>
mirrorlist=file:///etc/yum.repos.d/custom-base
gpgcheck=0


<고친 fedora-updates.repo>
mirrorlist=file:///etc/yum.repos.d/custom-updates


다시 실행할 서비스 없이 다음에 yum 실행할 때 바로 적용된다.

2007년 2월 13일 화요일

MySQL 백업

mysqldump 사용



syntax

# mysqldump [options] database [tables]
# mysqldump [options] --databases [options] db1 [db2 db3...]
# mysqldupm [options] --all-databases [options]

1. 모든 DB 백업하기

# mysqldump -u root -p -A > all.sql

2 특정 DB만 백업하기

# mysqldump -u root -p testdb > testdb.sql

3. 원하는 DB 만 골라서 백업하기

# mysqldump -u root -p --databases testdb1 testdb2 > testdb.sql

4. 특정 테이블만 백업하기

# mysqldump -u root -p test sutdent > test_student.sql

2006년 4월 4일 화요일

GRUB 부트로더에서 새로 컴파일한 커널올리기

출처 : http://infoncom.dongguk.ac.kr/%7Eswhong/cgi-bin/MoinMoin/wiki-moinmoin/ 

GRUB 부트로더에서 새로 컴파일한 커널올리기

커널을 건드리기 시작했다. 필자는 lilo를 사용해 새로 컴파일한 커널을 사용하기 위해 lilo.conf를 수정하는데는 익숙하지만,

GRUB을 사용해보지는 않았다. 커널을 수정하기 전에 GRUB 설정을 수정하는 방법을 소개한다.

/boot/grub

이 디렉토리에 가보면 (grub을 설치했다면) grub.conf 파일이 있다. 필자는 윈도우XP를 깔고, RHL9.0을 깔아 GRUB으로 멀티 부팅을 시켰다.

이제 새로운 커널을 컴파일해 보자. /usr/src/linux 에서 make (mrproper | clean | bzImage | modules | modules_install) 을 차례로 수행한다.

이제 /usr/src/linux/arch/i386/boot/bzImage 를 복사해서 /boot 디렉토리 밑으로 가져와 원하는 이름으로 바꾸자. 필자는 vmlinuz-2.4.20-test 라는 이름으로 복사했다.

그리고 나서 initial ramdisk를 만들어야 한다. 이것은 GRUB이 lilo와는 틀리게 1024 cylinder를 극복하기 위한 방안이다. 즉, bios에서 1024 cylinder주소값 이상을 가르치지

못함으로 해서 1024내에 적재된 boot partition만 인식할 수 있었던 것을 initial ramdisk안에서 좀더 넓은 boot partition address를 인식하기 위해 사용한다.

이때 initrd안에는 모듈이 포함되게 되는데, 커널 컴파일시 make modules; make modules_install; 을 수행하면 /lib/module/2.4.20 과 같이 커널 버전의 이름으로 모듈 디렉토리가 생긴다.

하지만, 기존에 있던 모듈을 덮어쓰지 않기 위해 /lib/module/2.4.20custom 이라는 디렉토리가 생기더라는 것이 중요하다.

이제 우리는 이 모듈들을 포함하여 initial ramdisk를 만들어야 하는데, 다음과 같이 생성한다.

mkinitrd target-file.img source-directory

즉, 필자는 initrd-2.4.20-test.img 라는 이름을 가진 initial ramdisk를 만들기 위해 다음과 같이 명령을 수행했다.

mkinitrd inird-2.4.20-test.img 2.4.20custom

자 이제 /boot 디렉터리안에 initrd-2.4.20-test.img가 생성되었을 것이다.

이제 새로운 커널로 부팅할 수 있도록 grub의 설정파일을 건드려 보자. grub의 설정파일은 /boot/grub/grub.conf 이다.

필자가 수정하기 전의 필자의 머쉰(windxp 와 redhat9.0 가 깔려있는)의 grub.conf는 다음과 같았다.

# grub.conf generated by anaconda #
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,5)
# kernel /vmlinuz-version ro root=/dev/hda9
# initrd /initrd-version.img
# boot=/dev/hda
default=2
timeout=10
fallback 0
splashimage=(hd0,5)/grub/splash.xpm.gz

title Red Hat Linux (2.4.20-8)
root (hd0,5) kernel /vmlinuz-2.4.20-8 ro root=LABEL=/ hdc=ide-scsi
initrd /initrd-2.4.20-8.img



title DOS
rootnoverify (hd0,0)
chainloader +1

이것을 대충 보면 몇가지 궁금한 사항이 생긴다. root (hd0, 5) 라든가 kernel ... 라든가.. 하지만, 필자는 이것을 설명하기엔 시간이 너무 없다.

reference에 링크해 놓은 싸이트를 찾아보라. 아주 잘 설명되어 있다.

자, 그럼 이것을 다음과 같이 바꾸어 내가 새로 컴파일한 커널 이미지 /boot/vmlinuz-2.4.20-test 와 initial ramdisk인 /boot/initrd-2.4.20-test.img 를 넣어보자.

# grub.conf generated by anaconda #
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,5)
# kernel /vmlinuz-version ro root=/dev/hda9
# initrd /initrd-version.img
# boot=/dev/hda
default=2
timeout=10
fallback 0
splashimage=(hd0,5)/grub/splash.xpm.gz
title Red Hat Linux (2.4.20-8)
root (hd0,5)
kernel /vmlinuz-2.4.20-8 ro root=LABEL=/ hdc=ide-scsi
initrd /initrd-2.4.20-8.img



title Red Hat Linux (2.4.20-test)
root (hd0,5)
kernel /vmlinuz-2.4.20-test ro root=LABEL=/ hdc=ide-scsi
initrd /initrd-2.4.20-test.img
title DOS
rootnoverify (hd0,0)
chainloader +1

자, 뭐 대충 통밥으로 다 똑같이 하고 커널 이미지와 initial ramdisk 이름만 바꾸어 준 것을 알 수 있을 것이다. 카카...

하지만, 필자는 initial ramdisk 만드는 것을 몰라 많이 고생을 했다.... 그래서 적는 것이니... 허접하다고는 하지 말기 바란다.

마지막으로 할 일은 설정된 grub.conf를 bios에 굽는 일이다. 다음과 같이 하자.

grub-install /dev/hda

자 이제 모든 것이 완료 되었다.

이제 재부팅을 하여 grub 부트로더가 뜨면 내가 올린 커널을 선택해 보자... 두근두근... 카카... 이제 커널을 수정해 볼까?

2006년 4월 3일 월요일

Fedora Core 5 공개

레드햇(Red Hat)은 리눅스 배포본 「페도라 코어(Fedora Core)5」를 공개했다. 이 새로운 버전에는 그래픽이나 가상화 관련의 새로운 기능 외에도 MS의 소프트웨어 체제를 기반으로 개발한 데스크톱 유틸리티도 몇 가지 추가되었다.

레드햇은 페도라로 검증한 기능을 후에 동사의 유료 제품인 「레드햇 엔터프라이즈 리눅스(Red Hat Enterprise Linux)」에 탑재하고 있다. 또 페도라는 보다 새로운 기능을 요구하는 많은 리눅스 사용자의 욕구를 채우기 위해서 프로그래밍이나 테스트에는 사외의 사람들이 관여하고 있다.

이번에 발표된 버전5에는 수많은 새로운 기능이 추가되었으며, 리눅스의 2대GUI인 「GNOME」과「KDE」도 각각 버전2.14와 버전 3.5로 업데이트 되었다.

페도라 코어5는 고성능의 그래픽 기능을 가지는 머신 전용으로서 유저 인터페이스에 3 D 효과를 추가하는 「Accelerated Indirect GL X」를 지원하고 있다. 그러나 어떤 버그에 의해서 엔비디아(Nvidia)나 ATI에서 나오는 정품3 D그래픽 칩용 드라이버를 이용할 수 없는 것이 있다. 대부분의 유저는 이들의 최고 속도의 그래픽스 기능을 살리기 위해서 업데이트 된 커넬을 다운로드해야 한다.

페도라 코어의 새로운 버전은 MS가 윈도우 비스타의 발표를 다시-이번은 2007년 1월까지-연기하는 것을 발표한 것과 전후로 공개되었다. 그러나 리눅스 사용자가 오랜 세월 제품을 연마해 사용하기 쉬게 하려고 노력함에도 불구하고 윈도우는 여전히 데스크톱PC시장을 지배하고 있다.

페도라 코어5에는 「카이로(Cairo)」라는 다른 그래픽 관련 기능도 추가되었다. 카이로는 파이어폭스나 다른 애플리케이션이 2 D의 벡터 그래픽을 만드는데 이용 가능한 라이브러리다.

페도라 코어5의 그래픽 관련 하부조직에는 「Xorg 7.0」이 추가되었다. 이것은 소프트웨어의 컴포넌트를 독립한 모듈에 분할해, 프로그래머가 보다 신속히 개선할 수 있도록 하는 시도다.

노벨은 개발자 전용으로 페도라와 경쟁하는 「OpenSUSE」를 내고 있어 리눅스의 그래픽스 기능 강화를 위해 「Xgl」라는 다른 어프로치를 가지고 있다. 그에 대해 레드햇에서는 자사의 어프로치 쪽이 혼란이 적다고 생각하고 있다.

다만 레드햇은 경쟁사가 개발하고 싶은 기술을 실제로 채용하고 있다. 그것은 MS의 「.NET」소프트웨어의 오픈 소스 버전에 해당하는 「모노(Mono)」다. 페도라 코어5에는 모노를 기반으로 개발된 세 개의 애플리케이션--데스크톱 검색용의 「Beagle」, 사진 파일 관리용의 「F-Spot」, 메모용의 「Tomboy」가 포함되어 있다.

그 외 유틸리티 관련해서는 GNOME의 전원 관리용 모듈이나 스크린 세이버용 모듈도 업데이트 되었다. 「GStreamer」라이브러리의 버전 0.10은 미디어 플레이어나 비디오 편집 소프트웨어등의 애플리케이션 전용의 기초로 포함되어 있다.

페도라 코어5의 서버 관련 기능에서는 데이터베이스 소프트웨어도 업데이트되어 MySQL는 버전 5.0에, 또 PostgreSQL는 버전 8.1으로 업그레이드 되었다. 또 이 OS에는 「젠(Xen)」의 새로운 관리툴도 포함되어 있다. 젠은 복수의 OS를 동시에 움직이기 위한 「하이퍼바이저(hypervisor)」소프트웨어다.

페도라 코어5에 채용되고 있는 리눅스 커널은 버전 2.6.16이다.

덧붙여 페도라 프로젝트의 웹 사이트에는 Fedora Core 6에 관한 다양한 아이디어가 게재되고 있다. @

Stephen Shankland ( CNET News.com )

2006년 4월 1일 토요일

Fedora Core4 pop3, imap 설정

새로 설치한 페도라코어4에 dovecot을 이용해서 메일서버를 구현하는 방법입니다.

메일서버를 구축하기 위한 필수패키지는 sendmail, sendmailcf 와 오늘 얘기할 dovecot이 페도라서버에 설치되어 있어야 한다.

dovecot 공식홈페이지 : http://www.dovecot.org

dovecot은 예전에 사용하던 imap을 대체하는 새로운 메일데몬으로 기존의 IMAP에 비해 보안이 향상되었다.


한방에 한꺼번에 설치하려면

yum -y install sendmail sendmailcf dovecot 명령으로 해결된다.

이제 센드메일을 설정할 차례이다.

/etc/mail/sendmail.cf 내용중

Cwlocalhost 를 Cw자신의도메인네임명으로 수정한다.

ex) Cwmydomain.com

/etc/mail/access 에 도메인네임을 추가한다.

mydomain.com       RELAY
수정한 후에는 makemap hash /etc/mail/access < /etc/mail/access명령을 수행한후에 센드메일을 재시작해야 수정된 내용이 적용된다.

이제 메일사용자에게 메일내용을 보여주는 dovecot 데몬의 설정화일을 변경한다.


/etc/dovecot.conf 화일 변경


protocal = pop3 pop3s imap imaps 수정
imap_listen = [::],pop3_listen = [::] 부분을
imap_listen = *, pop3_listen = * 으로 수정
imapslisten = [::],pop3s_listen = [::] 부분을
imaps_listen = *, pop3s_listen = * 으로 수정
[::]는 ipv6 프로토콜을 의미하며 우리는 ipv4를 사용하므로 *로 바꿔준다.

ssl_disable = no 주석제거
login_executable = /usr/libexec/dovecopt/imap_login 주석제거
login_user = dovecot 주석제거
login_executable = /usr/libexec/dovecopt/pop3_login 주석제거
#mail_extra_groups = mail_extra_groups = mail 수정
imap_executable = /usr/libexec/dovecot/imap 주석제거
pop3_executable = /usr/libexec/dovecot/pop3 주석제거
auth_executable = /usr/libexec/dovecot/auth 주석제거

위와 같이 수정한다.


이후, 페도라코어의 방화벽을 셋팅한다.
/etc/sysconfig/system-config-securitylevel 로 콘솔에서 직접 수정할수 있다.

추가로 53Ltcp, 53:upd, 25:tcp, 110:tcp, 143:tcp, 995:tcp, 993:tcp 포트를 열어준다.


dovecot 사용시 selinux를 꺼야 제대로 실행됩니다.
설정화일 : /etc/selinux/config 화일 disabled해주면 됩니다.

리눅스 자동 백업 스크립트

fsck 를 잘 못 쓰는 바람에 연구실 서버를 완전히 날려먹었다.
그안에 포함되어 있던 선배들 자료와 수천만원짜리 소스도 날렸다.
내 인생의 최대의 실수다. fsck 를 잘못 쓴거보다는..
백업을 안했다는게 너무 괴롭다.
소잃고 외양간 고친다고... 백업 스크립트라도 하나 만들어서
다시는 그런 실수를 하지 않도록 해야겠다.
-----------------------------------------------------------------------------------
백업이라는것이 모든 관리자들이 해야 하지만 그렇게 안되는게 사실 귀찮아서 이다.

귀찮아서 백업을 않하는것이다.

그러다 이지경까지 왔지만...

백업을 받는 컴퓨터는 따로 둔다.
왜냐면 하나를 날려먹어도 하나는 살려둬야 하잖아.
그리고 서버 사용시간대를 피한 아침 6시

기본 발상은 이렇다.
일단 crond 데몬으로 아침 6마다 백업 스크립트를 실행하는데
그 백업 스크립트는 특정 디렉토리를 tar.gz 로 압축하고
그걸 백업 서버의 ftp 로 접속해서 저장한다.
이정도만 되더라도 사용자들의 데이터는 안전하게 유지할수 있는것이다.

그럼 먼저 crond 을 보도록 하자
crond 는 특정 시간이나 날짜(좀 복잡하게도 가능)에 정해진 일을 수행하는 데몬이다.
자세한거는 직접들 찾아보시고

# crontab -e 0 6 * * * /bin/backup.sh

이렇게 명령을 주게되면 crond 에 매일 아침 6시에 /bin/backup.sh 를 실행하라는
것을 의미한다. 자세한 의미는 굳이 설명하지 않겠다.
이러면 crond 는 매일 아침 6정각에 /bin/backup.sh 를 실행한다.

다음은 backup.sh 의 내용이다.

#!/bin/bash
dstring="backup_`date +'%y%m%d'`.tar.gz"  # 파일명을 만들어낸다.
                                                             # 04년06월21일같은경우에
                                                             # backup_040621.tar.gz 를 만든다.
wall < /bin/start_backup_message             # 접속되어있는 모든 사용자에게
                                                             # 백업이 시작됨을 알리고
/etc/init.d/network stop                            # 네트워크 서비스를 중지시킨다.
tar cfz $dstring "/home"                        # home 디렉토리를 파일명으로 압축한다.
/etc/init.d/ network start                           # 네트워크 서비스 재개

Server="Backup Server Address"   # 서버IP
Password="PASSWORD"              # backup 받는 유저의 패스워드
UsrID="USERID"                           # ID

ftp -n $Server <<End-Of-Session  # ftp 에 접속 -n 옵션은 자동로그인을 안한다.
user $UsrID $Password                # 로그인
binary
put "$dstring"
bye
End-Of-Session

rm -f $dstring                               # 백업파일 삭제

wall < /bin/end_backup_message  # 백업이 끝났음을 알린다

네트워크 서비스를 중지시키는 이유는 간단하다.
백업이 진행될동안 서버에 파일을 올리지 않게 하기 위해서이다.
백업도중에 데이터의 용량이 커져버리면 왠지 모르게 문제가 생길것 같다.

이렇게 해서 테스트 해본결과 backup 서버의 특정 계정에
백업된 데이터가 들어왔다.

다른사람들도 꼭 한번 해보길 바란다... 나처럼 데이터 날려먹고 울지말고..

2006년 3월 7일 화요일

Error: cannot restore segment prot after reloc: Permission denied

Article Title:Error: cannot restore segment prot after reloc: Permission denied
Article ID:3092
Article Name:INSTALL88
Last Updated:8/5/2005 4:55:50 PM
Products:IDL; ENVI
OS Platforms:Linux-Intel

Topic:

Some Linux distributions with SELinux enabled may prevent IDL from running under the default security context. This TechTip is a workaround for CR#41937

Discussion:

Newer Linux distributions have enabled new kernel security extensions from the SELinux project at the NSA. These extensions allow finer-grained control over system security. However, SELinux also changes some default system behaviors, such as shared library loading, that can be problematic to third party programs.

If you receive the error message "cannot restore segment prot after reloc: Permission denied" when launching IDL, then your SELinux configuration is preventing IDL from launching.

To rectify this issue, you can either:

  • Change the default security context for IDL by issuing the command:

    chcon -t texrel_shlib_t /usr/local/rsi/idl_6.1/bin/bin.linux.x86/*.so

  • Disabling SELinux altogether by setting the line

    SELINUX=disabled

    in your /etc/sysconfig/selinux file.

For more information about SELinux, please consult your Linux distribution vendor.

FC4 를 깔고 호스팅 서버처럼 꾸미기

나를 엄청 고생한게 만든 FC4

원인은... 바로.. SElinux 이놈 때문에... 보안이 좋긴 좋지만... 어디 확실하게 설정하는곳도

없고... 아 열받는다.

========================================================================

계정별로 트래픽을 제어하는 부분과 하드 할당량을 설정할 수 있습니다.
단, 중간에 오류가 발생하는 부분이 생길 수도 있습니다.



# 페도라 코어 4 최소 설치 후 (이 부분은 따로 설명하지 않습니다.)



# yum 설치를 위해 GPG-KEY 포함
rpm --import /usr/share/rhn/RPM-GPG-KEY-fedora



# yum 업데이트
yum -y update



# 한글 설정
/etc/sysconfig/i18n

LANG="ko_KR.eucKR"
SUPPORTED="en_US.iso885915:en_US:en:ko_KR.eucKR:ko_KR:ko"
SYSFONT="lat0-sun16"
SYSFONTACM="iso15"



# 매뉴얼 설정 수정
vi /etc/man.config

수정
PAGER          /usr/bin/less -isr




# 디렉토리 색상 수정
vi /etc/DIR_COLORS.xterm

수정
DIR 00;33



# 소스 컴파일을 위한 컴파일러 및 각종 모듈 yum 설치
yum -y install gcc cpp gcc-c++ compat-gcc-32-g77 flex libjpeg-devel libpng-devel libtiff-devel freetype-devel openldap-devel pam-devel sendmail-cf vsftpd telnet-server




# zlib 소스 설치
cd /usr/local/src
wget
http://www.zlib.net/zlib-1.2.3.tar.bz2
tar xfj zlib-1.2.3.tar.bz2
cd zlib-1.2.3
make
make install




# freetype 2 설치
글짜를 그릴 때 쓰는 라이브러리 입니다.
wget
http://ftp.superuser.co.kr/pub/etc/freetype-2.1.5.tar.gz
tar xvfz freetype-2.1.5.tar.gz
cd freetype-2.1.5
./configure
make
make install




# openssl 소스 설치
cd /usr/local/src
wget
http://www.openssl.org/source/openssl-0.9.8a.tar.gz
tar xfz openssl-0.9.8a.tar.gz
cd openssl-0.9.8a
./config
make
make install




# curl 소스 설치
cd /usr/local/src
wget
http://curl.haxx.se/download/curl-7.15.1.tar.bz2
tar xfj curl-7.15.1.tar.bz2
cd curl-7.15.1
. /configure --with-ssl
make
make install




# gd lib 설치
cd /usr/local/src
wget
http://www.boutell.com/gd/http/gd-2.0.33.tar.gz
tar xfz gd-2.0.33.tar.gz
cd gd-2.0.33
./configure
make
make install




# webalizer 소스 설치
cd /usr/local/src
wget
ftp://ftp.mrunix.net/pub/webalizer/webalizer-2.01-10-src.tgz
tar xfz webalizer-2.01-10-src.tgz
cd webalizer-2.01-10
./configure --with-language=korean
make
make install



# mysql 4.1.x 설치
cd /usr/local/src
wget
http://mysql.byungsoo.net/Downloads/MySQL-4.1/mysql-4.1.16.tar.gz
tar xfz mysql-4.1.16.tar.gz
cd mysql-4.1.16
./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --with-charset=euckr
make
make install

/usr/local/mysql/bin/mysql_install_db
groupadd mysql
useradd -M -c MySQL_Server -d /usr/local/mysql -g mysql -s /bin/nologin mysql
chown root.mysql -R /usr/local/mysql
chown mysql.mysql -R /usr/local/mysql/data
cp /usr/local/mysql/share/mysql/my-huge.cnf /etc/my.cnf
echo "/usr/local/mysql/bin/mysqld_safe &" >> /etc/rc.local



# apache 1.3.x 설치
cd /usr/local/src
wget
http://ftp.apache-kr.org/httpd/apache_1.3.34.tar.gz
tar xfz apache_1.3.34.tar.gz
cd apache_1.3.34
./configure --prefix=/usr/local/apache --enable-module=so
make
make install
echo "/usr/local/apache/bin/apachectl start" >> /etc/rc.local


#freetype 소스설치후 적용하기위세 freetype 옵션추가
# php 소스 설치
cd /usr/local/src
wget
http://kr.php.net/get/php-4.4.2.tar.bz2/from/this/mirror
tar xfj php-4.4.2.tar.bz2
cd php-4.4.2
./configure --with-apxs=/usr/local/apache/bin/apxs --with-mysql=/usr/local/mysql --with-config-file-path=/usr/local/apache/conf --with-zlib-dir=/usr/local --with-jpeg-dir=/usr/local --with-png-dir=/usr/local --with-tiff-dir=/usr/local --with-freetype-dir=/usr/local --with-ttf --with-gd --with-openssl --with-gettext --with-kerberos --with-swf-dir=/usr/local --with-mod_charset --with-regex=php --with-curl --with-ldap --with-iconv --enable-gd-native-ttf --enable-ftp --enable-sockets --disable-debug  --enable-calendar --enable-sigchild --enable-magic-quotes --enable-bcmath --enable-exif --enable-mbstring --enable-dbase --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-yp --with-jpeg-dir --with-freetype-dir
make
make install
cp php.ini-dist /usr/local/apache/conf/php.ini


vi /usr/local/apache/conf/httpd.conf

수정
DirectoryIndex index.html index.htm index.php

수정 (public_html -> www)
UserDir www
#<Directory /home/*/www>



# vi /usr/local/apache/conf/mime.types
두줄 추가 (확장자는 탭키로 띄운다)
application/x-httpd-php        php ph inc
application/x-httpd-php-source  phps



# php 파일 이외에 다른파일명으로 php해석할수있게 설정 ex) htm html
# vi /usr/local/apache/conf/httpd.conf
-  .php 파일 및 html 파일에서 php 코드 실행되게 설정하려면
AddType application/x-httpd-php .php .phtml .php3 .html .htm
AddType application/x-httpd-php-source .phps



# vi /usr/local/apache/conf/php.ini
- 그림 파일 및 프래쉬 파일 로그 남기지 않게 설정
방문자 수가 많아지면 웹로그가 엄청 쌓이게 되고, 그 로그는 크기가  2G를 넘게 되면 웹페이지에 이상현상이 생깁니다. 그렇다고 로그를 안 남길 수는 없는 것이고, 이미지 파일들은 로그남기는 것에서 제외합니다.
CustomLog logs/access_log common 이렇게 되어 있는 것을 ..
SetEnvIfNoCase Request_URI (gif|png|jpg|css|js|bmp|jpeg|swf)$ IMAGE=1
CustomLog /usr/local/apache/logs/access_log common env=!IMAGE
이렇게 바꾸면^^; 쉽게 가능합니다.
- 업로드 용량 제한 풀기
기본적으로 업로드는 2M로 제한되어 있습니다. 만약 2M 이상으로 하면 여러 가지 설정들을 바꾸어 줘야 합니다. 업로드 되는 시간을 길 게 해 주어야 하고, 한번에 잡아먹을 메모리를 크게 해 주어야 합니다.
default_socket_timeout = 600
post_max_size = 20M
memory_limit = 20M
upload_max_filesize = 20M



- 업로드 용량 제한 풀기
# vi /usr/local/apache/conf/php.ini
기본적으로 업로드는 2M로 제한되어 있습니다. 만약 2M 이상으로 하면 여러 가지 설정들을 바꾸어 줘야 합니다. 업로드 되는 시간을 길 게 해 주어야 하고, 한번에 잡아먹을 메모리를 크게 해 주어야 합니다.
default_socket_timeout = 600
post_max_size = 20M
memory_limit = 20M
upload_max_filesize = 20M



- post, get , 쿠키 , 세션등의 변수를 일반변수로 (개인 서버용일경우 보안상 OFF 권장)
예전에 php는 기본적으로 위 변수를 일반변수로 사용할 수 있었습니다. 하지만 보안에 취약 하기 때문에 php 설치시 기본적으로 일반변수로 사용못하게 설정합니다. 이렇게 되면 문제가 예전에 사용하던 짜여졌던 프로그램은 정상적으로 실행되지 않습니다. 보안보다는 호환성이 더 중요하죠^^;
register_globals=On  이렇게 설정합니다.




# ZendOptimizer 설치
cd /usr/local/src
wget
ftp://ftp.sir.co.kr/zendoptimizer/ZendOptimizer-2.5.10a-linux-glibc21-i386.tar.gz
tar xfz ZendOptimizer-2.5.10a-linux-glibc21-i386.tar.gz
cd ZendOptimizer-2.5.10a-linux-glibc21-i386
./install.sh

php.ini 경로
/usr/local/apache/conf



# mod_throttle 소스 설치
cd /usr/local/src
wget
ftp://ftp.sir.co.kr/etc/mod_throttle-3.1.2.tgz
tar xfz mod_throttle-3.1.2.tgz
cd mod_throttle-3.1.2/
make install

#####################################################
##### 인스톨시 다음과 같은 에러시 다음과 같이 하세요.            ############
##### make: *** [install] Error 127make: *** [install] Error 127 ############
####################################################
---> 해당 디렉토리에 Makefile 에 APXS 경로를 지정해준다.


(참고 인스톨시 에러가 발생한다. 그리고 APM세팅 방식을 DSO방식으로 설치한다.
STATIC방식으로 설치해도 되지만, 그 부분은 다시 설정해야한다.)

* static방식으로 설치 했을 경우 ...
configure 시--add-module=$mod_throttle_source_PATH/mod_throttle.c 추가.

* 그럼 DSO방식으로 설치 했을 경우...
* 모듈을 만들어준다.
[
root@abcd mod_throttle-3.1.2]# /usr/local/apache/bin/apxs -c mod_throttle.c(모듈을 만들어준다)
gcc -DLINUX=22 -DUSE_HSREGEX -fpic -DSHARED_CORE -DSHARED_MODULE
-I/usr/local/apache/include -c mod_throttle.c
gcc -shared -o mod_throttle.so mod_throttle.o

* 에러부분에 추가 해주면 된다.

[
root@abcd mod_throttle-3.1.2]# /usr/local/apache/bin/apxs -i -a -n 'throttle' mod_throttle.so
[activating module `throttle' in /usr/local/apache/conf/httpd.conf]
cp mod_throttle.so /usr/local/apache/libexec/mod_throttle.so
chmod 755 /usr/local/apache/libexec/mod_throttle.so
cp /usr/local/apache/conf/httpd.conf /usr/local/apache/conf/httpd.conf.bak
cp /usr/local/apache/conf/httpd.conf.new /usr/local/apache/conf/httpd.conf
rm /usr/local/apache/conf/httpd.conf.new

 
##############################################



vi /usr/local/apache/conf/httpd.conf

<IfModule mod_throttle.c>
    ThrottlePolicy Volume 500M 1d

    <Location /throttle-status>
        SetHandler throttle-status
    </Location>

    <Location /throttle-me>
        SetHandler throttle-me
    </Location>

    <Location /~*/throttle-me>
        SetHandler throttle-me
    </Location>
</IfModule>

<VirtualHost 211.xx.xxx.xxx>
    ServerAdmin
root@xxx.com
    ServerName xxx.com
    DocumentRoot /home/xxx
    # 하루 500M
    ThrottlePolicy Volume 500M 1d
    # 하루 천번
    ThrottlePolicy Request 1000 1d
</VirtualHost>





# quota 설정

1. fstab 옵션추가 (usrquota,grpquota) :
vi /etc/fstab
/home 에 usrquota 추가
default,usrquota


2. remount (umount , mount) :
mount -o remount /home


3. 데이터베이스 파일생성(quota.user , quota.group) :
touch /home/quota.user
chmod 600 /home/quota.user
quotacheck -av
convertquota -u /home

4. 사용자마다 적용수치 기록 :
edquota 계정
repquota -a


5. 활성화 :
quotaon /home





# qpopper 4.0.8 소스 설치
cd /usr/local/src
wget
ftp://ftp.qualcomm.com/eudora/servers/unix/popper/qpopper4.0.8.tar.gz

tar xvfz qpopper4.0.8.tar.gz
cd qpopper4.0.8
./configure --enable-specialauth --enable-servermode --enable-shy
make
cp popper/popper /usr/sbin/popper

vi /etc/xinetd.d/pop3

service pop3
{
    disable        = no
    socket_type    = stream
    wait            = no
    user            = root
    server          = /usr/sbin/popper
    log_on_success  += HOST DURATION
    log_on_failure  += HOST
}

# /etc/rc.d/init.d/xinetd restart




# sendmail 수정 및 실행
vi /etc/mail/sendmail.mc

TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
DAEMON_OPTIONS(`Port=smtp,Addr=0.0.0.0, Name=MTA')dnl





# 계정당 용량 설정
vi  /etc/sendmail.cf
Mlocal,        P=/usr/bin/procmail, F=lsDFMAw5:/|@qSPfhn9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL,
                M=20495360, <-- 이 부분만 추가 :  byte 단위 (예:20메가)
                T=DNS/RFC822/X-Unix,
                A=procmail -t -Y -a $h -d $u


m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
#/etc/rc.d/init.d/sendmail restart
#/etc/rc.d/init.d/saslauthd restart





# 기본 서비스

ntsysv 실행

auditd
crond
iptables
kudzu
named
network
pop3
saslauthd (보내는 메일서버 패스워드 인증?)
sendmail
sshd
syslog
telnet
vsftpd
xinetd



# 그룹사용자 추가
groupadd webhost





# path 추가

vi /etc/profile

pathmunge /usr/X11R6/bin after
pathmunge /usr/local/mysql/bin after
pathmunge /usr/local/apache/bin after





# vsftpd 설정 변경

vi /etc/vsftpd/vsftpd.conf

주석제거
xferlog_file=/var/log/vsftpd.log





# 재시작

2006년 3월 3일 금요일

Diff, Patch, CVS 사용법

리눅스 개발자들에게 중요한 것 중의 하나가 오픈소스 프로젝트 진행이다. 사실 국내에서도 오픈소스 프로젝트는 많은 사람들이 관심을 갖고 있지만 막상 프로젝트에 참여하는 사람들의 숫자는 여전히 부족하다. 여기서는 여러 개발자들이 동시에 오픈소스 프로젝트에 참가할 때 거의 필수적으로 쓰이는 diff, patch, CVS(Concurrent Versions System)와 같은 소스코드 버전 관리툴에 대해 살펴 보고 오픈소스 프로젝트를 진행할 때 알아두면 좋은 특성이나 작업 방식에 대해서도 알아 본다.

오픈소스 프로젝트란 도대체 어떤 것일까? 리눅스와 오픈소스의 부상과 더불어 오픈소스 개발 방식은 기존의 상용 소프트웨어 개발 방식에 비해 적은 비용으로 양질의 소프트웨어를 개발할 수 있으며 소프트웨어 시장 독점의 문제가 없다는 의견이 설득력을 계속 높여가고 있다.

그러나 필자가 보기에는 오픈소스 개발 방식은 그 효율성을 논의하기 전에 왜 이런 식의 개발 방식이 만들어 졌으며 왜 오픈소스 스타일의 개발 방식이 자연스럽게 정착되었는지를 이해하는 것이 더욱 중요하다고 생각한다. 필자의 의견으로는 오픈소스는 소프트웨어를 소프트웨어 그 자체가 지닌 특성에 맞도록 자연스럽게 개발하는 한 방법이라고 생각한다.

당연한 얘기지만 어떠한 소프트웨어의 소스코드를 공개하면 그 소프트웨어가 계속 바뀌어 나갈 수 있는 길이 열리게 된다. 소스코드를 공개해서 개발 작업을 진행하는 오픈소스 개발 방법이 두드러지게 나타난 것은 1970년대 초 AT&T에서 자사의 운영체제인 유닉스의 소스코드를 공개한 이후부터라고 보는 것이 정설이다. AT&T에서는 대학과 같은 교육, 연구 기관에 자사의 제품인 유닉스를 공급하면서 돈을 받고 소스코드를 그대로 제공하는 라이선스 방식을 취했다.

소프트웨어를 배포할 때 소스가 아닌 바이너리를 주로 배포하는 지금으로서는 언뜻 상상하기 어려운 관행일 수도 있지만 컴퓨터의 종류가 통일되어 있지 않고, 소수의 전문가 집단에서 유닉스를 주로 사용했다는 점을 생각해 본다면 AT&T 입장에서 유지보수 비용을 줄여주는 이러한 소스코드 형태의 배포는 나름대로 합리적인 선택이라고도 할 수 있겠다.

그러나 여기서 예상하지 못한 일이 벌어진 것이 이들 사용자, 혹은 사용자이면서 개발자이기도 한 사람들이 마음대로 뜯어고치고 덧붙이기 시작한 코드들이 오리지널 AT&T 유닉스보다 오히려 더 중요한 위치를 차지하게 된 것이다(BSD 유닉스의 발전도 이러한 관습에 뿌리를 두고 있다).

따라서 자유 소프트웨어나 오픈소스와 같은 용어들은 소프트웨어 개발 방식의 측면에서 볼 때 이미 존재하고 있던 개발 방식을 새롭게 재조명하고 있다고 생각할 수 있다. 자유 소프트웨어에서는 소스코드가 공개된 소프트웨어의 보호에 좀 더 중점을 두고 있으며 오픈소스에서는 소스코드가 공개된 채로 개발되는 소프트웨어의 개발 효율성에 좀 더 관심을 집중하는 편이다. 어느 경우이든 간에, 소스코드를 공개해서 개발자의 참여를 이끌어 내는 소프트웨어 개발 방식은 변함이 없으며, 오픈소스라는 단어가 아예 없던 시절에도 이것은 마찬가지인 것이다.

그렇다면, 이제 간단한 상황 하나를 가정해 보기로 하자. 여러분들이 초기 유닉스 시절 대학 전산실에 근무하던 도중 유닉스가 도입되었다고 생각해보자. 고된 포팅과 설정 작업 끝에 시스템이 제대로 돌아가기 시작했는데 이 와중에서 버그를 하나 발견하고 그 부분의 소스코드를 수정했다. 이럴 때 다음 버전의 유닉스에 여러분들이 고친 부분이 반영되도록 하려면 어떻게 해야 할까?

이럴 때 가장 상식적인 해법은 고친 부분의 소스코드를 원저자에게 보내주면 될 것이다. 그리고 그 방법으로 가장 편리한 것은 아마도 이메일이 좋을 것이다. 인터넷이 없던 시절이라면 아마도 일반 메일을 이용했을 것이다. 약간은 논외의 이야기지만, 인터넷 초창기에는 국내에서 유즈넷 뉴스그룹에 올라온 글을 보기 위해 정기적으로 뉴스서버 데이터 백업을 외국에서 자기 테이프에 받아 소포로 전송받기도 했다고 한다. 어쨌든 이러한 이메일의 간편함 덕분에 이메일은 오픈소스 개발 작업에서 가장 중요한 통신 수단이며 패치 전송 수단으로 자리 잡게 된다.

여기서 하나 생각해 봐야 할 것이 원저자의 입장이다. 이렇게 패치를 담고 있는 메일의 숫자가 적을 때는 원저자는 그저 전송된 패치를 고맙게 받아 적용하기만 하면 되겠지만 패치의 숫자가 늘어나고, 같은 버그에 대해서도 두 종류 이상의 중복 패치가 생기게 되면 어떤 패치를 선택할 것인지, 그리고 모은 패치를 어떻게 통합해서 하나의 소스코드 트리로 만들고 그것을 배포(public release)할 것인지 선택해야 하는 문제가 생긴다. 이런 경우, 보통 오픈소스계의 관습은 원저자, 혹은 프로젝트 리더에게 어떤 패치를 받아들일 것인지의 결정권을 맡겨버리는 경향이 있다. 이럴 때 원저자나 프로젝트 리더는 ‘자비로운 독재자(benevolent dictator)’라는 역할을 맡게 되는 것이다.

또한, 패치가 전송될 때 사람들마다 통일되지 않은 방식으로 패치를 전송하게 되면 프로젝트 리더의 입장에서는 여러 종류의 패치를 하나의 소스코드 트리에 적용시키는 데 많은 혼란을 겪게 될 것이다. 이를 해결하기 위해 등장한 심플한 도구가 바로 diff와 patch이다.

diff와 patch
diff는 유닉스 사용자 튜토리얼에도 가끔씩 등장하는 간단한 유틸리티이다. diff의 역할은 두 파일간의 차이점을 보여주는 데 소스코드의 바뀐 부분을 보여 줄 때 많이 쓰인다. patch는 이러한 diff의 출력 결과를 이용해서 이 바뀐 부분을 원래의 소스코드에 업데이트할 때 쓰는 유틸리티이다.

diff의 일반용법
우선, diff의 형식은 다음과 같다.

diff [options] from-file to-file

diff는 두 개의 파일을 필요로 한다는데 주의하자. from-file은 원래의 파일, 즉 구 버전의 파일이며, to-file은 새로이 바뀐 새 버전의 파일이다. diff는 이렇게 하면 from-file에서 to-file로 어떠한 변화가 있었는지를 출력해 준다. from-file과 to-file은 모두 디렉토리가 올 수도 있는데 디렉토리가 오는 경우는 조금 뒤에 살펴보기로 하자. 참고로 간단한 예제 hello1.c와 hello2.c의 예를 들어보자. 다음에서 볼 수 있듯이 hello2.c는 hello1.c에서 hello, world 부분이 hello, the world of linux로 대치되었고 그 아랫줄에 공백 라인 하나와 printf("Testing one two three.\n");가 추가되었음을 볼 수 있다.

*** hello1.c:
#include
#include
main()
{
   printf("hello, world.\n");
}

*** hello2.c:
#include
main()
{
   printf("hello, the world of Linux.\n");
   printf("Testing one two three.\n");
}

diff 결과는 다음과 같다.

$ diff hello1.c hello2.c
2d1
< #include
6c5,7
<     printf("hello, world.\n");
---
>     printf("hello, the world of Linux.\n");
>
>     printf("Testing one two three.\n");

첫 줄의 2d1은 hello1의 두 번째 줄에서 한 줄을 삭제(delete)하는 변화가 일어났다는 의미이다. 그리고 조금 아래의 6c5,7은 hello1의 6번째 줄을 아랫부분으로 바꾸는데(change) 그 결과가 5번째부터 7번째 라인까지 들어가게 된다는 의미이다. 그러나 실제로 프로그램 소스코드에서는 오리지널 diff의 결과물보다는 unified format의 diff 출력을 쓰는 경우가 많다. unified format을 쓰려면 diff에 -u 옵션을 추가한다.

$ diff -u hello1.c hello2.c
--- hello1.c    Tue Aug  3 14:34:46 2004
+++ hello2.c    Tue Aug  3 13:25:49 2004
@@ -1,7 +1,8 @@
#include
-#include

main()
{
-    printf("hello, world.\n");
+    printf("hello, the world of Linux.\n");
+
+    printf("Testing one two three.\n");
}

참고로 unified format에서는 변경되는 부분만이 아닌 변경되는 부분 근처의 내용(context)도 같이 출력됨을 볼 수 있다. 사람이 좀 더 읽기 편리한 context format 출력 옵션인 -c를 사용한 결과는 다음과 같다. context format 역시 바뀌는 부분 근처의 내용도 참고하기 좋게 출력을 해 준다. 어쨌거나 오픈소스 프로젝트에서는 diff를 쓸 때 주로 -u 옵션을 붙인다는 점을 꼭 외워 두도록 하자.

$ diff -c hello1.c hello2.c
*** hello1.c    Tue Aug  3 14:34:46 2004
--- hello2.c    Tue Aug  3 13:25:49 2004
***************
*** 1,7 ****
#include
- #include
 
main()
{
!     printf("hello, world.\n");
}
--- 1,8 ----
#include
 
main()
{
!     printf("hello, the world of Linux.\n");
!
!     printf("Testing one two three.\n");
}

이렇게 diff로 소스코드의 변경된 부분을 저장한 다음 이것을 원저자에게 메일로 보내면 된다.

$ diff -u hello1.c hello2.c > hello.diff

여러 개의 소스 파일을 diff로 비교하기
앞의 경우는 소스코드 파일 하나만이 변경되었지만 상황에 따라서는 패치 과정에 여러 파일이 수정되고 새로운 파일이 추가되는 경우가 발생할 수도 있다. diff는 디렉토리 단위의 파일 비교도 가능하다. 우선, 다음 예제를 보자.

$ pwd
/home/foobar
$ ls -F
src1/  src2/            # src1은 원본, src2는 새로운 기능 추가본
$ ls src1
hello1.c  hello2.c
$ ls src2
hello1.c  hello2.c  hello3.c
$ more src1/*c
::::::::::::::
src1/hello1.c
::::::::::::::
#include
#include

main()
{
   printf("hello, world.\n");
}
::::::::::::::
src1/hello2.c
::::::::::::::
#include

main()
{
   printf("hello, the world of Linux.\n");

   printf("Testing one two three.\n");
}
$ more src2/*c
::::::::::::::
src2/hello1.c
::::::::::::::
#include

main()
{
   printf("hello, world.\n");
}
::::::::::::::
src2/hello2.c
::::::::::::::
#include

main()
{
   printf("hello, the world of Linux.\n");

   printf("Testing one two three four.\n");
}
::::::::::::::
src2/hello3.c
::::::::::::::
#include
#include

main()
{
   /* needs to be filled in */
}

src2에서는 hello3.c 파일이 새로 추가되었으며, hello2.c에서 수정 부분이 있고, hello1.c에서 빠진 부분이 있다. 이 두 디렉토리 사이에서 diff를 실행하려면 다음과 같은 명령을 쓴다.

$ pwd
/home/foobar
$ ls -F
src1/ src2/             # 경로를 제대로 확인한 뒤 diff를 실행한다
$ diff -urN src1 src2
diff -urN src1/hello1.c src2/hello1.c
--- src1/hello1.c       Tue Aug  3 14:34:46 2004
+++ src2/hello1.c       Tue Aug  3 13:35:44 2004
@@ -1,5 +1,4 @@
#include
-#include

main()
{
diff -urN src1/hello2.c src2/hello2.c
--- src1/hello2.c       Tue Aug  3 13:25:49 2004
+++ src2/hello2.c       Tue Aug  3 13:35:57 2004
@@ -4,5 +4,5 @@
{
    printf("hello, the world of Linux.\n");

-    printf("Testing one two three.\n");
+    printf("Testing one two three four.\n");
}
diff -urN src1/hello3.c src2/hello3.c
--- src1/hello3.c       Thu Jan  1 09:00:00 1970
+++ src2/hello3.c       Tue Aug  3 13:37:02 2004
@@ -0,0 +1,7 @@
+#include
+#include
+
+main()
+{
+    /* needs to be filled in */
+}

diff 명령에서 -r 옵션은 recursive 옵션으로 서브 디렉토리까지 diff가 모두 탐색하라는 의미이고, -N 옵션은 hello3.c와 같이 새로 만들어진 파일까지도 포함해 diff 출력을 생성하라는 의미다. 이 옵션 역시 -urN으로 외워 두는 것이 좋다.

patch 사용하기
이렇게 만들어진 diff의 결과물은 patch 명령을 통해서 원저자의 소스코드로 업데이트된다. patch 명령은 -p 옵션만 정확히 이해하면 사용하는데 무리가 없다.
-p 옵션은 strip 옵션이라고 부르는데 diff 파일에 명시되어 있는 디렉토리에서 몇 단계를 벗겨(strip)낼 것인가를 결정한다. -p0 옵션은 디렉토리 단계를 하나도 벗겨내지 않겠다는 것이고, -p1 옵션은 한 단계를 벗겨낸다는 의미이고 -p2는 두 단계를 의미한다. 쉽게 이해하기 위해 <표 1>를 보자. foobar/include/net 디렉토리가 있다고 할 때 p 옵션을 적용하면 다음과 같이 디렉토리가 벗겨져 나간다.

p0 foobar/include/net
p1 include/net
p2 net

이것이 diff로 생성시킨 패치를 적용할 때 어떤 의미를 가지게 될까? 우선, 파일 두 개를 비교했을 때 생성된 diff 패치와 디렉토리 두 개를 비교했을 때 생성된 diff 패치의 헤더 부분을 비교해보자.

◆ 파일 두 개를 비교했을 경우:
$ diff -u hello1.c hello2.c
--- hello1.c    Tue Aug  3 14:34:46 2004
+++ hello2.c    Tue Aug  3 13:25:49 2004
(이하 생략)

◆ 디렉토리 두 개를 비교했을 경우:
$ diff -urN src1 src2
diff -urN src1/hello1.c src2/hello1.c
--- src1/hello1.c       Tue Aug  3 14:34:46 2004
+++ src2/hello1.c       Tue Aug  3 13:35:44 2004
(이하 생략)

즉, diff가 생성한 패치 파일에는 원본 파일과 바뀐 파일의 디렉토리가 명시되어 있음을 알 수 있다. patch 명령을 사용할 때는 이 경로명을 고려해서 patch 명령을 실행시켜 줘야 한다.

패치 적용하기
여러분이 원저자의 입장에서 제공받은 패치를 적용시키려면 다음과 같은 방법을 사용하면 된다. 패치 파일은 표준 입력(standard input)으로 들어가며, 항상 -p 옵션을 주의 깊게 사용해야 한다. 이번 예제에서는 디렉토리 두 개를 비교한 패치가 전송되었다고 가정해 보자. 원저자는 diff 패치의 헤더 부분을 읽고 패치의 경로명을 확인한 다음 적절한 디렉토리로 가서 patch 명령을 실행한다. 우선, -p0 옵션 사용 예부터 보자. diff 패치의 헤더 부분은 다음과 같다.

diff -urN src1/hello1.c src2/hello1.c
--- src1/hello1.c       Tue Aug  3 14:34:46 2004
+++ src2/hello1.c       Tue Aug  3 13:35:44 2004
... 이하 생략 ...

따라서 원저자는 이 패치를 hello.diff로 저장한 다음 자신의 소스코드가 있는 src1까지 가서 패치를 적용한다.

$ cd projects
$ pwd
/home/foobar/projects
$ ls -F
hello.diff   src1/

diff 파일에 기술된 경로명과 현재 경로명이 일치하고 있음을 주의깊게 보자.

$ patch -p0 < hello.diff
$ patch -p0 < hello.diff
patching file src1/hello1.c
patching file src1/hello2.c
patching file src1/hello3.c

패치 전과 패치 후의 결과를 비교해 보면 다음과 같다.

패치 전:

$ pwd
/home/foobar/projects/src1
$ ls -al
total 16
drwxr-xr-x    2 jwsohn   jwsohn       4096  8월  3 16:35 .
drwxr-xr-x    3 jwsohn   jwsohn       4096  8월  3 16:35 ..
-rw-r--r--    1 jwsohn   jwsohn         82  8월  3 14:34 hello1.c
-rw-r--r--    1 jwsohn   jwsohn        116  8월  3 13:25 hello2.c

패치 후:

$ pwd
/home/foobar/projects/src1
$ ls -al
total 20
drwxr-xr-x    2 jwsohn   jwsohn       4096  8월  3 16:41 .
drwxr-xr-x    3 jwsohn   jwsohn       4096  8월  3 16:35 ..
-rw-r--r--    1 jwsohn   jwsohn         62  8월  3 16:41 hello1.c
-rw-r--r--    1 jwsohn   jwsohn        121  8월  3 16:41 hello2.c
-rw-r--r--    1 jwsohn   jwsohn         83  8월  3 16:41 hello3.c

이제 -p1 옵션을 적용해서 patch 명령을 써 보자. diff 파일에 기술된 경로명에서 디렉토리를 한 단계 벗겨내면 src1 디렉토리가 없어지므로 다음과 같은 방식으로 패치 파일이 적용된다.

$ pwd
/home/foobar/projects
$ ls -F
hello.diff  src1/
$ cd src1
$ patch -p1 < ../hello.diff
patching file hello1.c
patching file hello2.c
patching file hello3.c

참고로 diff 파일의 경로는 어디에 위치하든 상관이 없다. 파일 하나에 대한 패치를 적용할 때는 -p0 옵션을 쓰면 될 것이다.

CVS 사용
CVS는 약자 중 Concurrent가 의미하듯이 한번에 여러 명의 개발자가 동일한 소스코드 트리에 동시에 수정을 가하면서 작업을 할 수 있도록 도와주는 도구이다. 사실 오픈소스 프로젝트에 참가하는 일반 개발자의 입장에서는 CVS에 대한 일반적인 지식은 별다른 필요가 없다고 생각해도 무방하다. 실제 소스코드 트리를 수정할 수 있는 권한을 갖고 있는 사람들은 프로젝트 리더인 자비로운 독재자 한 사람이나 프로젝트와 관련이 깊은 소수의 개발자들일 것이기 때문이다.

즉, 소스코드 수정 사항이 생기면 CVS를 굳이 쓸 필요가 없이 그냥 FTP나 http로 다운받은 소스코드 위에 diff를 돌려서 패치만 이메일과 같은 수단으로 보내 주면 소스코드 수정 권한이 있는 그쪽 사람들이(보통 ‘커미터’라고 부른다) 알아서 처리를 해 줄 것이기 때문이다.
하지만 가장 최신 버전의 nightly build된 소프트웨어는 CVS 서버에 접속해야만 구할 수 있는 경우가 대부분이다. 따라서 오픈소스 개발 프로젝트에 관심이 있는 개발자라면 다음 측면에서 CVS 사용법을 알아야 할 필요가 있을 것이다.

[1] FTP나 http 서버에서 소스코드를 다운받는 대신에
[2] CVS 서버에서 가장 최신 소스코드를 다운 받고
[3] 자신이 패치한 소스코드와 CVS 서버의 소스코드의 diff를 생성하는 방법

익명 CVS 체크아웃
이제 CVS에서 소스코드를 다운받는 방법을 알아보기로 하자. 일반적으로 오픈소스 프로젝트들은 대부분 CVS 서버를 읽기 전용으로 세팅해 놓고 누구든지 들어와서 소스코드를 다운받아 갈 수 있도록 해 놓고 있다. 익명 FTP(anonymous FTP)와 비슷한 개념으로 생각하면 되겠다. CVS 서버에 사용자가 접속을 해서 소스코드를 한 카피 다운받아 가는 것을 CVS에서는 체크아웃(check-out)이라는 용어로 표현한다.
참고로 CVS는 로컬 서버에서 사용할 수도 있고, 따로 CVS 서버를 두고 원격으로 접속할 수도 있다. 여기서는 CVS가 원격 서버라고 가정하기로 한다. CVS 서버에서 소스코드를 다운받는 명령은 다음과 같다. KLDP.net 서버에 위치한 moniwiki 프로젝트를 예로 들어 보겠다.

$ cvs -d:pserver:anonymous@cvs.kldp.net:cvsroot/moniwiki login
$ cvs -d:pserver:anonymous@cvs.kldp.net:cvsroot/moniwiki checkout moniwiki

익명 FTP에 접속할 때 보다는 조금 복잡해 보인다. 우선, 첫줄의 cvs 명령은 CVS 서버에 anonmous, 즉 익명 사용자로 로그인하는 과정이다. CVS 서버가 암호를 요구하면 그냥 엔터 키를 쳐 주면 인증이 끝나고 읽기 권한이 부여된다. 일단 로그인을 한번 한 다음부터는 사용자의 홈 디렉토리에 .cvspass 파일이 생기면서 인증 절차가 생략된다. 즉, 매번 접속할 때마다 anonymous 인증 과정을 거쳐야 하는 익명 FTP와는 달리, CVS에서는 한번만 익명 로그인을 해서 .cvspass 파일을 생성하고 나면 다시 cvs login 명령으로 인증 과정을 거칠 필요가 없다.

그 다음 -d 옵션은 CVS 서버에서 제공하고 있는 루트 디렉토리를 의미한다. moniwiki 프로젝트의 경우는 cvsroot/moniwiki로 지정되어 있다. 앞의 pserver는 CVS 명령이 소스코드를 다운받으면서 쓸 프로토콜명이며 뒤의 anonymous@cvs.kldp.net은 CVS 로그인시 사용할 계정이다.

두 번째 cvs 명령은 소스코드 한 카피를 다운받는 체크아웃 과정을 실행하게 된다. 체크아웃(checkout)한 다음의 moniwki는 CVS 서버에서 지정해 놓은 프로젝트 이름이며(모듈이라고 부른다) 이곳 CVS 서버에서는 moniwki로 지정해 두었다. 두 번째 명령을 실행하면 사용자의 현재 디렉토리에 moniwiki라는 디렉토리가 생성되고 소스코드 다운로드가 시작된다. 여기에, -z3 옵션을 주면 전송시 압축을 사용하기 때문에 전송 속도가 빨라진다.

$ cvs -z3 -d:pserver:anonymous@cvs.kldp.net:cvsroot/moniwiki checkout moniwiki

그런데 CVS 서버에 접속할 때마다 -d 옵션 뒤의 긴 디렉토리 이름을 타이핑하기는 아무래도 불편한 감이 있다. -d 옵션을 생략하려면 환경변수 CVSROOT에 -d 옵션을 등록해 둔다.

$ export CVSROOT=:pserver:anonymous@cvs.kldp.net:/cvsroot/moniwiki

그 다음부터는 다음 명령으로도 충분하다.

$ cvs login
$ cvs checkout moniwiki

소스코드를 받은 지 시간이 어느 정도 지났다면 그동안 CVS 서버의 내용이 새롭게 업데이트되어 있을 수도 있다. 바뀐 부분을 다운받으려면 CVS에서 update 명령을 사용한다.

$ cvs update -dP

여기서 -P 옵션은 Prune 옵션으로 비어있는 디렉토리를 자동으로 삭제해 주는 역할을 한다. -d 옵션은 그동안 서버 쪽에 새로 만들어진 디렉토리가 있으면 다운 받은 이쪽에도 동일한 디렉토리를 만들어 준다.

CVS 서버 원본에서 diff로 패치 파일 만들기
이제 기본적인 CVS 서버에서 소스코드 다운로드 방법을 알았으니 직접 CVS 서버의 소스코드를 이용해서 패치 파일을 만들어 보자. CVS는 diff 명령을 아예 자체적으로 내장하고 있다. 조금 전 다운받은 moniwiki의 소스코드를 예로 들어보자. 여기서, 필자는 monisetup.php 파일에 간단히 /* testing one two three */라는 주석문을 하나 삽입했다.

$ cd moniwiki
$ ls
COPYING                 doc                     secure.sh
CVS                     imgs                    theme
INSTALL                 index.html              tools
README                  lib                     wiki.php
THANKS                  locale                  wikihttpd.php
applets                 monisetup.bat           wikilib.php
config.php.default      monisetup.php           wikismiley.php
css                     monisetup.sh
data                    plugin
$ cvs diff -u -p monisetup.php
Index: monisetup.php
===================================================================
RCS file: /cvsroot/moniwiki/moniwiki/monisetup.php,v
retrieving revision 1.11
diff -u -p -r1.11 monisetup.php
--- monisetup.php       3 Jan 2004 14:26:50 -0000       1.11
+++ monisetup.php       3 Aug 2004 09:14:21 -0000
@@ -486,4 +486,5 @@ if ($_SERVER['REQUEST_METHOD']!="POST")

}

+/* testing one two three */
?>

cvs diff 명령이 마치 로컬에서 monisetup.php 파일에 diff 명령을 실행한 것과 같은 결과가 나왔음을 알 수 있다. cvs diff 명령 뒤의 -u 옵션은 diff와 마찬가지로 unified format을 의미하며 -p 옵션은 cvs diff 의 출력을 표준 출력(standard output)으로 보내라는 의미이다. 디렉토리 안의 모든 파일에 대해 diff 명령으로 비교를 하려면 다음과 같은 방법을 사용한다.

$ cvs -Q diff -u -p              
Index: monisetup.php
===================================================================
RCS file: /cvsroot/moniwiki/moniwiki/monisetup.php,v
retrieving revision 1.11
diff -u -p -r1.11 monisetup.php
--- monisetup.php       3 Jan 2004 14:26:50 -0000       1.11
+++ monisetup.php       3 Aug 2004 09:19:27 -0000
@@ -486,4 +486,5 @@ if ($_SERVER['REQUEST_METHOD']!="POST")

}

+/* testing one two three */
?>
Index: css/log.css
===================================================================
RCS file: /cvsroot/moniwiki/moniwiki/css/log.css,v
retrieving revision 1.1
diff -u -p -r1.1 log.css
--- css/log.css 11 Feb 2004 08:48:27 -0000      1.1
+++ css/log.css 3 Aug 2004 09:19:27 -0000
@@ -1,4 +1,5 @@
/* MoniWiki CSS 2003/11/01 by wkpark */
+/* another testing comment */
body {
  font-family:Georgia,Verdana,Lucida,sans-serif;font-size:12px;
  background-color:#FFFFFF;

여기서는 monisetup.php 파일과 css/log.css 파일에 수정된 부분이 있음을 알 수 있다. cvs diff 명령에서 -Q 옵션은 Quiet 옵션으로 diff 출력 이외의 다른 메시지를 출력하지 않도록 해 준다. 그런데 여기서 하나 의문이 들 수 있다. 분명히 CVS에서는 cvs를 이용해서 직접 소스코드에 수정을 가할 수 있을 것인데 여기에서 왜 굳이 구식 diff를 이용한 방법을 또 사용하고 있는 것을까?

그 이유는 앞에서도 잠깐 언급했듯이, CVS 서버의 내용을 수정할 수 있는 권한이 있는 개발자는 소수이기 때문이다. 그리고 자비로운 독재자라는 용어에서 알 수 있듯이 제출된 패치를 받아들일지 아닐지의 여부는 관습적으로 보통 그쪽 프로젝트 리더들의 몫이 된다.

따라서 CVS 서버에 읽기 전용의 권한만을 갖고 있는 일반 오픈소스 프로젝트 참가자들은 이메일이나 혹은 메일링 리스트에 diff를 이용해서 패치 파일을 포스팅하는 것이 오픈소스 프로젝트에 참가하는 가장 무난한 방법이다. 일반적으로 프로젝트의 참가자가 지나치게 많지 않은 경우를 제외하고는 오픈소스 프로젝트에 올라오는 패치는 아무리 사소한 것이라도 쉽게 CVS 서버의 원본 소스코드에(repository라고 부른다) 반영 된다.

따라서 일반 개발자의 입장에서는 프로젝트 리더나 메인 개발자가 되기 전에는 CVS 서버에서 쓰기 권한이 그다지 필요하지는 않다. 이제 간단하게 CVS 서버에서 자주 쓰이는 기본적인 개념과 용어에 대해 알아보기로 하자.

CVS의 개념과 여러 용어
CVS 모델, copy-moodify-merge model
CVS는 이전에 많이 쓰이던 RCS(Revision Control System)과는 달리 lock-modify-unlock이 아닌 copy-modify-merge 모델을 사용한다. 여러 명의 개발자가 하나의 소스코드 트리에서 개발 작업을 할 때 가장 큰 문제는 같은 부분의 소스코드에 두 명 이상의 개발자가 서로 다른 소스코드를 작성하고 있을 때 발생한다. 이것을 CVS에서는 conflict이 발생했다고 한다.

RCS의 lock-modify-unlock 접근방식은 이러한 conflict를 한번에 두 명 이상의 개발자가 같은 소스코드 부분에 접근할 수 없도록 해서 conflict 상황을 미연에 방지한다. 하지만 CVS에서는 이러한 conflict 상황이 발생하는 것을 허용한다. 그렇다면 CVS에서는 이런 소스코드 conflict 상황이 발생하면 어떻게 대처할까?

재미있게도 CVS에서는 이런 상황에서 아무 일도 하지 않는다. 다만, CVS는 어느 부분에서 소스코드 conflict가 발생했는지, 그리고 어떤 사람이 conflict에 관계되어 있는지만 정확하게 알려 준다. 따라서 소스코드의 conflict 문제를 해결하는 것은 기계가 아닌 사람의 몫이 된다.

lock-modify-unlock 모델은 프로젝트의 전체 개발자 숫자가 소수이고 각각의 개발자들이 다른 개발자들이 현재 어떤 작업을 하고 있는지 쉽게 알 수 있는 상황에 유리하다. 그러나 개발자의 숫자가 많아지면 이미 잠금이 걸려 있는 파일에는 다른 개발자들이 접근할 수 없기 때문에 전체적인 업데이트가 늦어지는 문제가 발생하게 되고 좀 더 유연한 환경을 제공하기 위해 CVS가 도입되기에 이르렀다. 따라서 copy-modify-merge 모델의 CVS를 사용하는 개발자는 기본적으로 다음과 같은 과정을 거치며 개발 작업을 진행해 나가게 된다.

[1] 개발자는 CVS 서버로부터 소스코드 카피를 다운로드(check-out)한 다음
[2] 소스코드를 수정하고
[3] 완료된 작업은 다시 CVS 서버로 올려준다(check-in, commit)

여기서 conflict의 발생 여부는 commit 작업 단계에서 알 수 있다. 그리고 조금 전에 잠깐 살펴보았듯이 현재 개발자의 컴퓨터의 소스코드를 cvs 서버 쪽과 가능한 한 동일하게 유지하려면 update를 자주 해 주는 것이 좋다.

CVS와 관련된 용어
CVS와 관련된 용어는 통일된 번역이 아직 존재하지 않는 것 같아 원문 그대로 싣고 여기에 설명을 덧붙이도록 하겠다.

◆ repository : CVS 서버에 들어가 있는 바로 그 원본(master copy) 소스코드를 의미한다. 나중에 최종 출시가 되는 소스코드가 바로 이 repository이며 repository는 그동안 버전업되어 온 정보를 모두 포함하고 있다. cvs respository의 개수는 하나가 된다.

◆ working copy : 각각의 개발자가 작업을 위해 cvs repository에서 복사해 갖고 나간(check-out) 소스코드가 working copy이다. 따라서 working copy는 개발자의 수만큼 존재한다고 볼 수 있다. 개발자는 이 working copy에서 소스코드 수정 작업을 한 다음 나중에 check-in 혹은 commit 단계를 거쳐 원본 cvs repository에 수정을 가하게 된다.

◆ check-out : 개발자가 자신이 작업할 working copy를 CVS 서버에서 한 카피 복사해 가는 것을 check-out이라고 한다.

◆ update : update는 check-out과 비슷하게 cvs repository에서 원본 소프트웨어를 한 카피 가져오는 역할을 하지만, update는 단어의 원래 뜻 그대로 수정된 부분만 가져와서 현재 개발자가 쓰고 있는 working copy가 항상 최신의 갱신본이 될 수 있도록 해 준다. 일반적으로, 개발자는 한번 working copy를 check-out 한 뒤에는 최신의 소스코드를 유지하기 위해 이 update 명령을 주로 쓰게 된다.

◆ check-in 혹은 commit : 여기서 잠깐 조심해서 봐야 할 것이 update와 check-in의 관계이다. 얼핏 보기에는 CVS에서 check-out과 check-in이 반대의 개념이 되어야 할 것 같은데 실상 check-in의 반대 개념은 update이다. check-in은 내가 작성한 소스코드를 repository에 병합시켜서 다른 개발자들도 내가 작성한 수정 부분을 볼 수 있게 해 주는 소위 publish 작업이기 때문이다. 따라서 그 반대 개념은 내가 다른 사람들이 작성한 소스코드 수정본을 나의 working copy에 반영시키는 것인데 이 작업이 update 과정이다. 따라서 check-in 과정은 오히려 commit이라는 단어를 써서 표현하는 것이 혼동을 미리 방지하는 효과가 있지 않나 싶다. 참고로 commit 권한은 잠시 언급했듯이 소수의 주요 프로젝트 리더들이 갖게 되는 경우가 많다. 어떤 오픈소스 프로젝트에서 커미터의 역할을 담당한다는 것은 그 사람의 기여도가 높고 그만큼 높은 위치를 배정받았다는 뜻이 된다.

update와 commit에 관해서 또 하나 알아놓을 상식은 update와 commit 작업은 가능하면 자주 해 주는 것이 좋다는 사실이다. 다른 사람들이 내가 어떤 작업을 하는지 잘 알고, 나 역시 다른 사람들이 어떤 작업을 하고 있는지 잘 아는 것이 효율적인 협업(collaboration)의 기초가 됨은 두말할 필요가 없다. 추가적으로 CVS의 commit 명령 사용 예는 다음과 같다. -m 옵션 뒤에는 이번 commit에 대한 간략한 설명이나 주석문이 따라온다.

$ cvs commit -m "added additioinal messages" hello2.c   # 파일 하나 commit 예

$ pwd
/home/foobar/projects/src1
$ cvs commit -m "removed redundant declarations"       # 전체 디렉토리 commit 예

◆ log message : 수정된 소스코드를 commit할 때 이 소스코드가 어떤 역할을 하는지, 어떤 부분이 바뀌었는지 등을 기술하는 주석문 역할의 메시지이다. 이것 역시 코딩시 주석문 작성에 신경을 많이 쓰는 것처럼 수정된 소스코드를 commit할 때 마다 간결하고 정확하게 써 주는 것이 좋다.

오픈소스 프로젝트에 많은 참여를
지금까지 여러 명의 개발자, 특히 오픈소스 프로젝트에 참가할 때 필수적으로 쓰이는 유틸리티인 diff와 patch, 그리고 CVS의 기본 사용법에 대해서 알아보았다. 최근 들어서는 문서 작성도 오픈소스와 비슷하게 여러 사람이 동시에 같은 페이지를 고쳐 나가는 방식이 정착되어 가고 있다. 위키(wiki)의 사용이 늘어나고 있는 것이 바로 그것인데 위키는 내부적으로 RCS를 사용해서 문서의 버전 컨트롤을 해 나가는 경우가 많다. 즉, 위키를 통한 문서 작성 방식도 CVS를 이용한 오픈소스 소프트웨어 개발과 근본적으로 다르지 않은 것이다.

앞에서도 강조했듯이, 오픈소스 프로젝트에 참여하기 위해서 가장 중요한 것은 diff와 patch의 사용법을 아는 것이다. 일견 간단해 보이는 이 유틸리티들이 이메일, 그리고 이메일의 확장판인 메일링 리스트와 초기 유즈넷 뉴스그룹과 결합되면서 인터넷상에서 중요 오픈소스 소프트웨어 개발의 문을 열어젖힌 주역들이다.

또한, 이렇게 오픈소스 프로젝트에 참여하는 것이 생각만큼 어렵지 않다는 점을 일반 개발자들이 인지하는 것도 중요하다고 하겠다. 필자 역시 CVS의 사용법을 알기 전에는 내가 CVS의 사용법을 모르는데 오픈소스 프로젝트 참여가 가능하겠는가라는 쓸모없는 생각을 했던 적이 있다. 필자의 경우는 실제 떨어지는 코딩 능력이 오픈소스 프로젝트 참여에 장벽이 되고 있는데 이 글을 읽는 많은 독자들이 이번 연재를 계기로 오픈소스 프로젝트에 좀 더 많이 참여해 보는 기회를 가질 수 있으면 좋겠다는 것이 필자의 바람이다. 단 한 줄의 diff로 만든 패치라도 오픈소스 개발자에게는 많은 도움이 되며 또한 격려의 응원이 된다.