특정 서버에서 sendmail 데몬이 제대로 시작되지 않는 증상이 발생되었다.
이로인해 부팅시 sendmail 데몬이 start 될때 한참 동안 응답이 없어 부팅 지연도 발생되었다.

0. 서버 호스트명 정보
OS :  CentOS 6.3 x86_64 minimal

1) 샌드메일이 비정상적으로 구동되는 서버
호스트명 : Storage-Server
LAN IP : 192.168.0.3

2) 샌드메일이 정상적으로 구동되는 서버
호스트명 : WEB-Server
LAN IP : 192.168.0.2

1. 해결하기
# 먼저 문제의 시스템에서 sendmail을 시작시키는 bash 스크립트를 디버깅 한다. -x 옵션을 주고 실행하면 된다.
[root@Storage-Server ~]# bash -x /etc/init.d/sendmail start
.
.
.
+ /bin/bash -c 'ulimit -S -c 0 >/dev/null 2>&1 ; /usr/sbin/sendmail -bd -q1h'
--> 여기서 멈춤

# 문제가 되는 부분의 명령어 일부만 실행해 보자 sendmail 실행파일에서 문제가 보였다.
[root@Storage-Server ~]# /usr/sbin/sendmail -bd -q1h
멈춤..

# 그런데 /usr/sbin/sendmail 은 싱볼릭링크이고 실제 파일은 sendmail.sendmail 이다.
[root@Storage-Server ~]# ls -la /usr/sbin/sendmail
lrwxrwxrwx. 1 root root 21 2013-02-18 11:20 /usr/sbin/sendmail -> /etc/alternatives/mta
[root@Storage-Server ~]# ls -la /etc/alternatives/mta
lrwxrwxrwx. 1 root root 27 2013-02-18 11:20 /etc/alternatives/mta -> /usr/sbin/sendmail.sendmail
[root@Storage-Server ~]# ls -la /usr/sbin/sendmail.sendmail
-rwxr-sr-x. 1 root smmsp 833512 2010-11-12 04:36 /usr/sbin/sendmail.sendmail

# 정상적인 시스템에선 아래와 같은 메시지와 함께 멈춰서 있다.
[root@WEB-Server ~]# /usr/sbin/sendmail.sendmail
Recipient names must be specified

# starce 디버깅 툴을 설치.
[root@Storage-Server ~]# yum install -y strace

# 디버깅
[root@Storage-Server ~]# strace /usr/sbin/sendmail.sendmail
.
.
.
open("/etc/hosts", O_RDONLY)            = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=190, …}) = 0
read(3, "127.0.0.1   localhost localhost."…, 4096) = 190
close(3)                                = 0
open("/etc/localtime", O_RDONLY)        = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=380, …}) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=380, …}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb7d21cc000
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\0\5\0\0\0\0"…, 4096) = 380
lseek(3, -228, SEEK_CUR)                = 152
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\6\0\0\0\6\0\0\0\0"…, 4096) = 228
close(3)                                = 0
munmap(0x7fb7d21cc000, 4096)            = 0
socket(PF_FILE, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 3
connect(3, {sa_family=AF_FILE, path="/dev/log"}, 110) = 0
sendto(3, "<18>Feb 20 14:12:45 sendmail[198"…, 109, MSG_NOSIGNAL, NULL, 0) = 109
rt_sigprocmask(SIG_BLOCK, [ALRM], [], 8) = 0
rt_sigaction(SIGALRM, {0x7fb7d2275140, [], SA_RESTORER|SA_RESTART, 0x7fb7d01c2920}, {SIG_DFL, [], 0}, 8) = 0
alarm(60)                               = 0
rt_sigprocmask(SIG_UNBLOCK, [ALRM], [ALRM], 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [ALRM], [], 8) = 0
pause(
여기서 멈춘다.

# 디버깅 결과를 파일로 저장
[root@Storage-Server ~]# strace -o /tmp/Sendmail-Strace.txt /usr/sbin/sendmail.sendmail
멈춰 있을때 인터럽트 한다. (Ctrl - C)

# 또한 정상적인 시스템에서 디버깅 결과를 파일로 저장해 본다. - 필요시 비교.
[root@WEB-Server ~]# strace -o /tmp/Sendmail-Strace.txt /usr/sbin/sendmail.sendmail
- 문제의 시스템과 정상적인 시스템을 비교

# 비교보다 문제의 서버에서 open 시스템 콜만 추려서 먼저 살펴보는게 우선이다.
(때론 read 까지 같이 봐야 할 경우도 있다. -> strace -e open,read 명령행)
[root@Storage-Server ~]# strace -e open /usr/sbin/sendmail.sendmail
.
.
.
open("/etc/host.conf", O_RDONLY)        = 3
open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 3
open("/etc/hosts", O_RDONLY)            = 3
open("/etc/localtime", O_RDONLY)        = 3
멈춤…

# 문제 발생 직전의 설정파일들 /etc/host.conf /etc/hosts를 살펴본다. 그런데 /etc/hosts 파일에 이상한 설정값이 보였다.

[root@Storage-Server ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.2 Storage-Server       --->  이 부분이 문제. IP와 호스트명을 알맞게 변경한다. (192.168.0.2 WEB-Server 이런 식으로..)

3. 마치며..
문제의 부분인 Storage-Server 명을 다른 이름으로 바꾸면 문제가 발생하지 않는다. 예를 들어 Storage-Server2 식으로..
즉, 자신의 호스트명과 일치하는게 들어가면 sendmail이 실행이 안 된다. 그 이유는 알아보지 않아 왜 그러는지는 모르겠다.

서버의 용도가 바뀌면서 호스트네임을 바꾸게 된게 원인이었다. 원래는 Storage-Server가 WEB-Server라는 호스트명이었다.
그런데 깜빡하고 그에 맞게 hosts 파일을 수정하지 않아서 문제가 발생한 것이다. 생각지도 못 한 이것이 문제를 일으킨것이었다.

별거 아닌것이 문제를 일으켰는데도 로그에서도 확인이 안되고 데몬은 묵묵부답 응답이 없고.. 눈에 안보이니 답답할 노릇이다.
네트워크 상에서 벌어지는 일들을 TCPDUMP를 이용하여 들여다 보듯이 각종 디버깅 툴을 이용하면 프로그램 내면의 흐름과 그 프로그램이 어떤 파일들과 라이브러리들을 이용해서 구동되는지 알 수 있다.
알고보면 별거 없는 bash 디버깅 모드와 strace를 활용한 트러블슈팅에 대해서 알아 보았다.

bash 디버깅 모드와 strace를 활용한 트러블슈팅

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다