<?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>Rest Valley &#187; Config</title> <atom:link href="http://lihdd.net/category/config/feed/" rel="self" type="application/rss+xml" /><link>http://lihdd.net</link> <description>The scratchpad of quark</description> <lastBuildDate>Sat, 09 Oct 2010 13:56:19 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=</generator> <item><title>坏道惊魂</title><link>http://lihdd.net/seagate-bad-blocks/</link> <comments>http://lihdd.net/seagate-bad-blocks/#comments</comments> <pubDate>Mon, 10 May 2010 13:35:52 +0000</pubDate> <dc:creator>quark</dc:creator> <category><![CDATA[Config]]></category> <category><![CDATA[badblocks]]></category> <category><![CDATA[Hardware]]></category> <category><![CDATA[seagate]]></category> <category><![CDATA[smartctl]]></category><guid
isPermaLink="false">http://lihdd.net/?p=417</guid> <description><![CDATA[天气渐渐热了起来，听着本本风扇狂转的声音，右手感觉到硬盘滚烫的温度，我觉得现有数据很是需要备份一下。 我以前一直觉得坏道什么的太难遇到了，直到去年十二月的一天，类似这样的消息在屏幕出现： kernel: sd 4:0:0:0: [sda] Unhandled sense code kernel: sd 4:0:0:0: [sda] Result: hostbyte=0x00 driverbyte=0x08 kernel: sd 4:0:0:0: [sda] Sense Key : 0x3 [current] kernel: sd 4:0:0:0: [sda] ASC=0x14 ASCQ=0x0 kernel: sd 4:0:0:0: [sda] CDB: cdb[0]=0x28: 28 00 25 42 ea af 00 00 01 00 kernel: end_request: I/O error, dev sda, sector 625142447 [...]]]></description> <content:encoded><![CDATA[<p><img
class="alignright size-full wp-image-418" title="drive-harddisk" src="http://lihdd.net/wp-content/uploads/2010/05/drive-harddisk.png" alt="" width="128" height="128" align="right" />天气渐渐热了起来，听着本本风扇狂转的声音，右手感觉到硬盘滚烫的温度，我觉得现有数据很是需要备份一下。</p><p>我以前一直觉得坏道什么的太难遇到了，直到去年十二月的一天，类似这样的消息在屏幕出现：</p><div
class="wp_syntax"><div
class="code"><pre class="text" style="font-family:monospace;">kernel: sd 4:0:0:0: [sda] Unhandled sense code
kernel: sd 4:0:0:0: [sda] Result: hostbyte=0x00 driverbyte=0x08
kernel: sd 4:0:0:0: [sda] Sense Key : 0x3 [current]
kernel: sd 4:0:0:0: [sda] ASC=0x14 ASCQ=0x0
kernel: sd 4:0:0:0: [sda] CDB: cdb[0]=0x28: 28 00 25 42 ea af 00 00 01 00
kernel: end_request: I/O error, dev sda, sector 625142447
kernel: Buffer I/O error on device sda, logical block 78142805</pre></div></div><p>这些消息会反复地出现，持续三分钟左右，在此期间做不得其他事情。这些消息出现在对磁盘执行 mount 或 fsck 之前，也就是说系统刚发现这个硬盘还没有开始挂载的时候，就会僵持三分钟。当然，等到 mount 的时候，又是一个三分钟。换句话说，光是进入 Linux 系统就需要六分多钟。神奇的是 Windows 并不会僵持住 <img
src='http://lihdd.net/wp-includes/images/smilies/icon_eek.gif' alt='8-O' class='wp-smiley' /></p><p>查阅一些资料之后，排除了是内核 Bug 或者是参数设置不正确，了解到那些稀奇古怪的十六进制数字背后还有一些标准，我终于相信坏道就在眼前。实在忍受不了需要六分钟才能进入 Linux 系统，同时我也担心坏道会扩散，就在第二天去换了一个一样容量的硬盘。</p><p>最近，出于备份的需要有把这块硬盘拿出来了，那么怎么处理坏道呢？</p><p><span
id="more-417"></span>传统的方法可能是用 <code>badblocks</code> 这个程序去检测一下坏道在哪里了。<code>badblocks</code> 有两种检查方式，一种是只读的，一种是读写的。一般想要彻底查出来坏道就要选择读写的方法，而 <code>badblocks</code> 在这时会依次填上 0xaa, 0&#215;55, 0xff, 0&#215;00，并分别读一次来确认是否有坏道。 <code>badblocks</code> 没有特别的优化，倘若填写 0xaa 之后检查的时候就发现需要检查的所有区域都已经坏掉了， <code>badblocks</code> 并不会终止检查，而是会傻傻地执行完剩下的所有检查。对于一块 320G 笔记本硬盘来说，全盘的读写检查大概需要 24 个小时。</p><p>在 <code>badblocks</code> 全盘读写检查的第 18 个小时，我不小心一个操作把它终止掉了 <img
src='http://lihdd.net/wp-includes/images/smilies/icon_neutral.gif' alt=':-|' class='wp-smiley' /> 。这么漫长的操作肯定不愿意再来一次了，于是我用了一次 <code>badblocks</code> 全盘只读检查，结果 <code>badblocks</code> 说没有发现坏道 &#8230;</p><p>查阅相关资料后发现，从一开始就用不到 <code>badblocks</code>。现代硬盘具有自我检查机制，在一个“坏道”彻底坏掉之前的很长时间，它先是在读取的时候变得困难，而不是完全无法读取（希捷官方所言）。这时候，支持 <a
href="http://en.wikipedia.org/wiki/S.M.A.R.T.">SMART</a> 标准的硬盘（许多年前的有硬盘就都普遍支持了）会防患于未然，把这个 sector 记录成 &#8220;Pending&#8221;，用 <code>smartctl</code> 命令就可以查看到 Current Pending Sector：</p><div
class="wp_syntax"><div
class="code"><pre class="text" style="font-family:monospace;"># smartctl -A /dev/sdb
....
... Current_Pending_Sector ... 1
....</pre></div></div><p>这就表明硬盘自己发现了一个不稳定的 sector 了，这时候，如果读写这个 sector 变得正常的话，这个 sector 会被硬盘记录成正常，Current Pending Sector 会减少。如果依然发生了读取困难或者是不能读取的情况，硬盘不会做任何事情。当写入失败的时候，硬盘会自动将这个 sector 映射到它的保留区的一个好的 sector，并把这个 sector 标记成 &#8220;remapped&#8221;，由于一般坏道在真正坏掉之前还是可以读出内容的，硬盘会自动将读出来的内容复制到保留区，remap 完成之后，Current Pending Sector 也会减少，这一切都是在硬件层面上完成的，如果正常的话，普通软件（比如 <code>badblocks</code>）是根本没法发现这个 sector 是坏掉的，即便它去写那个 sector。</p><p>那么问题是不是就变得简单了呢，向标记为 Pending 的 sector 写一点东西就可以让硬件搞定这些问题了？看起来是的。在写之前需要知道有问题的 sector 在哪里，这个在 kernel log 里面已经看到了。现代的硬盘自己也会记录错误的 log，通过 <code>smartctl /dev/sdb -l error</code> 命令就能查看，虽然数量有限（我这里只有最后的 5 条），不一定会看到想要看的错误信息。</p><p>通过 fdisk 可以看到一个 sector 的大小：</p><div
class="wp_syntax"><div
class="code"><pre class="text" style="font-family:monospace;"># fdisk -lu /dev/sdb
&nbsp;
Disk /dev/sdb: 320.1 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders, total 625142448 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
....</pre></div></div><p>按照文章开头处 kernel log 中提到的 625142447，向这个地方写一点东西，让硬盘立即 remap 这个 Pending Sector：</p><div
class="wp_syntax"><div
class="code"><pre class="text" style="font-family:monospace;"># dd if=/dev/zero of=/dev/sdb bs=512 count=1 seek=625142447
dd: writing `/dev/sdb': Input/output error
1+0 records in
0+0 records out
0 bytes (0 B) copied, 7.26951 s, 0.0 kB/s</pre></div></div><p>有的朋友可能读到这里就发现我悲剧了，因为如果硬件正常的话，它会进行 remap，然后就能写成功了，但显然事与愿违，硬盘没有进行 remap，这时用 <code>badblocks</code> 也能发现这个坏道：</p><div
class="wp_syntax"><div
class="code"><pre class="text" style="font-family:monospace;"># badblocks -svw -b 512 /dev/sdb 625142447 625142447
Checking for bad blocks in read-write mode
From block 625142447 to 625142447
Testing with pattern 0xaa: done
625142447
Reading and comparing: done
Testing with pattern 0x55: done
Reading and comparing: done
Testing with pattern 0xff: done
Reading and comparing: done
Testing with pattern 0x00: done
Reading and comparing: done
Pass completed, 1 bad blocks found.</pre></div></div><p>用 <code>smartctl</code> 可以验证 Current Pending Sector 还是 1，并没有变成 0。一切都没有改变，所有的硬盘 SMART 自检都会失败，kernel 还是会产生那样的 log，并持续几十秒挡住你，不让用这块硬盘。</p><p>这时候我突然想到了这块希捷硬盘可能还在保修期 <img
src='http://lihdd.net/wp-includes/images/smilies/icon_eek.gif' alt='8-O' class='wp-smiley' /></p><div
class="wp_syntax"><div
class="code"><pre class="text" style="font-family:monospace;">厂商保修信息：
    * 该商品保修期为36个月。
    * 3 年有限责任质保(第一年免费包换，第二，三年保修)</pre></div></div><p>看起来只能换不能修了，早知道在刚出问题的时候就去换一个了 <img
src='http://lihdd.net/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> 想到 Windows 下使用没有问题，说清楚问题所在还是挺麻烦的。并且邮寄费用并不便宜，寄来寄去说不定还会导致彻底坏掉了，还是不要修了 &#8230;.</p><p>绝望中突然看到了希望，那就是希捷硬盘可以使用的 <a
href="http://www.seagate.com/www/en-us/support/downloads/seatools">SeaTools</a> 。它有两个版本，Windows 版能做的事情比 <code>smartctl</code> 命令还要少，真的没啥用，而且把希捷自家的硬盘放到外面的盒子里就认不出来是希捷的了。不过官方说 DOS 版本能修复坏道，这应该是最后的希望了。</p><p>于是赶紧下载，刻录成光盘，由于 SeaTools for DOS 不支持移动硬盘，就把现在用的硬盘换下来，用光盘启动，见到了久违的 FreeDOS 。SeaTools for DOS 的坏道修复功能不依靠 SMART 信息，需要执行一次全盘扫描，扫描用了两个小时，接着果然提供了一个 Repair 选项，果断使用，成功了 <img
src='http://lihdd.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> 在此之后这快硬盘用起来完全正常，即便查看 SMART 信息也看不出来有一个坏道被映射了。SeaTools for DOS 还提供了设置硬盘容量的功能，实际上这次有问题的 sector 就是整个硬盘有效 sector 的倒数第二个，修改硬盘容量，减少 1 MB，也应该是解决问题的不错办法。</p><p>总结起来，这次这个事情之后有一些经验：</p><ol><li>对于硬盘健康情况的检测，<code>badblocks</code> 这种东西太旧了，而且对现代硬盘也不一定有效。<code>smartctl</code> 可以多快好省地完成许多相关事情。</li><li>虽然 SMART 是存在好多年的标准，但硬件不一定完全遵守它。厂商自己提供的工具才是最靠谱的！更广泛一点，软件和标准也是这样。</li><li><code>palimpsest</code> 用来查看 SMART 信息和做硬盘自检很不错，如果不喜欢命令行的 <code>smartctl</code> 就可以用它。而 <code>gparted</code> 则侧重于做编辑分区的工作。<div
id="attachment_419" class="wp-caption aligncenter" style="width: 310px"><a
href="http://lihdd.net/wp-content/uploads/2010/05/palimpsest_smart_info.png"><img
class="size-medium wp-image-419 " title="palimpsest_smart_info" src="http://lihdd.net/wp-content/uploads/2010/05/palimpsest_smart_info-300x251.png" alt="" width="300" height="251" /></a><p
class="wp-caption-text">用 Palimpsest 查看硬盘的 SMART 信息</p></div></li><li>Linux 可以早于 Windows 发现磁盘可疑坏道，可疑坏道出现后的很长一段时间内还是可以读取的，只是硬盘要多用一点力气。</li><li>发现硬盘问题时应该立即换下可疑硬盘，备份数据到可靠的硬盘里，再考虑修复。除非很了解正在使用的 FS，掌握 <code>debugfs</code> 等的用法，否则不要直接尝试在线修复坏道。</li><li>定期使用如 <code>rsync</code> 的软件备份数据到别的地方，硬盘数据，正如国歌中的中华民族，到了最危险的时候。</li><li>有时候见到把硬盘的最后 8 MB 空出来，不分到任何分区去，也许是有一定道理的。</li></ol> ]]></content:encoded> <wfw:commentRss>http://lihdd.net/seagate-bad-blocks/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>让 Archlinux 的 pacman 健步如飞</title><link>http://lihdd.net/archlinux-pacman-accelerate/</link> <comments>http://lihdd.net/archlinux-pacman-accelerate/#comments</comments> <pubDate>Wed, 05 May 2010 01:38:46 +0000</pubDate> <dc:creator>quark</dc:creator> <category><![CDATA[Config]]></category> <category><![CDATA[archlinux]]></category> <category><![CDATA[pacman]]></category><guid
isPermaLink="false">http://lihdd.net/?p=403</guid> <description><![CDATA[使用 Archlinux 的朋友大概遇到过这样的烦恼，软件安装得比较多的时候，再用 pacman 做任何事情的时候都可以看到硬盘狂转一段时间，然后才有反应。 pacman 官方给了一个 pacman-optimize，它会把 pacman 数据库文件打包到别的地方，删除，然后再放回去。这样做可能会让这些零碎的文件在硬盘上是连续排列的，但实际效果却不是很好。 虽然用 Archlinux 应该有三年左右了，但我还从来没有看过 pacman 的数据库是什么模样。有一天终于忍不住去看了一下 /var/lib/pacman 下面到底是什么，原来是这么多零碎的小文件啊！ 于是解决方案也就有了：把所谓的 pacman 数据库放到 reiserfs 文件系统里。如果你本来在这个地方用的就是 reiserfs 的话，那么不需要做任何事情， pacman 应该就很快了。如果你和我一样用的是 ext4 这样的文件系统，也不必慌张地把整个分区都换成 reiserfs。 新建一个 160 MB 的 reiserfs 文件 pacman_db.fs： truncate pacman_db.fs --size 160M mkfs.reiserfs -f ./pacman_db.fs 把现有的 pacman 数据库复制到这个 reiserfs 里面： sudo mount pacman_db.fs -t reiserfs /mnt -o [...]]]></description> <content:encoded><![CDATA[<p><a
href="http://lihdd.net/wp-content/uploads/2010/05/pacman.png"><img
class="alignright size-full wp-image-404" title="pacman" src="http://lihdd.net/wp-content/uploads/2010/05/pacman.png" alt="pacman" width="128" height="119" /></a>使用 Archlinux 的朋友大概遇到过这样的烦恼，软件安装得比较多的时候，再用 <code>pacman</code> 做任何事情的时候都可以看到硬盘狂转一段时间，然后才有反应。</p><p><code>pacman</code> 官方给了一个 <code>pacman-optimize</code>，它会把 <code>pacman</code> 数据库文件打包到别的地方，删除，然后再放回去。这样做可能会让这些零碎的文件在硬盘上是连续排列的，但实际效果却不是很好。</p><p>虽然用 Archlinux 应该有三年左右了，但我还从来没有看过 <code>pacman</code> 的数据库是什么模样。有一天终于忍不住去看了一下 <code>/var/lib/pacman</code> 下面到底是什么，原来是这么多零碎的小文件啊！</p><p>于是解决方案也就有了：把所谓的 <code>pacman</code> 数据库放到 reiserfs 文件系统里。如果你本来在这个地方用的就是 reiserfs 的话，那么不需要做任何事情， <code>pacman</code> 应该就很快了。如果你和我一样用的是 ext4 这样的文件系统，也不必慌张地把整个分区都换成 reiserfs。<span
id="more-403"></span></p><p>新建一个 160 MB 的 reiserfs 文件 <code>pacman_db.fs</code>：</p><div
class="wp_syntax"><div
class="code"><pre class="bash" style="font-family:monospace;">truncate pacman_db.fs <span style="color: #660033;">--size</span> 160M
mkfs.reiserfs <span style="color: #660033;">-f</span> .<span style="color: #000000; font-weight: bold;">/</span>pacman_db.fs</pre></div></div><p>把现有的 <code>pacman</code> 数据库复制到这个 reiserfs 里面：</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;">mount</span> pacman_db.fs <span style="color: #660033;">-t</span> reiserfs <span style="color: #000000; font-weight: bold;">/</span>mnt <span style="color: #660033;">-o</span> loop 
<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-a</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>pacman<span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000; font-weight: bold;">/</span>mnt
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">umount</span> <span style="color: #000000; font-weight: bold;">/</span>mnt</pre></div></div><p>接下来修改 <code>/etc/fstab</code>，加上一行：</p><div
class="wp_syntax"><div
class="code"><pre class="auto" style="font-family:monospace;">/[path_to_pacman_db]/pacman_db.fs /var/lib/pacman reiserfs defaults,loop 0 4</pre></div></div><p>左边的 <code>[path_to_pacman_db]</code> 需要根据实际情况填一下。最右边的 4 应该是比 <code>fstab</code> 中其他条目大一些的数字，表示 <code>fsck</code> 检查时最后处理这个地方。</p><p>如果想让这个设置立即生效，执行 <code>sudo mount /var/lib/pacman</code> 即可。否则，重启一下就可以了。现在，使用 <code>pacman -Syu</code> 更新一下系统，是不是比以前快许多？ <img
src='http://lihdd.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> ]]></content:encoded> <wfw:commentRss>http://lihdd.net/archlinux-pacman-accelerate/feed/</wfw:commentRss> <slash:comments>21</slash:comments> </item> <item><title>关于 ibus-sogoupycc 的扩展</title><link>http://lihdd.net/ibus-sogoupycc-extensions/</link> <comments>http://lihdd.net/ibus-sogoupycc-extensions/#comments</comments> <pubDate>Thu, 18 Mar 2010 12:06:19 +0000</pubDate> <dc:creator>quark</dc:creator> <category><![CDATA[Config]]></category> <category><![CDATA[Script]]></category> <category><![CDATA[extension]]></category> <category><![CDATA[ibus]]></category> <category><![CDATA[ibus-sogoupycc]]></category> <category><![CDATA[lua]]></category><guid
isPermaLink="false">http://lihdd.net/?p=340</guid> <description><![CDATA[本来想把一些示例放在项目的 wiki 页上的，但是我还想说一些其他的闲话，而且目前扩展虽然有一些实用性了，却缺乏执行保护，可以把输入法弄得不稳定，所以这些内容就放到这里好了。如果你只想看看如何使用输入法的扩展，请向下找到 表情后从那里开始看。 似乎扩展是很流行的样子，各种浏览器，foobar2000，谷歌拼音，WPS，都可以用扩展。 其中，有的软件成功了，令人爱不释手，比如像 Firefox，foobar2000。有的软件却没有因为扩展成功，比如谷歌拼音。或者说扩展没有给人带来好感，比如 IE 浏览器。 我觉得作为一个支持扩展的软件，最重要的就是扩展要比较有用，可以做一些事情，这一点上谷歌拼音做得就不好，由于扩展而变得比较成功的软件在这方面做得都比较好。其次，扩展要容易开发，再往后，出于安全的考虑，扩展的能力要受到约束。这两点 IE 相比 Firefox 就弱了一些，不过 Firefox 的扩展写起来还是挺麻烦的，比如其中的多国语言化就非常麻烦，对于不同的地方要使用不同的方法，总共有三种。而由于 Firefox 的灵活性，出现了 Mozilla Jetpack 和 GreaseMonkey 等，都可以让扩展写起来方便一些。 在很长的一段时间内，我觉得编写软件，技术含量是最重要的， 一个更好的算法可以带来更快的速度，或者更好的结果，当然用户体验就会好。但是现在看法有些改变，因为目前，很多东西不是需要从头做起的，除非出于学习、版权目的，或者是原先的项目代码烂到不能看而没法维护，没有必要重新实现别人已经实现的东西。大部分软件应该在乎实用性，在不违反版权的情况下，尽量使用已有的东西。 从一开始，我觉得 ibus-sogoupycc 这样一个输入法的技术含量肯定不如 sunpinyin，Linux 下的输入法用 sunpinyin 就不错了，一度怀疑是否要有将 ibus-sogoupycc 写下去的必要。但是现在，我觉得是有必要的，因为在中国大部分有网络的地方，这样一个输入法用起来是更舒服的，至少对我自己来说。 出于同样的实用性的考虑，我提供了输入法扩展能力。本来我想提供一个完全兼容谷歌拼音的接口，但是后来觉得谷歌拼音的扩展接口设计得并不好，和目前输入法的无需选词流畅输入有冲突，没有遵循的必要。 开头提到的这个表情在这里： ，不难找吧。 扩展的设置应该放在用户配置文件中，目前添加一个扩展的方法是： ime.register_command&#40;key, modifiers, caption, script&#41; 这里，key 和 modifiers 都是数字类型，后两者是字符串类型。 修改用户配置文件后一般要重新启动输入法才能生效，可以右击任务栏上的 ibus 图标，选择重新启动。 Hello world 下面的代码注册了一个用 Alt + H [...]]]></description> <content:encoded><![CDATA[<p><img
src="http://lihdd.net/wp-content/uploads/2010/03/extensions.png" alt="" title="extensions" width="100" height="125" class="alignright size-full wp-image-344" />本来想把一些示例放在项目的 wiki 页上的，但是我还想说一些其他的闲话，而且目前扩展虽然有一些实用性了，却缺乏执行保护，可以把输入法弄得不稳定，所以这些内容就放到这里好了。如果你只想看看如何使用输入法的扩展，请向下找到 <img
src='http://lihdd.net/wp-includes/images/smilies/wink.png' alt='^_.' class='wp-smiley' /> 表情后从那里开始看。</p><p>似乎扩展是很流行的样子，各种浏览器，foobar2000，谷歌拼音，WPS，都可以用扩展。</p><p>其中，有的软件成功了，令人爱不释手，比如像 Firefox，foobar2000。有的软件却没有因为扩展成功，比如谷歌拼音。或者说扩展没有给人带来好感，比如 IE 浏览器。<span
id="more-340"></span></p><p>我觉得作为一个支持扩展的软件，最重要的就是扩展要比较有用，可以做一些事情，这一点上谷歌拼音做得就不好，由于扩展而变得比较成功的软件在这方面做得都比较好。其次，扩展要容易开发，再往后，出于安全的考虑，扩展的能力要受到约束。这两点 IE 相比 Firefox 就弱了一些，不过 Firefox 的扩展写起来还是挺麻烦的，比如其中的多国语言化就非常麻烦，对于不同的地方要使用不同的方法，总共有三种。而由于 Firefox 的灵活性，出现了 <a
href="https://jetpack.mozillalabs.com/">Mozilla Jetpack</a> 和 <a
href="https://addons.mozilla.org/firefox/addon/748">GreaseMonkey</a> 等，都可以让扩展写起来方便一些。</p><p>在很长的一段时间内，我觉得编写软件，技术含量是最重要的， 一个更好的算法可以带来更快的速度，或者更好的结果，当然用户体验就会好。但是现在看法有些改变，因为目前，很多东西不是需要从头做起的，除非出于学习、版权目的，或者是原先的项目代码烂到不能看而没法维护，没有必要重新实现别人已经实现的东西。大部分软件应该在乎实用性，在不违反版权的情况下，尽量使用已有的东西。</p><p>从一开始，我觉得 ibus-sogoupycc 这样一个输入法的技术含量肯定不如 <a
href="http://code.google.com/p/sunpinyin/">sunpinyin</a>，Linux 下的输入法用 sunpinyin 就不错了，一度怀疑是否要有将 ibus-sogoupycc 写下去的必要。但是现在，我觉得是有必要的，因为在中国大部分有网络的地方，这样一个输入法用起来是更舒服的，至少对我自己来说。<br
/><div
id="attachment_347" class="wp-caption aligncenter" style="width: 266px"><img
src="http://lihdd.net/wp-content/uploads/2010/03/ibus-sogoupycc-0.2.0_demo.gif" alt="" title="ibus-sogoupycc-0.2.0_demo" width="256" height="179" class="size-full wp-image-347" /><p
class="wp-caption-text">使用信号很弱的无线网，输入起来感觉也不错</p></div></p><p>出于同样的实用性的考虑，我提供了输入法扩展能力。本来我想提供一个完全兼容谷歌拼音的接口，但是后来觉得谷歌拼音的扩展接口设计得并不好，和目前输入法的无需选词流畅输入有冲突，没有遵循的必要。</p><p><em>开头提到的这个表情在这里： <img
src='http://lihdd.net/wp-includes/images/smilies/wink.png' alt='^_.' class='wp-smiley' /> ，不难找吧。</em></p><p>扩展的设置应该放在用户配置文件中，目前添加一个扩展的方法是：</p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;">ime.register_command<span style="color: #66cc66;">&#40;</span>key, modifiers, caption, script<span style="color: #66cc66;">&#41;</span></pre></div></div><p>这里，key 和 modifiers 都是数字类型，后两者是字符串类型。</p><p>修改用户配置文件后一般要重新启动输入法才能生效，可以右击任务栏上的 ibus 图标，选择重新启动。</p><p><strong>Hello world</strong><br
/> 下面的代码注册了一个用 Alt + H 可以激活的扩展，只要输入法被激活，无论处于中英文状态，都可以用这个热键运行这个扩展。</p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;">ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;h&quot;</span><span style="color: #66cc66;">&#41;</span>:byte<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, key.MOD1_MASK, <span style="color: #ff0000;">&quot;hello&quot;</span>, <span style="color: #ff0000;">&quot;ime.notify('hello world')&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div><p>重新启动 ibus 之后，按下方形的扩展按钮(ibus-1.2.0.20090927 版本下，方形按钮会消失，这是 ibus 的已知问题，此时通过热键仍然可以运行扩展)，可以看到一个标题为 hello 的菜单项，单击它，就可以运行扩展。<br
/><div
id="attachment_343" class="wp-caption aligncenter" style="width: 197px"><img
src="http://lihdd.net/wp-content/uploads/2010/03/ime_extension_menu.png" alt="" title="ime_extension_menu" width="187" height="301" class="size-full wp-image-343" /><p
class="wp-caption-text">输入法扩展菜单</p></div><br
/> 这里，第一个参数是按键，<code>("h"):byte()</code> 表示 h 的 ASCII 码，<code>"ime.notify('hello world')"</code> 是一段字符串表示的 lua 代码，它利用输入法提供的 <code>ime.notify</code> 方法显示了一些内容。</p><p><strong>插入系统时间</strong></p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;">ime.register_command<span style="color: #66cc66;">&#40;</span>key.Shift_R, <span style="color: #cc66cc;">0</span>, <span style="color: #ff0000;">&quot;插入系统时间&quot;</span>, <span style="color: #ff0000;">&quot;ime.commit(os.date())&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div><p>这里的 <code>ime.commit</code> 也是输入法提供的方法，用来直接向客户端程序输入文字，<code>os.date</code> 是 Lua 标准库函数。这段代码注册了一个用 右Shift 激活的插入系统时间的功能。</p><p>Lua 的标准库函数在扩展中都是可以用的，比如可以用 <code>os.execute('mousepad &#038;')</code> 在后台运行一个 mousepad。</p><p><strong>执行 Lua 代码</strong></p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;">ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'L'</span><span style="color: #66cc66;">&#41;</span>:byte<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, key.SHIFT_MASK + key.MOD1_MASK ,
  <span style="color: #ff0000;">&quot;执行 Lua 代码&quot;</span>, <span style="color: #ff0000;">&quot;ime.execute('ime.notify('..ime.get_selection()..')')&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div><p>这段代码注册了一个用 Shift + Alt + L 热键，把选中内容当做 Lua 脚本执行，并用桌面提示显示结果的扩展，这里因为有了 Shift 辅助键，所以要取大写字母 L 的 ASCII 码。其中使用方法 <code>ime.get_selection</code> 获得选定文字的内容，<code>ime.execute</code> 用来把一个字符串当做 Lua 脚本运行，双点号是字符串连接操作。</p><p>这个扩展可以比较有用，比如当选定 <code>315+23*6145</code> 这样的表达式之后，运行一下扩展就可以知道计算结果，也可以选定 <code>ime.VERSION</code> 这样的内部变量，查看其内容。甚至可以选定一段 <code>ime.register_command</code> 代码，动态添加扩展 <img
src='http://lihdd.net/wp-includes/images/smilies/happy.png' alt='(:' class='wp-smiley' /></p><p><strong>“回音”效果</strong><br
/> 不知道从什么地方开始流行这种效果，我想说明的是，声明一个函数并且在扩展中调用是可以的：</p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #b1b100;">function</span> echo_effect<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #b1b100;">local</span> s <span style="color: #66cc66;">=</span> ime.get_selection<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #b1b100;">for</span> i <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>, #s, <span style="color: #cc66cc;">3</span> <span style="color: #b1b100;">do</span> ime.commit<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>i <span style="color: #66cc66;">==</span> <span style="color: #cc66cc;">1</span> <span style="color: #b1b100;">and</span> <span style="color: #ff0000;">''</span> <span style="color: #b1b100;">or</span> <span style="color: #ff0000;">'，'</span><span style="color: #66cc66;">&#41;</span>..s:sub<span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">end</span>
<span style="color: #b1b100;">end</span>
ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'E'</span><span style="color: #66cc66;">&#41;</span>:byte<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, key.SHIFT_MASK + key.CONTROL_MASK,
  <span style="color: #ff0000;">&quot;产生回音&quot;</span>, <span style="color: #ff0000;">&quot;echo_effect()&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div><p>这里简单地使用了 3 个字节 作为步长，所以只能处理纯中文。对文字 &#8220;这是回音你懂吗&#8221; 使用这个扩展会得到：&#8221;这是回音你懂吗，是回音你懂吗，回音你懂吗，音你懂吗，你懂吗，懂吗，吗&#8221; <img
src='http://lihdd.net/wp-includes/images/smilies/sigh.png' alt=':sigh:' class='wp-smiley' /></p><p><strong>全半角切换</strong><br
/> 输入法本身没有提供全半角切换功能，但是通过扩展可以实现类似功能：</p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;">ime.second_punc_map <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>
<span style="color: #b1b100;">function</span> toggle_punc_map<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
	ime.second_punc_map, ime.punc_map <span style="color: #66cc66;">=</span> ime.punc_map, ime.second_punc_map
	ime.apply_settings<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
	ime.notify<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'已切换到'</span> .. <span style="color: #66cc66;">&#40;</span>ime.punc_map<span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'.'</span><span style="color: #66cc66;">&#93;</span> <span style="color: #b1b100;">and</span> <span style="color: #ff0000;">'全'</span> <span style="color: #b1b100;">or</span> <span style="color: #ff0000;">'半'</span><span style="color: #66cc66;">&#41;</span> ..<span style="color: #ff0000;">'角'</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #b1b100;">end</span>
ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">','</span><span style="color: #66cc66;">&#41;</span>:byte<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, key.CONTROL_MASK , <span style="color: #ff0000;">&quot;全半角切换&quot;</span>, <span style="color: #ff0000;">&quot;toggle_punc_map()&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div><p>注册了 Ctrl + 逗号 作为切换热键，并会用桌面提示显示切换结果。</p><p><strong>全双拼切换</strong><br
/> 可以仿造上例写出：</p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;">ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #ff0000;">&quot;全双拼切换&quot;</span>,
  <span style="color: #ff0000;">&quot;ime.use_double_pinyin = not ime.use_double_pinyin ime.apply_settings()&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div><p>前面填写的两个 0 表示这个扩展没有热键，你也可以再加上一句 <code>ime.notify</code>，使得切换的时候有桌面提示。</p><p><strong>对缓存的操作</strong><br
/> 缓存是存在全局的 <code>request_cache</code> 中的，可以直接对其操作：</p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #b1b100;">function</span> show_request_cache<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #b1b100;">for</span> i,v <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">pairs</span><span style="color: #66cc66;">&#40;</span>request_cache<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">do</span>
		ime.commit<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'&quot;'</span>..i..<span style="color: #ff0000;">'&quot; =&gt; &quot;'</span>..v..<span style="color: #ff0000;">'&quot;<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #b1b100;">end</span>
<span style="color: #b1b100;">end</span>
ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span> , <span style="color: #ff0000;">&quot;查看缓存&quot;</span>, <span style="color: #ff0000;">&quot;show_request_cache()&quot;</span><span style="color: #66cc66;">&#41;</span>
ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span> , <span style="color: #ff0000;">&quot;清空缓存&quot;</span>, <span style="color: #ff0000;">&quot;request_cache = {}&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div><p>其中的 <code>ime.commit</code> 方法用来向客户端插入文本，还有一个方法是 <code>ime.request</code>，用来向输入法提交一个拼音请求，比如下面这段代码片段将向输入法提交《春晓》的拼音：</p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #b1b100;">for</span> _, v <span style="color: #b1b100;">in</span> <span style="color: #b1b100;">pairs</span>
<span style="color: #66cc66;">&#123;</span><span style="color: #ff0000;">'chun mian bu jue xiao'</span>, <span style="color: #ff0000;">'chu chu wen ti niao'</span>,
 <span style="color: #ff0000;">'ye lai feng yu sheng'</span>, <span style="color: #ff0000;">'hua luo zhi duo shao'</span><span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">do</span>
	ime.request<span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span>
	ime.commit<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #b1b100;">end</span></pre></div></div><p><strong>给自己发送飞信</strong><br
/> 输入法全局配置文件默认加载了 <code>socket.http</code> 和 <code>socket.url</code> 模块，可以用它们来访问网络。</p><p>比如，下面的代码通过 <a
href="http://api.bz/">api.bz</a> 这个在线接口把选定文字内容通过飞信发送给自己：</p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #b1b100;">function</span> send_sms<span style="color: #66cc66;">&#40;</span>content<span style="color: #66cc66;">&#41;</span>
	http.TIMEOUT <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2</span>
	<span style="color: #b1b100;">local</span> res <span style="color: #66cc66;">=</span> http.request<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'https://sms.api.bz/fetion.php?username=15566119320&amp;password=nevermind&amp;sendto=15566119320&amp;message='</span>..url.escape<span style="color: #66cc66;">&#40;</span>content<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
	ime.notify<span style="color: #66cc66;">&#40;</span>res <span style="color: #b1b100;">or</span> <span style="color: #ff0000;">'飞信发送失败'</span>, content, <span style="color: #ff0000;">'info'</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #b1b100;">end</span>
&nbsp;
ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'m'</span><span style="color: #66cc66;">&#41;</span>:byte<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, key.CONTROL_MASK + key.MOD1_MASK, <span style="color: #ff0000;">&quot;飞信发送&quot;</span>, <span style="color: #ff0000;">&quot;send_sms(ime.get_selection())&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div><p>以上填写的飞信用户名和密码皆为虚构，实际用的时候需要改一下。</p><p><strong>简繁体转换和翻译</strong><br
/> 使用 Google API 来翻译文字，从简体中文翻译成繁体中文就实现了转换成繁体 <img
src='http://lihdd.net/wp-includes/images/smilies/happy.png' alt='(:' class='wp-smiley' /></p><div
class="wp_syntax"><div
class="code"><pre class="lua" style="font-family:monospace;"><span style="color: #b1b100;">function</span> google_translate<span style="color: #66cc66;">&#40;</span>text, langpair<span style="color: #66cc66;">&#41;</span>
	<span style="color: #b1b100;">local</span> url <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&amp;q='</span>..url.escape<span style="color: #66cc66;">&#40;</span>text<span style="color: #66cc66;">&#41;</span>..<span style="color: #ff0000;">'&amp;langpair='</span>..url.escape<span style="color: #66cc66;">&#40;</span>langpair<span style="color: #66cc66;">&#41;</span>
	http.TIMEOUT <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>
	<span style="color: #b1b100;">local</span> res <span style="color: #66cc66;">=</span> http.request<span style="color: #66cc66;">&#40;</span>url<span style="color: #66cc66;">&#41;</span>
	<span style="color: #b1b100;">if</span> res <span style="color: #b1b100;">then</span> res <span style="color: #66cc66;">=</span> res:match<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'&quot;translatedText&quot;:&quot;(.-)&quot;}'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">end</span>
	<span style="color: #b1b100;">return</span> <span style="color: #b1b100;">tostring</span><span style="color: #66cc66;">&#40;</span>res <span style="color: #b1b100;">or</span> text<span style="color: #66cc66;">&#41;</span>
<span style="color: #b1b100;">end</span>
&nbsp;
ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'t'</span><span style="color: #66cc66;">&#41;</span>:byte<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, key.CONTROL_MASK + key.MOD1_MASK ,
  <span style="color: #ff0000;">&quot;转换成繁体&quot;</span>, <span style="color: #ff0000;">&quot;ime.commit(google_translate(ime.get_selection(), 'zh-CN|zh-TW'))&quot;</span><span style="color: #66cc66;">&#41;</span>
ime.register_command<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'e'</span><span style="color: #66cc66;">&#41;</span>:byte<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, key.CONTROL_MASK + key.MOD1_MASK ,
  <span style="color: #ff0000;">&quot;翻译成英文&quot;</span>, <span style="color: #ff0000;">&quot;ime.commit(google_translate(ime.get_selection(), 'zh-CN|en'))&quot;</span><span style="color: #66cc66;">&#41;</span></pre></div></div><p><strong>写在最后</strong></p><p>这是一个悲剧。</p><p>Lua 作者根本不相信多线程，原因是现在的主流语言中连 <code>a = a + 1</code> 都不是原子的，谈什么多线程呢？</p><p>我曾经做过一些尝试，确实让程序多线程地执行 Lua 代码，又共享一些全局数据，不是轻松的事情。我也想到一些解决办法，但是都太麻烦了，于是就偷懒不管那么多了。</p><p>这有什么影响呢？影响就是目前输入法执行 Lua 代码是单线程的，扩展中的 Lua 代码会造成阻塞。在有网络请求等操作的时候，要注意控制超时，否则程序可能被认为没有响应了，各种死法都有可能出现 <img
src='http://lihdd.net/wp-includes/images/smilies/hmm.png' alt='.~.' class='wp-smiley' /></p><p>目前输入法的自由程度到了可以随意 AOE，比如用 <code>os.execute('pkill Xorg')</code>，就可以干掉许多无辜者。正所谓权力越大，责任越大。到底安全与否，就看扩展中的代码自我约束得如何了 <img
src='http://lihdd.net/wp-includes/images/smilies/meeh.png' alt='._.' class='wp-smiley' /></p> ]]></content:encoded> <wfw:commentRss>http://lihdd.net/ibus-sogoupycc-extensions/feed/</wfw:commentRss> <slash:comments>15</slash:comments> </item> <item><title>Linux下VirtualBox中运行真实磁盘上的操作系统</title><link>http://lihdd.net/host-os-in-virtualbox/</link> <comments>http://lihdd.net/host-os-in-virtualbox/#comments</comments> <pubDate>Sun, 01 Nov 2009 10:55:43 +0000</pubDate> <dc:creator>quark</dc:creator> <category><![CDATA[Config]]></category> <category><![CDATA[VirtualBox]]></category><guid
isPermaLink="false">http://lihdd.net/?p=264</guid> <description><![CDATA[虽然各种虚拟机都会说把真实磁盘的分直接给虚拟机用会如何如何有风险，但是好处也是显而易见的：可以选择是直接运行或是在Linux下的虚拟机运行某个操作系统，同时节约了磁盘空间和同步时间。 我这样做已经有一段时间了，除了Windows会发现硬件改变要求重新激活之外，还没有发现问题 :-) 但是周围的同学似乎觉得这样做比较麻烦，很有风险，或者无从下手。其实比较简单也没有这么可怕啦，下面普及一下： 首先要创建一个特殊的虚拟磁盘文件，指向真实磁盘的某个分区，这可以参考VirtualBox用户手册中的9.10章节。简单来说： 注：由于这些命令需要/dev/sda的读写权限，以后虚拟机在使用这些vmdk文件的时候，也需要这样的权限，建议把当前用户加在disk组里解决问题：gpasswd disk -a `whoami` # 把整个sda映射出去 VBoxManage internalcommands createrawvmdk -filename /path/to/sda.vmdk -rawdisk /dev/sda # 或者，处于安全考虑，只允许sda1和sda5在虚拟机里用到，虚拟机里仍然可以知道有其他分区存在，但是不能读写 VBoxManage internalcommands createrawvmdk -filename /path/to/sda1_and_sda5.vmdk -rawdisk /dev/sda -partitions 1,5 -relative 这里的relative参数保证了创建出来的虚拟磁盘文件的可移植性，在sda1或者sda5的实际位置和大小变化后也可以用，没有这个参数的话到时候就要重新创建一遍vmdk文件了。 创建好可能会产生多个文件：a.vmdk和a-pt.vmdk，实际在虚拟机里使用前一个文件，后一个需要存在。 这样就基本完成啦，不过如果你打开这样配置的虚拟机后就会发现一个问题，MBR在这种默认情况下是和真实硬盘相同的，GRUB是和主机相同的，如果GRUB配置文件所在分区虚拟机没有访问权限的话，就会引导不能 当然，虚拟机里的MBR可以设置得和主机不一样，不过操作起来比较麻烦，据说也有一定的危险。安全的做法是使用携带特定配置文件的GRUB的Live CD镜像来引导，下面就开始做这样一张CD镜像（适用于GRUB 1.0）： # 准备一个目录 mkdir -p iso/boot/grub # 复制必要文件 cp /usr/lib/grub/*-pc/stage2_eltorito /boot/grub/menu.lst iso/boot/grub # 编辑复制过来的 menu.lst ，去掉其中的 savedefault ，... vim iso/boot/grub/menu.lst [...]]]></description> <content:encoded><![CDATA[<p>虽然各种虚拟机都会说把真实磁盘的分直接给虚拟机用会如何如何有风险，但是好处也是显而易见的：可以选择是直接运行或是在Linux下的虚拟机运行某个操作系统，同时节约了磁盘空间和同步时间。</p><p>我这样做已经有一段时间了，除了Windows会发现硬件改变要求重新激活之外，还没有发现问题 :-) 但是周围的同学似乎觉得这样做比较麻烦，很有风险，或者无从下手。其实比较简单也没有这么可怕啦，下面普及一下：</p><p><span
id="more-264"></span>首先要创建一个特殊的虚拟磁盘文件，指向真实磁盘的某个分区，这可以参考VirtualBox用户手册中的9.10章节。简单来说：</p><p>注：由于这些命令需要/dev/sda的读写权限，以后虚拟机在使用这些vmdk文件的时候，也需要这样的权限，建议把当前用户加在disk组里解决问题：<code>gpasswd disk -a `whoami`</code></p><div
class="wp_syntax"><div
class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># 把整个sda映射出去</span>
VBoxManage internalcommands createrawvmdk <span style="color: #660033;">-filename</span> <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>sda.vmdk <span style="color: #660033;">-rawdisk</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda
<span style="color: #666666; font-style: italic;"># 或者，处于安全考虑，只允许sda1和sda5在虚拟机里用到，虚拟机里仍然可以知道有其他分区存在，但是不能读写</span>
VBoxManage internalcommands createrawvmdk <span style="color: #660033;">-filename</span> <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>sda1_and_sda5.vmdk <span style="color: #660033;">-rawdisk</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda <span style="color: #660033;">-partitions</span> <span style="color: #000000;">1</span>,<span style="color: #000000;">5</span> <span style="color: #660033;">-relative</span></pre></div></div><p>这里的relative参数保证了创建出来的虚拟磁盘文件的可移植性，在sda1或者sda5的实际位置和大小变化后也可以用，没有这个参数的话到时候就要重新创建一遍vmdk文件了。<br
/> 创建好可能会产生多个文件：a.vmdk和a-pt.vmdk，实际在虚拟机里使用前一个文件，后一个需要存在。</p><p>这样就基本完成啦，不过如果你打开这样配置的虚拟机后就会发现一个问题，MBR在这种默认情况下是和真实硬盘相同的，GRUB是和主机相同的，如果GRUB配置文件所在分区虚拟机没有访问权限的话，就会引导不能 <img
src='http://lihdd.net/wp-includes/images/smilies/icon_eek.gif' alt='8-O' class='wp-smiley' /></p><p>当然，虚拟机里的MBR可以设置得和主机不一样，不过操作起来比较麻烦，据说也有一定的危险。安全的做法是使用携带特定配置文件的GRUB的Live CD镜像来引导，下面就开始做这样一张CD镜像（适用于GRUB 1.0）：</p><div
class="wp_syntax"><div
class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># 准备一个目录</span>
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> iso<span style="color: #000000; font-weight: bold;">/</span>boot<span style="color: #000000; font-weight: bold;">/</span>grub
<span style="color: #666666; font-style: italic;"># 复制必要文件</span>
<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>grub<span style="color: #000000; font-weight: bold;">/*</span>-pc<span style="color: #000000; font-weight: bold;">/</span>stage2_eltorito <span style="color: #000000; font-weight: bold;">/</span>boot<span style="color: #000000; font-weight: bold;">/</span>grub<span style="color: #000000; font-weight: bold;">/</span>menu.lst iso<span style="color: #000000; font-weight: bold;">/</span>boot<span style="color: #000000; font-weight: bold;">/</span>grub
<span style="color: #666666; font-style: italic;"># 编辑复制过来的 menu.lst ，去掉其中的 savedefault ，...</span>
<span style="color: #c20cb9; font-weight: bold;">vim</span> iso<span style="color: #000000; font-weight: bold;">/</span>boot<span style="color: #000000; font-weight: bold;">/</span>grub<span style="color: #000000; font-weight: bold;">/</span>menu.lst
<span style="color: #666666; font-style: italic;"># 创建iso</span>
mkisofs <span style="color: #660033;">-R</span> <span style="color: #660033;">-b</span> boot<span style="color: #000000; font-weight: bold;">/</span>grub<span style="color: #000000; font-weight: bold;">/</span>stage2_eltorito <span style="color: #660033;">-no-emul-boot</span> <span style="color: #660033;">-boot-load-size</span> <span style="color: #000000;">4</span> <span style="color: #660033;">-boot-info-table</span> <span style="color: #660033;">-o</span> grub-custom.iso iso</pre></div></div><p>在虚拟机里设置使用这张iso引导之后，就大功告成啦～</p><p><img
class="aligncenter size-medium wp-image-268" title="host_windows_7_in_virtualbox" src="http://lihdd.net/wp-content/uploads/2009/11/host_windows_7_in_virtualbox-300x227.png" alt="host_windows_7_in_virtualbox" width="300" height="227" /></p> ]]></content:encoded> <wfw:commentRss>http://lihdd.net/host-os-in-virtualbox/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: lihdd.net @ 2012-05-19 14:12:44 -->
