<?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>LinuxPlayer</title>
	<atom:link href="http://www.linuxplayer.org/feed" rel="self" type="application/rss+xml" />
	<link>http://www.linuxplayer.org</link>
	<description>Sharing Linux/Unix system play and administration experience</description>
	<lastBuildDate>Sat, 18 Feb 2012 23:09:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>Setup Linux as wifi hotspot with NetworkManager</title>
		<link>http://www.linuxplayer.org/2012/02/setup-linux-as-wifi-hotspot-with-networkmanager?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=setup-linux-as-wifi-hotspot-with-networkmanager</link>
		<comments>http://www.linuxplayer.org/2012/02/setup-linux-as-wifi-hotspot-with-networkmanager#comments</comments>
		<pubDate>Sat, 18 Feb 2012 23:07:31 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[Linux Desktop]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[NetworkManager]]></category>
		<category><![CDATA[WEP]]></category>
		<category><![CDATA[wifi]]></category>
		<category><![CDATA[wireless]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=528</guid>
		<description><![CDATA[First of all, note that if your wireless card does not support master/hostap mode, you can only use ad-hoc mode, which allows only one device to connect. Secondly, NetworkManager only support WEP for ad-hoc mode, so don&#8217;t select other Security method like WPA. If you don&#8217;t want to ask for trouble, select &#8220;WEP 40/128-bit Key&#8221;. &#8230; </p><p><a class="more-link block-button" href="http://www.linuxplayer.org/2012/02/setup-linux-as-wifi-hotspot-with-networkmanager">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>First of all, note that if your wireless card does not support master/hostap mode, you can only use ad-hoc mode, which allows only one device to connect.<br />
Secondly, NetworkManager only support WEP for ad-hoc mode, so don&#8217;t select other Security method like WPA. If you don&#8217;t want to ask for trouble, select &#8220;WEP 40/128-bit Key&#8221;.</p>
<p>The setup is indeed very simple. just click the network icon from the top right corner of your screen, select &#8220;Network settings&#8221;, select wireless, then click &#8220;Use as hotspot&#8221;, it will setup everything for you, including the secret key, and the SSID, you can click the &#8220;configure&#8221; button to change some settings, like the SSID, and the secret, but keep the above 2 point in mind.<br />
If everything goes OK, you can connect your mobile device to the hotspot in about 30 seconds. in case of problem, do check /var/log/messages for help.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2012/02/setup-linux-as-wifi-hotspot-with-networkmanager/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>why squid listen on high udp port number</title>
		<link>http://www.linuxplayer.org/2012/02/why-squid-listen-on-high-udp-port-number?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-squid-listen-on-high-udp-port-number</link>
		<comments>http://www.linuxplayer.org/2012/02/why-squid-listen-on-high-udp-port-number#comments</comments>
		<pubDate>Thu, 16 Feb 2012 18:55:52 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[squid]]></category>
		<category><![CDATA[udp_incoming_address]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=525</guid>
		<description><![CDATA[When starting squid with the default configuration (compiled from source), you may notice that the squid process listens not only on TCP port 3128, but also a high UDP port. netstat -tlunp &#124; grep squid tcp 0 0 :::3128 :::* LISTEN 3520/(squid) udp 0 0 0.0.0.0:52431 0.0.0.0:* 3520/(squid) udp 0 0 :::51621 :::* 3520/(squid) What &#8230; </p><p><a class="more-link block-button" href="http://www.linuxplayer.org/2012/02/why-squid-listen-on-high-udp-port-number">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>When starting squid with the default configuration (compiled from source), you may notice that the squid process listens  not only on TCP port 3128, but also a high UDP port.</p>
<pre>
netstat -tlunp | grep squid
</pre>
<p><code><br />
tcp        0      0 :::3128                     :::*                        LISTEN      3520/(squid)<br />
udp        0      0 0.0.0.0:52431               0.0.0.0:*                               3520/(squid)<br />
udp        0      0 :::51621                    :::*                                    3520/(squid)<br />
</code><br />
What in the hell is that 52431 UDP port used for? Let&#8217;s find out.<span id="more-525"></span><br />
Edit squid.conf, add the following line to configure debug output:</p>
<pre>
debug_options 78,9 5,9 50,9
</pre>
<p>restart squid, check the debug output in cache.log:</p>
<pre>
2012/02/17 02:06:37| Starting Squid Cache version 3.1.19 for x86_64-unknown-linux-gnu...
2012/02/17 02:06:37.140| idnsInit: attempt open DNS socket to: [::]
2012/02/17 02:06:37.140| comm_openex: Attempt open socket for: [::]
2012/02/17 02:06:37.140| comm_openex: Opened socket FD 7 : family=10, type=2, protocol=17
2012/02/17 02:06:37.140| comm_open: FD 7 is a new socket
2012/02/17 02:06:37.140| commBind: bind socket FD 7 to [::]
2012/02/17 02:06:37.140| idnsInit: attempt open DNS socket to: 0.0.0.0
2012/02/17 02:06:37.140| comm_openex: Attempt open socket for: 0.0.0.0
2012/02/17 02:06:37.140| comm_openex: Opened socket FD 8 : family=2, type=2, protocol=17
2012/02/17 02:06:37.140| comm_open: FD 8 is a new socket
2012/02/17 02:06:37.140| commBind: bind socket FD 8 to 0.0.0.0
2012/02/17 02:06:37.140| comm_local_port: FD 7: port 51621(family=10)
2012/02/17 02:06:37.140| DNS Socket created at [::], FD 7
2012/02/17 02:06:37.141| commSetSelect(FD 7,type=1,handler=1,client_data=0,timeout=0)
2012/02/17 02:06:37.141| comm_local_port: FD 8: port 52431(family=2)
2012/02/17 02:06:37.141| DNS Socket created at 0.0.0.0, FD 8
2012/02/17 02:06:37.141| commSetSelect(FD 8,type=1,handler=1,client_data=0,timeout=0)
2012/02/17 02:06:37.141| Adding nameserver 127.0.0.1 from /etc/resolv.conf
...
</pre>
<p>from the above output, we can figure out that those 2 high ports are used for DNS things. In fact, it&#8217;s used for the &#8220;internal dns&#8221;, a mechanism for squid to effectively manages DNS queries. </p>
<p>Some sys admins like to bind local service to internal interface only, so there come&#8217;s a requirement: how can we make squid to &#8216;listen&#8217; ONLY on internal interface for those udp ports? According to the  Squid configuration directives:</p>
<pre>
udp_incoming_address	is used for UDP packets received from other
				caches.

	The default behavior is to not bind to any specific address.

	Only change this if you want to have all UDP queries received on
	a specific interface/address.

	NOTE: udp_incoming_address is used by the ICP, HTCP, and DNS
	modules. Altering it will affect all of them in the same manner.
</pre>
<p>Add udp_incoming_address xxx.xxx.xx.xx to squid.conf, the udp ports will then bind to xxx.xxx.xx.xx.<br />
However, there may be a trap. If you have two interfaces, one with IP 192.168.1.1, the other 12.34.56.78.<br />
when you set &#8220;udp_incoming_address 192.168.1.1&#8243;, the proxy may stuck because of DNS problem. especially, when you can&#8217;t reach the dns server from local IP. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2012/02/why-squid-listen-on-high-udp-port-number/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux系统编程知识在运维排错中的应用</title>
		<link>http://www.linuxplayer.org/2011/12/linux-systems-programming-for-trouble-shooting?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=linux-systems-programming-for-trouble-shooting</link>
		<comments>http://www.linuxplayer.org/2011/12/linux-systems-programming-for-trouble-shooting#comments</comments>
		<pubDate>Mon, 26 Dec 2011 11:05:54 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[netstat]]></category>
		<category><![CDATA[strace]]></category>
		<category><![CDATA[trouble-shooting]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=515</guid>
		<description><![CDATA[1.    谁偷了我的磁盘空间？ 发现大小为10G的/home分区磁盘空间使用了9.8G,但是通过du得到的大小却是5G. 另外的4.8G空间哪里去了呢？ df -Th /home Filesystem    Type    Size  Used Avail Use% Mounted on /dev/sda3      ext3     10G   9.8G  0.2G  98% /home du -hs /home 5.0G    /home/ du和df都不太可能出错，文件系统也没有损坏的迹象，那问题出在哪儿呢？查看unlink系统调用的手册页： unlink()  deletes  a  name from the filesystem. If that name was the last link to a file and no processes have the file open the file is &#8230; </p><p><a class="more-link block-button" href="http://www.linuxplayer.org/2011/12/linux-systems-programming-for-trouble-shooting">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<h3>1.    谁偷了我的磁盘空间？</h3>
<p>发现大小为10G的/home分区磁盘空间使用了9.8G,但是通过du得到的大小却是5G. 另外的4.8G空间哪里去了呢？</p>
<div style="background: #000000; color: #008000; border: 2px solid #808080;">df -Th /home</p>
<p>Filesystem    Type    Size  Used Avail Use% Mounted on</p>
<p>/dev/sda3      ext3     10G   9.8G  0.2G  98% /home</p>
<p>du -hs /home</p>
<p>5.0G    /home/</p></div>
<p>du和df都不太可能出错，文件系统也没有损坏的迹象，那问题出在哪儿呢？查看unlink系统调用的手册页：<br />
<span id="more-515"></span><br />
<span style="font-style: italic; color: #99cc00;"> <span style="color: #ff0000;"> unlink()  deletes  a  name from the filesystem. If that name was the last link to a file and no processes have the file open the file is deleted</span></span><br style="font-style: italic; color: #ff0000;" /><span style="font-style: italic; color: #ff0000;"> and the space it was using is made available for reuse.</span><br style="font-style: italic; color: #ff0000;" /><br style="font-style: italic; color: #ff0000;" /><span style="font-style: italic; color: #ff0000;"> If the name was the last link to a file but any processes still have the file open the file  will  remain  in  existence  until  the  last  file</span><br style="font-style: italic; color: #ff0000;" /><span style="font-style: italic; color: #ff0000;"> descriptor referring to it is closed.</span><br />
可以看出，如果一个文件被删除了，但是还有其他hard link,或者有进程打开它，那么磁盘空间不会被释放.<br />
如何找出这样的文件呢？</p>
<div style="background: #000000; color: #008000; border: 2px solid #808080;">lsof | grep deleted<br />
#COMMAND     PID      USER   FD      TYPE             DEVICE     SIZE       NODE    NAME<br />
testsvr      10126    root   3w      REG               8,3    5153960755    2801561 /home/curuwong/nohup.out (deleted)</div>
<p>nohup.out这个文件名字虽然从/home/curuwong目录消失了，但是所占据的磁盘空间仍然没有被释放，因为有个叫做testsvr的程序还在打开着这个文件。</p>
<p>du得到的空间占用情况和df的结果差距明显的情形，还有一种原因，那就是某个原本有内容的目录被作为挂载点mount上其他分区，于是那个目录下原本的内容就看不到了，但是它们都还在那里，在占用着空间。你看不见的东西，不意味着它们就不存在。^_^</p>
<h3>2. wget监听udp端口?(对，你没看错)</h3>
<p>我们某业务上有个叫做virusscanner服务,它监听udp端口9999.这个服务进程会不断地通过system函数启动wget通过http去拉取一些东西(OK,我知道你想说使用libcurl会更高效).<br />
virusscanner刚启动时,通过netstat查看端口监听状况：</p>
<div style="background: #000000; color: #008000; border: 2px solid #808080;">netstat -lunp | grep :9999<br />
udp        0      0 0.0.0.0:9999                0.0.0.0:*                             3913/virusscanner</div>
<p>然而一段时间之后:</p>
<div style="background: #000000; color: #008000; border: 2px solid #808080;">udp        0      0 0.0.0.0:9999                0.0.0.0:*                               857/wget</div>
<p>从常识出发，我们想象不出通过HTTP下载东西的wget会和UDP扯上什么关系. 那为什么会出现上面的诡异情况呢？</p>
<p>这里主要有两点:<br />
1). 父子进程间的描述符继承<br />
2). 进程PID轮转.</p>
<p>system函数主要做的事情，就是启动一个程序并等待其执行完毕，这主要涉及两个系统调用: fork和exec系列<br />
查看open(2)系统调用的手册页：<br />
<span style="color: #ff0000; font-style: italic;">The  new file descriptor is set to remain open across an execve(2)</span><br />
默认情况下，在父进程打开的文件描述符，在子进程中依然保持打开。<br />
这样的结果是，virusscanner打开并监听的udp端口(socket函数的返回值也是文件描述符)，在子进程wget中也是处于打开状态,可以被访问。</p>
<p>至于为什么netstat的输出刚开始显示viruscanner，后来显示wget,这就是PID轮转的结果了。从上面的分析我们知道，virusscanner和wget都在&#8221;监听&#8221;那个udp端口，netstat只是输出pid较小的进程.<br />
在Linux系统下，PID不是无限增长的，它有个最大值，可以通过文件/proc/sys/kernel/pid-max指定。当pid超过这个最大值时，新进程的pid又会从最小的没使用的开始。结果是：某一时刻，子进程的pid会比父进程的pid还小，于是netstat里面的输出，看到的就会是pid较小的子进程wget了。</p>
<p>那对上面的问题，有什么解决办法呢？很简单，修改virusscanner的代码，调用system()函数之前，<br />
在父进程的socket文件描述符上，通过fcntl设置&#8221;执行时关闭“标志就可以了。</p>
<pre>
fcntl(sock_fd, F_SETFD, fcntl(sock_fd, F_GETFD, 0) | FD_CLOEXEC);
</pre>
<h3>3. 有16G内存的空闲系统下，mysql查询竟然报内存不足(数据量小于百万)？</h3>
<p>在32位Linux下，启用PAE之后，系统可以管理最多64G的物理内存。然而由于指针大小的限制，<br />
32位程序最多只能寻址4G的内存。要是只有一个mysqld进程，剩下的28G内存都白白浪费了<br />
(这个不完全正确，因为系统会使用一部分内存来作为buffer和cache,对mysql的运行效率还是<br />
有帮助的)<br />
所以在有大内存的机器上，建议安装64位系统.</p>
<h3>4. strace： 跟踪程序的系统调用</h3>
<p>当你发现一个进程看似挂起了，不知道它是在忙什么的时候，或者发现程序无法像平常那样工作的时候，可以试试strace:<br />
strace -t /path/to/program<br />
strace -t -p process_pid</p>
<p>会显示进程所做的系统调用，在明白每个系统调用的大致含义之后，你大概就能猜想出程序正在做什么，有什么问题。<br />
比如，我们发现有个rsync进程，启动时间为十天前，但现在还在进程列表里面，我们要确定它到底是在干嘛，可以通过ps查到pid,然后:<br />
strace -t -p rsync_pid<br />
发现它根本没有调用读写socket的函数，而是一直在select,等待可读写IO,进一步分析，我们可以知道，是网络连接问题导致rsync挂起。 直接kill掉之后重传就可以了。</p>
<p>又比如，我们不知道本机mysqld要读取的配置文件顺序是什么，但是我们知道my_print_defaults命令能找到和读取正确的文件，这时我们也可以通过strace来找到它:</p>
<div style="background: #000000; color: #008000; border: 2px solid #808080;">strace -t ./my_print_defaults mysqld 2&gt;&amp;1 | grep stat</p>
<p>23:35:03 fstat64(3, {st_mode=S_IFREG|0644, st_size=35775, &#8230;}) = 0<br />
23:35:03 fstat64(3, {st_mode=S_IFREG|0755, st_size=114145, &#8230;}) = 0<br />
23:35:03 fstat64(3, {st_mode=S_IFREG|0755, st_size=47447, &#8230;}) = 0<br />
23:35:03 fstat64(3, {st_mode=S_IFREG|0755, st_size=96498, &#8230;}) = 0<br />
23:35:03 fstat64(3, {st_mode=S_IFREG|0755, st_size=195447, &#8230;}) = 0<br />
23:35:03 fstat64(3, {st_mode=S_IFREG|0755, st_size=1548470, &#8230;}) = 0<br />
23:35:03 stat64(&#8220;/etc/my.cnf&#8221;, {st_mode=S_IFREG|0644, st_size=5106, &#8230;}) = 0<br />
23:35:03 fstat64(3, {st_mode=S_IFREG|0644, st_size=5106, &#8230;}) = 0<br />
23:35:03 stat64(&#8220;/root/.my.cnf&#8221;, 0xbf9fc35c) = -1 ENOENT (No such file or directory)<br />
23:35:03 stat64(&#8220;/usr/local/mysql-5.0.22/etc/my.cnf&#8221;, 0xbf9fc35c) = -1 ENOENT (No such file or directory)</p></div>
<p>从输出可以看到，mysql需要读取的配置文件顺序为(版本5.0):<br />
/etc/my.cnf =&gt; ~/.my.cnf =&gt; $base_dir/etc/my.cnf<br />
并且我们知道其只有/etc/my.cnf存在，其他文件都不存在。</p>
<p>总结： 了解一些Linux系统编程知识，能够帮助我们更好地分析各种疑难问题，提高运维工作中的排错能力。</p>
<p>系统编程知识在运维中的应用还有很多，我后续会不断补充。这篇文章只是够抛砖引玉，大家在这方面什么经验,欢迎交流分享。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2011/12/linux-systems-programming-for-trouble-shooting/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bash quote trap: why rsync exclude pattern not work</title>
		<link>http://www.linuxplayer.org/2011/10/bash-quote-trap-why-rsync-exclude-pattern-not-work?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=bash-quote-trap-why-rsync-exclude-pattern-not-work</link>
		<comments>http://www.linuxplayer.org/2011/10/bash-quote-trap-why-rsync-exclude-pattern-not-work#comments</comments>
		<pubDate>Wed, 26 Oct 2011 16:26:06 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[quoting]]></category>
		<category><![CDATA[rsync]]></category>
		<category><![CDATA[show_arg]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=499</guid>
		<description><![CDATA[A friend wanted to sync all his files to a remote host, exluding the source files(those with suffix .c, .cpp, .h, .hpp). First I wrote this script #!/bin/bash ####sync.sh (version 1): sync files to remote host### SYNC_DST='xxx@example.com::sample_project' SYNC_OPT=' --exclude="*.[ch]" --exclude="*.[ch]pp" ' if [[ $# -eq 0 ]]; then echo "Usage $0 /src/path" exit 1 fi &#8230; </p><p><a class="more-link block-button" href="http://www.linuxplayer.org/2011/10/bash-quote-trap-why-rsync-exclude-pattern-not-work">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>A friend wanted to sync all his files to a remote host, exluding the source files(those with suffix .c, .cpp, .h, .hpp). First I wrote this script</p>
<pre>
#!/bin/bash
####sync.sh (version 1): sync files to remote host###
SYNC_DST='xxx@example.com::sample_project'
SYNC_OPT=' --exclude="*.[ch]" --exclude="*.[ch]pp" '
if [[ $# -eq 0 ]]; then
        echo "Usage $0 /src/path"
        exit 1
fi
src=$1
#for debug ...
echo rsync -avz $SYNC_OPT "$src" "$SYNC_DST"
rsync -avz $SYNC_OPT "$src" "$SYNC_DST"
</pre>
<p>Now we try to  sync the &#8216;src&#8217; directory:</p>
<pre>
./sync.sh src
####output########################################
rsync -avz --exclude="*.[ch]" --exclude="*.[ch]pp" src xxx@example.com::sample_project
sending incremental file list
src/
src/main
src/main.c
src/main.o
src/lib/
src/lib/lib.c
src/lib/lib.h
src/lib/lib.o
####output########################################
<span id="more-499"></span>
</pre>
<p>We can see that the source files are not excluded,we can also see the full sync command. After removing all the files in the remote host, I copy and run the sync command manually:</p>
<pre>
rsync -avz --exclude="*.[ch]" --exclude="*.[ch]pp" src xxx@example.com::sample_project
sending incremental file list
src/
src/main
src/main.o
src/lib/
src/lib/lib.o
</pre>
<p>It works great! But wait, why, why, the same command was used in sync.sh, why didn&#8217;t it work as expected?<br />
After some painful test and failure, I changed the line from</p>
<pre>
SYNC_OPT=' --exclude="*.[ch]" --exclude="*.[ch]pp" '
</pre>
<p>to</p>
<pre>
SYNC_OPT=' --exclude=*.[ch] --exclude=*.[ch]pp '
</pre>
<p>just remove the double quote in $SYNC_OPT variable and everything works as expected. Then I realize that it&#8217;s the quote in variable that caused rsync pattern to fail. Because <span style="color:red">in Bash, quotes have the quoting function only when they appears literally, otherwise, they are just quote character, nothing special</span>.<br />
 Let&#8217;s make it clear with some example.</p>
<pre>
#!/bin/bash
###show_arg.sh: used to show arguments provided to this script##
for arg in "$@"; do
   echo "==$arg=="
done
</pre>
<p>Let&#8217;s see how the show_arg.sh works</p>
<pre>
./show_arg.sh arg1 "arg 2" arg3
==arg1==
==arg 2==
==arg3==
</pre>
<p>We can see the that the show_arg.sh will print out each argument provided to it, one argument per line, surrounded by two &#8220;==&#8221;.<br />
replace <strong>rsync </strong>with <strong>show_arg.sh </strong>in sync.sh</p>
<pre>
#!/bin/bash
####sync.sh (version 2): show the real arguments###
SYNC_DST='xxx@example.com::sample_project'
SYNC_OPT=' --exclude="*.[ch]" --exclude="*.[ch]pp" '
if [[ $# -eq 0 ]]; then
        echo "Usage $0 /src/path"
        exit 1
fi
src=$1
./show_arg.sh -avz $SYNC_OPT "$src" "$SYNC_DST"
</pre>
<p>Test it again:</p>
<pre>
./sync.sh src
</pre>
<p>Output:</p>
<pre>
rsync -avz --exclude="*.[ch]" --exclude="*.[ch]pp" src xxx@example.com::sample_project
==-avz==
==--exclude="*.[ch]"==
==--exclude="*.[ch]pp"==
==src==
==xxx@example.com::sample_project==
</pre>
<p>It&#8217;s now obvious that the quotes are passed to rsync command literally, which definitely cause the pattern to fail. You may be happy and think that remove all the useless quotes will solve all problem. However, what if we really need the quotes?</p>
<p>For example, if we want to exclude files named &#8220;test a&#8221;(test <strong>space</strong> a, without quotes), we can&#8217;t write it like this:</p>
<pre>
SYNC_OPT=' --exclude=test a'
</pre>
<p>this will only exclude files named <strong>test</strong>, and takes <strong>a</strong> as file to sync. We must write it like this:</p>
<pre>
SYNC_OPT=' --exclude="test a"'
</pre>
<p>We know for now that with sync.sh version 1, it will definitely fail because of the quotes problem. Fortunately, Bash has a valuable <strong>eval</strong> command, it will process the quotes in variable as you would normally expect.</p>
<pre>
#!/bin/bash
####sync.sh (version 3): sync files, exclude file name with space###
SYNC_DST='dst'
SYNC_OPT=' --exclude="*.[ch]" --exclude="*.[ch]pp" --exclude="test a"'
if [[ $# -eq 0 ]]; then
        echo "Usage $0 /src/path"
        exit 1
fi
src=$1
#rsync -avz $SYNC_OPT "$src" "$SYNC_DST"
eval rsync -avz $SYNC_OPT "$src" "$SYNC_DST"
</pre>
<p>Test result<br />
<a href="http://www.linuxplayer.org/wp-content/uploads/2011/10/rsync_exclude.png"><img src="http://www.linuxplayer.org/wp-content/uploads/2011/10/rsync_exclude.png" alt="rsync exlude pattern works when use the eval command" title="rsync_exclude" width="479" height="368" class="aligncenter size-full wp-image-506" /></a></p>
<h3>Conclusion: In Bash shell, quotes have the quoting capability <strong>only</strong> when they appears literally, if they appear in variable, they are just the the quote character, nothing special. If you want the quotes in variable to have quoting function, eval them.</h3>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2011/10/bash-quote-trap-why-rsync-exclude-pattern-not-work/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using libcurl: follow redirect and get header only</title>
		<link>http://www.linuxplayer.org/2011/10/libcurl-follow-location-header-only?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=libcurl-follow-location-header-only</link>
		<comments>http://www.linuxplayer.org/2011/10/libcurl-follow-location-header-only#comments</comments>
		<pubDate>Sun, 02 Oct 2011 07:21:52 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[libcurl]]></category>
		<category><![CDATA[WWW::Curl]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=480</guid>
		<description><![CDATA[Let&#8217;s look at a sample code first(I use the WWW::Curl perl module here, the idea is the same for other language). #!/usr/bin/perl use warnings; use strict; use WWW::Curl::Easy; my $url = 'http://search.cpan.org/CPAN/authors/id/L/LO/LORN/LWP-Curl-0.09.tar.gz'; my $resp_body; #Get file length via HTTP HEAD request my $length; my $curl = WWW::Curl::Easy->new(); $curl->setopt(CURLOPT_URL, $url); #follow redirect $curl->setopt(CURLOPT_FOLLOWLOCATION, 1); #inlcude header &#8230; </p><p><a class="more-link block-button" href="http://www.linuxplayer.org/2011/10/libcurl-follow-location-header-only">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s look at a sample code first(I use the <a href="http://search.cpan.org/perldoc?WWW::Curl" target="_blank">WWW::Curl</a> perl module here, the idea is  the same  for other language).</p>
<pre>
#!/usr/bin/perl
use warnings;
use strict;

use WWW::Curl::Easy;

my $url = 'http://search.cpan.org/CPAN/authors/id/L/LO/LORN/LWP-Curl-0.09.tar.gz';
my $resp_body;

#Get file length via HTTP HEAD  request
my $length;
my $curl = WWW::Curl::Easy->new();
$curl->setopt(CURLOPT_URL, $url);
#follow redirect
$curl->setopt(CURLOPT_FOLLOWLOCATION, 1);
#inlcude header in response
$curl->setopt(CURLOPT_HEADER, 1);
#do not include body in response
$curl->setopt(CURLOPT_NOBODY, 1);
$curl->setopt(CURLOPT_WRITEDATA,\$resp_body);
my $retcode = $curl->perform();
if($retcode == 0){
        print "header:$resp_body\n";
        print "*" x 80,"\n";
        $length = $curl->getinfo(CURLINFO_CONTENT_LENGTH_DOWNLOAD);
        if($length == -1 ){
                print "content length not available\n";
        }
        else {
                print "length: $length\n";
        }
}else{
        print "error happened:$retcode " . $curl->strerror($retcode) ." | "
                . $curl->errbuf ."\n";
        exit 1;
}
</pre>
<p>There&#8217;s nothing complicated, the points are:</p>
<ul>
<li> CURLOPT_FOLLOWLOCATION: set to 1 to follow HTTP redirect response </li>
<li> CURLOPT_HEADER: set to 1 to include HTTP Header in response</li>
<li> CURLOPT_NOBODY: set to 1 to exclude body content from response, so that we get header only</li>
<li> CURLOPT_WRITEDATA: you get HTTP headers here, more about this later</li>
</ul>
<p>You may think that we should use <b>CURLOPT_WRITEHEADER</b> to collect the HTTP headers, but it doesn&#8217;t work,we get only the first response header in this way, not the final headers after several redirection.</p>
<p>check <a href="http://curl.haxx.se/libcurl/">http://curl.haxx.se/libcurl/ </a>for more about libcurl</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2011/10/libcurl-follow-location-header-only/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>add utf8 subject support to mailwatch 1.0.5</title>
		<link>http://www.linuxplayer.org/2011/08/add-utf8-subject-support-to-mailwatch-1-0-5?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=add-utf8-subject-support-to-mailwatch-1-0-5</link>
		<comments>http://www.linuxplayer.org/2011/08/add-utf8-subject-support-to-mailwatch-1-0-5#comments</comments>
		<pubDate>Fri, 19 Aug 2011 08:23:18 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[Email]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[mailwatch]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=475</guid>
		<description><![CDATA[In mailwatch v1.0.5, if the subject of a message is utf8 encoded, it can&#8217;t display correctly on the message list page. All the non-ascii characters will be replaced with question mark. For example. the subject &#8220;我爱Linux&#8221; will appears as &#8220;??Linux&#8221;. We can patch mailwatch to support this: 1. patch Mailwatch.pm --- MailWatch.pm.bak 2011-08-19 14:15:45.565769650 +0800 &#8230; </p><p><a class="more-link block-button" href="http://www.linuxplayer.org/2011/08/add-utf8-subject-support-to-mailwatch-1-0-5">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://mailwatch.sourceforge.net/" target="_blank">mailwatch</a> v1.0.5, if the subject of a message is utf8 encoded, it can&#8217;t display correctly on the message list page. All the non-ascii characters will be replaced with question mark. For example. the subject &#8220;我爱Linux&#8221; will appears as &#8220;??Linux&#8221;.</p>
<p>We can patch mailwatch to support this:</p>
<p>1. patch Mailwatch.pm</p>
<pre>
--- MailWatch.pm.bak    2011-08-19 14:15:45.565769650 +0800
+++ MailWatch.pm        2011-08-19 15:08:47.343311859 +0800
@@ -284,7 +284,7 @@
    $msg{from_domain} = $message->{fromdomain};
    $msg{to} = join(",", @{$message->{to}});
    $msg{to_domain} = $todomain;
-   $msg{subject} = $message->{subject};
+   $msg{subject} = $message->{utf8subject};
    $msg{clientip} = $clientip;
    $msg{archiveplaces} = join(",", @{$message->{archiveplaces}});
    $msg{isspam} = $message->{isspam};
</pre>
<p>2. patch mailscanner/detail.php</p>
<pre>
--- detail.php.bak      2011-08-19 14:54:51.515734927 +0800
+++ detail.php  2011-08-19 15:04:17.003311710 +0800
@@ -147,7 +147,7 @@
    $output .= "</tr>
</table>

\n";
    $row[$f] = $output;
   }
-  if ($fieldn == "To:" || $fieldn == "Subject:") {
+  if ($fieldn == "To:") {
    $row[$f] = htmlentities($row[$f]);
   }
   if ($fieldn == "To:") {
@@ -155,7 +155,7 @@
   }
   if ($fieldn == "Subject:") {
    $row[$f] = decode_header($row[$f]);
-   //$row[$f] = htmlentities($row[$f]);
+   $row[$f] = htmlentities($row[$f],ENT_COMPAT,'utf-8');
   }
   if ($fieldn == "Spam Report:") {
    $row[$f] = format_spam_report($row[$f]);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2011/08/add-utf8-subject-support-to-mailwatch-1-0-5/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache options directive trap</title>
		<link>http://www.linuxplayer.org/2011/08/apache-options-directive-trap?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=apache-options-directive-trap</link>
		<comments>http://www.linuxplayer.org/2011/08/apache-options-directive-trap#comments</comments>
		<pubDate>Tue, 02 Aug 2011 06:14:03 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[403 Forbidden]]></category>
		<category><![CDATA[Apache]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=465</guid>
		<description><![CDATA[When configuring the Apache HTTP server, we use the Options directive to control which server features are available in a particular directory. We may, for example, write a config like this: &#60;Directory /usr/share/nagios&#62; Options +ExecCGI Indexes FollowSymLinks ... &#60;/Directory&#62; With this configuration, we hope to enable CGI if it has not been enabled, and set &#8230; </p><p><a class="more-link block-button" href="http://www.linuxplayer.org/2011/08/apache-options-directive-trap">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>When configuring the Apache HTTP server, we use the <strong>Options</strong> directive to control which server features are available in a particular directory. We may, for example, write a config like this:</p>
<pre>
&lt;Directory /usr/share/nagios&gt;
    Options +ExecCGI Indexes FollowSymLinks
    ...
&lt;/Directory&gt;
</pre>
<p>With this configuration, we hope to enable CGI  if it has not been enabled, and set auto index and follow symlink option.  However, this is completely <strong>wrong</strong> and will not work. when you access a cgi  in this directory, you will get a <strong>403 Forbidden</strong> page.<br />
<span id="more-465"></span><br />
In fact, the apache document has already stated this:</p>
<pre>
Warning

Mixing Options with a + or - with those without is not valid syntax, and is likely to cause unexpected results.
</pre>
<p>That is to say, if you want to use the + or &#8211; sign, use them for all options, otherwise it will not work. So, the correct config should like this(all with plus sign)</p>
<pre>
&lt;Directory /usr/share/nagios&gt;
    Options +ExecCGI +Indexes +FollowSymLinks
    ...
&lt;/Directory&gt;
</pre>
<p>Also, if you want to remove some option, eg, disable SSI, you can write it this way.</p>
<pre>
&lt;Directory /usr/share/nagios&gt;
    Options +ExecCGI +Indexes +FollowSymLinks -Includes
    ...
&lt;/Directory&gt;
</pre>
<p>In fact, when we use the Options directive without + or &#8211; singn, we mean &#8220;set options to these &#8230;&#8221;. when use + singn, we mean &#8220;Add this option&#8221;. when we mix them together, Apache will be confused, it may wonder:</p>
<ol>
<li>Set options to those you specified here(this is the final result)</li>
<li>Add the specified option to, or remove from existing option(existing + to_be_added &#8211; to_be_removed = final)
</ol>
<p>If it picks 1, it can&#8217;t satisfy 2. If it picks 2, it can&#8217;t satisfy 1. So, it&#8217;s clear that we should  <strong>Never mix Options with a + or &#8211; with those without</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2011/08/apache-options-directive-trap/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build the Linux kernel for other host</title>
		<link>http://www.linuxplayer.org/2011/07/build-the-linux-kernel-for-other-host?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=build-the-linux-kernel-for-other-host</link>
		<comments>http://www.linuxplayer.org/2011/07/build-the-linux-kernel-for-other-host#comments</comments>
		<pubDate>Fri, 29 Jul 2011 15:40:42 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[install-kernel-dev.sh]]></category>
		<category><![CDATA[Kernel]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=453</guid>
		<description><![CDATA[Building the linux kernel is time and resource consuming, especially when you do this in a VM guest. fortunately, We can choose a fast Linux machine to take the burden of building, then install the kernel to the target Linux host This simple article assumes that you know how to config and compile your custom &#8230; </p><p><a class="more-link block-button" href="http://www.linuxplayer.org/2011/07/build-the-linux-kernel-for-other-host">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<h3>Building the linux kernel is time and resource consuming, especially when you do this in a VM guest.</h3>
<h4>fortunately, We can choose a fast Linux machine to take the burden of building, then install the kernel to the target Linux host</h4>
<p>This simple article assumes that you know how to config and compile your custom kernel. so I will focus on building the kernel for other host. </p>
<p><strong>1. Download the linux kernel from kernel.org</strong>.  extract, make xxxconfig, then make, assume that the directory you build your kernel is called KERNEL_BUILD_DIR<br />
<span id="more-453"></span><br />
<strong>2. create a directory to holding things that will be transfered to the target host and install.</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> KERNEL_BUILD_DIR
 <span style="color: #007800;">kversion</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #660033;">-s</span> kernelrelease<span style="color: #7a0874; font-weight: bold;">&#41;</span>
 <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$kversion</span></pre></div></div>

<p><strong>3. Install modules to that directory</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #007800;">INSTALL_MOD_PATH</span>=<span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$kversion</span> modules_install</pre></div></div>

<p><strong>4. Install the kernel image to that directory</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #007800;">INSTALL_PATH</span>=<span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$kversion</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></div></div>

<p><strong>5. Install kernel-dev files for build other module (this is optional)</strong></p>
<p>Do you need things like kernel-devel package(fedora) linux-headers(Ubuntu)?  if yes, download my <a href="http://linuxplayer.googlecode.com/git/scripts/install-kernel-dev.sh" target="_blank">install-kernel-dev.sh</a> from google code. then run: (you can save this script anywhere, but you must run it from the kernel build dir)</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">INSTALL_PATH</span>=<span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$kversion</span>
.<span style="color: #000000; font-weight: bold;">/</span>install-kernel-dev.sh</pre></div></div>

<p><strong>6. archive the resulting files</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$HOME</span>
<span style="color: #c20cb9; font-weight: bold;">tar</span> <span style="color: #660033;">-cjf</span> <span style="color: #007800;">$kversion</span>.tar.bz2 <span style="color: #007800;">$kversion</span></pre></div></div>

<p>Copy the xxx.tar.bz2 to your target machine</p>
<p><strong><br />
7. Install on the target host</strong><br />
1) Install modules and headers</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">tar</span> <span style="color: #660033;">-xjf</span> <span style="color: #000000;">2.6</span>.xxx.xx.tar.bz2 <span style="color: #666666; font-style: italic;"># (replace  xxx with your kernel version string)</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000;">2.6</span>.xxx.xx
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chown</span> root:root <span style="color: #000000; font-weight: bold;">*</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-a</span> lib<span style="color: #000000; font-weight: bold;">/</span>modules<span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>modules<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-a</span> usr<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>2) Install the kernel<br />
On Ubuntu</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;">cp</span> System.map-<span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">/</span>boot<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">cp</span> vmlinuz-<span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">/</span>boot<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> update-initramfs <span style="color: #660033;">-c</span> <span style="color: #660033;">-k</span> <span style="color: #000000;">2.6</span>.xxx.xxx   <span style="color: #666666; font-style: italic;"># (replace  xxx with your kernel version string)</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> update-grub2</pre></div></div>

<p>On CentOS/Fedora</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">installkernel <span style="color: #000000;">2.6</span>.xxx.xxx  vmlinuz-<span style="color: #000000; font-weight: bold;">*</span>  System.map-<span style="color: #000000; font-weight: bold;">*</span></pre></div></div>

<p>edit /boot/grub/menu.lst, change default=1 to default=0.</p>
<p>That&#8217;s all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2011/07/build-the-linux-kernel-for-other-host/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Install from source or use rpm, this is a question</title>
		<link>http://www.linuxplayer.org/2011/07/install-from-source-code-or-use-rpm?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=install-from-source-code-or-use-rpm</link>
		<comments>http://www.linuxplayer.org/2011/07/install-from-source-code-or-use-rpm#comments</comments>
		<pubDate>Wed, 20 Jul 2011 12:42:41 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[proftpd]]></category>
		<category><![CDATA[VRootAlias]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=444</guid>
		<description><![CDATA[Install software packages from prebuilt rpm is not always simple and good. If we need more configure option and consistent behavior, build from source]]></description>
			<content:encoded><![CDATA[<p>For RHEL and its derived distribution, installing software packages using rpm or yum is sometimes convenient, painless and time saving. However, because distribution vendors build rpms independent of software provider, there may be time delay, and even inconsistency between rpms and the original software package.</p>
<p>Here&#8217;s what I come across today. I installed <a href="http://www.proftpd.org" target="_blank">ProFTPD</a> from the epel repo on two servers. One is CentOS 6.0 and the other is CentOS 5.6. </p>
<pre>
#on CentOS 6.0
[curu@el6 ~]$ rpm -q proftpd
proftpd-1.3.3e-1.el6.x86_64
#on CentOS 5.6
[curu@el5 ~]# rpm -q proftpd
proftpd-1.3.3e-1.el5
</pre>
<p>Seems they are of the same version. However, When I copy the proftpd.conf from el6 to el5, I get this error</p>
<pre>
proftpd -t
Checking syntax of configuration file
 - Fatal: VRootAlias: source path 'etc/security/pam_env.conf' is not an absolute path on line 11 of '/etc/proftpd.conf'
</pre>
<p>And here&#8217;s line 11 of my /etc/proftpd.conf </p>
<pre>
VRootAlias                      /etc/security/pam_env.conf etc/security/pam_env.conf
</pre>
<p>According to the <a href="http://www.castaglia.org/proftpd/modules/mod_vroot.html#VRootAlias" target="_blank">mod_vroot document</a> on proftpd site </p>
<pre>
VRootAlias
Syntax: VRootAlias src-path dst-path
</pre>
<p>It&#8217;s obvious that my config is right, the src-path here is <strong>/etc/security/pam_env.conf</strong>, definitely absolute! But what&#8217;s wrong? Ask the source!</p>
<p>In order to find the cause of this inconsistency, I downloaded the source rpms of these two rpms, and finally find why. In fact, in the RPMs from EPEL, proftpd-1.3.3e-1.el5 comes with mod-vroot-0.8.5, whereas proftpd-1.3.3e-1.el6 comes with mod-vroot-0.9.2. The bad thing is, the directive syntax of VRootAlias has changed between these two version of mod_vroot. </p>
<p>for mod-vroot-0.8.5</p>
<pre>
VRootAlias
Syntax: VRootAlias dst-path src-path
</pre>
<p>Damn! the change is completely nonsense and incompatible. </p>
<p>So, what can when draw from this story?  <strong>Install software packages from prebuilt rpm is not always simple and good. If we need more configure option and consistent behavior, build from source</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2011/07/install-from-source-code-or-use-rpm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shorewall: allow communication between VPN clients</title>
		<link>http://www.linuxplayer.org/2011/07/shorewall-allow-traffic-between-vpn-clients?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=shorewall-allow-traffic-between-vpn-clients</link>
		<comments>http://www.linuxplayer.org/2011/07/shorewall-allow-traffic-between-vpn-clients#comments</comments>
		<pubDate>Thu, 07 Jul 2011 16:55:00 +0000</pubDate>
		<dc:creator>Curu Wong</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[VPN]]></category>
		<category><![CDATA[Openswan]]></category>
		<category><![CDATA[routeback]]></category>
		<category><![CDATA[Shorewall]]></category>

		<guid isPermaLink="false">http://www.linuxplayer.org/?p=433</guid>
		<description><![CDATA[If you setup Linux as a PPTP or L2TP/IPSec VPN server, every client connection will have a corresponding pppx interface on the server. You may have a shorewall interface config like this: /etc/shorewall/interfaces #zone interface boradcast options l2tp ppp+ - Assume that client A connected, get IP 192.168.1.100 for ppp0, client B get IP 192.168.1.101 &#8230; </p><p><a class="more-link block-button" href="http://www.linuxplayer.org/2011/07/shorewall-allow-traffic-between-vpn-clients">Continue reading &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>If you setup Linux as a PPTP or L2TP/IPSec VPN server, every client connection will have a corresponding pppx interface on the server. You may have a shorewall interface config like this:</p>
<p><strong>/etc/shorewall/interfaces</strong></p>
<pre>
#zone interface boradcast options
l2tp    ppp+    -
</pre>
<p>Assume that client A connected, get IP 192.168.1.100 for  ppp0, client B get IP 192.168.1.101 for ppp1. When client A try to ping client B. you may get the following shorewall log:</p>
<pre>
Jul  8 00:19:20 vpngateway kernel: Shorewall:FORWARD:REJECT:IN=ppp0 OUT=ppp1
 SRC=192.168.1.100 DST=192.168.1.101 LEN=60 TOS=0x00 PREC=0x00 TTL=127 ID=311
 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=52
</pre>
<p>In this case, if you really think that the connected VPN clients should be able to communicate with each other, you may add the routeback option to shorewall-interface config file, like this:</p>
<pre>
#zone interface boradcast options
l2tp    ppp+    -       routeback
</pre>
<p>Reference: <a href="http://www.shorewall.net/manpages/shorewall-interfaces.html" target="_blank">shorewall-interfaces</a> man page</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linuxplayer.org/2011/07/shorewall-allow-traffic-between-vpn-clients/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

