공룡호가 사는 세상 이야기

오라클 +1
EtherNet/IP 프로젝트를 진행하면서 SPARC Solaris 5.10 에서 공유 메모리를 사용하게 되었다.
기존에 Windows 에서는 공유 메모리 Key 제약도 char* 형태로 받아서 문제없이 진행되었지만
shmget 같은 경우는 key_t 형태로 Key 를 받기 때문에 기존에 char* 형태의 Key로
유일무일한 key_t 타입으로 변경하기엔 쉽지 않았다. 물론 이것만 보면 가능하겠지만
우리 프로젝트에서는 좀 더 많은 제약사항이 있었기에 힘들었다는 것이다.

이 문제를 해결하고, 당면한 문제는 Solaris 5.10 에서 공유 메모리 할당 받는 부분에서
Segmentation Fault 에러가 난 것이다.
Debugging 을 통해서 공유 메모리를 할당받은 것을 memset 하는 부분에서 나는 것을
알 수 있었고, 좀 더 삽질 끝에 공유메모리 개수에 따라 에러 유/무가 나타나는 것을
알 수 있었다. 이러면서 ipcs 명령어로 생성된 공유 메모리 상태를 확인하였는데
128개에서 더 이상 생성되지 않는 것이다.

Sun Document 를 찾아 본 결과 아래와 같은 결론을 지을 수가 있었다.

1. Solaris 8 버전 이하에서는 /etc/system 파일에서 IPC 설정을 하면서 제어가 가능했다.
2. 새롭게 Solaris 10 버전에서는 /etc/project 파일에서나 Resource controls 프로그램으로 
    IPC 설정이 가능하다.
3. 기존의 구성 설정은 무시된다.

간략하게 요약하면 위와 같다. 좀더 세부적인 항목은 아래를 살펴보자.

자원 제어

폐기된 항목

이전값

최대값

새 기본값

process.max-msg-qbytes

msginfo_msgmnb

4096

ULONG_MAX

65536

process.max-msg-messages

msginfo_msgtql

40

UINT_MAX

8192

process.max-sem-ops

seminfo_semopm

10

INT_MAX

512

process.max-sem-nsems

seminfo_semmsl

25

SHRT_MAX

512

project.max-shm-memory

shminfo_shmmax

0x800000

UINT64_MAX

실제 메모리의 1/4

project.max-shm-ids

shminfo_shmmni

100

224

128

project.max-msg-ids

msginfo_msgmni

50

224

128

project.max-sem-ids

seminfo_semmni

10

224

128


우리는 위의 표에서  project.max-shm-ids 부분을 주목할 필요가 있다.
바로 우리가 찾는 128 한계 값인 것이다. 이것을 우리가 원하는 값으로 수정해줄 필요가 있다.
자원제어(rctls) 기능은 Solaris 9에서 새롭게 지원되는 기능으로, 기존에 Solaris 8 이전에 제공되던
Software Express 파일럿 프로그램의 새로운 버전이라고 생각하면 된다.

각설하고 우리는 여기서 prctl 라는 Resource controls 프로그램을 사용하기로 하였다.
이 프로그램은 실행되는 프로세스, 태스크, 프로젝트 단위로 Resource를 얻거나 설정할 수 있다.
기타 다른 설정할 수 있는 프로그램으로는 rctladm 이라는게 있다고 한다.
물론, 찾아보면 zonecfg 로도 설정할 수 있고 /etc/project 파일에서 설정할 수 있다고 한다.
하지만, 내가 생각하기에 가장 명료한 prctl 로 제어를 하기로 했다.

# prctl -n project.max-shm-ids $$
NAME ...생략
           privileged       128 ... 이하 생략

value 인 128을 수정해야 한다.

# prctl -n project.max-shm-ids -v 1000 -r -i project user.root
# prctl -n project.max-shm-ids $$
........ 생략 1.00K .... 생략...

1000 개로 바뀐 걸 알 수 있다. 명령어에 대한 자세한 사항은 해당 man 페이지나
http://docs.sun.com/app/docs/doc/816-5165/prctl-1?l=ko&a=view 사이트에서
자세히 알 수 있고, 마지막 user.root 는 어디에 적용시킬지 정하는 건데
# id -p 를 통해서 현재 내 projid=1(user.root) 임을 확인하고 적용시켰다.
물론 그룹으로 해도 되며, group.root 형식으로 하면 된다.

두 번째로, shm-memory 값도 변경하여야 한다. 형식은 위와 같다.

# prctl -n project.max-shm-memory -v 100M -r -i project user.root

확인 하면 100MB로 설정 돼 있는 것을 알 수 있을 것이다.
물론 이는 시스템이 재부팅 되면 다시 기본 값으로 되돌아 온다.
이를 막기 위해서는 /etc/project 파일에 적어주는 것과
해당 명령을 부팅 시에 자동으로 적용 시킬 수 있게 만들어 주면 될 것이다.

참고자료 : http://download.oracle.com/docs/cd/B19306_01/install.102/b15690/pre_install.htm#sthref259