lsof anon_inode

사내에서 개발한 리눅스 플랫폼 프로그램을 테스팅하면서 File descriptor 를 감시해야 하는 경우가 생겼다.

Socket 을 열고 정상적으로 종료를 하는지 확인하는 내용이었는데.. 이를 위해서 lsof 유틸리티를 사용했다.

$ lsof -p [PID] | wc -l

의 명령어로 갯수를 확인하면서 open file descriptor 수를 감시했다.

그러던 중, lsof 의 결과 출력을 분석했는데 이상한 것이 있었다.

cbapid  5560 root    3u  0000                0,7        0       521 anon_inode
cbapid  5560 root    4u  0000                0,7        0       521 anon_inode
cbapid  5560 root    5r  0000               0,11        0 271110595 eventpoll
cbapid  5560 root    6u  0000                0,7        0       521 anon_inode
cbapid  5560 root    7r  0000               0,11        0 271110596 eventpoll
cbapid  5560 root    8u  0000                0,7        0       521 anon_inode
cbapid  5560 root    9u  0000                0,7        0       521 anon_inode
cbapid  5560 root   10r   CHR                1,9      0t0  97762892 /dev/urandom
cbapid  5560 root   11r  0000               0,11        0 271110599 eventpoll

anon_inode 와 같이 나타난 file descriptor 들이 많이 있는 것을 확인한 것이다.

anon_inode 가 무엇이고 왜 나타나는 것일까?

해답은 다음과 같다.

anon_inode 는 anonymouse_inode 의 약자이며, epoll 을 사용할 경우, 감시대상 file descriptor 들을 관리하기 위해서 생성하고 사용하는 file descriptor 인 것이다.
즉, 내부적으로 epoll 을 사용하는 library 가 있다면 나타나는 정상적인 현상인 것이다.

참조 :  http://stackoverflow.com/questions/8170902/why-is-the-jdk-nio-using-so-many-anon-inode-file-descriptors

 

 

mtp mount in gentoo

Gentoo 머신에 안드로이드 폰을 연결해서 사용할 일이 있었다. 그냥 될 줄 알고 케이블을 연결했는데 인식이 안되는 것이었다. 역시… 뭔가를 해주어야 했다.

Gentoo wiki 에서는 mtp mount 하는 방법을 세가지 소개하고 있다. 바로 mtpfs, go-mtpfs, kde 이다. 이중 나는 mtpfs 와 go-mtpfs 를 사용했다.

결론적으로 mtpfs 는 원활한 동작이 되지 않았다. Mount 까지는 성공한 듯 싶었으나, 실제 마운트된 디렉토리에서 파일들에 접근할 수가 없었다. go-mtpfs 의 경우 완벽하게 동작했다.

먼저 go 를 설지하자.

$ sudo emerge dev-lang/go

그리고 mtpfs 를 위한 추가 작업을 진행해주자.

pchero@localhost ~ $ mkdir go
pchero@localhost ~ $ export GOPATH=/home/pchero/go
pchero@localhost ~ $ go get github.com/hanwen/go-mtpfs

그리고 그룹을 추가해주고…

$ sudo gpasswd -a pchero plugdev

마운트할 디렉토리를 생성하고 휴대폰에 케이블을 연결한 뒤, 마운트를 해주자.

$ mkdir ~/Android$ ~/go/bin/go-mtfs ~/Android

언마운트를 할 때는 아래와 같이..

$ fusermount -u ~/Android/

출처: https://wiki.gentoo.org/wiki/MTP

Using wsdl files on C

회사 프로젝트로 wsdl 파일을 이용한 웹 서비스 프로그램을 제작해야 할 일이 있었다.

물론 사용 언어는 C.
먼저 wsdl 파일들에서 header 파일을 추출해야 했다.

이를 위해서 사용한 프로그램은 wsdl2h

 3개의 wsdl 파일에서 header 파일을 추출해야 했다.

다음의 명령어를 사용했다.

$ wsdl2h -c -o SoapEnv.h SendSms.wsdl

$ wsdl2h -c -n SendSms -o SendSms.h SendSms.wsdl

$ wsdl2h -c -n ReceiveSms -o ReceiveSms.h ReceiveSms.wsdl

$ wsdl2h -c -n SmsNotificationManagerService -o SmsNotificationManagerService.h SmsNotificationManagerService.wsdl

위의 명령어를 잘 보면 추출해야 하는 wsdl 파일은 3개인데, 사용한 명령어는 총 4개이다.
정확히는 SendSms.wsdl 파일에서 두개의 header 파일을 추출했다.

 이유는 실제 컴파일과 라이브러리 구현에 사용할 gsoap를 위해서 기본 header 파일이 필요했기 때문이다. 
그리고, 위에 나타낸 옵션 중, −c 옵션은 c 언어를 위한 헤더 파일 생성 옵션, −n 옵션은 namespace 영역을 구분짓기 위해 사용한 옵션이다.

하나 이상의 wsdl 파일을 사용한 라이브러리 제작시, −n 옵션이 특히 중요한데, 이유는 −n 옵션 없이 wsdl2h 를 사용할 경우, 여러개의 wsdl 사용시 서로 혼합된 namespace 영역을 사용하기 때문이다.
이는 나중에 wsdl 파일을 추가 하게 될 경우, 프로그램 코드상에서 호출되는 메소드 이름이 변경이 되는 등 여러모로 곤란이 생긴다. 때문에 반드시 필요한 옵션이다.
ref: http://www.cs.fsu.edu/~engelen/soapdoc2.html#tth_sEc8

wsdl2h 를 사용하면 각각의 헤더 파일들이 만들어 진다. 이렇게 만들어진 헤더파일들을 이용해 실제 C 에서 사용 가능한 코드로 만들어줘야 한다.이를 해주는 프로그램이 soapcpp2 이다. 이번 프로젝트에서 다음의 명령어/옵션을 사용했다.

$ soapcpp2 -C -c SoapEnv.h

$ soapcpp2 -C -c -n -pSendSms SendSms.h

$ soapcpp2 -C -c -n -pReceiveSms ReceiveSms.h

$ soapcpp2 -C -c -n -pSmsNotificationManagerService SmsNotificationManagerService.h

나는 이 명령어를 makefile 안에 넣어 두었다. 그리고 매번 컴파일을 실행할 때마다 위의 명령어가 자동으로 시작되도록 구성했다.
왜냐하면 soapcpp2 프로그램의 버전때문이었다. 

soapcpp2 프로그램으로 생성되는 파일들은 바로 C 로 컴파일이 가능한 *.c 파일과 *.h 파일들이다.이를 이용해서 라이브러리를 생성하고, 링크시켜서 사용하기 위해서는 libgsoap.a 파일과 같은 gsoap 라이브러리가 추가로 필요하다.
그런데, 만약 매번 soapcpp2 프로그램을 통해서 *.c 와 *.h 파일을 생성하지 않는다면, 이미 생성되어있는 파일들을 이용해서 라이브러리를 만들고 gsoap 라이브러리와 링크를 할텐데..
 때, *.c/*.h 파일을 생성한 soapcpp2 의 버전과 링크되는 libgsoap.a 파일의 버전이 서로 맞지 않는다면 링크가 안되는 문제가 발생한다.
이런 이유로 매번 컴파일을 진행할 때마다 위의 명령어를 통해서 새로이 stub 코드를 작성하도록 구성했다.

그리고, wsdl2h 사용할 때와 마찬가지로, namespace 영역 구분을 위해 −n 옵션과 −p 옵션을 추가했다. 그리고, gcc 컴파일을 진행시 −D 옵션을 이용해 Define 을 별도로 걸어주었다.
이는 지정된 namespace 영역을 사용하기 위해 필요한 조치이다.
makefile 안에 다음과 같은 Define 을 넣어주었다.ref: http://www.cs.fsu.edu/~engelen/soapdoc2.html#tth_sEc19.36

DEFS                    = -DWITH_OPENSSL -DWITH_NONAMESPACES

마지막으로, 왜 그런지는 모르겠는데..  이상하게 gsoap 라이브러리를 추가시, 자꾸 세그먼트 폴트가 났다.
계속 방법을 찾다가 제일 마지막에 gsoap 라이브러리를 추가 해야 오류가 나지않는 이상한 현상을 확인했다.
왜그러는지는 모르겠으나.. 다른 해결할 방법을 찾지 못했다.

LIBS            =  -lzmq -lczmq -luuid -ljansson -lssl -lcrypto -lpthread -lcurl -lgsoapssl -lgsoap

pmake error on ubuntu

ubuntu 에서 pmake 를 사용하던 도중, 아래의 오류가 나타났다.

library 를 컴파일하는 과정이었는데, 필요한 library는 모두 만들어 놓고, 아래의 오류를 나타내고 죽어버렸다.

building shared object ipvutil library

ranlib libipvutil_pic.a

lint -chapbxzF  -i strlcat.c

pmake: exec(lint) failed (No such file or directory)

lint 프로그램을 찾을 수 없다는 메시지였는데.. lint 가 무슨 프로그램인지 알 수 없었다. 결국 구글링..

http://en.wikipedia.org/wiki/Lint_%28software%29

즉, lint 는 일종의 cppcheck 와 같은 코드 검사기 같은 것이다.

하지만 lint는 bsd-unix 와 같은 unix 계열의 os 에서 주로 사용되는 검사기였다. 즉, ubuntu에는 기본이 아니라는 이야기..

lint 와 같은 역할을 하는 것으로 linux 에서는 splint 가 있어서 설치 한 뒤, ln 명령어로 lint 명령을 사용할 수 있도록 구성했으나, splint 및 lint 의 정확한 사용법을 모르는 상태에서  기본적으로 사용되는 옵션등이 맞지 않아 계속 오류를 나타냈다.

결국 lint 검사를 사용하지 않도록 하고 mk 파일 내용을 수정하는 것으로 해결을 했다.

/usr/share/mk 디렉토리에 있는 bsd.own.mk 파일을 다음과 같이 수정하도록 하자. 굵은 글씨로 나타낸 부분이 lint 사용을 막기 위해 추가한 부분이다.

#       $NetBSD: bsd.own.mk,v 1.120 1999/02/24 14:42:36 drochner Exp $

.if !defined(_BSD_OWN_MK_)

_BSD_OWN_MK_=1

.if defined(MAKECONF) && exists(${MAKECONF})

.include “${MAKECONF}”

.elif exists(/etc/mk.conf)

.include “/etc/mk.conf”

.endif

NOLINT=