<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><!-- this stylesheet will later on be added by lfparser automatically: -->
  
  <style type="text/css">
<!--
  pre { font-family:monospace,Courier }
  pre.code { font-family:monospace,Courier;background-color:#aedbe8; }
  p.code { width:80%; alignment:center; background-color:#aedbe8; 
        border-style:none; border-width:medium; border-color:#aedbe8; 
        padding:0.1cm ; text-align:left }
-->
  </style></head>
<body>
<h1>LF Tip:通过网络完全复制你的电脑</h1>

<h4>ArticleCategory: [Choose a category, translators: do not translate
this, see list below for available categories]</h4>

UNIX Basics
<h4>AuthorImage:[Here we need a little image from you]</h4>

<img alt="this is me" src="../../common/images2/GerritRenker.jpg" width="175" height="213">

<h4>TranslationInfo:[Author + translation history. mailto: or
http://homepage]</h4>

<p>original in en <a href="nospam:gerrit.renker(at)gmx.de">Gerrit
Renker</a></p>
<p>en to zh_CN <a href="nospam:daxiawj(Q)gmail.com">汪  君</a></p>

<h4>AboutTheAuthor:[A small biography about the author]</h4>
2001年获得计算机科学的学位。

<h4>Abstract:[Here you write a little summary]</h4>

当你需要从一台电脑复制数据到另一台电脑上去的时候,本文所讲基于网络的且安全、简易、有效的方法就派上用场了。

<h4>ArticleIllustration:[One image that will end up at the top of the article]</h4>


<img src="../../common/images2/article370.png" alt="[Illustration]" hspace="10"  width="136" height="150">

<h4>ArticleBody:[The main part of the article]</h4>


<h2>提要</h2>

尽管克隆动物(“多莉羊“)甚至人类胚胎的研究依然是一个充满争议和风险的领域,而掌握一些关于“克隆”电脑的知识不但没有害(正确的操作为前提),反而会使你仔细书写配置脚本的能力得到提升。
根据摩尔定律以及计算机生产的快速进程,我们在使用电脑时很可能会遇到需要“克隆”我们的电脑的情况——不管是台式机被笔记本取代还是换一台更快的机子。而我们就需要将电脑A 上的<i>所有文件分区</i> 复制到电脑B 上而且使它正常工作。通常有两种做法:一种就是直接打开机箱,然后将硬盘换掉就可以了——但是但打开机箱通常意味着失去质保,而且这通常很危险——一个没有经验的用户可能会给硬件带来机械的或者电子上的损伤。另一种方法要求两台电脑都有网卡(现在即使是在家用电脑中通常也满足),这种在下面会详细介绍的方法更安全。

<p>
下面描述的所有方法都是建立在网络连接的基础上,即,需要在“<i>源</i>”电脑(就是那台有数据要被复制的电脑)和“<i>目标</i>”电脑(就是需要数据的那台电脑)之间有网络连接。可以直接通过集线器连接,或者通过<i>特殊连接线(crossover cable)</i>将 两张网卡连接起来(注意:一般的网线是不行的)。
对目标电脑来说,需要一张Live-CD(如Knoppix 或 LNX-BBC)或一个最小安装,以保证可对网卡进行操作而且使<tt>ssh</tt> 和/或 <tt>netcat</tt>能用。甚至有的软盘上的系统(就像我用<tt>tomsrtb</tt>也能很好工作),而且如果你想安装另一个全新的发行版,这是一个很不错的选择。两台电脑的IP 要在同一个网段,以便他们能相互进行“会话”,如上图。

</p>


<h2>可能的方案 </h2>



<p>
通过基本的准备,有几种方法来进行复制:
</p>


<ul>
<li>通过 <tt>dd</tt>复制</li>
<li><tt>tar / cpio</tt> 管道</li>
<li><tt>rsync </tt> </li>
<li><tt>dump</tt> 和 <tt>restore</tt></li>
</ul>


如果你的两块硬盘不是同样的型号和大小,第一种方法是不可行的或非常复杂的(复制iso 镜像(<tt>dd if=/dev/cdrom of=the.iso</tt>)或者软盘通过<tt>dd</tt>很不错。<a href="../../common/src2/article370/diskcopy.txt">这里 (diskcopy 脚本)</a>是一个使用<tt>dd</tt>的脚本<tt>diskcopy</tt>)。使用<tt>dd</tt>的另一个缺点是:你未使用的空间也会被复制,从而浪费很多无谓的时间。
通过<tt>tar</tt> 和 <tt>cpio</tt>的管道会花费很长的时间(长达数小时),而且对文件名和符号连接会有一些限制,在<tt>/dev</tt>时会被阻塞,等等。因此,不推荐此法。
如果你的源电脑和目标电脑上的文件系统不一样,那么<b><tt>rsync(1)</tt></b>可能是最好的选择。这只需要有<tt>ssh</tt>正常的运行且文件传输协议正常。
而且它还有针对设备文件的<tt>-D</tt>选项以及其他很多针对各种场合各种需求的选项。这是对每天的备份、作镜像或其他任务来说很有用的一个工具,它的手册上还有很多值得学习的例子。通过<tt>rsync</tt>复制的例子在[<a href="#key-2">1</a>]可以找到。<br><br> 
这里,我们使用<tt>dump</tt> 和 <tt>restore</tt>,这样还可以重新分配整个文件系统。这是一个快速、有效且可以通过最少的努力达到我们的目的——简直是理想的解决方法。
我需要操作这个过程两次,因为有两台目标电脑。两台目标电脑都能很好的启动、工作,而且复制那些成G 的数据大概只花了我一个小时。这个方法要求源电脑和目标电脑有同样的文件系统。在此,我们假定是<tt>ext2</tt> 或<tt>ext3</tt>,因为这是现在最广泛的使用的两种文件系统()(参见 <a href="#sec:Other-systems">下面</a>).


<h2>配置ssh</h2>

一旦配置好最小安装的系统或者Live-CD,下一步就是配置<tt>ssh</tt>(如果你没有像下面描述的使用<tt>netcat</tt>来传送文件)。这需要源电脑运行<tt>sshd</tt>(the secure shell daemon)。如果不确定,请检查 <tt>/etc/init.d/</tt>。在目标电脑上输入(root帐户):
<pre class="code">ssh-keygen -t rsa</pre>

为简便起见,不要输入密码。公钥就会保存在<tt>/root/.ssh/id_rsa.pub</tt>文件里。复制此文件到源电脑上


<pre class="code">scp /root/.ssh/id_rsa   SourcePC:/tmp</pre>


在此 <tt>SourcePC</tt> 是你源电脑的IP 地址,当提示你是否确认时,输入完整的“<tt>yes</tt>”(单独的“<tt>y</tt>” 有时会不行)。在源电脑上你还会被要求输入root 的密码。现在把目标电脑加入你源电脑的可信任网络节点里去


<pre class="code">cat /tmp/id_rsa.pub &gt;&gt; /root/.ssh/authorized_keys</pre>



为检查是否成功完成,重复上面的复制命令,应该不会再要求你输入密码了!

<h2> 在目标电脑上创建文件系统</h2>



<p>
通常第一步都是对你的硬盘分区,然后创建<tt>ext2/ext3</tt>文件系统。
ext3 的需要在<tt>mke2fs</tt> 命令里加一个<tt>-j</tt> (journalling)的选项(需要内核对<tt>ext3</tt>的支持)。你甚至可以将<tt>ext2</tt>的分区转化为 <tt>ext3</tt>的, 参见<b><tt>tune2fs(8</tt>)</b>。 
假设我们的源电脑上有如下的分区:

</p>

<table align="center" bgcolor="#000000" border="0" cellpadding="2" cellspacing="2" width="56%">
  <tbody>
    <tr>
      <th bgcolor="#ffffff" valign="top">Filesystem</th>
      <th bgcolor="#ffffff" valign="top">Size</th>
      <th bgcolor="#ffffff" valign="top">Used</th>
      <th bgcolor="#ffffff" valign="top">Use%</th>
      <th bgcolor="#ffffff" valign="top">Mounted on</th>

    </tr>
    <tr>
      <td bgcolor="#ffffff" valign="top">/dev/hda3
      </td>
      <td bgcolor="#ffffff" valign="top">2.7G</td>
      <td bgcolor="#ffffff" valign="top">552M</td>
      <td bgcolor="#ffffff" valign="top">22%</td>
      <td bgcolor="#ffffff" valign="top">/</td>
    </tr>
    <tr>
      <td bgcolor="#ffffff" valign="top">/dev/hda5
      </td>
      <td bgcolor="#ffffff" valign="top">7.8G <br>
      </td>
      <td bgcolor="#ffffff" valign="top">1.6G</td>
      <td bgcolor="#ffffff" valign="top">22%</td>
      <td bgcolor="#ffffff" valign="top">/usr</td>
    </tr>
    <tr>
      <td bgcolor="#ffffff" valign="top">/dev/hda7
      </td>
      <td bgcolor="#ffffff" valign="top">6.3G</td>
      <td bgcolor="#ffffff" valign="top">1.7G</td>
      <td bgcolor="#ffffff" valign="top">28%</td>
      <td bgcolor="#ffffff" valign="top">/usr/share</td>
    </tr>
    <tr>
      <td bgcolor="#ffffff" valign="top">/dev/hda8
      </td>
      <td bgcolor="#ffffff" valign="top">3.4G</td>
      <td bgcolor="#ffffff" valign="top">601M</td>
      <td bgcolor="#ffffff" valign="top">19%</td>
      <td bgcolor="#ffffff" valign="top">/home</td>
    </tr>
    <tr>
      <td bgcolor="#ffffff" valign="top">/dev/hda12
      </td>
      <td bgcolor="#ffffff" valign="top">5.3G</td>
      <td bgcolor="#ffffff" valign="top">1.9G</td>
      <td bgcolor="#ffffff" valign="top">37%</td>
      <td bgcolor="#ffffff" valign="top"> /opt</td>
    </tr>
    <tr>
      <td bgcolor="#ffffff" valign="top">/dev/hda1
      </td>
      <td bgcolor="#ffffff" valign="top">587M</td>
      <td bgcolor="#ffffff" valign="top">70M</td>
      <td bgcolor="#ffffff" valign="top">13% <br>
      </td>
      <td bgcolor="#ffffff" valign="top">/var/backup</td>
    </tr>
  </tbody>
</table>


<p>
我推荐大家一定要做一些分区,否则,文件系统的错误使用或者硬盘磁道的一点损坏就会完全破坏掉你<em>所有的</em>数据。而且根据Murphy 定律,在事先没有做好硬盘分区而是直接使用整块硬盘的时候,这通常就会发生。我最近就遇到过这样的情况,如果事先没有做好分区的话,就会由于主分区的一点问题而丢失掉我的所有数据。上面的文件表明<tt>/usr</tt> 分区增长的太大了,所以<tt>/usr/share</tt>必须被加入。是该换一个大点的硬盘的时候了。 

</p>

在目标电脑上,使用<tt>parted</tt> (推荐) 或者你喜爱的分区工具(Qtparted 是一个很好的图形界面的工具,据说是Partition Magic 克隆版)。创建的分区不能比源电脑上对应的分区小。另外,别忘了 swap 分区。保存好分区表,在刚创建的分区上创建文件系统,可以使用

<pre class="code">mke2fs -j -L &lt;label&gt; /dev/xxx</pre>


这里 <tt>xxx</tt> 是你的分区名,然后用<tt>&lt;label&gt;</tt>设置卷标号。我经常使用如 “<tt>/usr</tt>”一类的作为卷标。你也可以通过<tt><b>tune2fs(8)</b></tt>来设置各种任务,比如周期性的文件系统检查。


<h1>传送文件系统 </h1>



首先你需要加载所有新创建的分区,我们先从主文件系统(“/”)开始,其他的按顺序依次进行。当然可以将源电脑上的两个分区整合到目标电脑上的一个分区上去,事实上,这正是我们要做的——将上例中<tt>/usr/</tt> 和 <tt>/usr/share</tt>合并为一个分区。
我们加载未来的主文件系统
<pre class="code">mount /dev/xxx   /mnt</pre>
在复制的时候,转到目标目录里面去是很必要的
<pre class="code">cd /mnt</pre>
在目标电脑上键入
<pre class="code">ssh sourcePC 'dump -0 -f - /' | restore -r -f -</pre>
这里 <tt>targetPC</tt> 是你目标电脑的 IP 地址。参数“<tt>-0</tt>” 表示完全备份,“<tt>-f -</tt>”表示使用<tt>stdin</tt>/<tt>stdout</tt>做为文件描述符,而“<tt>-r</tt>”意思是指示 restore 去重新创建通过网络传送的文件系统到目标电脑上去。更多内容请参考<b><tt>dump(8)</tt></b> 和 <b><tt>restore(8)</tt></b>。
下面你看到的是传送主文件系统的输出。<br>



<pre class="code">$ ssh 10.42.3.42 'dump -0 -f - /' | restore -r -f -
DUMP: Date of this level 0 dump: Tue Feb 22 15:50:12 2005
DUMP: Dumping /dev/hda3 (/) to standard output
DUMP: Label: debian
DUMP: Writing 10 Kilobyte records
DUMP: mapping (Pass I) [regular files]
DUMP: mapping (Pass II) [directories]
DUMP: estimated 547312 blocks.
DUMP: Volume 1 started with block 1 at: Tue Feb 22 15:50:14 2005
DUMP: dumping (Pass III) [directories]
DUMP: dumping (Pass IV) [regular files]
DUMP: Volume 1 completed at: Tue Feb 22 15:51:43 2005
DUMP: Volume 1 546590 blocks (533.78MB)
DUMP: Volume 1 took 0:01:29
DUMP: Volume 1 transfer rate: 6141 kB/s
DUMP: 546590 blocks (533.78MB)
DUMP: finished in 89 seconds, throughput 6141 kBytes/sec
DUMP: Date of this level 0 dump: Tue Feb 22 15:50:12 2005
DUMP: Date this dump completed: Tue Feb 22 15:51:43 2005
DUMP: Average transfer rate: 6141 kB/s
DUMP: DUMP IS DONE
</pre>
Restore 通常会创建一个名叫 <tt>restoresymtable</tt>的文件,如果你确信在文件系统重建过程中没有错误发生,你可以将这个文件删掉。
完成主文件系统的复制,下面我们依次完成其他子分区的复制。从 <tt>/usr</tt>开始吧(假定你现在的工作目录是未来的主文件系统)。

<pre class="code">mount /dev/xxx  ./usr

cd ./usr

ssh targetPC 'dump -0 -f - /usr' | restore -r -f -
</pre>

这个 mount-cd-dump/restore 循环现在可以对你的所有目录重复进行操作。上面提到的对 <tt>/usr/share</tt>(在源电脑上是个独立的分区)的处理, 可以简单的通过切换目录到 <tt>./usr/share</tt> (注意这个“.”),然后简单的重复

<pre class="code">ssh targetPC 'dump -0 -f - /usr/share' | restore -r -f -</pre>


在目标文件系统有你要 restore 的文件时,Restore 会报错。通过 ssh 复制一整台电脑的数据会花费大概一个小时和100MB 网卡(也许还要特殊数据线crossover cable)。
<p>
<strong>注意: </strong>转储文件系统时,并不需要加载,你可以仅仅通过给定 <i>分区名</i>, 如 <big><tt>/dev/hda6</tt></big>,而非加载后的目录名。 
</p>




<h1>另一个选择 &nbsp;<tt>netcat</tt> </h1>


<p>

另一个种方法不使用 ssh,而使用 <tt>netcat(1)</tt>, netcat 简称 nc. Netcat 是一把非常简单易用的基于 TCP/IP 协议(C/S模型的)的“瑞士军刀”,它能允许我们通过网络创建管道(pipe)。上面的例子只需像下面一样改一点点东西就可以用了。我们假设加载在 <big><tt>/var/backup</tt></big> 上的分区是我们要通过<big><tt>dump/restore</tt></big> 来传送的。
 

</p>

在接收端(<em>目标电脑</em>),创建一个 <tt>netcat</tt> 的监听例程(<tt>-l</tt>),这个监听例程将管道输出到 <tt>restore</tt>。 


<pre class="code">nc -l -p 2000 -q 1 | restore -r -f -</pre>


在 <em>源电脑</em>, 创建另一个 <tt>netcat</tt> 的例程,这个例程将它从管道里得到的输入发给目标电脑,这里 <tt>target-IP</tt> 是目标电脑的 IP 地址。

<pre class="code">dump -0 -f - /var/backup | nc &lt;target-ip&gt;   2000</pre>

<tt>-q</tt> 选项是让 <tt>nc</tt> 在到达文件结束(EOF)时停止运行,但我是手动结束 nc 的。不过,仍然建议大家使用<tt>ssh</tt> 。




<h1> 后期工作 </h1>


恭喜你!到目前为止,你已经成功的复制了你的系统。剩下的问题就是让它好好的工作起来。首先,就是更新你的 <tt>/etc/fstab</tt> 文件。如果你的目标电脑的 IP 地址变了,那么网络配置文件 (Debian 里面是<tt>/etc/hosts</tt>和<tt>/etc/network/interfaces</tt> 两个文件)。然后就是非常重要的 <i>启动配置</i> 文件,这个是无论如何都需要更新的。对<tt>lilo</tt> 来说, 就是需要修改 <tt>/etc/lilo.conf</tt>文件(特别是 <tt>root=...</tt> 选项) 然后运行 <tt>lilo -v</tt>)。 对 grub 来说, 编辑 <tt>/boot/grub/menu.lst</tt>(或 <tt>/boot/grub/grub.conf</tt>,取决于哪个是符号链接)然后运行 <tt>grub</tt>,

<pre class="code">grub&gt; root (hd0,xxx)

... filesystem is ...

grub&gt; setup (hd0)

... lots of output here

grub&gt; quit 
</pre>

或运行 <tt>grub-install /dev/xxx</tt> 其中 <tt>xxx</tt> 是你的硬盘。在此,检查你的<tt>root (hdn,xx)</tt> ,并加上 <tt>root=/dev/xxx</tt> 的设置。 

<p>
可能的情况是,你现在复制好的电脑有了一些更好的硬件,因此可能需要修改你 <i> 内核的配置 </i>。如果你的系统有很多预先配置的好的模块(如 RedHat, SuSe, Mandrake, Fedora ...) ,那么很可能已经有了合适的模块(module)了。否则, <tt>lspci -vv</tt> 并自己重新编译内核。如果你的显卡不同了,更新 <tt>/etc/X11/XF86Config-4</tt>(或者在 RH/Fedora 中<tt>xorg.conf</tt> )。如果可能,启动到运行级别 3 并使用工具来配置你的 X。在 debian 里,一些调查是必要的,我就很幸运的发现我的驱动从<tt>r128</tt> 变为了<tt>radeon</tt>。

</p>

<a name="sec:Other-systems"></a>
<h2>其他系统</h2>


<p>
这篇文章讲解了克隆 <tt>ext2/ext3</tt> 文件系统的全过程。很多类似的命令可以在很多其他的 *nix 系统上,诸如 FreeBSD, HP-UX, IRIX 等也提供 <tt>dump/restore</tt> 这些命令; 在 Solaris 中,这被称作 <tt>ufsdump/ufsrestore</tt>。当然也有的文件系统不提供 dump 功能,例如 ReiserFS,这种情况就最好使用 <tt>rsync</tt>了。关于使用 <tt>rsync</tt> 成功复制Linux 系统的问题,参见 [<a href="#key-2">1</a>]。

</p>

 
<h2>References </h2>

<dl compact="compact">
<dt><a name="key-2">[1]</a>
<i>''<a href="http://www.linuxgazette.com/issue83/okopnik.html">Replicating a Linux System - Yet Another Method</a></i>.'' Ben Okopnik, Linux Gazette Issue 83, October 2002.
</dt>
</dl>


<!-- vim: set sw=2 ts=2 et tw=74: -->
</body></html>