<?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/"
	>

<channel>
	<title>pigfoot's weblog &#187; Develop</title>
	<atom:link href="http://weblog.pigfoot.org/pigfoot/category/dev/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.pigfoot.org/pigfoot</link>
	<description>We should forget about small efficiencies -- Donald Knuth</description>
	<lastBuildDate>Fri, 30 Jul 2010 02:51:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Trend Micro Program Contest 2009 Training #3: Hadoop MapReduce</title>
		<link>http://weblog.pigfoot.org/pigfoot/2009/05/25/trend-micro-program-contest-2009-training-3-hadoop-mapreduce/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2009/05/25/trend-micro-program-contest-2009-training-3-hadoop-mapreduce/#comments</comments>
		<pubDate>Mon, 25 May 2009 09:47:40 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/?p=576</guid>
		<description><![CDATA[子曰：「性相近也，習相遠也。」Hadoop 和 Google 的 MapReduce 的實作就有這種感覺。 前一篇有提到，MapReduce 是 Google 所提出來的一個 software framework，只要把握它的原則，實作它並不會很困難。我們來看看 Google 和 Hadoop 三大碁石的對應表: Google Hadoop GFS (和 RedHat 的 GFS 是不一樣的) HDFS MapReduce MapReduce BigTable HBase Figure1: Google and Hadoop mapping table 雖然目前會先以 open-source 的 Hadoop MapReduce 為主，但是我們可以看的到這兩個都是用 Distributed file system 來作資料的交換，也有自己的 MapReduce 的方法，所以概念上相去不遠。 在開始講之前，有件事應該要先提一下，因為 Hadoop 是以 Java 開發的，所以不熟的人可能會很排斥，老實說我也如此。但是 Hadoop 有提供一些方法讓開發者可以用其它的語言來寫 MapReduce。 [...]]]></description>
			<content:encoded><![CDATA[<p>子曰：「性相近也，習相遠也。」Hadoop 和 Google 的 <a target="_blank" href="http://en.wikipedia.org/wiki/MapReduce">MapReduce</a> 的實作就有這種感覺。</p>
<p>前一篇有提到，MapReduce 是 Google 所提出來的一個 software framework，只要把握它的原則，實作它並不會很困難。我們來看看 Google 和 Hadoop 三大碁石的對應表:</p>
<div style="margin: 0px 4px 0px 0px; padding: 2px;">
<table class="tbl-main" cellpadding="4" cellspacing="1">
<tbody>
<tr class="tbl-header">
<td>Google</td>
<td>Hadoop</td>
</tr>
<tr class="tbl-body">
<td><a target="_blank" href="http://en.wikipedia.org/wiki/Google_File_System">GFS</a> (和 <a target="_blank" href="http://en.wikipedia.org/wiki/Red_Hat">RedHat</a> 的 <a target="_blank" href="http://en.wikipedia.org/wiki/Global_File_System">GFS</a> 是不一樣的)</td>
<td><a target="_blank" href="http://en.wikipedia.org/wiki/HDFS">HDFS</a></td>
</tr>
<tr class="tbl-body">
<td>MapReduce</td>
<td>MapReduce</td>
</tr>
<tr class="tbl-body">
<td><a target="_blank" href="http://en.wikipedia.org/wiki/BigTable">BigTable</a></td>
<td><a target="_blank" href="http://en.wikipedia.org/wiki/HBase">HBase</a></td>
</tr>
</tbody>
</table>
<div align="center"><small><strong>Figure1: Google and Hadoop mapping table</strong></small></div>
</div>
<p>雖然目前會先以 open-source 的 Hadoop MapReduce 為主，但是我們可以看的到這兩個都是用 <a target="_blank" href="en.wikipedia.org/wiki/Distributed_file_system">Distributed file system</a> 來作資料的交換，也有自己的 MapReduce 的方法，所以概念上相去不遠。</p>
<p>在開始講之前，有件事應該要先提一下，因為 Hadoop 是以 <a target="_blank" href="http://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a> 開發的，所以不熟的人可能會很排斥，老實說我也如此。但是 Hadoop 有提供一些方法讓開發者可以用其它的語言來寫 MapReduce。</p>
<p>我想 Java 的使用者不管是 Hadoop 的說明文件，還是範例程式應該都不是甚麼問題，因此我主要會以 <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29">C</a> 以及 <a target="_blank" href="http://en.wikipedia.org/wiki/Python_%28programming_language%29">Python</a> 為主，然後盡量也會帶點 <a target="_blank" href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">Ruby</a> 和 <a target="_blank" href="http://en.wikipedia.org/wiki/Perl">Perl</a>。</p>
<p>我們先來看看 Hadoop MapReduce 的 work flow:<br />
<a target=" _blank" href="http://farm4.static.flickr.com/3563/3499632181_39e38b78fb_o.png" title="hadoop-1 by pigfoot, on Flickr"><img src="http://farm4.static.flickr.com/3563/3499632181_39e38b78fb_o.png" width="508" height="337" alt="hadoop-1" /></a></p>
<div align="center"><small><strong>Figure2: Hadoop MapReduce work flow</strong></small></div>
<p>這張 work flow 我們往後也會一直看到。如同<a href="http://weblog.pigfoot.org/pigfoot/2009/05/05/trend-micro-program-contest-2009-training-2-mapreduce-overview/">前一篇</a>提到的，MapReduce 有四個很重要的步驟。我們來看看 Hadoop 在這四個階段作了甚麼事情。</p>
<p><strong>1) Input</strong><br />
將要處理的資料上傳到分散式檔案系統中。預設的格式是文字檔 (我們也不會用其它的檔案格式)，而分散式檔案系統以 HDFS 當範例。</p>
<p>完成上傳到分散式檔案系統之後，所有的資料都可以被每一個 node 去存取。而每一個檔案，會以行當單位，自動被分割成固定大小的 Block，分散在各個 node 之中，然而這件事對我們而言是 transparent 的。(不過這裡特別提的原因是這有可能會影響到 Map 的數目，所以有個印象即可。)</p>
<p>以 Block 大小是 64MB 當例子，假設原始檔案是 200MB，那第一個 Block 是從頭算起的第 64 MB，再往後找到第一個換行 (\n) 為止。這樣作是為了方便 Map 不用處理這種 boundary case。同樣的，第二個 Block 就是該換行的下一個 byte，取 64MB 再找換行，如此不斷的反覆直到檔案結尾。換句話說，最後一個 Block 的大小會隨機變動，也和下一個檔案無關。</p>
<p><strong>2) Map</strong><br />
雖然 Map 的數目是可以設定的，但是預設每個 Block 理論上都會被一個 Map 處理。那 Map 的邏輯就是讀 stdin，以行為單位處理之後，印成 key-value pair 到 stdout。就像是 unix 上的 <a target="_blank" href="http://en.wikipedia.org/wiki/Pipeline_%28Unix%29">pipeline</a>一樣。key 跟 value 預設是以 tab (\t) 當分割。(精確的說，是以第一個 tab 當中介，往前是 key，往後是 value，這也是可以設定的。)</p>
<p>因為 Map 的程式是我們可以動手的，所以我們可以記得 Map 就是把一行的文字，轉換成一個 key-value pair 的邏輯。</p>
<p><strong>3) Shuffle/Sort</strong><br />
為甚麼是 key-value pair 呢? 那是因為相同的 key 會送到同一個 reduce，而每個 reduce 會產生自己獨立的 output file。如果 map 的結果是隨機送往 reduce，那這個的 work flow 便會有其限制了。這就是第三個階段 Shuffle/Sort 的工作。</p>
<p>舉個例子，假設我們是要將 input file 的每個單字出現的次數。其中一行是 &#8220;one for all; all for one&#8221;，我們的 map 程式就是把每一個單字，都作成一個 key-value pair 往後送。Key 當然是單字本身，那 value 就是 1，代表 count 是 1。因此，上例會產生六個 key-value pair: (one,1), (for,1), (all,1), (all,1), (for,1), (one,1)。如果是隨機送往 reduce，那有可能 reduce1 收到前三個，reduce2 收到後三個，加上彼此的 reduce 不會互相參照，所以這結果並不是我們要的。(因為 for 這個字有些在 reduce1 的 output file，有些在 reduce2 的 output file，那還要特別寫程式作加總才是我們要的結果。當然如果 reduce 只有一個就沒有這樣的問題。)</p>
<p>那相同的 key 會送到同一個 reduce 的 case 會發生甚麼事? 我們可以保證同一個單字不會送到不同的 reduce，所以某個 reduce 的 output file 的任一單字的數目，一定代表原始所有檔案中，該單字的出現的次數。</p>
<p>那 sort 在做甚麼? 在上例我們看不出來關聯性，但是如果我們要的不單是單字出現的次數，還要排序，那就會有差別了。</p>
<p>一樣用 &#8220;one for all; all for one&#8221; 當例子。如果碰巧二個 reduce 收到的是:</p>
<p>1) Reduce1: (one, 1), (for, 1), <em>(for, 1)</em>, <em>(one, 1)</em><br />
2) Reduce2: (all, 1), <em>(all, 1)</em></p>
<p>PS: <em>斜體</em>代表是 all for one。</p>
<p>那每個 reduce 程式還要先讀完全部的 stdin 才能加以 sort，這樣就沒有效率了。反過來說，如果先把資料 sort 好再給 reduce 程式，reduce 就可以 streaming 的方式運作，寫法也比較簡單。</p>
<p><strong>4) Reduce</strong><br />
Reduce 的邏輯和 Map 相似。它是把 key-value pair，轉換成我們要的結果。也是拿上面的例子，經過 Shuffle/Sort 之後，Reduce 會收到:</p>
<p>1) Reduce1: (one, 1), <em>(one, 1)</em>, (for, 1), <em>(for, 1)</em><br />
2) Reduce2: (all, 1), <em>(all, 1)</em></p>
<p>PS: <em>斜體</em>代表是 all for one。注意，第二個 one 跑到 for 之前了。</p>
<p>所以我們 reduce 的作的事情是: &#8220;在遇到下一個單字前，累加 value，如果遇到新的單字，就印出這個單字和總量到 stdout。&#8221; 所以我們的結果是</p>
<p>1) Output1: (one, 2) 和 (for, 2) 共兩行<br />
2) Output2: (all, 2) 一行</p>
<p>這就是我們的結果。</p>
<p>這篇文章雖然長，但是瞭解之後可以大概的知道 Hadoop 整個 work flow。下一篇我們就要動手試我們的程式了。</p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=576&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2009/05/25/trend-micro-program-contest-2009-training-3-hadoop-mapreduce/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Trend Micro Program Contest 2009 Training #2: MapReduce overview</title>
		<link>http://weblog.pigfoot.org/pigfoot/2009/05/05/trend-micro-program-contest-2009-training-2-mapreduce-overview/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2009/05/05/trend-micro-program-contest-2009-training-2-mapreduce-overview/#comments</comments>
		<pubDate>Tue, 05 May 2009 06:41:37 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/?p=552</guid>
		<description><![CDATA[孫子兵法．謀攻篇：「凡用兵之法：十則圍之，五則攻之，倍則分之。」 這句話的意思是，當我們的兵力大過敵人兵力十倍，就用包圍攻擊來殲滅對方。反過來說，當對方的兵力大過我們，就想辦法分開他們而各自擊破。雖然我的翻譯不是很好，但是老祖宗的智慧，就是 computer science 中，一個非常著名的演算法 divide and conquer。 我們會用到雲端運算，要處理的資料一定是非比尋常的大，大多數的這類的分散式演算法本質上都和 divide and conquer 接近。我們這邊要介紹的 framework，就是 Google 所提的 MapReduce。 以下的圖，就是一個簡化過的 MapReduce 的 work flow。一般來說，它分成四個階段: 1) Input 雖然原始的資料量太大，但是我們有很多個 node 可以來運算。所以將原始的資料切成若干等份的 block，並往下一個階段送。 2) Map 對傳過來的 block 中的每一個元素，進行 Map function 的運算成為中繼資料。然後將中繼資料往下一個階段送。 3) Reduce 對傳過來的中繼資料，以及前一個 reduce 的結果，進行 Reduce function 的運算。然後將運算結果往下一個階段送。Reduce 和 Map 不同，它有兩個 input。 4) Output 將運算結果寫進檔案系統，完成運算。 這個 design pattern 就是這麼簡單，不知不覺得用上 [...]]]></description>
			<content:encoded><![CDATA[<p>孫子兵法．謀攻篇：「凡用兵之法：十則圍之，五則攻之，倍則分之。」</p>
<p>這句話的意思是，當我們的兵力大過敵人兵力十倍，就用包圍攻擊來殲滅對方。反過來說，當對方的兵力大過我們，就想辦法分開他們而各自擊破。雖然我的翻譯不是很好，但是老祖宗的智慧，就是 computer science 中，一個非常著名的演算法 <a target="_blank" href="http://en.wikipedia.org/wiki/Divide_and_conquer_algorithm">divide and conquer</a>。</p>
<p>我們會用到雲端運算，要處理的資料一定是非比尋常的大，大多數的這類的分散式演算法本質上都和 divide and conquer 接近。我們這邊要介紹的 framework，就是 Google 所提的 <a target="_blank" href="http://en.wikipedia.org/wiki/Mapreduce">MapReduce</a>。</p>
<p>以下的圖，就是一個簡化過的 MapReduce 的 work flow。一般來說，它分成四個階段:</p>
<p><img src="http://farm4.static.flickr.com/3130/3502556007_1d87893cff_o.png" width="384" height="241" alt="hadoop-2" /></p>
<p><strong>1) Input</strong><br />
<blockquote>雖然原始的資料量太大，但是我們有很多個 node 可以來運算。所以將原始的資料切成若干等份的 block，並往下一個階段送。</p></blockquote>
<p><strong>2) Map</strong><br />
<blockquote>對傳過來的 block 中的每一個元素，進行 Map function 的運算成為中繼資料。然後將中繼資料往下一個階段送。</p></blockquote>
<p><strong>3) Reduce</strong><br />
<blockquote>對傳過來的中繼資料，以及前一個 reduce 的結果，進行 Reduce function 的運算。然後將運算結果往下一個階段送。Reduce 和 Map 不同，它有兩個 input。</p></blockquote>
<p><strong>4) Output</strong><br />
<blockquote>將運算結果寫進檔案系統，完成運算。</p></blockquote>
<p>這個 design pattern 就是這麼簡單，不知不覺得用上 MapReduce。當然，Map 和 Reduce 的數目，與可以運算的 Node，都是影響效能的關鍵，這個我們容後再講。目前我們所要知道的，就是<strong>如何把問題轉化成 MapReduce 的解法</strong>，一旦可以套用，那問題幾乎是解了一半了，剩下的就是動手 coding 而己。</p>
<p>我再舉另一些例子。如何從某個電子書中找到最常用到的單字? 這個問題是不是有點像在用 google search 時，出現的關鍵字自動補齊功能 (search autocomplete) 呢? 只是問題簡化過而己。我們來看看這個問題怎麼用 MapReduce。</p>
<p><strong>1) Input</strong><br />
<blockquote>電子書以章為單位，分別送給每一個 Map。</p></blockquote>
<p><strong>2) Map</strong><br />
<blockquote>Map 找出該章裡所有的單字，接著送給 Reduce。</p></blockquote>
<p><strong>3) Reduce</strong><br />
<blockquote>Reduce 對上一個 Reduce 排序好的結果，加上對應的 Map 送過來的單字，兩者再排序之後送給下一個 Reduce。</p></blockquote>
<p><strong>4) Output</strong><br />
<blockquote>最後一個 Reduce 處理完之後，就是最終的單字排序名單。</p></blockquote>
<p>大家可以多想一些例子來練習這樣的 work flow。</p>
<p>雖然概念上是這樣，但是實際上的作法大家都略有差異。下一篇就是針對 Hadoop 的 MapReduce 來作說明。</p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=552&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2009/05/05/trend-micro-program-contest-2009-training-2-mapreduce-overview/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Trend Micro Program Contest 2009 Training #1: Hadoop Virtual Image</title>
		<link>http://weblog.pigfoot.org/pigfoot/2009/05/04/trend-micro-program-contest-2009-training-1-hadoop-virtual-image/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2009/05/04/trend-micro-program-contest-2009-training-1-hadoop-virtual-image/#comments</comments>
		<pubDate>Mon, 04 May 2009 10:44:01 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/?p=523</guid>
		<description><![CDATA[子曰：「工欲善其事,必先利其器。」 當然，比賽最好先熟一下工具會比較有信心。我第一個要先介紹的 framework 就是 Hadoop (Wikipedia: Hadoop)。 因為 Hadoop 算是一個非常知名的雲端運算平台，加上 Wikipedia 寫的也非常的仔細，所以我這邊就不贅述了。但是因為它的設定不太容易而且費時，加上這部份對於簡單的程式來說，並沒有太大的影響。所以我推薦在開發階段，可以先用 Hadoop Virtual Image 就可以了。 Hadoop Virtual Image 是一個 Ubuntu Linux 7.04 的 OS, 然後內建了 Java machine (Sun JRE 6 u2) 以及 Hadoop 0.13.0 的一個 virtual machine image。我們可以用免費的 VMware Player 來執行它。 雖然它沒有 GUI，但是最令人感到興奮的是，它預設已經把 Hadoop 的環境設定好成 pseudo-distributed mode (也就是在同一台電腦上用不同的 port 當作不同的機器，然後在利用 ssh 去跟這些假機器作溝通)。雖然預設只有一個機器，不過目前應該無傷大雅。 以下就是用 VMware [...]]]></description>
			<content:encoded><![CDATA[<p><a target=" _blank" href="http://hadoop.apache.org/"><img class="logoImage" alt="Hadoop" src="http://hadoop.apache.org/images/hadoop-logo.jpg" title="Scalable Distributed Computing"/></a></p>
<p>子曰：「工欲善其事,必先利其器。」</p>
<p>當然，比賽最好先熟一下工具會比較有信心。我第一個要先介紹的 framework 就是 <a target="_blank" href="http://hadoop.apache.org/">Hadoop</a> (Wikipedia: <a target="_blank" href="http://en.wikipedia.org/wiki/Hadoop">Hadoop</a>)。</p>
<p>因為 Hadoop 算是一個非常知名的雲端運算平台，加上 Wikipedia 寫的也非常的仔細，所以我這邊就不贅述了。但是因為它的設定不太容易而且費時，加上這部份對於簡單的程式來說，並沒有太大的影響。所以我推薦在開發階段，可以先用 <a target="_blank" href="http://code.google.com/edu/parallel/tools/hadoopvm/">Hadoop Virtual Image</a> 就可以了。</p>
<p><a target="_blank" href="http://dl.google.com/edutools/hadoop-vmware.zip">Hadoop Virtual Image</a> 是一個 <a target="_blank" href="www.ubuntu.com/">Ubuntu Linux</a> 7.04 的 OS, 然後內建了 Java machine (Sun JRE 6 u2) 以及 Hadoop 0.13.0 的一個 virtual machine image。我們可以用免費的 <a target="_blank" href="http://info.vmware.com/content/GLP_VMwarePlayer">VMware Player</a> 來執行它。</p>
<p>雖然它沒有 GUI，但是最令人感到興奮的是，它預設已經把 Hadoop 的環境設定好成 pseudo-distributed mode (也就是在同一台電腦上用不同的 port 當作不同的機器，然後在利用 ssh 去跟這些假機器作溝通)。雖然預設只有一個機器，不過目前應該無傷大雅。</p>
<p>以下就是用 VMware Player 執行這個 virtual machine image 的樣子。</p>
<p><a target=" _blank" href="http://farm4.static.flickr.com/3630/3487678067_4246d5fa75_o.png" title="hadoop-vmware_01 by pigfoot, on Flickr"><img src="http://farm4.static.flickr.com/3630/3487678067_eb066e96ac_m.jpg" width="240" height="151" alt="hadoop-vmware_01" /></a></p>
<p>然後用 guest 登入:</p>
<p><a target=" _blank" href="http://farm4.static.flickr.com/3639/3488492028_449ea61efa_o.png" title="hadoop-vmware_02 by pigfoot, on Flickr"><img src="http://farm4.static.flickr.com/3639/3488492028_d15942091d_m.jpg" width="240" height="151" alt="hadoop-vmware_02" /></a></p>
<p>因為這個 guest OS 已經裝了 Hadoop, 所以我們可以執行它裡面的範例程式來簡單的跑一下。指令如下:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ hadoop jar hadoop-examples.jar pi <span style="color: #000000;">4</span> <span style="color: #000000;">10000</span></div></div>
<p>這個範例就是在 Hadoop 的平台上, 用蒙地卡羅法 (Monte Carlo Method) 來分散計算 <a target="_blank" href="http://en.wikipedia.org/wiki/Pi">Pi</a> 的值。換句話說，這就是最簡單的雲端運算 (因為只有一個機器)。</p>
<p>下面是跑完的結果:</p>
<p><a target=" _blank" href="http://farm4.static.flickr.com/3411/3488492536_714023b60d_o.png" title="hadoop-vmware_03 by pigfoot, on Flickr"><img src="http://farm4.static.flickr.com/3411/3488492536_9808025c56_m.jpg" width="240" height="151" alt="hadoop-vmware_03" /></a></p>
<p>有看到上面的正常結果，代表我們的環境是正常的，可以開始作一些程式開發了。為了更了解雲端運算，它的 working flow 是一定要先知道。下一篇就是要來講 <a target="_blank" href="http://www.google.com/">Google</a> 所提出來的 <a target="_blank" href="http://en.wikipedia.org/wiki/Pi">MapReduce</a> framework。</p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=523&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2009/05/04/trend-micro-program-contest-2009-training-1-hadoop-virtual-image/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google App Engine SDK 1.1.9 released.</title>
		<link>http://weblog.pigfoot.org/pigfoot/2009/02/24/google-app-engine-sdk-119-released/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2009/02/24/google-app-engine-sdk-119-released/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 15:08:07 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/?p=456</guid>
		<description><![CDATA[Google App Engine SDK has a new released version 1.1.9. Finally, we can now use the Python standard libraries urllib, urllib2 or httplib to make HTTP requests.]]></description>
			<content:encoded><![CDATA[<p>Google App Engine SDK has a new released version <a target="_blank" href="http://googleappengine.blogspot.com/2009/02/sdk-version-119-released.html">1.1.9</a>.</p>
<p>Finally, we can now use the Python standard libraries <a target="_blank" href="http://www.python.org/doc/2.5.2/lib/module-urllib.html">urllib</a>, <a target="_blank" href="http://www.python.org/doc/2.5.2/lib/module-urllib2.html">urllib2</a> or <a target="_blank" href="http://www.python.org/doc/2.5.2/lib/module-httplib.html">httplib</a> to make HTTP requests.</p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=456&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2009/02/24/google-app-engine-sdk-119-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to force setuid program to make a core dump?</title>
		<link>http://weblog.pigfoot.org/pigfoot/2007/09/09/how-to-force-setuid-program-to-make-a-core-dump/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2007/09/09/how-to-force-setuid-program-to-make-a-core-dump/#comments</comments>
		<pubDate>Sun, 09 Sep 2007 15:19:38 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Develop]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/2007/09/09/how-to-force-setuid-program-to-make-a-core-dump/</guid>
		<description><![CDATA[前一陣子上班時, Samuel 跑過來問: &#8220;咦? 你們之前寫某個 Server 的時候, 怎麼讓程式自己產生 Core dump 啊?&#8221; &#8220;就是用 setrlimit(2) 的啊!&#8221; &#8220;那幫我看一下為啥我照著那樣寫不會動..&#8221; 沒想到就開始了殘酷的惡夢~ 讓我們花費了不少工夫才發現為甚麼. 在 Linux 上, 預設是不會有 Core dump 的, 而要讓程式產生 Core dump 的方法就是利用 bash built-in 的 ulimit 指令. 我去年這篇 How to enlarge Coredump Size and File Descriptor Limitations 剛好也有寫到. 不過意外常常有, 所以除了讓 System administrator 設 ulimit -c unlimited 之外, 我自己也會在程式裡面利用 setrlimit(2) [...]]]></description>
			<content:encoded><![CDATA[<p>前一陣子上班時, Samuel 跑過來問:</p>
<p><em>&#8220;咦? 你們之前寫某個 Server 的時候, 怎麼讓程式自己產生 <a target="_blank" href="http://en.wikipedia.org/wiki/Core_dump">Core dump</a> 啊?&#8221;</p>
<p>&#8220;就是用 <a target="_blank" href="http://www.opengroup.org/onlinepubs/009695399/functions/getrlimit.html">setrlimit(2)</a> 的啊!&#8221;</p>
<p>&#8220;那幫我看一下為啥我照著那樣寫不會動..&#8221;</em></p>
<p>沒想到就開始了殘酷的惡夢~ 讓我們花費了不少工夫才發現為甚麼.</p>
<p>在 Linux 上, 預設是不會有 Core dump 的, 而要讓程式產生 Core dump 的方法就是利用 bash built-in 的 ulimit 指令. 我去年這篇 <a href="http://weblog.pigfoot.org/pigfoot/2006/08/25/how-to-enlarge-coredump-size-and-file-descriptor-limitations/">How to enlarge Coredump Size and File Descriptor Limitations</a> 剛好也有寫到. </p>
<p>不過意外常常有, 所以除了讓 System administrator 設 <strong>ulimit -c unlimited</strong> 之外, 我自己也會在程式裡面利用 setrlimit(2) 這隻 system call, 讓程式在執行時, 能夠不管 administrator 有沒有用 ulimit 設定 Core dump size, 保證一定會產生 Core dump. 在程式 <a target="_blank" href="http://en.wikipedia.org/wiki/Crash_%28computing%29">crash</a> 的時候, Core dump 是很重要線索啊! 就像 <a target="_blank" href="http://zh.wikipedia.org/wiki/CSI%E7%8A%AF%E7%BD%AA%E7%8F%BE%E5%A0%B4">CSI</a> 一樣, 讓證據會說話.</p>
<p>可是在看完 Samuel 的程式時, 我和他兩個就覺得很奇怪, 應該是會 work 才對, 因為同樣的 code 寫的程式已經在 production server 上跑了一段時間, 應該不會有問題才對, 這時候, 我才猛然想起來, 管機器的 administrator 曾說過有時候 Core dump 不會出現. <em>&#8220;God! 該不會就是同一個問題吧?&#8221;</em></p>
<p>和 Samuel 兩個人找完資料的答案, 就是寫這篇文章的動機了. 我們發現, 如果一個程式按照上面的方法都無法產生 Core dump, 那要看看這個程式是否是用了 <a target="_blank" href="http://www.opengroup.org/onlinepubs/000095399/functions/setuid.html">setuid(2)</a> 這個 System call. 我們發現, <strong>一個 <a target="_blank" href="http://www.opengroup.org/onlinepubs/000095399/functions/setuid.html">setuid(2)</a> 或 <a target="_blank" href="http://www.opengroup.org/onlinepubs/009695399/functions/seteuid.html">seteuid(2)</a> 過後的程式, 是沒有辦法產生 Core dump 的</strong>.</p>
<p>好巧不巧, 通常 Server 為了一些安全性的考量, 也會實作 setuid(2) 或 seteuid(2) 來達到 Running with Least Privilege (相對應 Windows 的指令就是 Run As). 也就是說, setuid(2) 一定是不能略過的. 解決方法有兩種.</p>
<p>第一種是只有這個程式有效. 用的方法就是 prctl(2). 這個方法是可以改 source, 然後 rebuild 的狀況下才能用. Sample code 如下:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#include &lt;stdio.h&gt;;</span><br />
<span style="color: #339933;">#include &lt;stdlib.h&gt;;</span><br />
<span style="color: #339933;">#include &lt;errno.h&gt;;</span><br />
<span style="color: #339933;">#include &lt;unistd.h&gt;;</span><br />
<span style="color: #339933;">#include &lt;pwd.h&gt;;</span><br />
<span style="color: #339933;">#include &lt;sys/resource.h&gt;;</span><br />
<span style="color: #339933;">#include &lt;sys/prctl.h&gt;;</span><br />
<br />
<span style="color: #339933;">#define SU_USER &quot;nobody&quot;</span><br />
<br />
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">struct</span> rlimit corelimit<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">struct</span> passwd <span style="color: #339933;">*</span>pw <span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">char</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">*</span>cp <span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* if switch to nobody failed */</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>NULL <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span>pw <span style="color: #339933;">=</span> getpwnam<span style="color: #009900;">&#40;</span>SU_USER<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Cannot get uid from user(%s). Error: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SU_USER<span style="color: #339933;">,</span> strerror<span style="color: #009900;">&#40;</span>errno<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* try to switch to nobody */</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>setuid<span style="color: #009900;">&#40;</span>pw<span style="color: #339933;">-&gt;</span>pw_uid<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: #339933;">||</span> <span style="color: #009900;">&#40;</span>seteuid<span style="color: #009900;">&#40;</span>pw<span style="color: #339933;">-&gt;</span>pw_uid<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;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Cannot switch to user(%s). Error: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SU_USER<span style="color: #339933;">,</span> strerror<span style="color: #009900;">&#40;</span>errno<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">2</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* force to make coredump */</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>prctl<span style="color: #009900;">&#40;</span>PR_SET_DUMPABLE<span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Cannot enable core dumping. Error: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strerror<span style="color: #009900;">&#40;</span>errno<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">3</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* set core size to unlimited */</span><br />
&nbsp; &nbsp; corelimit.<span style="color: #202020;">rlim_cur</span> <span style="color: #339933;">=</span> RLIM_INFINITY<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; corelimit.<span style="color: #202020;">rlim_max</span> <span style="color: #339933;">=</span> RLIM_INFINITY<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>setrlimit<span style="color: #009900;">&#40;</span>RLIMIT_CORE<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>corelimit<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Setrlimit failed! Error: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strerror<span style="color: #009900;">&#40;</span>errno<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">4</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* force to coredump */</span><br />
&nbsp; &nbsp; <span style="color: #339933;">*</span>cp <span style="color: #339933;">=</span> <span style="color: #ff0000;">'1'</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>這種方法要注意的事情有:</p>
<ul>
<li><strong>一定要用 root 執行.</strong><br />
setuid 然後讓一般 user 去執行的方法不行.<br />
(e.g. sudo chown root a.out; sudo chgrp root a.out; sudo chmod 4755 a.out)</li>
<li><strong>因為 Core dump 產生的目錄和執行檔在同一個目錄下, 這個目錄的權限一定要是 root 這個 user, root 這個 group 同時都可以寫入才行. 要注意這個 case, 不要把 root 當成是 super-user, 而是要當作 regular user.</strong><br />
比方說, (drwxrwxr-x, root root) 和 (drwxrwxrwx, nobody nogroup) 可以, 但是 (drwxr-xr-x root root) 和 (drwxrwxr-x root nogroup) 都不行. 很弔詭吧! 我也不知道為甚麼~</li>
<p>第二種方法是 system-wide 的, 也就是會影響到所有在系統執行的程式. 方法就是 <strong>/proc/sys/fs/suid_dumpable</strong>. 因為這個和  kernel 的版本有關, 請 man 5 proc 比較保險. 這是在無法動 source code, 而且原程式沒有用 prctl(2) 情況下的殺手鐧.</p>
<p>要注意的事情和第一種方法一樣, 把 /proc/sys/fs/suid_dumpable 設成 1 或 2 的差別, 是會決定 core dump file 的擁有者. 如果設成 1, 就會和第一種方法一樣是被 switch 的 owner (本例是 nobody). 如果設 2 就一定是 root, 但是這個似乎要 kernel 2.6.13 以上才有 support? 我不是很確定.</p>
<p>希望這篇文章給大家當作個參考囉!</p>
<p>PS: 這篇竟然寫了快二個周末, 真是夠久的~</ul>
<p></sys></pwd></unistd></errno></stdlib></stdio></code></p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=423&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2007/09/09/how-to-force-setuid-program-to-make-a-core-dump/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What&#8217;s the maximum value of backlog argument in listen(2) system call?</title>
		<link>http://weblog.pigfoot.org/pigfoot/2007/07/05/whats-the-maximum-value-of-backlog-argument-in-listen2-system-call/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2007/07/05/whats-the-maximum-value-of-backlog-argument-in-listen2-system-call/#comments</comments>
		<pubDate>Thu, 05 Jul 2007 05:47:47 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Develop]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Kernel]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/2007/07/05/whats-the-maximum-value-of-backlog-argument-in-listen2-system-call/</guid>
		<description><![CDATA[When we write a network server program, I think lots of system calls have their own explicit parameters like socket(), bind(), accept(). But it&#8217;s very interesting when we use this system call listen(). Let&#8217;s see its prototype: int listen(int sockfd, int backlog); Yes, it&#8217;s very obvious that the first parameter is the socket fd. But, [...]]]></description>
			<content:encoded><![CDATA[<p>When we write a network server program, I think lots of system calls have their own explicit parameters like socket(), bind(), accept(). But it&#8217;s very interesting when we use this system call listen(). Let&#8217;s see its prototype:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">int listen(int sockfd, int backlog);</div></div>
<p>Yes, it&#8217;s very obvious that the first parameter is the socket fd. But, what&#8217;s the meaning of backlog number? Some body would tell us like manpage LISTEN(2) says: &#8220;<em>The backlog parameter defines the maximum length the queue of pending connections may grow to. If a connection request arrives with the queue full the client may receive an error with an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may be ignored so that retries succeed.</em>&#8221;</p>
<p>From a robust server&#8217;s perspective, what&#8217;s the maximum value it should be assign? At first, I assigned very large number like 1,024 (of course, listen system call still returns successfully). After saw the manpage LISTEN(2) in <a target="_blank" href="http://en.wikipedia.org/wiki/Linux">Linux</a>, I was wrong..</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">If the socket is of type AF_INET, and the backlog argument is greater than the constant SOMAXCONN (128 in Linux 2.0 &amp; 2.2), it is silently truncated to SOMAXCONN.</div></div>
<p>It doesn&#8217;t mention kernel 2.6. But it&#8217;s fine. Let&#8217;s investigate into Linux kernel source code.</p>
<p>In Linux kernel 2.6.20.1, we can see the listen system call implementation in <a target="_blank" href="http://lxr.linux.no/source/net/socket.c#L1304">net/socket.c line 1306</a>. As it shows, the maximum number of backlog cannot be large than sysctl_somaxconn, which is assigned to SOMAXCONN. Furthermore, SOMAXCONN is defined 128 in <a target="_blank" href="http://lxr.linux.no/source/include/linux/socket.h#L226">include/linux/socket.h line 226</a>.</p>
<p>In my opinion, in Linux 2.0 to 2.6, this means backlog cannot exceed 128 by default, or it would be truncated to SOMAXCONN silently like the manpage says.</p>
<p>How about <a target="_blank" href="http://en.wikipedia.org/wiki/FreeBSD">FreeBSD</a>? We can see the note of manpage LISTEN(2) in FreeBSD 6:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">The listen() system call appeared in 4.2BSD. The ability to configure the maximum backlog at run-time, and to use a negative backlog to request the maximum allowable value, was introduced in FreeBSD 2.2.</div></div>
<p>I&#8217;m not very familiar with FreeBSD kernel, but let me try to trace. The start point is to check <a target="_blank" href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/uipc_syscalls.c?only_with_tag=RELENG_6">sys/kern/uipc_syscalls.c</a> of cvstag RELENG_6 in FreeBSD. We can see listen system call will invoke <em>solisten(so, uap->backlog, td)</em>. Thus, we go to <a target="_blank" href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/uipc_socket.c?only_with_tag=RELENG_6">sys/kern/uipc_socket.c</a> now to see the implementation of <em>solisten(struct socket *so, int backlog, struct thread *td)</em>. The same, the maximum value is somaxconn which is assigned to SOMAXCONN by default. Finally, we can see the value is defined in <a target="_blank" href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/socket.h?only_with_tag=RELENG_6">sys/sys/socket.h</a>. The value is the same as Linux &#8212; 128.</p>
<p><strong>To put it another way, if you&#8217;re writing a server program in either Linux or FreeBSD platform, it&#8217;s very appropriate to assign the value of backlog to 128. in FreeBSD, however, you can assign a negative backlog to request the maximum allowable value.</strong></p>
<p>You may ask what&#8217;s the value of backlog in popular modern server? Let&#8217;s check the source of <a target="_blank" href="http://en.wikipedia.org/wiki/Apache_HTTP_Server">Apache HTTP Server</a>. As you see in <a target="_blank" href="http://svn.apache.org/viewvc/httpd/httpd/trunk/server/listen.c?view=markup">/server/listen.c</a>, ap_listenbacklog is assigned to DEFAULT_LISTENBACKLOG which is defined 511 in <a target="_blank" href="http://svn.apache.org/viewvc/httpd/httpd/trunk/include/mpm_common.h?view=markup">/include/mpm_common.h</a>.</p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=416&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2007/07/05/whats-the-maximum-value-of-backlog-argument-in-listen2-system-call/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Updated UltraSPARC-T1 tuning guide available</title>
		<link>http://weblog.pigfoot.org/pigfoot/2007/01/31/updated-ultrasparc-t1-tuning-guide-available/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2007/01/31/updated-ultrasparc-t1-tuning-guide-available/#comments</comments>
		<pubDate>Wed, 31 Jan 2007 05:40:41 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Sun]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/2007/01/31/updated-ultrasparc-t1-tuning-guide-available/</guid>
		<description><![CDATA[According to Darryl Gove&#8217;s post yesterday, the UltraSPARC-T1 tuning guide has been updated to include information about the Cool Tools.]]></description>
			<content:encoded><![CDATA[<p>According to Darryl Gove&#8217;s <a target="_blank" href="http://blogs.sun.com/d/entry/updated_ultrasparc_t1_tuning_guide">post</a> yesterday, the <a href="http://www.sun.com/blueprints/1205/819-5144.pdf">UltraSPARC-T1 tuning guide</a> has been updated to include information about the Cool Tools.</p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=405&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2007/01/31/updated-ultrasparc-t1-tuning-guide-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zero copy between ISR, kernel and User</title>
		<link>http://weblog.pigfoot.org/pigfoot/2006/09/28/zero-copy-between-isr-kernel-and-user/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2006/09/28/zero-copy-between-isr-kernel-and-user/#comments</comments>
		<pubDate>Thu, 28 Sep 2006 04:06:56 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Kernel]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/2006/09/28/zero-copy-between-isr-kernel-and-user/</guid>
		<description><![CDATA[Zero copy between ISR, kernel and User, from LKML. Q: I would like to allow the transferring of data between ISR&#8217;s, kernel and user code, without requiring copying. I envision allocating buffers in the kernel and then mapping them so that they appear at the same addresses to all code, and never being swapped out [...]]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="http://groups.google.com/group/linux.kernel/tree/browse_frm/thread/c93cd3f9b874c3a9/6eaa68a3fed0c8fa">Zero copy between ISR, kernel and User</a>, from <a target="_blank" href="http://en.wikipedia.org/wiki/LKML"><acronym title="Linux Kernel Mailing List">LKML</acronym></a>.</p>
<p><strong>Q:</strong></p>
<p>I would like to allow the transferring of data between ISR&#8217;s, kernel and user code, without requiring copying.</p>
<p>I envision allocating buffers in the kernel and then mapping them so that they appear at the same addresses to all code, and never being swapped out of memory.</p>
<p>Is this feasible for all supported Linux architectures and is there existing code that someone could point me towards?</p>
<p><strong>A:</strong></p>
<p>Your better off having application mmap a device, then transfer the data to there. Something like AF_PACKET.</p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=381&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2006/09/28/zero-copy-between-isr-kernel-and-user/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>POSIX Asynchronous I/O</title>
		<link>http://weblog.pigfoot.org/pigfoot/2006/09/27/posix-asynchronous-io/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2006/09/27/posix-asynchronous-io/#comments</comments>
		<pubDate>Wed, 27 Sep 2006 06:35:02 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Kernel]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/2006/09/27/posix-asynchronous-io/</guid>
		<description><![CDATA[POSIX Asynchronous I/O, from OSNews. Used judiciously, asynchronous I/O (short for AIO) can provide a significant speed benefit, says David Chisnall. Perhaps enough to help your program overcome the fact that modern processors can really zoom, while hard drives still drag. Code using AIO on Linux must be linked with -lrt to provide support for [...]]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="http://www.informit.com/articles/article.asp?p=607373">POSIX Asynchronous I/O</a>, from <a target="_blank" href="http://www.osnews.com/story.php?news_id=15955">OSNews</a>.</p>
<p>Used judiciously, asynchronous I/O (short for AIO) can provide a significant speed benefit, <a target="_blank" href="http://www.informit.com/articles/article.asp?p=607373">says David Chisnall</a>. Perhaps enough to help your program overcome the fact that modern processors can really zoom, while hard drives still drag.</p>
<p>Code using AIO on Linux must be linked with <strong>-lrt</strong> to provide support for the POSIX real-time extensions, which means it may not be the kernel I/O mechanism, especially Kernel AIO Support for Linux has not been merged into mainline kernel yet.</p>
<p>After studying <a target="_blank" href="http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/rt/?cvsroot=glibc">rt extensions in glibc source</a>, I <a target="_blank" href="http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/pthread/?cvsroot=glibc">find</a> how do they implement posix AIO in glibc &#8212; a thread pool plus a request waiting queue. Besides, helper thread will be spawned to manage the request, hence it&#8217;s not so trivial.</p>
<p>There is something interesting when freeing allocated resources. You can see the function <font face="Courier New">libc_freeres_fn()</font> in <a target="_blank" href="http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/pthread/aio_misc.c?cvsroot=glibc">aio_misc.c</a>. This is also why it is unnecessary to implement &#8220;<em>destroy</em>&#8221; API.</p>
<p>Whereas, <a target="_blank" href="http://www.freebsd.org/">FreeBSD</a> has <a target="_blank" href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/syscalls.c?rev=1.207&#038;content-type=text/x-cvsweb-markup">AIO family system calls</a>. I, however, have no experience with AIO in FreeBSD, but it seems AIO in FreeBSD has kernel support? If so, it would be more efficient than Linux until now?</p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=379&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2006/09/27/posix-asynchronous-io/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cool picture of all the new Vista Icons</title>
		<link>http://weblog.pigfoot.org/pigfoot/2006/09/26/cool-picture-of-all-the-new-vista-icons/</link>
		<comments>http://weblog.pigfoot.org/pigfoot/2006/09/26/cool-picture-of-all-the-new-vista-icons/#comments</comments>
		<pubDate>Tue, 26 Sep 2006 07:46:27 +0000</pubDate>
		<dc:creator>pigfoot</dc:creator>
				<category><![CDATA[Develop]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://weblog.pigfoot.org/pigfoot/2006/09/26/cool-picture-of-all-the-new-vista-icons/</guid>
		<description><![CDATA[Cool picture of all the new Vista Icons. Besides, here is a tutorial from MSDN on how Microsoft makes their Windows XP icons.]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="http://www.istartedsomething.com/20060924/vista-fitted-nearly-finished/">Cool picture of all the new Vista Icons</a>.</p>
<p><a href="http://www.istartedsomething.com/wp-content/uploads/2006/09/vista256.jpg"><img id="image678" alt="Windows Vista 256x256 high-resolution icons" class="pigfoot" src="http://www.istartedsomething.com/wp-content/uploads/2006/09/vista256_s.jpg" /></a></p>
<p>Besides, here is a tutorial from <a target="_blank" href="http://digg.com/design/How_Microsoft_makes_their_Icons">MSDN</a> on <a target="_blank" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwxp/html/winxpicons.asp">how Microsoft makes their Windows XP icons</a>.</p>
<img src="http://weblog.pigfoot.org/pigfoot/?ak_action=api_record_view&id=372&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.pigfoot.org/pigfoot/2006/09/26/cool-picture-of-all-the-new-vista-icons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
