Tumgik
lunatine · 11 years
Text
lunatine.net 이사
텀블러가 간편하고 Markdown을 지원해서 잘 사용하고 있었는데 SNS 관련 된 부분과 복잡한 테마 관리 등으로 인해 결국 이사를 결심했다.
텀블러는 tumblr.lunatine.net으로 도메인을 변경하였고 lunatine.net은 다른 블로그 플랫폼으로 Linux 관련 문서만 옮겨서 이사하였다.
개인적인 간단한 이야기는 텀블러에 계속 올릴까 했으나, 이미 SNS 서비스로 충분히 하고 있기 때문에 (귀차니즘) 아마 텀블러는 더 이상 사용하지 않고 보관소로 남지 않을까 싶다.
0 notes
lunatine · 11 years
Text
[FAQ] Linux에서 MBR 파티션 테이블 살펴보기
MBR 파티션 테이블
본 문서는 리눅스 시스템에서 MBR 파티션 테이블의 구조를 확인하는 방법에 대해서 설명하고 있습니다.1
MBR이란?
MBR은 Master Boot Record의 약자로 부팅을 하기 위한 정보를 담고 있으며 일반적으로 0번 섹터에 저장 되어 있습니다. MBR이 여전히 많이 쓰이고 있지만 오래 된 기술이다보니 그 크기는 1개 섹터 크기 (512Byte)로 되어있어 제약사항이 많습니다. 상세한 정보는 위키피디아 문서를 참고하시면 됩니다.
위키피디아 MBR 문서
MBR 구조
표1. (출처 : Microsoft Technet)
MBR은 위와 같은 구조로 되어있습니다. 부팅을 위한 코드 공간이 446Byte. 프라이머리 파티션 테이블을 위한 공간이 64Byte 그리고 MBR 시그니쳐 값으로 2Byte (0xAA55)를 사용합니다. 본 문서에서는 프라이머리 파티션 테이블 부분을 살펴보도록 하겠습니다.
MBR Primary Partition Table
표2. (출처: 위키피디아)
64Byte의 MBR 파티션 테이블 구조는 위와 같은 16Byte 레코드 4개로 이루어져 있습니다. 각 레코드에는 파티션의 상태 정보와 종류, C/H/S 기반의 시작/끝 주소, LBA 기반의 섹터 시작 주소와 파티션 크기 정보가 담겨져 있습니다. 요즘에는 CHS 기반으로 접근하지 않기 때문에 실질적으로 첫 번째 LBA주소와 파티션 크기를 통해서 파티션 테이블 레이아웃을 표현 합니다.
먼저 디스크의 파티션 테이블을 살펴보면 아래와 같습니다. 섹터단위로 보기 위해서 -lu 옵션을 주었습니다. 아래 파티션 테이블은 첫 번째 파티션이 [AF](abbr:Advanced Format) 디스크를 위해서 2048 섹터부터 시작하도록 파티셔닝 되어있습니다.
$ fdisk -lu /dev/sda Disk /dev/sda: 256.1 GB, 256060514304 bytes 255 heads, 63 sectors/track, 31130 cylinders, total 500118192 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000f1ef8 Device Boot Start End Blocks Id System /dev/sda1 * 2048 199999487 99998720 83 Linux /dev/sda2 199999488 500118191 150059352 83 Linux
앞서 살펴본 MBR 파티션 테이블에서는 Start에 해당하는 LBA주소 2048과 그 크기인 199997440이 저장되어있고 이를 통해서 End 위치2 를 표기하게 됩니다.
자, 이제 MBR 파티션 테이블을 열어서 실제로 저장이 되어있는지 확인해 보도록 하겠습니다.
MBR 파티션 테이블 열어보기
먼저 MBR은 0번 섹터에 저장 되기 때문에 아래 커맨드를 통해서 MBR을 통째로 덤프 받도록 합니다. (본 예제에서는 /dev/sda가 OS 디스크 입니다) 1섹터는 512byte 이기 때문에 512byte 1개를 파일로 내려 받습니다.
$ dd if=/dev/sda of=mbr.dump bs=512 count=1
이제 이 파일에서 파티션 테이블에 해당하는 뒤쪽 66byte만 확인하면 아래와 같습니다.
사실 MBR을 따로 받았기 때문에 -n 66 옵션은 생략해도 무방합니다. 그리고 MBR을 저장하지 않고 직접 디스크에서 덤프하는 방법도 있습니다. 본 예제에서는 덤프받은 파일을 가지고 설명합니다.
$ hexdump -s 446 -n 66 mbr.dump 00001be 2080 0021 fe83 ffff 0800 0000 b800 0beb 00001ce 6400 a104 e983 9a7f c000 0beb 72b0 11e3 00001de 0000 0000 0000 0000 0000 0000 0000 0000 * 00001fe aa55 0000200
마지막에 앞서 살펴본 MBR의 시그니쳐인 0xAA55의 값인 aa55가 보입니다.
이렇게 보면 읽기 어렵기 때문에 MBR 파티션테이블의 레코드가 16Byte 이므로 16Byte씩 끊어서 보기좋게 표시해 보도록 하겠습니다.
$ hexdump -s 446 -e '8/1 "0x%02x " "\t" 2/4 "%0d "\n"' mbr.dump 0x80 0x20 0x21 0x00 0x83 0xfe 0xff 0xff 2048 199997440 0x00 0x64 0x04 0xa1 0x83 0xe9 0x7f 0x9a 199999488 300118704 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0 0 * 0x55 0xaa 0x 0x 0x 0x 0x 0x
먼저, 표2.의 파티션테이블의 레코드 명세에 따라서 8Byte는 1Byte 씩 Hex로 표기하도록 하였고 나머지 8Byte는 4Byte씩 숫자로 표기하도록 하였습니다. 그 결과 첫 번째 줄의 마지막 두 컬럼에 fdisk로 확인했던 첫 번째 파티션의 시작 주소인 2048과 그 크기를 확인 할 수 있습니다. 마찬가지로 총 2개의 파티션 테이블을 가지고 있기 때문에 두 번째 줄에서도 두 번째 파티션의 시작 주소와 크기를 확인할 수 있습니다.
이제 Hex로 표기한 8Byte를 살펴보도록 하겠습니다. 첫 번째 줄을 살펴보면 표2.의 명세대로 첫 번째 Byte는 파티션의 상태를 의미합니다. 첫 번째 줄의 0x80을 통해서 부트 파티션임을 확인 할 수 있으며 이는 fdisk에서 "*" 로 표기 된 부트 플래그를 의미하는 걸 알 수 있습니다.
그 뒤의 3Byte(0x20 0x21 0x00)는 C/H/S 값을 의미하며 다음 1Byte 0x83은 파티션의 종류를 의미합니다. 낯익은 숫자인데 이 숫자는 fdisk에서 파티션 타입을 지정할 때 사용하는 값과 정확히 일치합니다.
그리고 나머지 3Byte (0xfe 0xff 0xff)는 종료 지점을 나타내는 CHS 값 입니다.
다시, 시작지점 C/H/S를 나타내는 앞의 3Byte 값을 CHS to LBA 변환 식에 대입해 보면
LBA = ( ( CYLINDER * heads per cylinder + HEAD ) * sectors per track ) + SECTOR – 1 LBA = ( ( 0x00 * 255 + 0x20 ) * 63) + 0x21 -1 = 2048
위와 같이 시작 지점을 나타내는 LBA 주소 값을 얻을 수 있습니다. 실제로 요즘에는 사용되지 않는(다만 OS에서 지원해주고 있는) C/H/S 값은 LBA를 통해 역으로 계산 된 것이기 때문에 참고로만 보시면 됩니다.
이렇게 실제 디스크의 첫 번째 섹터에 있는 MBR을 열어보고 시스템 툴에서 보여주는 값이 어떻게 저장되어 있는지 확인해 보았습니다.
보너스
MBR은 0번 섹터에 기록되기 때문에 [GPT] 는 1번 섹터부터 기록 됩니다.
MBR이 담긴 섹터의 앞쪽 446Byte는 부트코드가 담겨있는데 이곳에 GRUB 부트로더가 들어있습니다. ($ hexdump -C -n446 mbr.dump로 확인해 보세요)
MBR의 파티션 테이블 레코드에서 파티션 크기를 나타내는 값이 4Byte이기 때문에 2^32인 2TB까지만 사용이 가능합니다. 즉, MBR로 단일 파티션이 2TB이상 사용하지 못하는 이유입니다.
이 문서는 MBR에 대한 질문을 받아서 설명해 줬던 내용을 정리한 것입니다. ↩︎
2048 + 199997440 - 1 (2048부터 시작하기 때문) ↩︎
0 notes
lunatine · 11 years
Text
[FAQ] libudev.so.0 라이브러리 오류
Error while loading shared libraries (libudev.so.0)
오류메시지
error while loading shared libraries: libudev.so.0: cannot open shared object file
환경 - Ubuntu 13.04 또는 Linux Mint 15 (64bit)
Ubuntu 저장소를 이용한 패키지 설치가 아닌 외부 패키지를 설치했을 때 이런 메시지를 종종 볼 수 있는데 오류 메시지 그대로 라이브러리를 찾지 못해서 발생하는 메시지이다. 아래 명령을 통해서 쉽게 수정 할 수 있다.
$ cd /lib/x86_64-linux-gnu $ sudo ln -s libudev.so.1 libudev.so.0 $ sudo ldconfig
별 것 아닌 메시지 이지만 libudev 파일 위치를 몰라서 헤매는 경우를 봤기에 간단히 포스팅 해봅니다.
2 notes · View notes
lunatine · 11 years
Text
[FAQ] Upstart 사용에 대해서
Upstart
기존 Unix "System V"에 있던 init 시스템을 대체하기 위한 프로그램 입니다. init을 대체할 뿐만 아니라 다양한 기능을 제공 합니다 또한, upstart는 이벤트 기반으로 동작하기 때문에 설정 내용에 따라서 init 뿐만 아니라 cron, atd, anacron을 대체 할 수도 있으며 inetd와 유사하게 설정도 가능합니다.
예제로 알아보는 job 설정
기본적으로 upstart의 job 설정파일은 /etc/init 아래에 존재 합니다
상세한 내용보다는 즉시 써먹을 만한 간단한 설정에 대해서 소개 합니다
예제 : tty1 설정 파일
# tty1 - getty # # This service maintains a getty on tty1 from the point the system is # started until it is shut down again. start on stopped rc RUNLEVEL=[2345] and ( not-container or container CONTAINER=lxc or container CONTAINER=lxc-libvirt) stop on runlevel [!2345] respawn exec /sbin/getty -8 38400 tty1
JOB 파일의 문법은 직관적 형태를 띄고 있습니다.
start on / stop on
먼저 start on, stop on에 대해서 살펴보면 뒤에 지시되는 이벤트에 대해서 각각 시작, 정지를 하도록 지정하는 내용입니다. upstart는 관리자가 직접 시작/종료 처리를 해 줄 수도 있지만 JOB 파일에 지정한 이벤트에 따라서 자동으로 시작/종료가 가능합니다. start on/stop on 뒤에는 보통 아래와 같은 이벤트 지시지가 따라 붙습니다
start on startup start on runlevel [23] start on stopped rcS start on started tty1
startup : 시스템이 부팅할 때를 의미합니다 (보통 start on과 같이 쓰임)
runlevel : 뒤에 지정 된 런레벨을 의미합니다. 만약 [!23] 으로 설정되었다면 2,3 런레벨을 제외한 나머지 경우를 의미합니다. 런레벨은 0~6,S가 올 수 있습니다.
stopped : 뒤에 지정 된 JOB이 종료 되었을 때를 의미합니다.
started : 뒤에 지정 된 JOB이 시작 되었을 때를 의미합니다.
shutdown : 시스템 종료할 때를 의미합니다. (보통 stop on과 같이 쓰임)
respawn
이 지시자가 있으면 해당 프로세스가 죽었을 경우 (또는 crash 되었을 경우) 자동으로 프로세스를 다시 실행시켜 줍니다.
exec
실제 서비스가 시작될 때 실행하는 내용을 담고 있습니다. 위 예제에서는 /sbin/getty를 실행하도록 되어있습니다.
이 외에도 많은 설정 방법이 존재하는데 Upstart Cookbook을 참고하시면 됩니다.
Upstart 명령
Upstart 명령은 아래와 같습니다. init system을 대체하기 때문에 init과 동일한 이름의 명령도 존재 합니다.
서비스 제어 (service 명령으로도 바꿔서 사용할 수 있습니다)
initctl - service 명령의 대체 명령으로 사용이 가능합니다. 보통 initctl [JOB이름] [명령] 형태로 사용합니다
start - 서비스 시작
stop - 서비스 종료
reload - SIGHUP 시그널을 전송합니다.
restart - JOB설정파일을 읽지 않고 서비스를 재시작 합니다
status - 서비스 상태 확인
예제
$ initctl console stop : initctl을 통해서 console JOB을 종료한다 $ stop console : console JOB을 종료한다 $ start serial : serial JOB을 실행한다
리부팅 / 시스템 종료
halt - 시스템을 종료 후 전원을 OFF합니다
poweroff - halt와 동일합니다.
reboot - 시스템을 재부팅합니다.
shutdown - 시스템을 종료합니다.
그 외의 명령 (직접 실행 할 일은 없음)
init - Upstart 프로세스 관리 데몬
runlevel - 기존 runlevel 호환성을 위한 명령
telinit - 기존 runlevel 호환성을 위한 명령
upstart-udev-bridge - Upstart와 Udev간의 연계를 위한 명령
그 외
initctl list 명령으로 현재 upstart로 관리되는 프로세스의 상태를 모두 확인 할 수 있습니다.
환경변수로 지정 된 값에 대해서 수동으로 시작/종료 할 경우에는 명령 뒤에 옵션으로 지정할 수 있습니다
예시) initctl serial stop 을 실행했을 경우 $ initctl serial stop stop: Unknown parameter: DEV 수동으로 실행 할 경우에는 DEV 변수 값이 필요하기 때문에 아래와 같이 실행합니다. $ initctl serial stop DEV=ttyS0
References
upstart homepage : http://upstart.ubuntu.com/
0 notes
lunatine · 12 years
Photo
Tumblr media
오늘 본 가장 슬픈 사진....
뉴스기사 : http://t.co/Ov88if7wZZ
솔직히 뉴스 기사 따위는 눈에 들어오지도 않았다. 사진의 아이를 보니 짠한 마음에 슬퍼지기만 했다.
아이는 최대한 부모와 가깝게 지내야 하는 것인데..
맘이 아프다.
1 note · View note
lunatine · 12 years
Text
League of Legends 맥(Mac OS X) 버전으로 한국 서버 접속
안내
텀블러는 더이상 사용하지 않기 때문에 이 문서는 더 이상 갱신되지 않습니다. 블로그 새 문서로이동
맥 클라이언트 에디터 프로그램을 사용하시기를 권장 드립니다.
0.0.0.39 버전부터 lol.properties 설정 값이 아래와 같이 변경 되었음
출처 : ThisIsGame
host=prod.kr.lol.riotgames.com xmpp_server_url=chat.kr.lol.riotgames.com lq_uri=https://lq.kr.lol.riotgames.com rssStatusURLs=null regionTag=kr lobbyLandingURL=http://leagueoflegends.co.kr/Launcher/launcher_main.php featuredGamesURL=http://spectator.kr.lol.riotgames.com:8088/observer-mode/rest/featured storyPageURL=http://leagueoflegends.co.kr/Launcher/launcher_journal.php ladderURL=http://www.leagueoflegends.co.kr platformId=KR1
LOL
요즘 가장 Hot한 게임으로 유명한 League of Legends. 하지만, 인기가 있는 만큼 그리고 승부욕이 매우 강한 한국 사람들의 특성에 따라서 승리에 적합한 플레이를 하지 못할 경우 서로의 부모님 안부를 물어보고 주변 사람들의 안부도 물어보는 훈훈한 장면이 연출 된다고 한다.
나는 주로 심심풀이로 1~2시간 정도 하는데 AI하고만 놀고 있다. 스트레스 해소를 위해 게임을 하면서 다른 이유로 인해 스트레스 받는 것은 내 플레이 스타일하고 맞지 않는다. 무엇보다 내가 게임을 단지 즐기는 편이지 승부욕은 없기 때문일지도 모르겠다. 여튼, 지인들과 같이 모여서 오프라인에서 만나서 노는게 아닌 이상 AI하고만 대결을 펼치는 편이다.
그래서, 가상 머신에 LOL을 설치해서 가끔 플레이 하는 정도인데 최근에 후배를 만나 LOL 맥 버전 정식 클라이언트가 나왔다는 소식을 접했다. 그래서 찾아보니 아직은 북미 한정으로 베타버전으로 배포되고 있었다. 물론, 나야 AI하고만 놀기 때문에 북미 서버밖에 접속 안되는 것이 큰 문제는 안되지만 상대적으로 빠른 응답속도를 위해서 한국 서버로 접속 하고 싶은 생각이 들었다. 느낌상 과거 디아블로3 맥 클라이언트를 수정한 것처럼 수정하면 가능할 것 같았다.
LOL 북미버전 다운로드
아래 주소는 LOL Mac OS X 북미버전을 다운로드 링크이다. http://signup.leagueoflegends.com/en/signup/redownload
dmg 파일을 다운로드하고 드래그&드롭으로 설치 후 실행하면 게임에 필요한 파일을 다운로드 하기 시작한다.
로케일 설정
런처에서 다운로드 및 설치가 완료 되면 아래 경로의 파일을 찾아서 수정해 준다. 터미널에서 찾거나 아래처럼 파인더에서 패키지 내용보기로 들어가면 된다.
파인더 : 패키지 내용보기 > Contents > LOL > RADS > system > locale.cfg 터미널 : /Applications/League of Legends.app/Contents/LOL/RADS/system/locale.cfg locale = en_US 위 내용을 아래와 같이 바꾼다 locale = ko_KR
한글 언어팩 다운로드 확인
로케일 값을 수정 한 후에 런처를 실행하면 한글과 관련 된 데이터를 추가로 다운로드하게 된다
다운로드가 모두 완료 되면 런처를 종료하고 서버 접속에 필요한 정보를 수정 해 준다
서버 접속 정보 수정
아래 경로의 파일을 찾아서 먼저 백업을 해 둔다. (북미와 한국의 패치버전이 다를 경우에는 접속이 안되는 문제가 발생 할 수 있기 때문에 백업해 둔다) 그리고 편집기로 아래와 같이 수정해 준다.
기본 접속 정보 파일 위치
/Applications/League of Legends.app/Contents/LOL/RADS/projects/lol_air_client_config_na/releases/0.0.0.38/deploy/lol.properties
0.0.0.38은 버전 번호이다. 이 파일을 편집기로 열면 아래와 같다
한국서버 접속 정보 파일로 수정
위에서 찾은 파일을 아래와 같이 수정해 준다
host=prod.kr.lol.riotgames.com xmpp_server_url=chat.kr.lol.riotgames.com ladderURL=http://www.leagueoflegends.co.kr storyPageURL=http://www.leagueoflegends.co.kr/Launcher/launcher_journal.php lq_uri=https://lq.kr.lol.riotgames.com/login-queue/rest/queue ekg_uri=https://ekg.riotgames.com regionTag=kr rssStatusURLs=null lobbyLandingURL=http://leagueoflegends.co.kr/Launcher/launcher_main.php loadModuleChampionDetail=true featuredGamesURL=http://spectator.kr.lol.riotgames.com:8088/observer-mode/rest/featured
저장 후 플레이
설정 파일을 모두 저장하고 런처를 실행 시키면 끝. 그런데, 사용자 지원에 충실하기로 소문난 라이엇게임즈이기 때문에 조만간 한국어 클라이언트가 올라올 듯 하다.
이 내용은 어디까지나 임시방편.
0 notes
lunatine · 12 years
Text
[FAQ] Cylinder 값이 초과 되었는데? (CHS vs LBA)
이미 인터넷에 CHS와 LBA에 대한 내용을 다룬 훌륭한 문서가 많이 있다. 다만, 최근 Cylinder 값의 초과에 대해서 이상하게 생각하는 경우에 대한 답변을 위해 본 문서를 작성하게 되었다. # Advanced Format과 alignment 최근 Advanced Format(AF) 디스크가 등장하면서 디스크를 파티셔닝하는데 정렬(alignment)에 대한 이슈가 생겨났다. 기존 섹터가 512byte 단위였던 것이 4096byte(4K)로 증가하면서 디스크 접근에 있어서 성능저하를 막기 위해 파티션의 시작지점을 4K 단위로 맞춰 줄 필요가 생긴 것이다. 최신 parted에서는 aligment 옵션을 제공하지만 fdisk와 같은 툴 에서는 제공하지 않아 Bash 쉘 스크립트로 섹터 값으로 계산해서 파티셔닝 하도록 툴을 만들어 해결 했고 이를 업무에 활용하였다. 그런데, 파티션 결과에 대한 문의 사항이 많아 이 문서를 작성하게 되었다. 본 글에서는 AF에 대해서는 다루지 않을 것이기 때문에 관련 된 내용은 구글(Google)신에게.. # Cylinder의 초과 먼저 500GB SATA 디스크의 파티션 정보(fdisk -l /dev/sda)를 보면 ![Imgur](http://i.imgur.com/eE5zJ.png) 분명히 디스크 정보에는 실린더가 **60788**개가 존재 한다고 되어있는데 파티션 된 정보를 보면 **60789**까지 파티셔닝이 되어있다. 디스크에 허용된 범위를 초과해 버린 잘못된 파티셔닝이 아닌가 하는 의구심이 들 수 있다. 또한, 3개 파티션의 시작과 끝 부분이 다음 파티션 실린더 값과 동일하다. 파티션의 시작과 끝이 서로 맞물려 버렸으니 문제가 된다라고 생각할 수 있다. 그러면 해당 디스크 정보를 섹터(sector) 단위로 확인해 보자. (fdisk -lu /dev/sda) ![Imgur](http://i.imgur.com/WYCBZ.png) 위 그림에서 보이는 것 처럼 전체 976562176개의 섹터 중에서 976562175까지만을 사용 한 것을 알 수 있다. 그리고, 각 파티션은 맞물리는 섹터가 없이 깔끔하게 나뉘어 있는 것을 볼 수 있다. * 참고로 첫 번째 파티션이 2048부터 시작하는 것은 AF 디스크 정렬을 위해서 이다 전체 섹터를 다 사용하지도 않았는데 왜 실린더는 초과한 것으로 보일까? 먼저 이렇게 된 배경을 살펴보도록 하겠다. # CHS (Cylinder-Head-Sector) CHS 주소 지정 방식은 물리적인 디스크의 위치를 나타내기 위한 주소 방식이다. ![Imgur](http://i.imgur.com/ylwj4wY.png) 위 그림의 각 항목은 * Platter : 원형 판. 과거 플로피 디스크의 내부 저장 마그네틱 판 또는 CD-ROM 처럼 원형이다. * Track : 나무의 나이테처럼 원형으로 데이터를 기록하는 줄이 트랙이다. * Sector : 트랙을 일정한 구간으로 나누어 놓은 것이 섹터이며 512byte (AF는 4KB)이다. 1부터 시작. * Head : 디스크를 읽어들이는 부분. * Cylinder : 트랙을 수직으로 잘랐을 때 같은 위치에 있는 트랙의 집합으로 물리적인 값이라기보다는 논리적인 값 이다. 위 그림은 총 3개의 플래터와 6개의 헤드를 가지고 있다. 즉, 플래터가 양면에 데이터를 기록 할 수 있다. 운영체제에 의해서 특정 파일을 접근하려고 하면 [BIOS INT 13h][] 인터럽트를 통해서 디스크 컨트롤러에 명령을 내리게 되는데 만약 CHS(10/3/6)라는 주소에 접근하도록 명령을 내렸다면 **4번 째 헤드를 11번 째 실린더의 6번 째 섹터**에 위치시키고 데이터를 읽게 된다. 이러한 디스크 접근 방법이 CHS 방식이며 초기에 제안된 ATA 표준에 의해서 28bit 블럭 주소방식을 사용하였다. 28bit는 실린더 16bit, 헤드 4bit, 섹터 8bit로 할당 되었다. 나중에 [ATA-1][]이 정식으로 소개되면서 [BIOS INT 13h][]가 지정할 수 있는 24bit에 맞추어 아래와 같이 바뀌었다. * Sylinder : 10bit (2^10 = 1024) * Head : 8bit (2^8 = 256) * Sector : 6bit (2^6 = 64) 결과적으로 아래 표와 같이 가용공간을 계산 할 수 있게 된다. (※ 참고로 섹터는 1부터 시작한다) ![Imgur](http://i.imgur.com/rYRLw.png) 표에서 나타난 것 처럼 CHS 방식으로는 504MB까지 밖에 사용할 수 없기 때문에 이를 개선하고자 [ECHS][](Extended CHS)라는 것이 등장하였다. Large Mode라고도 불리우는 ECHS는 BIOS가 전달하는 값에 특정 값을 곱하거나 나누어서 확장시키는 방식인데 그 결과 아래 표와 같은 가용 공간을 사용 할 수 있게 되었다. ![Imgur](http://i.imgur.com/lSBdE.png) 즉, [BIOS INT 13h][]는 실린더를 1024로 제한하고 있지만 실제 디스크는 그 이상의 실린더를 사용하고 전달하는 과정에서 8로 나누어 1024 제한을 충족시키는 방식이다. 하지만, 이 방식도 위 표에서 나타나는 것 처럼 7.88GB 이상을 사용할 수 없기 때문에 그리 오래가지 못하였다. 이 모든걸 해결하고자 등장 한 것이 [LBA][](Logical Block Addressing) 모드이다. # LBA 앞서 이야기 한 CHS를 해결하고자 등장 한 것이 [LBA][]라는 것은 정확한 말은 아니다. 실제로 [LBA][] 주소 지정방식은 IDE 표준에서 22bit를 옵션으로 포함하고 있었으며 [ATA-1][]이 공표될 때 28bit로 확장되었다. (※ ATA-6에서는 48bit) 단지, CHS가 물리적 접근에 있어서는 보다 명료했으며 먼저 사용되기 시작하였고 한계점을 드러내면서 LBA가 주목 받은 것이다. LBA 방식은 CHS 처럼 물리적인 연산이 아닌 사용가능한 모든 섹터를 배열로 나타낸 것이다. 즉, LBA 주소 0은 CHS(0,0,1)이다. 실질적으로 ATA-6가 등장하면서 48bit LBA 주소가 제안되었고 LBA 주소로 접근하면 디스크 컨트롤러가 알아서 물리적인 주소로 변환해서 접근하기 때문에 신경 쓸 필요가 없지만 CHS로 디스크 정보를 보여주는 툴의 이해를 위해서 (혹은, 임베디드 같은 분야에서 필요로해서) CHS와 LBA와의 상관관계를 살펴보도록 하겠다. * 참고로 [BIOS INT 13h][]의 위키 문서에도 나와있지만 웨스턴디지털과 피닉스 테크놀러지에서 INT 13h Extensions을 소개하였다. 이는 현 시스템들이 사용하는 방식이며 64bit LBA 주소(8ZiB까지 사용가능)까지 지원한다. 먼저, CHS를 LBA로 변환하는 수식이다. [참고문서](http://www.datarecoverytools.co.uk/2009/12/22/chs-lba-addressing-and-their-conversion-algorithms/) LBA = ((실린더 x 실린더 당 헤드 + 헤드) x 트랙 당 섹터) + 섹터 - 1 중요한 것은 LBA 주소로 부터 CHS주소인 실린더, 헤드, 섹터 값을 얻어내는 것인데 이는 아래와 같다. 실린더 = LBA / (실린더 당 헤드 * 트랙당 섹터) 헤드 = (LBA % (실린더 당 헤드 * 트랙당 섹터)) / 트랙당 섹터 섹터 = (LBA % (실린더 당 헤드 * 트랙당 섹터)) % 트랙당 섹터 + 1 # fdisk의 결과는? ![Imgur](http://i.imgur.com/WYCBZ.png) 이제 다시 처음 살펴봤던 500GB 디스크의 fdisk 결과를 살펴보면 전체 섹터는 976562176개 였다. LBA는 논리적인 섹터 배열 주소 값이기 때문에 마지막 파티션의 끝 섹터 976562175는 LBA로 976562174이며 실린더 값을 구해보면 다음과 같다. 실린더 = 976562174 / (255 * 63) = 60788.183877995645 실린더는 논리적인 값이기 때문에 정확히 나누어 떨어지지 않는다. 여튼, 소숫점을 떼어내면 해당 파티션이 끝나는 위치의 실린더는 fdisk가 보여주는 전체 실린더 개수 60788과 일치한다. 정리하면 /dev/sda3 파티션의 마지막 섹터가 속한 실린더 위치는 60788.183877995645라는 위치가 된다. 그렇기 때문에 fdisk는 이것을 60789 (60788을 넘어선 위치)로 판단한 것 같다. 상세한 것은 fdisk 소스를 열어보면 되겠지만 시간도 걸리고 크게 중요한 것은 아니라서 생략했다. 대신 구시대 유물인 fdisk 보다 최신의 파티션 툴인 parted의 결과를 보여주면 아래와 같다. ![Imgur](http://i.imgur.com/lsY4w.png) parted는 해당 디스크가 60788 실린더를 가지고 있으며 마지막 파티션이 60788에서 끝난다고 표기해 주고 있다. 첫 번째 파티션의 시작 지점의 표현이 fdisk와는 달리 0부터 표기되는 것을 볼 수 있다. # 결론은 실린더는 물리적인 것이 아니라 트랙에 존재하는 섹터의 논리적인 집합이기 때문에 그 표현이 툴에 따라서 달라질 수 있다는 것을 볼 수 있다. 따라서, 섹터 단위로 정확히 파티셔닝을 했다면 실린더 값이 겹치거나 초과되어 보일지라도 전혀 문제가 없다고 볼 수 있다. 즉, 디스크 파티셔닝의 핵심은 섹터이다. [ATA-1]: http://en.wikipedia.org/wiki/Parallel_ATA#IDE_and_ATA-1 "ATA-1" [BIOS INT 13h]: http://en.wikipedia.org/wiki/INT_13H "BIOS INT_13h" [ECHS]: http://www.pcguide.com/ref/hdd/bios/modesECHS-c.html "ECHS" [LBA]: http://en.wikipedia.org/wiki/Logical_block_addressing "LBA"
0 notes
lunatine · 12 years
Text
[FAQ] Linux 메모리 효율을 위한 vfs_cache_pressure
# 유휴 메모리가 전부 어디로 간거지? (Page Cache) Linux는 I/O 성능을 높이기 위해서 Page Cache를 사용한다. 이 글에서는 Page Cache에 대해서는 다루지 않지만 간단히 설명하면 다음과 같다. Linux는 물리적인 저장/통신 장치와 데이터를 주고 받을 때 메모리에 먼저 적재한 후에 데이터를 주고 받는데 이는 동일한 데이터에 대한 접근을 할 경우 메모리에서 바로 가져오도록 하여 I/O 성능을 높이기 위함이다. 이를 Page라는 단위로 관리를 하며 흔히 Page Cache라고 이야기 한다. 따라서, 한번이라도 데이터를 읽거나 쓴 적이 있다면 메모리는 Page Cache에 적재되고 아래의 파일에서 Cached 영역으로 표기 된다. /proc/meminfo Linux 커뮤니티에서 흔히 받는 질문 중 하나인 '왜? 제 Linux의 Free 메모리가 이것밖에 안되나요?'의 원인이 Page Cache 매커니즘이다. # 메모리를 전부 사용하고 있는 시스템 아래 그림은 특정 시스템의 메모리 사용현황을 RRDTool을 이용해서 그래프로 도식화 한 것이다. 24GB 메모리의 대부분을 사용중에 있는 것으로 나타나는데 실제 해당 서버의 프로세스가 사용하고 있는 메모리 크기를 확인해 보면 15GB 정도를 사용하고 있는 시스템이었다. ![시스템1](https://lh4.googleusercontent.com/-hJeiJRbIWeM/UBo20Cr9TgI/AAAAAAAAACU/BI00tARL5-Y/s800/vfs_cache_pressure1.jpg) 그렇다면, 남은 메모리는 어디로 간 것일까? 그래프에서 Page Cache로 잡힌 부분은 Cached (파란색)으로 표기가 된다. 따라서, 남은 메모리가 Page Cache에 의해서 사용 된 것이 아니라는 걸 알 수 있다. 그 많은 메모리는 대체 어디로 사라진 걸까? # Slab Slab Allocator라는 것이 있다. 이는 일종의 자원 할당자 중 하나로 4KB의 크기를 가진 Page로 데이터를 저장하고 관리할 경우 발생하는 단편화를 최소화 하기 위해 고안 된 물건이다. Linux의 커널은 자료구조로 Slab을 사용하고 있으며 /proc/meminfo에서 아래 항목은 Linux 커널이 사용하는 캐시 크기를 의미한다. Slab: 349364 kB Linux 커널에서 커널과 디바이��� 드라이버, 파일시스템 등은 영구적이지 않은 데이터들을 저장하기 위한 공간이 필요한데(inode, task 구조체, 장치 구조체 등) 이것이 Slab 구조하에 관리 되고 있다. 따라서, 앞서 언급한 meminfo 파일의 Slab 항목은 이러한 데이터들의 메모리상 크기를 의미한다. 그래서 커널 캐시라고도 표현한다. 이러한 캐시 데이터 중에서 본 글의 목적과 관련성이 높은 것은 inode와 dentry에 대한 캐시이다. inode와 dentry는 파일 자료구조를 의미한다. VFS(Virtual File System)와 관련된 부분을 공부하다보면 자주 만나게 되는 dentry는 경로명 탐색을 위한 캐시 역할도 수행한다고 알려져 있다. 간단히 얘기해서 어떠한 파일을 생성할 때 파일의 정보를 담고 있는 inode와 dentry는 보다 빠른 데이터 접근을 위해서 커널의 Slab 자료구조에 추가된다고 이해하면 된다. # 사라진 메모리를 찾아보자 앞서 살펴본 시스템에서 어플리케이션(프로세스)이 사용하는 메모리를 뺀 나머지 메모리는 /proc/meminfo 파일의 Slab 항목에서 찾을 수 있었다. Slab의 크기가 9GB 정도 되는 것으로 확인 되었다. 즉, 커널이 Slab 자료구조에 계속해서 캐시데이터로 담고 있었던 것이다. 왜 이런 일이 벌어졌을까? 이는 동작하고 있는 프로세스의 성격과 관련이 높다. 해당 프로세스가 주로 하는 작업의 패턴을 확인 해 본 결과 특정 파일들을 다량으로 생성하고 이 데이터를 가공처리하는 작업을 반복하고 있었다. 다만, 이러한 작업 과정에서 생성되고 삭제되는 파일이 매우 많은 것으로 확인 되었다. 앞서 이야기 한대로 Linux 커널은 파일시스템의 성능을 나아가 시스템의 성능을 개선하기 위해 inode와 dentry를 메모리에 캐시한다. 하지만, 파일을 빈번하게 생성/삭제 하거나 다량의 파일을 다루는 시스템의 경우 해당 파일을 자주 재활용하지 않는다면 (즉, 생성/기록 후에 데이터를 지속해서 접근하여 읽지 않는 경우) 캐시에 메모리를 사용하기 보다는 I/O를 위한 버퍼 또는 프로세스에 할당되어 활용 되는 편이 좋다. Linux Slab 자료구조의 상태에 대해서 자세히 살펴 볼 수 있는 slabtop이란 명령이 존재한다. 이 명령을 실행 해 보면 inode 캐시(ext3혹은 ext4_inode_cache라는 이름)와 dentry_cache의 현재 크기를 알 수 있다. Slab에 대해서 조금 더 알고 싶으면 [이 글](http://www.secretmango.com/jimb/Whitepapers/slabs/slab.html)을 추천한다. # vfs_cache_pressure Linux 커널의 vm 구조와 관련된 파라미터로 vfs_cache_pressure라는 것이 존재한다. 이 파라미터는 디렉토리와 inode 오브젝트에 대한 캐시로 사용된 메모리를 반환(reclaim)하는 경향의 정도를 지정하는 항목이다. 기본 값은 100. 이 값을 0으로 설정하게 되면 Linux 커널은 오브젝트에 대한 캐시를 반환하려고 하지 않을 것이며 얼마 지나지 않아 시스템은 Out of Memory 상태를 호소할 것이다. (커널이 메모리를 다 먹어버렸다고!!) 그리고, 100 이상의 값을 주면 Linux 커널은 오브젝트에 대한 캐시를 가급적 반환하려고 하며 (다른 말로 가급적 캐시해서 보관하려고 하지 않으려 든다) 이를 이용하면 inode와 dentry 캐시를 줄일 수가 있다. # 메모리를 되찾자 vfs_cache_pressure를 이용해서 Linux 커널에게 캐시 데이터를 반환하도록 요구해 보자. 100이상의 값을 설정하면 되는데 경험상 10000정도로 설정하면 큰 문제 없이 (즉, 커널이 반환한 캐시 데이터로 인해 성능이 저하되는 문제 등) 운영할 수 있다. 이 값에 대해서는 각자 사용하는 시스템에 값을 바꾸어보면서 확인하는게 가장 좋다. 해당 값의 변경은 아래와 같이 할 수 있다. (이 글에 관심이 있는 분이라면 당연히 알만한 내용이지만) echo 10000 > /proc/sys/vm/vfs_cache_pressure 또는 $ sysctl vm.vfs_cache_pressure=10000 영구적으로 설정하기 위해서는 /etc/sysctl.conf 파일에 아래와 같이 추가 vm.vfs_cache_pressure = 10000 앞서 살펴본 시스템에서 값을 변경하고 나니 아래와 같이 바뀌었다. 9GB 정도의 Real 영역이 해제되고 이 영역이 Buffer로 활용되기 시작하였다. ![시스템2](https://lh4.googleusercontent.com/-58K71GSvprE/UBo20woClNI/AAAAAAAAACc/RWaSTR0wWJg/s800/vfs_cache_pressure2.jpg) 즉, 커널이 잡고 있던 캐시를 해제하여 Buffer로 활용되고 나니 시스템의 부하 값 (Load 값)이 낮아지기 시작했다. 힘겨워 하던 시스템을 안정시킬 수 있게 되었다. ![시스템3](https://lh6.googleusercontent.com/-2iHpoEvlZ6A/UBqrDpNhXFI/AAAAAAAAAC0/at-KyH-n3V4/s800/vfs_cache_pressure3.jpeg) > Load 값 : 현재 시스템에서 실행 중인 프로세스와 non-interruptible 상태에 있는 프로세스의 숫자에 대한 평균 값으로 시스템의 부하 정도를 가늠하는 지표로 사용된다. 좀 더 재밌는 설명을 원한다면 [이 글](http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages)을 추천한다. # 그래서 재미없는 이야기로 기술되었지만 요약하자면 기본적으로 Linux 커널은 유휴 메모리가 있다면 캐시하려고 들기 때문에 어떤 경우에는 이렇게 사용되는 메모리의 양을 조절하면 더 좋은 효과를 얻을 수 있다는 이야기 이다. (이 말이 더 어렵다) # 추가로 알아두면 좋은 팁 앞서 vfs_cache_pressure를 통해서 Linux 커널의 VFS 관련 오브젝트 캐시경향을 조절하는 방법외에도 이러한 정책을 세워서 효과를 보기보다 지금 당장 캐시를 비우기만 하고 싶을 때는 아래와 같은 방법이 있다. echo 1 > /proc/sys/vm/drop_caches echo 2 > /proc/sys/vm/drop_caches echo 3 > /proc/sys/vm/drop_caches 각각의 숫자 값은 아래와 같은 의미를 가지고 있으며 해당 값이 설정되면 영구적으로 지속되는 것이 아니라 값이 설정되는 순간만 그 값에 따라서 반영 될 뿐이다. > **주의** : 아래 명령을 수행하기 전에 반드시 sync 등을 통해서 캐시에 휘발성으로 담긴 데이터를 실제 저장 장치에 반영시키도록 해야 한다. * drop_caches = 1 * Page cache를 해제 한다. * drop_caches = 2 * inode, dentry cache를 해제 한다. * drop_caches = 3 * Page cache, inode cache, dentry cache를 모두 해제 한다. 만약, 3번으로 설정하면 시스템이 잠시 멈추는 증상을 경험 할 수도 있다. (모든 캐시를 비우기 위해서 혼신의 힘을 다할테니깐) ## 주저리 다른 쓸 주제들이 아직도 많은데.... 이놈의 귀차니즘....
6 notes · View notes
lunatine · 12 years
Text
[FAQ] Linux Swappiness 관련
# Swap Linux 시스템에서는 다양한 용도로 스왑을 사용한다. 일반적으로 부족한 메모리를 보충하기 위한 용도로만 알려져 있지만 아래와 같은 용도로 활용이 되고 있다. + 메모리를 많이 사용하는 프로그램을 위해 (가장 일반적인 용도) + Hibernation (메모리의 내용을 디스크에 저장해 두기 위한 용도) 일반 노트북이나 랩탑에서 Hibernation을 하기 위해서는 시스템의 메모리 크기보다 큰 스왑 공간이 반드시 필요하다. 메모리의 정보를 모두 디스크에 담아야 하기 때문이다. + 예측에서 벗어난 메모리 공간을 사용하는 프로그램에 대비하기 위한 경우 + 메모리의 효율을 높이기 위해서 스왑 영역은 일반적으로 디스크에 존재하기 때문에 메모리에 비교할 수 없을 정도로 성능이 떨어지지만 이러한 스왑 영역이 메모리 사용 효율을 높일 수 있다. 프로세스가 데이터를 읽어들일 때 메모리에 저장하여 읽게 되고 이러한 작업이 빈번하게 발생할 경우 메모리에 캐시하여 응답속도를 높이는 형태로 동작한다. 즉, 메모리에 캐시할 수 있는 공간이 많으면 많을 수록 효율을 높일 수 있는데 스왑 영역은 프로세스가 예약한 메모리 공간 중에서 사용되지 않는 혹은 당장 필요하지 않는 부분을 저장하여 **메모리가 캐시 역할을 할 수 있는 공간을 더 확보** 할 수 있도록 한다. # 메모리가 많은데도 Swap을 사용합니다 자주 문의 받는 내용 중 하나이다. 분명 시스템의 RAM은 여유가 있음에도 스왑으로 할당해 둔 공간에 데이터를 쓰는 경우가 종종 있다. 사실 크게 문제되지는 않지만 스왑 영역과 데이터를 자주 주고 받게 된다면 디스크 I/O의 성능에 전체 시스템의 성능이 영향을 받는 경우가 있다. Linux가 메모리가 많음에도 불구하고 스왑공간을 사용하는 이유는 스왑 사용여부를 결정하는 값의 계산식에서 비롯되는데 Linux Kernel의 mm/vmscan.c에는 아래와 같은 코드가 있다. swap_tendency = mapped_ratio / 2 + distress + sc->swappiness; 스왑을 사용하려는 경향(tendency)을 계산하는데 있어서 mapped_ratio와 distress 그리고 swappiness라는 변수가 영햐을 미친다. 먼저, mapped_ratio는 아래와 같이 계산되는데 mapped_ratio = ((global_page_state(NR_FILE_MAPPED) + global_page_state(NR_ANON_PAGES)) * 100) / vm_total_pages; 쉽게 말해서 전체 메모리 중에서 프로세스가 사용하고 있는(Mapped) 메모리의 크기에 대한 비율(% 값)이다. 두 번째로 distress 변수는 아래와 같이 표현되며 distress = 100 >> min(zone->prev_priority, priority); 페이지(메모리 저장구조 단위)를 얼마나 많이 스캔하게 될 건지를 뜻한다. 일반적으로 값은 0이며 100에 가까울 수록 스캔해야하는 양이 많아져서 시스템에 문제가 있다는 뜻이다. (커널 코드 주석에서는 Great Trouble이라고 표현되어 있다) 그리고 swappiness 값은 사용자가 직접 수정할 수 있는 변수로 /proc/sys/vm/swappiness에서 확인 할 수 있으며 기본 값은 60이다. 첫 번째 확인했던 수식을 다시금 정리하면 일반적인 경우에 distress는 0이고 swappiness는 60이기 때문에 아래와 같이 표현 된다. swap_tendency = mapped_ratio / 2 + 0 + 60; 만약, 4GB 메모리를 가진 시스템에서 3GB를 사용 중이라고 가정하면 swap_tendency = (3GB / 4GB * 100) / 2 + 0 + 60 = 97.5 97.5이기 때문에 바로 스왑이 일어나지는 않는다. (100이상이면 발생한다) # swappiness 값에 따른 영향 실질적으로 사용자가 변경할 수 있는 값은 swappiness 변수 이기 때문에 이 값에 따른 스왑이 발생하는 시점을 유추해 볼 필요가 있을 것이다. 먼저 기본 값인 60일 경우에는 언제 스왑이 발생할지 계산해 보기위해서는 swap_tendency가 100이 되는 시점을 찾으면 되는데 100 = mapped_ratio / 2 + distress + swappiness mapped_ratio = (100 - distress - swappiness) * 2 mapped_ratio = (100 - 0 - 60) * 2 = 80 즉, 80% 이상의 메모리를 사용하게 되면 스왑이 발생하게 될 것을 예측 할 수 있다. **다만 distress가 0인 상황에서라는 전제조건이 필요하다.** 만약, swappiness 값을 10으로 설정하고 distress가 0이면 mapped_ratio는 200%이기 때문에 스왑이 발생하는 경우의 조건이 성립하지 않지만 distress가 50이면 80%로 계산된다. # 그래서 앞의 예제와 같이 distress 값은 **유동적**이기 때문에 결과적으로 **swappiness 값의 설정이 절대적인 결과를 얻는 값으로 사용될 수 없지만** 0에 가까울 수록 가급적 스왑을 하지 않으려 할 것이고 100에 가까울 수록 스왑을 하도록 설정할 수 있다는 부분은 어렵지 않게 알 수 있다. # 추가적으로 자주 질문 받던 내용을 정리하기 위해 다시금 리눅스 소스코드를 열어보았다가 발견한 사실로 위에서 언급한 계산 식이 vmscan.c 코드에서 사라졌다. 몇 개의 버전을 더 받아서 확인해 본 결과 CentOS 5.7/RHEL 5.7의 2.6.18-274 커널에는 존재하지만 kernel.org에서 내려받은 2.6.35.13과 3.4 커널 코드에는 존재하지 않았다. 즉, 메모리 관리 기법에 대한 변화로 인해서 해당 코드는 삭제 된 것으로 추측된다. (2.6.20 커널의 패치 파일에서는 수식 변경이 발견되었고 그 뒤 버전에서는 아예 사라졌다) 변경된 내용에 대한 내용까지 조사해서 정리하면 좋겠지만 이 문서를 작성하면서 고려하지 않았던 내용이기 때문에 이 부분은 나중으로 미루려고 한다. 다만, 최신 커널 문서에서도 여전히 **swappiness 값은 0과 100사이에서 동일한 의미로 설명**되고 있기 때문에 설정 값에 대한 내부 처리 부분의 변경은 다시 확인해야겠지만 당장 설정하는데 별다른 문제는 없다.
0 notes
lunatine · 12 years
Text
[FAQ] Linux LD_ASSUME_KERNEL 변수에 대한 이야기
간혹, 특정 어플리케이션을 설치 후 실행 할 때 라이브러리 경로를 못 찾는 경우가 있다. (특히, 오라클, JAVA 등) 이러한 경우 LD_LIBRARY_PATH가 잘못 설정되어 문제가 되기도 하지만 LD_ASSUME_KERNEL 변수 때문에 발생하기도 한다. # Linux 커널의 Threads 구조 변천사 LD_ASSUME_KERNEL 변수는 Linux 커널의 Threads 라이브러리 구조의 변천사와 관련이 있다. Linux 커널 2.6 버전 이전에는 POSIX Threads에 적합하지 않은 스레드 구조를 가지고 있었으며 Linux Threads를 개선하기 위한 2가지의 프로젝트가 가동 되었다. 그 중 하나는 IBM쪽 개발자들에 의한 NGPT (Next Generation POSIX Threads)이었고 다른 하나는 Redhat 개발자들에 의한 [NTPL][](Native POSIX Thread Library) 였다.결과적으로 NGPT는 사라지고 [NTPL][]이 Redhat 9이 릴리즈 되면서 소개가 되었다. 하지만, 문제는 여기에서 발생한다. 과거 자체적인 구조의 Threads 라이브러리를 가지고 있던 Linux를 개선하기위해 [NTPL][]이 소개되었지만 기존 소프트웨어와 [NTPL][]이 호환되지 않는 문제점이 발생하였다. 따라서, Redhat 9이 릴리즈 될 무렵에 3가지 구조의 Threads 라이브러리를 제공하게 되었는데 + /lib/tls/libpthread.so (Kernel 2.4.20 NPTL) + /lib/i686/libpthread.so (Kernel 2.4.1의 비교적 최신 LinuxThreads - 32bit 기준) + /lib/libpthread.so (Kernel 2.2.5의 오래된 LinuxThreads) ���렇게 3가지의 라이브러리를 제공한 것은 기존의 어플리케이션과 호환성을 위한 것이다. 대부분의 어플리케이션은 [DSO][](Dynamic Shared Object) 형태로 링커를 통해서 라이브러리를 호출하는 구조이기 때문에 여러 종류의 라이브러리를 제공하는 구조를 취할 수 밖에 없었다. # LD_ASSUME_KERNEL 변수의 의미 어플리케이션이 실행될 때 Dynamic Linker에 의해서 Shared Library를 링크하고 불러들이게 되는데 앞서 이야기한 대로 3가지 구조의 라이브러리가 존재하기 때문에 각 어플리케이션에 적합한 라이브러리를 링크할 필요성이 발생하였다. ※ 일반적으로 별도의 라이브러리를 링크하기 위해서는 LD_LIBRARY_PATH와 같은 변수를 사용한다. 앞서 이야기한 libpthread의 3가지 타입은 특수한 경우이다. ※ Dynamic Library 파일에는 해당 파일이 구동되기 위한 최소한의 OS ABI 버전 정보를 담고 있는데 (.note.ABI-tag로 불리우는 ELF note 섹션) 특정 라이브러리에 대해서 아래와 같은 명령으로 확인해 볼 수 있다. (아래는 RHEL5에서 실행한 결과) $ eu-readelf -n /lib/libc-2.5.so Note section [ 1] '.note.ABI-tag' of 32 bytes at offset 0x174: Owner Data size Type GNU 16 VERSION OS: Linux, ABI: 2.6.9 3가지 구조의 라이브러리를 찾아가기 위해서 LD_ASSUME_KERNEL 이란 변수가 사용되게 되었고 이 변수를 해당 라이브러리의 ABI 버전으로 지정하여 적합한 라이브러리를 찾아가도록 지정하는 것이다. # LD_ASSUME_KERNEL의 필요성? 결론적으로 이야기하면 현재의 Linux에서는 보통의 경우 해당 변수가 필요하지 않다. (현재는 GNU C 라이브러리에 NTPL이 완전히 통합되어 있다) 이러한 변수가 필요한 어플리케이션(최신버전의 Oracle에 대해서는 잘 모르기 때문에 확답하긴 어렵지만 적어도 9i 시절의 Oracle의 경우는 해당 변수가 필요하였다) 을 사용해야하는 경우가 아닌이상 필요없는 변수이다. 만약, 필요성이 없음에서 설정되어서 문제를 일으킨다면 간단히 주석처리해버리자. 보통 .bash_profile, .cshrc과 같은 환경설정 파일에 등록되어있을 것이다. 요즘 Linux에서 LD_ASSUME_KERNEL을 사용하면 어떻게 되는지 궁금한 분들은 아래와 같은 명령을 실행해보면 된다. $ LD_ASSUME_KERNEL=2.4.20 ls # 마무리.. 어찌보면 추억의 변수명이다. (요즘도 화두가 되는지는 모르겠다) 잊고 있던 변수명인데 오라클을 설치 중에 기본 명령도 안먹는 증상이 발생한다는 문의를 받고 확인하던 중에 발견하고 이 기회에 간단히 정리해 보았다. [NTPL] : http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library [DSO] : http://en.wikipedia.org/wiki/Dynamic_Shared_Object
3 notes · View notes
lunatine · 13 years
Text
[FAQ] VirtualBox에서 RHEL5 부팅 오류/멈춤 현상
VirtualBox에 RHEL5 설치하기
별것 아니지만 VirtualBox에 RHEL5를 설치하다가 겪을 수 있는 증상에 대해서 간단히 공유하려한다. VirtualBox 버전에 따라 그리고 GuestOS인 RHEL의 버전에 따라 발생하는 경우가 다를 수 있지만 개인적으로 RHEL5 64bit 배포판에서 대부분 발생한 증상이다.
증상
보통 GuestOS를 설치하기 위해서 ISO 이미지파일을 마운트하여 부팅시키는데 부팅 초반에 멈추는 증상이다. 이는 ISO 이미지로 부팅할 때 뿐만 아니라 설치 후에 부팅할 때도 발생하곤 한다.
원인
발생하는 경우데 따라서 조금씩 다른 것으로 보이지만 결과적으로 NMI Watchdog이 CPU0에서 LOCKUP 되는 증상이 발생하면서 일어난다. 따라서 NMI Watchdog만 잘 달래면 해결될 수 있는 문제이기도 하다.
해결방법
ISO로 부팅할 경우에는 원하는 커맨드 뒤에 아래의 옵션을 입력한다.
nmi_watchdog=0 예) > linux nmi_watchdog=0
설치 후에 발생하는 문제의 경우에는 grub.conf 부트로더 설정파일의 커널설정 라인에 위의 옵션을 추가해 준다.
예) kernel /boot/vmlinuz-2.6.18-274.el5 ro root=/dev/sda1 nmi_watchdog=0
만약, 설치 후 처음 부팅 때도 발생한다면 GRUB 부트로더 화면에서 'e'를 눌러 에디터 모드로 들어가서 커널 설정 라인에 위 내용을 추가 해 준다.
별거 아닌 것이긴 하지만.. 디버깅하면서 메시지를 확인하지 않는다면 이미지 불량으로 착각하고 삽질할 가능성이 높은 증상이다.
15 notes · View notes
lunatine · 13 years
Text
[FAQ] Synergy 서버 실행 오류 해결 방안
Synergy
최근에 MBP를 마련하면서 Windows와 번갈아가면서 하는 작업이 늘게 되어서 Synergy를 사용하게 되었는데 설정을 바꿔가며 테스트 하다가 이상한 증상이 발견되어 이를 해결하는 방법을 공유 하고자 한다.
환경 및 증상
환경 : Synergy 서버는 Windows7 64bit 버전
증상 : Synergy 서버를 종료 했다가 다시 실행하면 아래와 같은 오류 메시지가 발생하면서 실행되지 않음
ERROR: failed to initialize hook library, is synergy already running?
FATAL: failed to start server: unable to open screen
해결방법
먼저, 알아두어야 할 것은 Synergy 서버프로세스가 이미 떠 있다면 종료 시키면 해결된다. 하지만, 서버프로세스 중복에 의한 경우는 ���의 없고 Hooking 하는 부분에서 무언가 트러블을 일으키는 것으로 보인다.
Ctrl+Alt+Delete를 눌르고 사용자전환(W)을 선택한다
로그인 창이 나오면 방금전에 사용하던 계정으로 다시 로그인한다.
스크린과 관련된 부분이 초기화 되면서 Synergy 서버가 정상적으로 실행된다
일종의 버그라고 보여지며.. 현재까지는 Windows7 64bit에서만 확인되었다.
4 notes · View notes
lunatine · 13 years
Text
[FAQ] ht = HyperThread에 대한 오해
과거에 대략 정리했던 내용을 다시 포스팅하는 이유는 문서 정리차원입니다.
일반적으로 Linux의 CPU정보 (/proc/cpuinfo)에서 ht 플래그 가 보이면 HyperThread가 지원되는 CPU로 알려져 있습니다. 따라서 해당 플래그의 존재 여부에 따라서 HyperThread가 되고 안되고를 많이 판단하는�� 결과부터 이야기 한다면 적어도 지금의 CPU로는 ht 플래그로는 HyperThread 기능 여부를 정확히 판별할 수 없습니다.
개인적으로 HyperThread 기능이 없는 CPU가 ht 플래그를 가지고 있는 것을 발견하였고 이에 대한 의문점을 해결하기 위해 커널 소스를 모두 보았으나 소스의 변화나 특이점은 없었습니다. 그래서 CPU 매뉴얼과 유사 자료를 찾던 중 아래와 같은 내용이 있었습니다.
"ht" in 'flags' field of /proc/cpuinfo indicate that the processor supports the Machine Specific Registers to report back HT or multi-core capability. Additional fields (listed down below) in the CPU records of /proc/cpufinfo will give more precise information about the CPU topology as seen by the operating system.
"physical id" : Physical package id of the logical CPU "siblings" : Total number of logical processors (include both threads and cores) in the physical package currently in use by the OS "cpu cores" : Total number of cores in the physical package currently in use by the OS "core id" : Core id of the logical CPU
위의 내용을 핵심만을 살펴보면, ht 플래그는 멀티스레드/멀티코어에 대한 하드웨어 레지스터를 지원하느냐에 대한 플래그 값 입니다.
즉, 과거에는 die 하나에 1개의 코어가 올라가는게 당연하였기 때문에 ht 플래그는 곧 HyperThread를 의미했지만 요즘과 같이 die 하나에 4개의 코어 이상이 올라가는 시대에는 멀티코어에 대한 하드웨어 레지스터를 지원한다는 의미밖에 되지 않습니다.
따라서, HyperThread의 활성화 여부를 명확히 확인하기 위해서는 /proc/cpuinfo 파일에서 보여주는 코어개수가 sibling 코어 개수와 같으면 HyperThread가 꺼진 상태이고 2배이면 켜진 상태인 것입니다.
0 notes
lunatine · 13 years
Text
[FAQ] Thunderbird 성능 개선 팁
Thunderbird를 사용하다보면 컴퓨터의 리소스는 넉넉함에도 불구하고 창 이동이나 사용자 행동에 대한 반응이 조금은 느린듯한 느낌이 들 때가 있다. 무언가 그래픽적인 처리가 버벅거리는 듯한 모습인데 이 경우 아래 옵션을 적용하면 효과가 있다. 개인적으로 업무용 데스크탑은 16GB 메모리를 사용하고 있음에도 반응이 느려서 아래 옵션을 적용하였고 효과를 크게 보았다.
먼저, Thunderbird의 옵션->고급 페이지로 들어가서 고급설정 항목의 '설정편집'을 눌러 아래 항목을 검색하여 값을 수정한다.
gfx.direct2d.disabled true layers.acceleration.disabled true
Direct2D 관련된 부분의 값을 수정해 주는 옵션이다. 만약 사용하는 데스크탑이 Linux나 Mac OS X일 경우에는 아래 옵션을 활성화 해주면 도움이 될 수 있다.
layers.prefer-opengl true
나의 경우는 옵션을 적용한 후에 수기가바이트에 달하는 메일박스에서 새로운 메일을 확인할 때 마다 화면에 보여주는 속도가 많이 개선되었다.
그 외의 팁은 아래 페이지를 참고하면 된다.
모질라 위키
0 notes
lunatine · 13 years
Text
[FAQ] NIC의 순서가 부팅 때마다 바뀌는 증상
이미 여러 인터넷 커뮤니티에서 알려진대로 RHEL 기준으로 RHEL5 부터 서버를 리부팅 할 때 마다 네트워크 카드의 순서가 뒤 바뀌는 증상이 발생하곤 한다.
예를 들어 PCI 장치번호로 00:08.0이 eth0 였고 00:09.0가 eth1이었는데 리부팅을 하고 보니 eth0가 eth1으로 잡히고 eth1이 eth2로 잡히는 증상 또는 서로 바뀌는 증상들이 발생하는 것이다.
이것에 대한 해결 방법은 여러가지가 존재하는데 하나씩 살펴보면
NIC의 MAC 주소를 이용하는 방법
가장 정확하고 간편한 방법 중의 하나로 네트워크 장치 설정에 대해서 MAC 주소를 지정하는 방법이다. Redhat 계열로 예를 들면
/etc/sysconfig/network-scripts/ifcfg-eth0
위 파일에 HWADDR 항목을 추가해서 실제 NIC 장치의 MAC주소를 지정하면 몇 번을 리부팅해도 바뀌지 않는다.
DEVICE=eth0 BOOTPROTO=static BROADCAST=123.123.123.255 IPADDR=123.123.123.123 NETMASK=255.255.255.224 NETWORK=123.123.123.0 HWADDR=00:A0:D1:12:E7:11
다만, 이와 같은 방법의 경우 서버시스템의 장애로 인해 서버를 교체하게 되면 (즉, 디스크는 유지하고 서버만 교체) HWADDR이 달라지게 되므로 다시 수정해 주어야 하는 번거로움이 생길 수 있다.
참고가 되는 문서 : 레드햇 KBASE
udev 룰셋을 통한 해결방법
최근 리눅스에서는 udev를 통해서 장치를 관리할 수 있고 원하는대로 룰셋을 지정할 수 있다. 이러한 udev의 룰셋을 이용하는 방법으로 아래와 같은 udev 룰을 추가한다.
파일위치 : /etc/udev/rules.d/10-local.rules (없는 파일이므로 새로생성)
SUBSYSTEM=="pci", SYSFS{class}=="0x020000", OPTIONS="ignore_device"
해당 파일에 기록한 udev의 의미는 sysfs의 해당 클래스에 대해서 룰셋 지정을 무시하라는 것이다. 기본적으로 60-net.rules 파일에 기록된 내용에 의해서 추가되기전에 이와 같은 룰셋을 지정하여 순서대로 (일반적으로 PCI 버스 순서) 인식하도록 하는 방법이다.
룰셋 파일 하나만 추가해주면 되고 생각보다 잘 적용되는 방법이다. 이와 유사하게 커널 부트 파라미터로 지정해서 장치인식을 Legacy 방식으로 하는 방법도 있지만 udev를 쓰는 환경이라면 이러한 방법을 더 추천한다.
참고할만한 링크 : Redhat bugzilla
/etc/iftab 설정파일로 지정하기
다른 배포판은 확인을 못해봤지만 wireless-tools 패키지에 들어있는 ifrename 유틸리티를 이용하는 방법이다. /etc/iftab이란 설정파일을 아래와 같은 방식으로 작성하고
eth0 businfo 0000:00:08.0 eth1 businfo 0000:00:09.0
위의 내용에서 0000:00:08.0은 lspci 등의 명령으로 확인할 수 있는 PCI 장치 번호이다. iftab을 작성했으면 아래의 rc 스크립트를 등록한다.
파일명 : /etc/init.d/ifrename
#!/bin/sh NAME=ifrename IFRENAME=/sbin/ifrename IFTAB=/etc/iftab test -f $IFRENAME || exit 0 test -f $IFTAB || exit 0 case "$1" in start|reload|force-reload|restart) $IFRENAME ;; test) $IFRENAME -DV ;; stop) ;; *) echo "Usage: $NAME {start|stop|reload|force-reload|restart}" ;; esac exit 0
그리고, 부팅하는 런레벨에 맞추어 S09ifrename 정도로 심볼릭을 걸어준다.
ln -s /etc/init.d/ifrename /etc/rc3.d/S09ifrename
이 방법은 서버가 바뀌어도 H/W 스펙이 같다면 PCI 값이 바뀌는 경우가 없기 때문에 유용한 방법이지만 대체로 udev 룰셋보다 번거롭기 때문에 잘 쓰이지는 않는다. 하지만, 별도의 멀티포트 NIC카드를 구매해서 장착한 경우라면 앞서 설명한 udev 룰셋으로 해결이 안될 수 있기 때문에 (즉, 내가 장착한 카드를 eth0로 잡고 싶지만 버스순서 때문에 온보드 NIC이 먼저 잡히는 경우 등) 이러한 방법을 사용하면 된다.
참고할 만한 링크
7 notes · View notes
lunatine · 13 years
Text
[FAQ] Linux 디스크 사용량의 차이 (df 명령과 du)
자주 받는 질문 중의 하나.. 'df 명령으로 보니 디스크 사용량이 100%인데 실제 du 명령으로 파일 크기를 합산하면 100%가 되지 않는 이유가 뭔가요?'
이러한 질문을 받고 서버를 확인해보면 상당 수가 MySQL DB관련 서버인 경우가 많은데 이는 df 명령과 du 명령의 차이점에 의해서 발생하는 것이다.
df 명령은 현재 마운트 된 파일시스템의 상태를 기초로하여 사용률을 보여주는 것이고 du는 실제 디렉토리와 파일을 확인하고 그 크기를 조사하기 때문이다.
그런데 왜 다른건데?
현재 실행 중인 프로세스가 오픈한 파일에 대해서 삭제처리를 한 후에 해당 프로세스(태스크)를 종료하지 않으면 그 파일은 deleted 상태로 남게 된다. 즉, 파일시스템에 deleted 상태정보로 유지되고 있는 것이다. 그렇기 때문에 df 명령으로 확인하게 되면 deleted 파일이 차지하는 용량까지 더해져서 du 명령과는 차이를 나타낼 수가 있다. 특히, MySQL에서 큰 데이터베이스를 날렸을 경우에는 그 차이가 크게 느껴질 수 있다.
확인하는 방법은?
lsof라는 명령이 있다. 이 명령을 통해서 'deleted' 상태에 있는 파일을 확인할 수 있으니 각각의 파일 정보에서 해당 PID를 찾아서 그 프로세스를 리셋하거나 종료하면 df에서 잠식당한 공간을 확보할 수 있다.
lsof | grep deleted
실제로는 사용하지 않아서 그냥 내버려 둬도 되지 않느냐라고 볼 수 있지만.. 파일시스템 상태정보와 관련이 있기 때문에 실제 사용량이 많지 않아도 df에서 100%로 보이면 여유공간이 없다고 파일 생성이 되 질 않는다.
68 notes · View notes
lunatine · 13 years
Text
[FAQ] nVidia 그래픽카드의 메모리 ECC 기능 비활성화
nVidia 그래픽카드의 메모리 ECC 기능을 비활성화 하게 되면 성능향상을 얻을 수 있는데 리눅스에서는 아래와 같은 방법으로 비활성화가 가능하다
$ nvidia-smi -e 0
0대신에 1을 입력하면 활성화하게 되며 위 값을 변경한 후에는 시스템 리부팅이 이루어져야 제대로 적용된다.
실행예시
root@tbox ~]# nvidia-smi -e 0
Disabled ECC support for GPU 0:6:0.
Disabled ECC support for GPU 0:14:0.
Reboot required.
8 notes · View notes