<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>EMSTONE Bebop &#187; Linux</title>
	<atom:link href="http://bebop.emstone.com/tags/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://bebop.emstone.com</link>
	<description>엠스톤 개발팀 블로그</description>
	<lastBuildDate>Sun, 29 Jan 2012 05:25:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
		<item>
		<title>모니터 없이 X 서버 실행 후 나중에 모니터 연결해도 화면이 안보인다면</title>
		<link>http://lethean.pe.kr/2012/01/29/setup-new-connected-monitors-automatically-after-starting-x-server-without-connected-monitors/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=setup-new-connected-monitors-automatically-after-starting-x-server-without-connected-monitors&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25eb%25aa%25a8%25eb%258b%2588%25ed%2584%25b0-%25ec%2597%2586%25ec%259d%25b4-x-%25ec%2584%259c%25eb%25b2%2584-%25ec%258b%25a4%25ed%2596%2589-%25ed%259b%2584-%25eb%2582%2598%25ec%25a4%2591%25ec%2597%2590-%25eb%25aa%25a8%25eb%258b%2588%25ed%2584%25b0-%25ec%2597%25b0%25ea%25b2%25b0%25ed%2595%25b4%25eb%258f%2584-%25ed%2599%2594</link>
		<comments>http://lethean.pe.kr/2012/01/29/setup-new-connected-monitors-automatically-after-starting-x-server-without-connected-monitors/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=setup-new-connected-monitors-automatically-after-starting-x-server-without-connected-monitors#comments</comments>
		<pubDate>Sun, 29 Jan 2012 05:25:29 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Udev]]></category>
		<category><![CDATA[Xorg]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1864</guid>
		<description><![CDATA[제목이 조금 길지만, 이 글의 내용은 제목 그대로입니다. (참고로, 이 글은 최근 인텔 그래픽 칩셋을 대상으로 작성되었습니다. 즉, 다른 그래픽 칩셋 드라이버는 어떻게 동작하는지 확인을 안 해 보았다는 의미입니다) 요즘 X 서버는 연결된 모니터가 없고, /etc/X11/xorg.conf 파일에 수직/수평 주파수가 정의되어 &#8230; <a href="http://lethean.pe.kr/2012/01/29/setup-new-connected-monitors-automatically-after-starting-x-server-without-connected-monitors/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2012/01/29/setup-new-connected-monitors-automatically-after-starting-x-server-without-connected-monitors/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=setup-new-connected-monitors-automatically-after-starting-x-server-without-connected-monitors">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>제목이 조금 길지만, 이 글의 내용은 제목 그대로입니다. (참고로, 이 글은 최근 인텔 그래픽 칩셋을 대상으로 작성되었습니다. 즉, 다른 그래픽 칩셋 드라이버는 어떻게 동작하는지 확인을 안 해 보았다는 의미입니다)</p>
<p>요즘 X 서버는 연결된 모니터가 없고, <code>/etc/X11/xorg.conf</code> 파일에 수직/수평 주파수가 정의되어 있지 않다고 하더라도 일단 정상적으로 실행됩니다. 다만, 초기 해상도가 320&#215;200 처럼 매우 작을 수 있습니다. 그런데 나중에 필요에 의해 모니터를 연결했는데 화면이 보이지 않는 경우가 발생합니다. 이 경우, 네트웍으로 접속해서 다음 명령어를 실행합니다.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">DISPLAY</span>=:<span style="color: #000000;">0.0</span>
$ xrandr <span style="color: #660033;">--auto</span></pre></div></div>

<p>그러면 X 서버가 알아서 연결되어 있는 모니터를 출력으로 재설정하고 가장 선호하는(preferred) 해상도와 주파수를 선택합니다. 그런데 이를 자동으로 동작하게 하려면 udev 데몬의 도움을 받아야 합니다. 그래서 <code>/etc/udev/rules.d</code> 디렉토리에 확장자가 <code>'.rules'</code>인 파일을 생성하고 다음과 같이 내용을 채웁니다.</p>

<div class="wp_syntax"><div class="code"><pre class="" style="font-family:monospace;">ACTION==&quot;change&quot;, SUBSYSTEM==&quot;drm&quot;, KERNEL==&quot;card*&quot;, RUN+=&quot;/usr/bin/auto-xrandr.sh&quot;</pre></div></div>

<p>그리고 <code>/usr/bin/auto-xrandr.sh</code> 파일을 아래와 같이 작성한뒤 실행권한을 줍니다.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$DISPLAY</span>&quot;</span> = <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">DISPLAY</span>=:<span style="color: #000000;">0.0</span>
xrandr <span style="color: #660033;">--auto</span>
xrandr <span style="color: #660033;">--dpi</span> <span style="color: #000000;">96</span></pre></div></div>

<p>그러면 이제부터 모니터 연결시 자동으로 연결을 재설정하게 됩니다.</p>
<p>그런데, 만일 네트웍으로 접속했거나, udev 데몬에 의해 실행되는 경우 X 서버 인증이 안된 계정이라며 <code>xrandr</code> 명령이 실행이 거부됩니다. 이를 제대로 처리하려면 복잡한 인증 과정이 필요한데, 이를 쉽게 처리하려면 그냥 X 서버 시작할때 자동으로 실행되는 초기화 스크립트에 <code>'xhost +'</code> 명령어를 주면 인증을 무시하게 됩니다. 물론 보안상 좋은 방법은 아니지만, 폐쇠된 환경이라면 별로 문제가 없을 겁니다.</p>
<p>각각의 명령어에 대해 더 궁금하신 분은 관련 명령어 매뉴얼 페이지를 확인해 보시기 바랍니다.</p>
<p>참고로 조금만 더 설명하면, 노트북 외부 모니터 단자에 빔 프로젝트나 외부 모니터를 연결했을 경우도 xrandr 명령을 직접 사용하거나 지금까지 설명한 방법을 조금 다르게 응용할 수 있습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2012/01/29/setup-new-connected-monitors-automatically-after-starting-x-server-without-connected-monitors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>eventfd 소개</title>
		<link>http://lethean.pe.kr/2011/07/07/eventfd/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=eventfd&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=eventfd-%25ec%2586%258c%25ea%25b0%259c</link>
		<comments>http://lethean.pe.kr/2011/07/07/eventfd/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=eventfd#comments</comments>
		<pubDate>Thu, 07 Jul 2011 08:36:13 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[glibc]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1731</guid>
		<description><![CDATA[리눅스에서 비단 부모 자식 프로세스간 통신 뿐 아니라, 쓰레드간 메시지 전달에도 pipe()를 자주 이용합니다. 읽거나 쓸때 별도로 뮤텍스로 보호해줄 필요가 없기 때문이기도 하지만, 무엇보다도 poll(), select(), epoll() 등과 함께 사용할 수 있기 때문입니다. 예를 들어 예전에 적었던 GLib 쓰레드 프로그래밍에서 쓰레드간 통신에 g_async_queue()를 &#8230; <a href="http://lethean.pe.kr/2011/07/07/eventfd/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2011/07/07/eventfd/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=eventfd">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>리눅스에서 비단 부모 자식 프로세스간 통신 뿐 아니라, 쓰레드간 메시지 전달에도 <a href="http://www.kernel.org/doc/man-pages/online/pages/man2/pipe.2.html">pipe()</a>를 자주 이용합니다. 읽거나 쓸때 별도로 뮤텍스로 보호해줄 필요가 없기 때문이기도 하지만, 무엇보다도 poll(), select(), epoll() 등과 함께 사용할 수 있기 때문입니다. 예를 들어 예전에 적었던 <a href="http://lethean.pe.kr/2008/08/06/glib-thread-programming/">GLib 쓰레드 프로그래밍</a>에서 쓰레드간 통신에 g_async_queue()를 이용하는데, 이 방법의 단점은 쓰레드가 오직 이 메시지가 도착했을때만 깨어난다는 점입니다. 만일 이 쓰레드가 네트웍 소켓 작업이나 파일 읽기 쓰기 작업을 비동기적으로 계속 처리해야 한다면 타임아웃을 주어 처리하거나 반대로 다시 주기적으로 메시지큐를 검사하는 방법밖에 없습니다. 하지만, 리눅스에서 모든 소켓 작업, 파일 작업은 디스크립터(descriptor)로 단일화되어 있기 때문에 pipe()로 생성된 디스크립터와 실제 작업 디스크립터를 한꺼번에 epoll() 등을 이용해 처리하면 불필요한 오버헤드 없이 정확하게 작업을 처리해야할 시점에 깨어나 필요한 작업을 처리하게 됩니다. 즉, 메시지큐에 실제 메시지를 넣고 파이프의 쓰기 디스크립터에 더미 데이터를 쓰면, 작업 쓰레드에서는 파이프 읽기 디스크립터에 내용이 있을 경우 poll() 등이 감지하기 때문에 자동으로 깨어나 처리하는 방식입니다. 심지어, 파이프 전송시 더미 데이터가 아닌 메시지 내용 혹은 주소(pointer)를 쓰고, 읽는 쓰레드에서 이를 읽어 처리하면 별도의 메시지큐도 불필요하게 됩니다.</p>
<p>이 글에서 소개하려는 <a href="http://www.kernel.org/doc/man-pages/online/pages/man2/eventfd.2.html">eventfd()</a>는 파이프 역할을 어느 정도 대체하기 위해 최근(?) 리눅스 커널에 추가된 API입니다. 읽고 쓰기에 각각 다른 두 개의 파일 디스크립터를 사용하는 파이프와 달리 eventfd는 한 개의 파일 디스크립터를 가지고 동시에 읽고 쓰기 작업을 처리합니다. 또한 별도 커널 버퍼와 복사 과정이 필요한 파이프와 달리 정수 값을 더하고(쓰고) 읽는 작업만 처리하기 때문에 성능도 훨씬 좋다고 합니다. 물론 파일 디스크립터이기 때문에 poll() 등과 함께 사용할 수 있습니다.</p>
<p>동작 방식을 간단하게 설명하면, write() 호출시 64비트 정수값을 쓰면 내부 버퍼 값에 더하면서, read() 호출시 내부 버퍼 값이 0일 경우 기다리다가, 값이 바뀌면 그 값을 읽어오고 0으로 초기화합니다.(세마포어 방식일 경우 1을 읽어오고 그 값에서 1을 감소합니다) 즉, 읽기 작업에 대한 poll() 호출은 내부 버퍼 값이 0일 경우 입력이 없는 것으로, 1 이상의 값일 경우 입력이 있는 것으로 간주하고 디스크립터를 감지하게 됩니다. (예제 코드는 매뉴얼 페이지에 포함된 코드를 확인하시길&#8230; 물론 예제 코드는 쓰레드간 통신에도 잘 동작합니다)</p>
<p>매뉴얼에 의하면 리눅스 커널 2.6.22, glibc 2.8 버전부터 eventfd() 함수를 지원합니다. 대부분의 요즘 리눅스 데스크탑 / 서버 배포판에서는 당연히 사용할 수 있지만 임베디드 시스템에서는 버전을 확인해야할 필요가 있습니다. 물론, eventfd가 메시지 내용 자체를 전송할 수 없다는 단점도 있지만, 이와 함께 리눅스 커널이 제공하는 <a href="http://www.kernel.org/doc/man-pages/online/pages/man2/signalfd.2.html">signalfd()</a>, <a href="http://www.kernel.org/doc/man-pages/online/pages/man2/timerfd_create.2.html">timerfd()</a>, <a href="http://linux.die.net/man/4/epoll">epoll()</a> 등을 함께 사용하면 고전 유닉스 프로그래밍의 한계에서 벗어나 마음껏 이벤트 기반 코드를 만들 수 있습니다.</p>
<p>물론 이미 잘 만들어진 <a href="http://lethean.pe.kr/2009/09/21/using-glib-mainloop/">GLib 메인루프</a>나 <a href="http://bebop.emstone.com/2011/05/18/libevent/">libevent</a> 등과 같은 라이브러리를 사용하는 것도 좋지만&#8230; :)</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/07/07/eventfd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>PCD – Process Control Daemon</title>
		<link>http://lethean.pe.kr/2011/05/30/pcd-process-control-daemon/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pcd-process-control-daemon&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pcd-%25e2%2580%2593-process-control-daemon</link>
		<comments>http://lethean.pe.kr/2011/05/30/pcd-process-control-daemon/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pcd-process-control-daemon#comments</comments>
		<pubDate>Mon, 30 May 2011 03:49:14 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Embedded]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1660</guid>
		<description><![CDATA[아치리눅스를 비롯한 몇몇 리눅스 배포판은 여전히 시스템 부팅 초기화에 필요한 작업, 예를 들어 로컬 파일 시스템을 마운트하거나 웹서버, X서버 같은 시스템 프로그램을 자동으로 실행하기 위해 전통적인 유닉스의 SysV 시스템 구동 스크립트 방식(런레벨, rc.d 스크립트 등) 혹은 비슷한 방식을 이용하고 있습니다. &#8230; <a href="http://lethean.pe.kr/2011/05/30/pcd-process-control-daemon/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2011/05/30/pcd-process-control-daemon/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=pcd-process-control-daemon">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>아치리눅스를 비롯한 몇몇 리눅스 배포판은 여전히 시스템 부팅 초기화에 필요한 작업, 예를 들어 로컬 파일 시스템을 마운트하거나 웹서버, X서버 같은 시스템 프로그램을 자동으로 실행하기 위해 전통적인 유닉스의 SysV 시스템 구동 스크립트 방식(런레벨, rc.d 스크립트 등) 혹은 비슷한 방식을 이용하고 있습니다. 하지만 오래된 이 방식은 셸 스크립트 기반이라 전반적인 실행 속도가 느릴 뿐 아니라 프로세스간 의존성, 프로세스 종료시 예외처리(예: 자동 재실행) 등과 같은 기능을 지원하지 않아 많은 시스템 관리자 및 개발자의 불만을 산 것도 사실입니다. 특히 최근 몇 년동안 이슈가 되었던 리눅스 부팅 속도 단축을 위해 제일 먼저 처리되어야 하는 걸림돌로 여겨지기도 했습니다. 이런 이유로, 우분투(Ubuntu)는 오래전부터 자체적으로 개발한 <a href="http://upstart.ubuntu.com/">Upstart</a> 프로그램으로 이를 교체했고, 페도라(Fedora) 역시 Fedora 15부터 <a href="http://www.freedesktop.org/wiki/Software/systemd">Systemd</a> 프로그램을 이용해 구동 과정을 관리합니다. 즉, 요즘 리눅스 서버 / 데스크탑 시스템에서 시스템 초기 부팅 작업을 위한 솔루션은, 가히 춘추전국시대라고 할 수 있을만큼, 각각을 리눅스 표준으로 정착하려고 노력하는 이들이 있는가 하면, 그냥 옛것이 좋은 것이라고 고수하는 이도 있고, 더 단순하고 본인 입맛에 맞는 시스템을 직접 개발해서 사용하는 이도 있을만큼 다양합니다.</p>
<p>그런데 여담이지만, 아치리눅스 부팅 과정 커스터마이징과 속도를 경험해봐서 그런 건지, 범용 배포판은 어쩔 수 없이 모든 사용자가 만족할 수 있도록 가능한 많은 서비스 프로그램을 기본적으로 설치하고 이를 모두 시작하기 때문에 느려질 수 밖에 없는 건데, 부팅 속도 향상을 위해 시작 프로세스 관리 데몬의 성능과 기능을 개선하는 방향으로만 접근하고 있는 게 아닌가 하는 생각도 듭니다. 물론 다른 고급 기능을 제공한다고 하지만, 어차피 대부분의 기능은 배포판 개발자들만 사용하는 거고&#8230; :) 참고로, 이 <a href="http://free-electrons.com/blog/boot-time-genivi-2011/">발표자료</a>만 봐도 부팅 속도와 초기화 프로그램의 능력은 무관한 것 같습니다.</p>
<p>아무튼, 지금까지 설명한 배경이 최근 <a href="http://free-electrons.com/blog/elc-2011-videos/">임베디드 리눅스 컨퍼런스 2011 발표 슬라이드</a>를 읽다가 <a href="http://elinux.org/images/b/ba/Elc2011_shalom.odp">PCD(Process Control Daemon)라는 프로세스 관리 데몬을 소개하는 내용</a>을 보고 흥미를 가질 수 밖에 없었던 이유입니다. 위에 소개한 최신 프로그램들이 제공하는 기본 기능을 충실히 구현한 것은 물론, 임베디드 시스템을 우선 대상으로 개발했기 때문에 실행파일 크기가 매우 작고 빠르다는 점이 가장 매력적인 장점인 것 같습니다. (자세한 기능은 직접 확인해 보시길&#8230; :)</p>
<p>Systemd / Upstart 프로그램은 기능은 강력하지만 임베디드 시스템에 적용하기에는 너무 덩치가 크고 라이브러리 의존성도 무시하지 못할만큼 무겁습니다. 또한 임베디드 시스템은 개발자가 시스템의 모든 프로세스를 통제하고 완벽하게 관리해야 하기 때문에, 시스템에 대해 배포판 개발자와 동등하거나 더 많은 이해를 필요로 하므로 이러한 도구를 이용하면 작업이 수월해질 수 있습니다. 더 나아가, 이 프로그램을 조금 더 응용하면 데스크탑 / 서버용 시스템에서 여러 프로세스로 동작하는 시스템을 개발할 때도 유용하지 않을까 하는 생각도 듭니다.</p>
<p>물론 임베디드 리눅스 개발시 하나의 셸 스크립트 안에서 부팅 과정에 필요한 모든 작업을 처리하는 방식이 무조건 나쁜 건 아닙니다. 다만 복잡도가 더 높은 시스템을 설계할 때는 반드시 이런 프로세스 / 세션 관리 / 예외 처리 프로그램을 사용하거나 알아두면 나중에 참고하는 데 도움이 되지 않을까 생각해 봅니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/05/30/pcd-process-control-daemon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>libmicrohttpd 내장 웹서버 라이브러리</title>
		<link>http://lethean.pe.kr/2011/05/02/libmicrohttpd-embedded-web-server-library/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=libmicrohttpd-embedded-web-server-library&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=libmicrohttpd-%25eb%2582%25b4%25ec%259e%25a5-%25ec%259b%25b9%25ec%2584%259c%25eb%25b2%2584-%25eb%259d%25bc%25ec%259d%25b4%25eb%25b8%258c%25eb%259f%25ac%25eb%25a6%25ac</link>
		<comments>http://lethean.pe.kr/2011/05/02/libmicrohttpd-embedded-web-server-library/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=libmicrohttpd-embedded-web-server-library#comments</comments>
		<pubDate>Mon, 02 May 2011 04:26:52 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Embedded]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1656</guid>
		<description><![CDATA[최근 프로젝트에서 내장 웹서버를 운영하기 위해 libmicrohttpd 라이브러리를 적용해 보았습니다. 물론, 임베디드 시스템에서 많이 사용하는 GoAhead 등과 같은 상용 라이브러리를 사용하거나, BusyBox 내장 웹서버, 또는 다른 많은 오픈소스 라이브러리를 사용할 수도 있지만, 라이센스도(LGPL 또는 eCos) 괜찮고, 성능과 API 구성이 단순하고 &#8230; <a href="http://lethean.pe.kr/2011/05/02/libmicrohttpd-embedded-web-server-library/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2011/05/02/libmicrohttpd-embedded-web-server-library/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=libmicrohttpd-embedded-web-server-library">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>최근 프로젝트에서 내장 웹서버를 운영하기 위해 <a href="http://www.gnu.org/software/libmicrohttpd/">libmicrohttpd</a> 라이브러리를 적용해 보았습니다. 물론, 임베디드 시스템에서 많이 사용하는 <a href="http://www.goahead.com/">GoAhead</a> 등과 같은 상용 라이브러리를 사용하거나, <a href="http://www.busybox.net/">BusyBox</a> 내장 웹서버, 또는 다른 많은 오픈소스 라이브러리를 사용할 수도 있지만, 라이센스도(LGPL 또는 eCos) 괜찮고, 성능과 API 구성이 단순하고 명쾌한 것 같아서 시도해 보았습니다. (물론 아직도 주변에는 라이센스 무시하고 상용 라이브러리 몰래 사용하는 곳이 많긴 하지만&#8230; :-) 참고로, 이 라이브러리는 <a href="http://xbmc.org/">XBMC</a> 프로젝트를 들여다보다가 내부에서 사용하는 걸 우연하게 발견했습니다.</p>
<p>내장 웹서버 라이브러리를 사용하면 얻을 수 있는 가장 좋은 장점은 MJPEG, RTSP-over-HTTP 등과 같은 웹기반 스트리밍 서버를 만들때 매우 편리하다는 점입니다. 한 프로세스 안에서 웹서버 + 스트리밍 생성 루틴이 함께 동작하므로 메모리 복사 오버헤드가 줄어들고 프로그래밍 복잡도 역시 감소합니다. 또한 CGI 프로세스가 따로 동작할 필요가 없으므로 웹을 통해 설정을 변경해도 별도의 프로세스간 통신이 불필요합니다.</p>
<p>물론, 내장 웹서버 방식이 장점만 있는 건 아닙니다. 기존 스탠드얼론 웹서버가 알아서 자동으로 해주던 부분, 예를 들어 디렉토리 인덱스 파일 생성, 동시 접속 클라이언트 수 관리, 클라이언트 캐시를 위한 수정 시각 고려 등을 프로그래머가 직접 작성해야 합니다. 특히 libmicrohttpd 라이브리는 GoAhead 등과 같은 상용 라이브러리에 비하면 자동화 부분이 조금 부족합니다. 예를 들어 파일 시스템의 일반 파일에 대한 웹서비스 처리도 직접 만들어야 합니다. 물론, 대부분 필요한 기능은 예제 소스를 참고하면 어렵지 않게 구현할 수 있습니다. 하지만 제 생각에는, 웹서버 라이브러리가 너무 많은 기능을 자동화하지 않는게 오히려 더 맞다고 생각하는데, 왜냐하면 대부분 응용 프로그램에서 웹서버를 내장하는 경우는 특수한 용도(RESTful / SOAP)이거나 필요한 기능만 구현하기 위해서이기 때문에 나머지는 모두 개발자가 제어하는게 라이브러리의 제 역할이 아닌가 생각합니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/05/02/libmicrohttpd-embedded-web-server-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>도메인 메일 호스트(MX) 주소 얻기</title>
		<link>http://lethean.pe.kr/2011/04/05/get-domain-mx-host-name/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=get-domain-mx-host-name&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25eb%258f%2584%25eb%25a9%2594%25ec%259d%25b8-%25eb%25a9%2594%25ec%259d%25bc-%25ed%2598%25b8%25ec%258a%25a4%25ed%258a%25b8mx-%25ec%25a3%25bc%25ec%2586%258c-%25ec%2596%25bb%25ea%25b8%25b0</link>
		<comments>http://lethean.pe.kr/2011/04/05/get-domain-mx-host-name/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=get-domain-mx-host-name#comments</comments>
		<pubDate>Tue, 05 Apr 2011 07:03:05 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[glibc]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1646</guid>
		<description><![CDATA[예를 들어 nobody@hades.net이라는 메일 주소의 서버는 hades.net인 것 같지만 실제로 메일을 호스팅하는 서버는 해당 도메인 서버에 질의해서 MX 레코드에 기록된 호스트를 찾아야 합니다. 그리고 이 작업을 위해 DNS 관련 프로토콜을 직접 구현하거나. djbdns 등과 같은 라이브러리를 이용합니다. 그런데, 요즘 기존 &#8230; <a href="http://lethean.pe.kr/2011/04/05/get-domain-mx-host-name/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2011/04/05/get-domain-mx-host-name/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=get-domain-mx-host-name">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>예를 들어 nobody@hades.net이라는 메일 주소의 서버는 hades.net인 것 같지만 실제로 메일을 호스팅하는 서버는 해당 도메인 서버에 질의해서 MX 레코드에 기록된 호스트를 찾아야 합니다. 그리고 이 작업을 위해 DNS 관련 프로토콜을 직접 구현하거나. <a href="http://cr.yp.to/djbdns.html">djbdns</a> 등과 같은 라이브러리를 이용합니다.</p>
<p>그런데, 요즘 기존 코드를 리팩토링하면서 가능한 오래된(?) 라이브러리에 대한 의존성을 없애고 있는데 위에서 설명한 작업을 하는 함수가 리눅스 기본 glibc 라이브러리가 <em>당연히</em> 제공하는 걸 알게 되어 잠시 허탈했습니다.</p>
<p>다음은 도메인 이름을 인수로 주면 해당 도메인의 MX 레코드, 즉 메일서버 호스트를 glibc API를 이용해 작성한 코드입니다.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;netinet/in.h&gt;</span>
<span style="color: #339933;">#include &lt;arpa/nameser.h&gt;</span>
<span style="color: #339933;">#include &lt;resolv.h&gt;</span>
&nbsp;
<span style="color: #993333;">static</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>
lookup_mx <span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>name<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> response<span style="color: #009900;">&#91;</span>NS_PACKETSZ<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>  <span style="color: #808080; font-style: italic;">/* big enough, right? */</span>
  ns_msg        handle<span style="color: #339933;">;</span>
  <span style="color: #993333;">int</span>           ns_index<span style="color: #339933;">;</span>
  <span style="color: #993333;">int</span>           len<span style="color: #339933;">;</span>
&nbsp;
  len <span style="color: #339933;">=</span> res_search <span style="color: #009900;">&#40;</span>name<span style="color: #339933;">,</span> C_IN<span style="color: #339933;">,</span> T_MX<span style="color: #339933;">,</span> response<span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span> <span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>len <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #808080; font-style: italic;">/* failed to search MX records */</span>
      <span style="color: #b1b100;">return</span> strdup <span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ns_initparse <span style="color: #009900;">&#40;</span>response<span style="color: #339933;">,</span> len<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>handle<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #808080; font-style: italic;">/* failed to parse MX records for '%s'&quot;, name); */</span>
      <span style="color: #b1b100;">return</span> strdup <span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  len <span style="color: #339933;">=</span> ns_msg_count <span style="color: #009900;">&#40;</span>handle<span style="color: #339933;">,</span> ns_s_an<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>len <span style="color: #339933;">&lt;=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #808080; font-style: italic;">/* no mx records */</span>
      <span style="color: #b1b100;">return</span> strdup <span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>ns_index <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> ns_index <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> ns_index<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      ns_rr rr<span style="color: #339933;">;</span>
      <span style="color: #993333;">char</span>  dispbuf<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4096</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ns_parserr <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>handle<span style="color: #339933;">,</span> ns_s_an<span style="color: #339933;">,</span> ns_index<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>rr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          <span style="color: #808080; font-style: italic;">/* WARN: ns_parserr failed */</span>
          <span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      ns_sprintrr <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>handle<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>rr<span style="color: #339933;">,</span> NULL<span style="color: #339933;">,</span> NULL<span style="color: #339933;">,</span> dispbuf<span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span> <span style="color: #009900;">&#40;</span>dispbuf<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ns_rr_class <span style="color: #009900;">&#40;</span>rr<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> ns_c_in <span style="color: #339933;">&amp;&amp;</span> ns_rr_type <span style="color: #009900;">&#40;</span>rr<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> ns_t_mx<span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          <span style="color: #993333;">char</span> mxname<span style="color: #009900;">&#91;</span>MAXDNAME<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
          dn_expand <span style="color: #009900;">&#40;</span>ns_msg_base <span style="color: #009900;">&#40;</span>handle<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                     ns_msg_base <span style="color: #009900;">&#40;</span>handle<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> ns_msg_size <span style="color: #009900;">&#40;</span>handle<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                     ns_rr_rdata<span style="color: #009900;">&#40;</span>rr<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> NS_INT16SZ<span style="color: #339933;">,</span>
                     mxname<span style="color: #339933;">,</span>
                     <span style="color: #993333;">sizeof</span> <span style="color: #009900;">&#40;</span>mxname<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          <span style="color: #b1b100;">return</span> strdup <span style="color: #009900;">&#40;</span>mxname<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">return</span> strdup <span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>관련 자료는 <a href="http://stackoverflow.com/">Stack Overflow</a>에서 본 것 같기도 하고&#8230; 아무튼, 명색이 전문 리눅스 C 프로그래머로서 15년 넘게 버티고 있으면서도 아직까지도 기본 C 라이브러리가 제공하는 함수도 제대로 알지 못하는 스스로를 돌아보게 됩니다. :(</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/04/05/get-domain-mx-host-name/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>GUDev 사용하기</title>
		<link>http://lethean.pe.kr/2011/03/07/using-gudev/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-gudev&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gudev-%25ec%2582%25ac%25ec%259a%25a9%25ed%2595%2598%25ea%25b8%25b0</link>
		<comments>http://lethean.pe.kr/2011/03/07/using-gudev/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-gudev#comments</comments>
		<pubDate>Mon, 07 Mar 2011 12:15:48 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[GLib]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Udev]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1611</guid>
		<description><![CDATA[이제는 리눅스 데스크탑 뿐 아니라 임베디드 시스템에서도 당연하게 사용하는 udev 시스템은 단순히 장치 파일을 자동으로 생성해 주는 역할 뿐 아니라 여러 핫플러그(hot-plug) 방식 장치를 감지하는데도 유용하게 사용됩니다. 비단 키보드, 마우스 같은 입력 장치 뿐 아니라 USB 플래시, SATA / IDE &#8230; <a href="http://lethean.pe.kr/2011/03/07/using-gudev/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2011/03/07/using-gudev/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=using-gudev">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>이제는 리눅스 데스크탑 뿐 아니라 임베디드 시스템에서도 당연하게 사용하는 <a href="http://en.wikipedia.org/wiki/Udev">udev</a> 시스템은 단순히 장치 파일을 자동으로 생성해 주는 역할 뿐 아니라 여러 핫플러그(hot-plug) 방식 장치를 감지하는데도 유용하게 사용됩니다. 비단 키보드, 마우스 같은 입력 장치 뿐 아니라 USB 플래시, SATA / IDE / SCSI 하드디스크, CD-RW 등과 같은 저장장치가 삽입되었거나 제거되었을 경우 쉽게 감지할 수 있게 도와줍니다.</p>
<p>이러한 udev 서브 시스템의 혜택을 개발자가 얻기 위해 많은 방법이 존재하지만, 이 글에서는 GLib 메인루프 기반으로 동작하는 <a href="http://www.kernel.org/pub/linux/utils/kernel/hotplug/gudev/">GUDev</a> 라이브러리를 이용하는 법을 설명합니다. GLib 라이브러리를 사용하지 않을 경우 직접 <a href="http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/">libudev</a> 라이브러리를 사용해도 되지만, 기본 개념만 파악하면 쉽게 어떤 라이브러리를 사용해도 상관없기 때문에 인터페이스가 더 편하고 직관적인 GUDev 라이브러리를 사용합니다. 참고로, 이 글은 &#8220;<a href="http://www.signal11.us/oss/udev/">libudev and Sysfs Tutorial</a>﻿&#8221; 글과 &#8220;<a href="http://www.piware.de/2010/06/gudev-vala-bindings/">gudev Vala bindings</a>&#8221; 글을 참고했습니다.</p>
<p>먼저 라이브러리를 설치하려면 우분투에서는 <code>libgudev-1.0-dev</code> 패키지, 아치리눅스에서는 <code>udev</code> 패키지를 설치하면 됩니다. (여담이지만, 아치리눅스는 개발에 필요한 헤더파일과 라이브러리가 별도 패키지로 분리되어 있는 경우가 별로 없는 것 같습니다)</p>
<p>다음 소스 코드는 현재 시스템에 장착된 모든 블럭 장치(block)를 보여주고, 이후 USB 플래시가 삽입되거나 제거되었을때 이를 감지하여 표시하도록 한 소스 코드입니다.(<code>gudev.c</code>)</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;gudev/gudev.h&gt;</span>
&nbsp;
<span style="color: #993333;">static</span> <span style="color: #993333;">void</span>
print_device <span style="color: #009900;">&#40;</span>GUdevDevice <span style="color: #339933;">*</span>device<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">const</span> gchar <span style="color: #339933;">*</span> <span style="color: #993333;">const</span> <span style="color: #339933;">*</span>symlinks<span style="color: #339933;">;</span>
&nbsp;
  g_print <span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;  subsystem       : %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  devtype         : %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  name            : %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  number          : %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  sysfs_path      : %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  driver          : %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  action          : %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  seqnum          : %lld<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  device_type     : %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  device_number   : %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;  device_file     : %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
           <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>
           g_udev_device_get_subsystem <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_devtype <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_name <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_number <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_sysfs_path <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_driver <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_action <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_seqnum <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_device_type <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_device_number <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
           g_udev_device_get_device_file <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">static</span> <span style="color: #993333;">void</span>
uevented <span style="color: #009900;">&#40;</span>GUdevClient <span style="color: #339933;">*</span>client<span style="color: #339933;">,</span>
          gchar       <span style="color: #339933;">*</span>action<span style="color: #339933;">,</span>
          GUdevDevice <span style="color: #339933;">*</span>device<span style="color: #339933;">,</span>
          gpointer     user_data<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  g_print <span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;[action:%s]<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> action<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  print_device <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">static</span> <span style="color: #993333;">void</span>
print_block_device <span style="color: #009900;">&#40;</span>gpointer data<span style="color: #339933;">,</span>
                    gpointer user_data<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  GUdevDevice <span style="color: #339933;">*</span>device <span style="color: #339933;">=</span> data<span style="color: #339933;">;</span>
&nbsp;
  print_device <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  g_object_unref <span style="color: #009900;">&#40;</span>device<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">static</span> <span style="color: #993333;">void</span>
print_block_devices <span style="color: #009900;">&#40;</span>GUdevClient <span style="color: #339933;">*</span>client<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  GList <span style="color: #339933;">*</span>devices<span style="color: #339933;">;</span>
&nbsp;
  devices <span style="color: #339933;">=</span> g_udev_client_query_by_subsystem <span style="color: #009900;">&#40;</span>client<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;block&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>devices<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    g_print <span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;[block devices]<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    g_list_foreach <span style="color: #009900;">&#40;</span>devices<span style="color: #339933;">,</span> print_block_device<span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    g_list_free <span style="color: #009900;">&#40;</span>devices<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span>
main <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span>    argc<span style="color: #339933;">,</span>
      <span style="color: #993333;">char</span> <span style="color: #339933;">**</span>argv<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">const</span> gchar <span style="color: #339933;">*</span>subsystems<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span>
    <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;usb/usb_interface&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;scsi/scsi_device&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;block&quot;</span><span style="color: #339933;">,</span> NULL <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  GUdevClient <span style="color: #339933;">*</span>client<span style="color: #339933;">;</span>
  GMainLoop   <span style="color: #339933;">*</span>main_loop<span style="color: #339933;">;</span>
&nbsp;
  g_type_init <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  main_loop <span style="color: #339933;">=</span> g_main_loop_new <span style="color: #009900;">&#40;</span>NULL<span style="color: #339933;">,</span> FALSE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  client <span style="color: #339933;">=</span> g_udev_client_new <span style="color: #009900;">&#40;</span>subsystems<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  g_signal_connect <span style="color: #009900;">&#40;</span>client<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;uevent&quot;</span><span style="color: #339933;">,</span> G_CALLBACK <span style="color: #009900;">&#40;</span>uevented<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  print_block_devices <span style="color: #009900;">&#40;</span>client<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  g_main_loop_run <span style="color: #009900;">&#40;</span>main_loop<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  g_object_unref <span style="color: #009900;">&#40;</span>client<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>컴파일 하려면 다음과 같이 실행하면 됩니다.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-o</span> gudev gudev.c <span style="color: #000000; font-weight: bold;">`</span>pkg-config <span style="color: #660033;">--cflags</span> <span style="color: #660033;">--libs</span> gudev-<span style="color: #000000;">1.0</span><span style="color: #000000; font-weight: bold;">`</span></pre></div></div>

<p>소스 코드를 간단하게 설명하면, 제일 먼저 <code><a href="http://www.kernel.org/pub/linux/utils/kernel/hotplug/gudev/GUdevClient.html#g-udev-client-new">g_udev_client_new()</a></code> 함수를 이용해 <code>GUdevClient</code> 객체를 생성합니다. 이때 넘겨주는 인수는 변화를 감지하고 싶은 서브 시스템 목록인데, 여기서는 모든 블럭 장치와 USB, SCSI 서브 시스템을 지정했습니다.(SCSI는 실제로 모든 종류의 하드디스크를 의미하기도 합니다) 만일 <code>NULL</code>을 지정하면 변화 감지 기능을 사용하지 않고 그냥 질의(query) 계열 API만 사용할 수 있으며, 비어있는 목록을 넘겨주면 시스템의 모든 서브시스템의 장치 변화를 감지해서 시그널로 알려줍니다. 참고로 매뉴얼에는 클라이언트를 생성한 쓰레드의 메인루프를 사용하여 감지 루틴이 실행된다고 하니, 만일 별도 쓰레드에서 이 감지 작업을 수행하려면 쓰레드를 먼저 만들고 그 쓰레드 안에서 생성해야 합니다. 이 예제에서는 테스트를 위해 기본 메인 루프를 사용하고 있습니다.</p>
<p>직접 장치 목록을 질의(query)하거나 시그널이 발생했을 경우 넘겨받는 <code>GUdevDevice</code> 객체와 <code><a href="http://www.kernel.org/pub/linux/utils/kernel/hotplug/gudev/GUdevDevice.html">g_udev_device_get_*()</a></code> 계열 API를 이용하면 장치의 세부 정보를 얻을 수 있습니다. 위 예제에서는 udev / sysfs 관련 속성 등은 출력하지 않고 있지만, 필요하다면 더 자세한 정보를 얻을 수 있습니다.</p>
<p>실행하면 대략 다음과 같이 출력됩니다. (당연히 실행 환경에 따라 결과가 다릅니다)</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ .<span style="color: #000000; font-weight: bold;">/</span>gudev
<span style="color: #7a0874; font-weight: bold;">&#91;</span>block devices<span style="color: #7a0874; font-weight: bold;">&#93;</span>
  subsystem       : block
  devtype         : disk
  name            : sda
  number          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1f.2<span style="color: #000000; font-weight: bold;">/</span>host0<span style="color: #000000; font-weight: bold;">/</span>target0:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span>block<span style="color: #000000; font-weight: bold;">/</span>sda
  driver          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  action          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  seqnum          : <span style="color: #000000;">0</span>
  device_type     : <span style="color: #000000;">98</span>
  device_number   : <span style="color: #000000;">2048</span>
  device_file     : <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda
&nbsp;
  subsystem       : block
  devtype         : partition
  name            : sda1
  number          : <span style="color: #000000;">1</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1f.2<span style="color: #000000; font-weight: bold;">/</span>host0<span style="color: #000000; font-weight: bold;">/</span>target0:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span>block<span style="color: #000000; font-weight: bold;">/</span>sda<span style="color: #000000; font-weight: bold;">/</span>sda1
  driver          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  action          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  seqnum          : <span style="color: #000000;">0</span>
  device_type     : <span style="color: #000000;">98</span>
  device_number   : <span style="color: #000000;">2049</span>
  device_file     : <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda1
&nbsp;
  subsystem       : block
  devtype         : disk
  name            : sr0
  number          : <span style="color: #000000;">0</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1f.2<span style="color: #000000; font-weight: bold;">/</span>host5<span style="color: #000000; font-weight: bold;">/</span>target5:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">5</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span>block<span style="color: #000000; font-weight: bold;">/</span>sr0
  driver          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  action          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  seqnum          : <span style="color: #000000;">0</span>
  device_type     : <span style="color: #000000;">98</span>
  device_number   : <span style="color: #000000;">2816</span>
  device_file     : <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sr0</pre></div></div>

<p>위 출력에서는 일반 디스크 장치(<code>/dev/sda</code>)와 디스크 파티션(<code>/dev/sda1</code>), DVD-RW 장치(<code>/dev/sr0</code>)가 있음을 보여줍니다. 여기서 만일 일반 USB 플래시 메모리를 삽입하면 다음과 같은 결과가 출력됩니다.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>action:add<span style="color: #7a0874; font-weight: bold;">&#93;</span>
  subsystem       : usb
  devtype         : usb_interface
  name            : <span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span>
  number          : <span style="color: #000000;">0</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1d.7<span style="color: #000000; font-weight: bold;">/</span>usb2<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span>
  driver          : usb-storage
  action          : add
  seqnum          : <span style="color: #000000;">1934</span>
  device_type     : <span style="color: #000000;">0</span>
  device_number   : <span style="color: #000000;">0</span>
  device_file     : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#91;</span>action:add<span style="color: #7a0874; font-weight: bold;">&#93;</span>
  subsystem       : scsi
  devtype         : scsi_device
  name            : <span style="color: #000000;">17</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>
  number          : <span style="color: #000000;">0</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1d.7<span style="color: #000000; font-weight: bold;">/</span>usb2<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span><span style="color: #000000; font-weight: bold;">/</span>host17<span style="color: #000000; font-weight: bold;">/</span>target17:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">17</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>
  driver          : sd
  action          : add
  seqnum          : <span style="color: #000000;">1938</span>
  device_type     : <span style="color: #000000;">0</span>
  device_number   : <span style="color: #000000;">0</span>
  device_file     : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#91;</span>action:change<span style="color: #7a0874; font-weight: bold;">&#93;</span>
  subsystem       : scsi
  devtype         : scsi_device
  name            : <span style="color: #000000;">17</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>
  number          : <span style="color: #000000;">0</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1d.7<span style="color: #000000; font-weight: bold;">/</span>usb2<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span><span style="color: #000000; font-weight: bold;">/</span>host17<span style="color: #000000; font-weight: bold;">/</span>target17:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">17</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>
  driver          : sd
  action          : change
  seqnum          : <span style="color: #000000;">1944</span>
  device_type     : <span style="color: #000000;">0</span>
  device_number   : <span style="color: #000000;">0</span>
  device_file     : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#91;</span>action:add<span style="color: #7a0874; font-weight: bold;">&#93;</span>
  subsystem       : block
  devtype         : disk
  name            : sdc
  number          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1d.7<span style="color: #000000; font-weight: bold;">/</span>usb2<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span><span style="color: #000000; font-weight: bold;">/</span>host17<span style="color: #000000; font-weight: bold;">/</span>target17:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">17</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span>block<span style="color: #000000; font-weight: bold;">/</span>sdc
  driver          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  action          : add
  seqnum          : <span style="color: #000000;">1945</span>
  device_type     : <span style="color: #000000;">98</span>
  device_number   : <span style="color: #000000;">2080</span>
  device_file     : <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sdc
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#91;</span>action:add<span style="color: #7a0874; font-weight: bold;">&#93;</span>
  subsystem       : block
  devtype         : partition
  name            : sdc1
  number          : <span style="color: #000000;">1</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1d.7<span style="color: #000000; font-weight: bold;">/</span>usb2<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span><span style="color: #000000; font-weight: bold;">/</span>host17<span style="color: #000000; font-weight: bold;">/</span>target17:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">17</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span>block<span style="color: #000000; font-weight: bold;">/</span>sdc<span style="color: #000000; font-weight: bold;">/</span>sdc1
  driver          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  action          : add
  seqnum          : <span style="color: #000000;">1946</span>
  device_type     : <span style="color: #000000;">98</span>
  device_number   : <span style="color: #000000;">2081</span>
  device_file     : <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sdc1</pre></div></div>

<p>위 예제 소스 코드에서 감시하기 위해 지정한  서브 시스템 모두의 변화를 보여주다보니 복잡해 보이지만, 결국 USB 플래시 메모리가 USB / SCSI / BLOCK 서브시스템에 모두 정상적으로 감지되는 걸 확인할 수 있습니다. 다시 장치를 제거하면 다음과 같이 출력됩니다.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>action:remove<span style="color: #7a0874; font-weight: bold;">&#93;</span>
  subsystem       : block
  devtype         : disk
  name            : sdc
  number          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1d.7<span style="color: #000000; font-weight: bold;">/</span>usb2<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span><span style="color: #000000; font-weight: bold;">/</span>host16<span style="color: #000000; font-weight: bold;">/</span>target16:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">16</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span>block<span style="color: #000000; font-weight: bold;">/</span>sdc
  driver          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  action          : remove
  seqnum          : <span style="color: #000000;">1926</span>
  device_type     : <span style="color: #000000;">0</span>
  device_number   : <span style="color: #000000;">2080</span>
  device_file     : <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sdc
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#91;</span>action:remove<span style="color: #7a0874; font-weight: bold;">&#93;</span>
  subsystem       : scsi
  devtype         : scsi_device
  name            : <span style="color: #000000;">16</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>
  number          : <span style="color: #000000;">0</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1d.7<span style="color: #000000; font-weight: bold;">/</span>usb2<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span><span style="color: #000000; font-weight: bold;">/</span>host16<span style="color: #000000; font-weight: bold;">/</span>target16:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">16</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>
  driver          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  action          : remove
  seqnum          : <span style="color: #000000;">1927</span>
  device_type     : <span style="color: #000000;">0</span>
  device_number   : <span style="color: #000000;">0</span>
  device_file     : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">&#91;</span>action:remove<span style="color: #7a0874; font-weight: bold;">&#93;</span>
  subsystem       : usb
  devtype         : usb_interface
  name            : <span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span>
  number          : <span style="color: #000000;">0</span>
  sysfs_path      : <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>devices<span style="color: #000000; font-weight: bold;">/</span>pci0000:00<span style="color: #000000; font-weight: bold;">/</span>0000:00:1d.7<span style="color: #000000; font-weight: bold;">/</span>usb2<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span>-<span style="color: #000000;">3</span>:<span style="color: #000000;">1.0</span>
  driver          : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  action          : remove
  seqnum          : <span style="color: #000000;">1931</span>
  device_type     : <span style="color: #000000;">0</span>
  device_number   : <span style="color: #000000;">0</span>
  device_file     : <span style="color: #7a0874; font-weight: bold;">&#40;</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>이 정보를 실제로 어떻게 활용할지는 이제 어플리케이션에게 달린 몫입니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/03/07/using-gudev/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>사진 파일 이름 변경하기</title>
		<link>http://lethean.pe.kr/2011/02/22/renaming-photo-files/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=renaming-photo-files&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ec%2582%25ac%25ec%25a7%2584-%25ed%258c%258c%25ec%259d%25bc-%25ec%259d%25b4%25eb%25a6%2584-%25eb%25b3%2580%25ea%25b2%25bd%25ed%2595%2598%25ea%25b8%25b0</link>
		<comments>http://lethean.pe.kr/2011/02/22/renaming-photo-files/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=renaming-photo-files#comments</comments>
		<pubDate>Tue, 22 Feb 2011 14:58:59 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ArchLinux]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1600</guid>
		<description><![CDATA[요즘 디지털 카메라나 휴대폰으로 촬영한 JPEG 파일에는 EXIF 정보가 삽입되어 있어서 나름 유용할 때가 많습니다. 카메라에 대한 자세한 사양(?) 정보에는 관심이 없지만, 촬영한 시각이라든지 카메라를 세워서 촬영했는지 여부는 물론, 카메라 GPS 옵션을 켜면 기록되는 촬영 장소의 정확한 좌표는 가끔 두려울 &#8230; <a href="http://lethean.pe.kr/2011/02/22/renaming-photo-files/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2011/02/22/renaming-photo-files/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=renaming-photo-files">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>요즘 디지털 카메라나 휴대폰으로 촬영한 JPEG 파일에는 <a href="http://en.wikipedia.org/wiki/EXIF">EXIF</a> 정보가 삽입되어 있어서 나름 유용할 때가 많습니다. 카메라에 대한 자세한 사양(?) 정보에는 관심이 없지만, 촬영한 시각이라든지 카메라를 세워서 촬영했는지 여부는 물론, 카메라 GPS 옵션을 켜면 기록되는 촬영 장소의 정확한 좌표는 가끔 두려울 때도 있습니다.</p>
<p>아무튼 요즘은 윈도우나 맥 부럽지 않은 리눅스 사진 관리 프로그램들이 많이 있어서 편하긴 한데, 이런 프로그램들이 존재하기 전부터, EXIF 정보가 포함되지도 않았던 시절부터 디렉토리별로 관리해오던 습관을 버리지 못하는 게 문제입니다. 예를 들어 폴더는 알아보기 쉽게 <code>YYYYMMDD-장소또는이벤트이름</code> 식으로 이름짓고, 안에 들어있는 JPEG 파일은 <code>YYYYMMDD-hhmmss-photo.jpg</code>, 동영상 파일은 <code>YYYYMMDD-hhmmss-movie.mp4</code> 식으로 이름을 지어 줍니다.</p>
<p>물론, 이런 작업을 모두 수작업으로 하지는 않습니다. EXIF 정보에 문외한이던 시절에는 <a href="http://live.gnome.org/gthumb">gthumb</a> 같은 프로그램의 이름일괄변경(<code>Rename...</code>) 기능을 이용해 자동으로 날짜 뒤에 일련번호를 붙이기도 했습니다.</p>
<p>하지만 요즘은 그것도 귀찮아서 <code>exiv2</code> / <code>rename</code> 명령어를 이용해 한꺼번에 변경해 버립니다. <a href="http://www.exiv2.org/"><code>exiv2</code></a> 프로그램을 이용해 EXIF 정보에 들어있는 촬영 시각을 기준으로 사진 파일 이름을 변경하고,  <code>rename</code> 명령어를 이용해 대문자로 된 <code>.JPG</code> 확장자를 소문자 <code>.jpg</code> 확장자로 한번에 변경합니다. 예를 들어 위에서 설명한 예처럼 파일 이름을 변경하려면 사진 파일이 들어 있는 디렉토리에서 다음과 같이 실행하면 됩니다.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ rename .JPG .jpg <span style="color: #000000; font-weight: bold;">*</span>.JPG
$ exiv2 <span style="color: #660033;">-r</span> <span style="color: #ff0000;">'%Y%m%d-%H%M%S-photo'</span> <span style="color: #660033;">-k</span> rename <span style="color: #000000; font-weight: bold;">*</span>.jpg</pre></div></div>

<p><code>rename</code> 명령어는 대부분 배포판에 기본으로 설치되어 있으나 <code>exiv2</code> 프로그램은 수동으로 패키지를 설치해야 할 수도 있습니다. 게다가, 우분투의 <code>rename</code> 명령어는 perl 패키지에 포함되어 있는 버전인데 아치 리눅스는 util-linux 패키지에 포함되어 있는 거라 사용법이 조금 다릅니다. 참고로 위 예제는 아치 리눅스 버전입니다. 하지만 <code>exiv2</code>, <code>rename</code> 명령어 모두 매뉴얼 페이지를 보면 자세한 사용 예제가 있으므로 쉽게 사용할 수 있습니다.</p>
<p>그리고 이 글은 사실, 나이가 들수록 자꾸만 옵션을 잊어버려 다시 찾기 귀찮아서 기록하고 있습니다&#8230; :)</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/02/22/renaming-photo-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>아치 리눅스(Arch Linux)로 갈아타다</title>
		<link>http://lethean.pe.kr/2011/02/21/migrated-to-arch-linux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=migrated-to-arch-linux&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ec%2595%2584%25ec%25b9%2598-%25eb%25a6%25ac%25eb%2588%2585%25ec%258a%25a4arch-linux%25eb%25a1%259c-%25ea%25b0%2588%25ec%2595%2584%25ed%2583%2580%25eb%258b%25a4</link>
		<comments>http://lethean.pe.kr/2011/02/21/migrated-to-arch-linux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=migrated-to-arch-linux#comments</comments>
		<pubDate>Mon, 21 Feb 2011 04:33:09 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ArchLinux]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1588</guid>
		<description><![CDATA[1996년부터 리눅스를 사용하면서 슬랙웨어, 레드햇, 데비안을 거쳐 우분투 배포판을 사용해 오다가 최근 아치 리눅스로 갈아 탔습니다. 우분투가 여러 이유로 편하긴 하지만, 어느 순간부터 점점 무거워지다가(mono, python 기반 기본 프로그램 때문?), 별로 사용하지 않고 원하지도 않는 기능들이 추가되는가 싶더니만(Ubuntu One 등) 급기야 &#8230; <a href="http://lethean.pe.kr/2011/02/21/migrated-to-arch-linux/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2011/02/21/migrated-to-arch-linux/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=migrated-to-arch-linux">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>1996년부터 리눅스를 사용하면서 <a href="http://slackware.com/">슬랙웨어</a>, <a href="http://www.redhat.com/">레드햇</a>, <a href="http://www.debian.org/">데비안</a>을 거쳐 <a href="http://www.ubuntu.com/">우분투</a> 배포판을 사용해 오다가 최근 <a href="http://www.archlinux.org/">아치 리눅스</a>로 갈아 탔습니다. 우분투가 여러 이유로 편하긴 하지만, 어느 순간부터 점점 무거워지다가(mono, python 기반 기본 프로그램 때문?), 별로 사용하지 않고 원하지도 않는 기능들이 추가되는가 싶더니만(Ubuntu One 등) 급기야 2011.4 버전부터 그놈 3(GNOME 3) 프로젝트의 공식 셸(GNOME Shell) 대신 자체 유나이티(Unity) 셸을 채택한다고 하는 순간, 아 이제 우분투와 이별의 순간이 다가왔구나 깨달았습니다. 그놈 셸이 유나이티보다 UX 측면에서 완성도가 더 높다고 생각하고 있었고, 개인적으로 더 선호하는 스타일이었기 때문이기도 하지만, 역시 상업 회사가 이끄는 배포판은 장점도 많지만 이런 단점도 있을 수 있다는 걸 다시 한 번 깨달았기 때문이기도 합니다. 물론 지금까지 우분투에 불만이 없었던 건 아니지만, 대부분 다른 장점에 의해 묻혀버렸는데, 이번 일을 계기로 쌓였던 불만이 한꺼번에 노출된 것 같기도 합니다.</p>
<p>그렇다고 데비안이나 페도라, 젠투 배포판으로 가기에는 별로 재미가 없을 것 같아서 여기 저기 확인해보다가 아치 리눅스를 선택하게 되었습니다. 여러가지 이유가 있지만, 32비트 버전의 경우 패키지 바이너리가 i686에 최적화되어 있고, 패키지 시스템이 의외로 빠르고 단순명료하게 동작하면서, 6개월마다 시스템을 갈아 엎을 일 없이 계속 조금씩 업그레이드 되어(rolling release) 최신 소프트웨어를 항상 바로 사용할 수 있다는 점이 맘에 들었습니다. 더 이상 우분투 개발 버전을 사용하면서 X가 실행되지 않는다든지, 부팅이 안된다든지, 잘 돌던 소프트웨어가 동작하지 않는다든지 걱정할 필요가 없어진 셈입니다. 게다가 아치 사용자 저장소(Arch User Repository; AUR)와 yaourt 프로그램을 사용하니 기존에 별도로 설치했던 dropbox, android-sdk, eclipse, openproj 등도 쉽게 패키지로 설치할 수 있어 더 편했습니다. 물론 GUI 방식 패키지 관리자가 없고 패키지 설치만으로 모든 설정이 자동으로 되는게 아니라 어느 정도 리눅스 경험자가 아니면 불편한 점도 많지만, 오히려 중급 사용자 이상일 경우 원리를 하나씩 알아가면서 설치하는 재미도 쏠쏠합니다. 게다가 별도 문서가 불필요할 정도로 아치리눅스 위키 페이지 정리가 잘 되어 있어 굳이 다른 구글링도 필요없는 것 같습니다. 물론, 한글 글꼴 패키지의 부족이나 부족한 그놈 테마 패키지 등 못마땅한 점이 없는 건 아니지만, 어차피 단점 없는 배포판은 없는 법, 나름 오랜만에 커스터마이징에 즐거운 시간을 보낸 것 같습니다.</p>
<p>인증 스크린샷이라도 하나 올리려다가, 별로 다른게 없어서 그만 두었습니다. 사용하는 배포판이 무엇이든, 어차피 설치 이후에는 결국 동일한 리눅스일 뿐이기 때문입니다. 여담이지만, 오래된 저사양 노트북에서도 동일한 그놈 환경인데 우분투보다 더 빨리 실행되는 듯한 느낌을 받고 있습니다. 물론 정신적인 영향이 더 큰 것 같기도 하지만&#8230; :)</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/02/21/migrated-to-arch-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>perf top 사용하기</title>
		<link>http://lethean.pe.kr/2011/01/16/using-perf-top/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-perf-top&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=perf-top-%25ec%2582%25ac%25ec%259a%25a9%25ed%2595%2598%25ea%25b8%25b0</link>
		<comments>http://lethean.pe.kr/2011/01/16/using-perf-top/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-perf-top#comments</comments>
		<pubDate>Sun, 16 Jan 2011 09:37:06 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Kernel]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Perf]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1569</guid>
		<description><![CDATA[리눅스에서 병목 현상 디버깅이나 현재 실행중인 프로세스 중에서 가장 CPU 리소스를 많이 소모하는 녀석을 찾아야 할 경우가 있습니다. 이런 경우 가장 전통적이고 간단한 방법은 top 명령어를 실행해서 키보드 단축키 &#8217;1&#8242; / &#8216;H&#8217;를 눌러 CPU / 쓰레드별 사용량을 확인하는 것입니다. 또한 이와 &#8230; <a href="http://lethean.pe.kr/2011/01/16/using-perf-top/">Continue reading <span>&#8594;</span></a> <a href="http://lethean.pe.kr/2011/01/16/using-perf-top/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=using-perf-top">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>리눅스에서 병목 현상 디버깅이나 현재 실행중인 프로세스 중에서 가장 CPU 리소스를 많이 소모하는 녀석을 찾아야 할 경우가 있습니다. 이런 경우 가장 전통적이고 간단한 방법은 <code>top</code> 명령어를 실행해서 키보드 단축키 &#8217;1&#8242; / &#8216;H&#8217;를 눌러 CPU / 쓰레드별 사용량을 확인하는 것입니다. 또한 이와 관련된 전통적인 유닉스 명령어도 많지만, 리눅스에서 실행 루틴 수준에서 더 정밀하게 분석하고 싶다면 <a href="http://www.google.co.kr/search?q=OProfile">OProfile</a>, <a href="http://www.google.co.kr/search?q=Valgrind">Valgrind</a>, <a href="http://lethean.pe.kr/2009/06/18/debugging-memory-leaks-with-tcmalloc-google-perftools/">Google Performance Tools</a> 등과 같은 도구를 사용해도 됩니다.</p>
<p>그런데, 최근 리눅스 커널과 배포판에는 <a href="https://perf.wiki.kernel.org/">perf</a> 추적(trace) 도구가 포함되어 있습니다. 그리고 이를 기반으로 한 여러 명령어 중에서, 이 글에서 소개하는 <code>perf top</code> 명령어를 사용하면 쉽게 현재 실행중인 커널 / 사용자 프로세스의 CPU 사용 내역을 확인할 수 있습니다. 이 명령어는 기본적으로 <code>top</code> 명령어와 비슷하게 동작하지만, OProfile 같은 도구처럼 별도의 복잡한 설정 과정이 필요없다는 장점이 있습니다. 게다가 그 원리를 조금만 이해하면 다양한 응용이 가능하고, 최근 리눅스 커널에 추가된 많은 추적 도구 중에서 가장 활발하게 개발되고 있는 프레임워크이기 때문에 익숙해지는 것도 나쁘지 않을 것 같습니다.</p>
<p>우분투 리눅스에서 perf 도구를 사용하려면 제일 먼저 다음과 같이 해당 패키지를 설치해야 합니다.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> linux-tools</pre></div></div>

<p>실행하기 위해서 반드시 perf 이벤트 접근 권한이 있어야 하므로 루트 계정 또는 <code>sudo</code> 명령을 이용해 다음과 같이 무작정 실행하면 됩니다.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> perf top</pre></div></div>

<p><a href="http://lethean.pe.kr/wp-content/uploads/2011/01/perf-top-screenshot.png" rel="lightbox[1569]"><img class="alignnone size-full wp-image-1576" title="perf-top-screenshot" src="http://lethean.pe.kr/wp-content/uploads/2011/01/perf-top-screenshot.png" alt="" width="564" height="392" /></a></p>
<p>위 출력 화면을 간단하게 설명하면, 마지막 갱신 주기 동안 <code>AES_encrypt</code> 함수가 가장 많이 실행되었습니다. 목록은 위에서 아래로 더 많이 실행된 순서로 정렬되어 있는데, 각 열(column)을 설명하면, 맨 앞의 샘플(samples)과 퍼센트(pcnt)는 총 성능 카운터 샘플링 중에서 차지한 회수와 비율을 나타내고 함수(function)과 동적 공유 객체(DSO)는 샘플링된 위치를 보여줍니다. 따라서 가장 많이 샘플링된 함수가 갱신 주기 동안 가장 많이 실행된 부분이라고 해석하면 됩니다.</p>
<p>예를 들어 위 실행 결과는, <code>git pull</code> 명령으로 ssh 방식 네트웍 서버로부터 데이터를 받아오는 작업을 처리하는 과정을 분석한 것입니다. ssh 연결이므로 암호화 관련 라이브러리 호출이 가장 많이 보이고, 커널에서 사용자 공간으로 복사하는 함수, e1000 이더넷 드라이버 인터럽트 핸들러 등이 눈에 띕니다.</p>
<p><code>man perf top</code> 또는 <code>perf top help</code> 명령으로 더 자세한 사용법을 얻을 수 있습니다. 많은 옵션이 있지만 그 중에서 자주 사용하는 옵션 몇 가지만 설명하면, <code>-v</code> 옵션은 함수 내에서 더 장확한 샘플링 위치를 보여주면서 상세한 메시지를 출력합니다. 그리고, <code>-s</code> 옵션은 지정한 함수만 어셈블리 단계에서 샘플링한 결과를 자세히 보여줍니다.</p>
<p>참고로, 데비안 / 우부툰에서 개발하는 분이라면 패키지로 설치한 라이브러리의 디버깅 심볼 포함 패키지를 함께 설치해 두면, 예를 들어 libc6 라이브러리는 libc6-dbg 패키지(끝에 &#8216;-dbg&#8217;가 더 붙음), 많은 개발 / 분석 도구에서 더 자세한 정보를 얻을 수 있습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/01/16/using-perf-top/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
		<item>
		<title>파일 공간 미리 할당하기</title>
		<link>http://lethean.pe.kr/2011/01/12/allocate-file-space-in-advance/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=allocate-file-space-in-advance&#038;utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ed%258c%258c%25ec%259d%25bc-%25ea%25b3%25b5%25ea%25b0%2584-%25eb%25af%25b8%25eb%25a6%25ac-%25ed%2595%25a0%25eb%258b%25b9%25ed%2595%2598%25ea%25b8%25b0</link>
		<comments>http://lethean.pe.kr/2011/01/12/allocate-file-space-in-advance/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=allocate-file-space-in-advance#comments</comments>
		<pubDate>Wed, 12 Jan 2011 06:41:41 +0000</pubDate>
		<dc:creator>lethean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[glibc]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[카스탈리엔]]></category>

		<guid isPermaLink="false">http://lethean.pe.kr/?p=1573</guid>
		<description><![CDATA[비단 비트토런트(BitTorrent)나 어뮬(aMule) 같은 P2P 응용 프로그램이 아니라도 파일 크기를 (대략이라도) 미리 알고 있을 경우, 디스크 공간을 미리 할당해서 단편화(fragmentation)를 줄이는 것은 물 <a href="http://lethean.pe.kr/2011/01/12/allocate-file-space-in-advance/?utm_source=rss&#38;utm_medium=rss&#38;utm_campaign=allocate-file-space-in-advance">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[비단 비트토런트(BitTorrent)나 어뮬(aMule) 같은 P2P 응용 프로그램이 아니라도 파일 크기를 (대략이라도) 미리 알고 있을 경우, 디스크 공간을 미리 할당해서 단편화(fragmentation)를 줄이는 것은 물론 용량 부족으로 인한 쓰기 오류를 미리 막는 기법은 종종 필요합니다. 예전에는 이를 위해 파일을 생성한뒤 원하는 크기의 &#8230; <a href="http://lethean.pe.kr/2011/01/12/allocate-file-space-in-advance/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></content:encoded>
			<wfw:commentRss>http://lethean.pe.kr/2011/01/12/allocate-file-space-in-advance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/kr/</creativeCommons:license>
	</item>
	</channel>
</rss>

