第四章 磁盘以及其他存储界质的使用

“在一个清晰的磁盘上你可以始终进行搜寻”

 

当你安装或者升级你的系统时,你需要在你的磁盘上做大量的工作。你必须在你的磁盘上创建文件系统使得文件能够存储在上面并且为你的系统的不同部分保留空间。

这一章叙述了所有这些初始的工作。通常,一旦你安装好系统,你就不必再从头开始这个工作,除非使用了软盘。如果你需要新增一个磁盘或想调整你的磁盘使用情况,你将需要再次阅读本章内容。

管理磁盘的基本任务有:

。格式化你的磁盘。要做各方面的事情来准备使用磁盘,如检查坏扇区。(如今对于许多硬盘来说已不需要格式化了。)

。如果你想将硬盘用于几种用途并且不想它们之间有任何的干扰,就需要对硬盘进行分区。分区的一个理由就是在同一个硬盘上安装不同的操作系统。另一个理由是将用户文件与系统文件分隔开来,这样做能简化备份并且能防止系统文件的毁坏。

。在每个硬盘上或分区上制作适当类型的文件系统。只有创建了文件系统,磁盘才对Linux可用;在上面文件才可被建立和访问。

。根据需要,自动地或手工地加载各种文件系统以形成单个树结构。(手工加载的文件系统通常也需要手工卸载下来。)

 

第五章包含了有关虚拟内存以及磁盘缓冲的信息,在使用磁盘时你同样要知道。

 

两种设备

UNIX,以及Linux,能够识别两种不同的设备:随机访问块设备(如磁盘)以及字符设备(如磁带和串行线路),其中有些设备是连续设备,有些是随机访问的设备。在文件系统中每种支持的设备都以设备文件的形式表示。当你读写一个设备文件时,数据就会从它所代表的设备中取进或写出。这样就不需要特殊的程序(也不需要特别的编程方法,如获取中断或轮流查询一条串行线路)来访问设备了;例如,要打印一个文件,只要键入:

$ cat filename > /dev/lp1

$

文件的内容就会在打印机上打印出来了(当然,文件的内容打印机应能识别)。然而,因为几个人同时将他们的文件输出到打印机不是个好主意,人们一般使用特殊的程序来打印他们的文件(通常使用lpr)。这个程序使得在同一时刻只有一个文件被打印出,并在打印机一旦打印完前一个文件就能自动地将文件发送到打印机。实际上,人们一点都不需要关心设备文件的。

由于在文件系统中设备是以文件的形式表示出的(在/dev目录中),使用命令ls就很容易看到有那些设备文件存在。在ls –l的输出中,第一栏含有文件的类型和权限。例如,查看我的系统上的串行设备:

$ ls -l /dev/cua0

crw-rw-rw- 1 root uucp 5, 64 Nov 30 1993 /dev/cua0

$

第一栏的第一个字符,也即,上面crw-rw-rw-中的‘c’,告诉一个见多识广的用户该文件的类型,在这个例子中是一个字符形设备。对于普通文件,第一个字符是‘-’,目录是‘d’,块设备是‘b’;详细信息请参见lsman page

可以看出,即使设备本身并没有被安装,所有的设备文件依然是存在的。所以,你有一个/dev/sda文件,并不意味着你就真的有一个SCSI硬盘。有了所有设备文件后,就使得安装简单化,很容易再增加新硬件(不再需要对新硬件找出正确的参数并为它创建设备文件了)。

 

硬盘

这个部分介绍有关于硬盘的术语。如果你已经知道这些术语和概念,你可以跳过本小节。

4-1是硬盘内重要部分的示意图。一个硬盘是由一个或多个圆盘组成,[1] 这些盘的单面或双面上覆盖着用于记录数据的一层磁性物质。在每个面上,都有一个读写头用于读取或改变记录着的数据。这些圆盘绕着同一个轴旋转;典型的旋转速度是每分钟3600转,而高性能的硬盘有更高的转速。读写头沿着圆盘的半径方向移动;这个移动加上圆盘的旋转使得读写头能访问到圆盘表面的所有部分。

处理器(CPU)与实际磁盘通过磁盘控制器进行通信。这使得计算机的其余部分不需要知道如何使用驱动器,因为不同硬盘类型的控制器能够使用相同的接口与计算机的其它部分通信。因此,计算机只需说“咳,硬盘,给我想要的数据”,而不是又长又复杂的电子信号来移动读写头到适当的方位并等待正确的位置位于读写头下以及做所有其它烦琐而又必需的事情。(实际上,到控制器的接口仍然很复杂,但相比之下已简单多了。)控制器也能做些其它的事情,例如缓冲或坏扇区自动替换等。

以上就是一个人要对硬件有所理解的全部了。当然还有许多其它的工作,比如马达旋转圆盘并移动读写头,以及控制机械部分动作的电子线路,但这与理解硬盘工作原理几乎是无关的。

圆盘表面通常划分成许多的同心圆环,称作磁道(tracks,并且这些圆环再被分为扇区(sectors)。这种分割是用于在硬盘上指定位置以及为文件分配硬盘空间的。为了在硬盘上找到指定的地方,人们可以说“面3、磁道5、扇区7”。通常,所有磁道上的扇区数是相同的,但有些硬盘在在外磁道上放置了更多的扇区(所有扇区的物理面积大小是一样的,因此在稍长的外磁道上可以放置更多的扇区)。典型地,一个扇区能容纳512字节的数据。硬盘本身不能处理比一个扇区更少的数据量。

4-1.硬盘原理图

以同样的方法,每个面也被分成磁道(及扇区)。这意味着当一个面的读写头位于一个磁道上时,其它面上的读写头也位于相应的磁道上。所有这些相关磁道总合起来就叫作一个柱面(cylinder)。从一个磁道(柱面)移动到另一个磁道(柱面)是需要时间的,所以常把要一起访问的数据放在一起(如,一个文件)一个柱面上,这样就不用移动读写头来读取所有的数据,因此可以提高性能。并不是总能够象这样来放置文件的;在磁盘上几个地方存储数据的文件被称为有碎片的(fragmented)。

面数(或磁头数,这两个是一回事)、柱面数以及扇区数有各种大小;它们的数值的说明被称为硬盘的规格参数(geometry)。规格参数通常存储在一个特殊的、由电池供电的称作CMOS RAM的内存处,在操作系统启动或驱动程序初始化期间,操作系统能够从它那里获得这些参数。

不幸的是,BIOS [2] 有一个设计限制,这使得它不能在CMOS RAM中指定大于1024个磁道的数值,对于一个大容量硬盘来说这个数也太小了。为了克服这个缺点,硬盘控制器会曲解规格参数,并且把计算机给出的地址(addresses)转换成符合实际情况的数值。例如,一个硬盘可能有8个头、2048个磁道以及每磁道有35个扇区。 [3] 其控制器可以对计算机说谎,并声称该硬盘有16个头、1024个磁道以及每个磁道有35个扇区,这样在磁道数上就没有超过限制,并且通过将磁头数减半以及将磁道数加倍来转换计算机给出的地址值。实际的算术运算可能很复杂,因为所给出的参数并不会象这里的一样好(但是再次重申,这些细节与理解原理是无关的)。这个转换曲解了操作系统对于磁盘是如何组织的看法,因此使用所有数据在同一柱面的窍门来提高性能是不切实际的。

这个转换仅对IDE硬盘是个问题。SCSI硬盘使用了一个连续(顺序)扇区号(也即,控制器将顺序扇区号翻译成磁头、柱面以及扇区三个数),以及一个完全不同的CPU与控制器交流的方式,因此它们是不存在这类问题的。然而,请注意,计算机也同样不能知道SCSI硬盘的实际规格参数。

既然Linux不会知道一个硬盘的实际规格参数,它的文件系统甚至也不强求将文件存储于同一个柱面上。而是试着给文件分配顺序编号的扇区,这几乎总能给出同样的性能。再有,控制器上的高速缓冲、控制器的自动提前获取功能使问题变得更加复杂化。

每个硬盘都以一个独立的设备文件来表示。(通常)可以有24IDE硬盘。它们分别表示为/dev/hda/dev/hdb/dev/hdc/dev/hddSCSI硬盘表示为/dev/sda/dev/sdb/dev/sdc,等等。对于其它类型的硬盘也有相类似的命名规则;更多的信息请参见XXX(设备列表)。注意,硬盘的设备文件可以访问整个硬盘,而不管各分区的(这在下面讨论),如果你不小心就很容易搞糟各分区以及其中的数据的。硬盘的设备文件通常仅用来访问主引导记录的(这也将在下面讨论)。

 

软盘

软盘是由单面或双面覆盖着磁性物质的软膜组成,如同硬盘一样。软盘本身不带有读写头,读写头是包含在驱动器中的。一张软盘与硬盘中的一个圆盘相对应,但是是可取走的并且一个驱动器可以访问不同的软盘,而硬盘却是不可分割的一个整体。

与硬盘一样,一张软盘也分成磁道和扇区(并且一张软盘的两面相应的磁道组成一个柱面),但是与硬盘比起来,它们的数量很少。

一个软盘驱动器可以使用几种不同类型的盘片;例如,一个3.5寸驱动器可以使用720kB以及1.44MB的磁盘。因为驱动器的操作有所不同并且操作系统必须知道磁盘容量的大小,所以软盘驱动器有许多设备文件,每个驱动器以及磁盘类型组合成一个设备文件。因此,/dev/fd0H1440表示第一个软驱(fd0),它必须是一个3.5英寸驱动器,使用一个3.5英寸、1440kB1440)大小的高密度盘片(H),也即,一张标准的3.5英寸HD软盘。有关软盘驱动器命名规则的更多信息,请参见XXX(设备列表)。

然而,软盘驱动器的命名是复杂的,因此Linux有一种特别的软盘设备类型,它能够自动地检测出驱动器中盘片的类型。其工作原理是使用不同软盘类型试读新插入软盘的第一个扇区直到它发现正确的类型为止。这自然需要软盘首先是格式化过的。这些自动设备称为/dev/fd0/dev/fd1,等等。

自动设备为访问一张盘片所使用的参数也可以用程序\cmd{setfdprm}来设置。在你需要用到不符合任何常规软盘容量大小的磁盘时,这是非常有用的,例如,如果磁盘的扇区数是与众不同的,或者由于某些原因自动检测失败并且适当的设备文件丢失。

除了许多标准软盘以外,Linux还能够处理许多非标准软盘。其中有些需要特殊的格式化程序。现在我们将略过这种磁盘类型,不过同时你可以查看/etc/fdprm文件。它详细说明了setfdprm能识别的设置。

操作系统必须知道在软盘驱动器中的盘片是什么时候给换掉的,例如,为了避免使用前张盘片的缓冲的数据。不幸的是,用于此的信号线常常是断掉的,更糟的是,当从MS-DOS中使用驱动器时,这不是总是受到注意的。在使用软盘时,如果你碰上了怪异的问题,这可能就是原因所在。唯一的修正方法是维修软盘驱动器。

 

CD-ROM

CD-ROM驱动器使用一光读取的、塑胶覆盖的盘片。信息以小“孔”的形式记录在盘片[4]的表面,这些小空沿着一螺旋线从盘片中间延伸至盘片边沿。驱动器引导一激光束沿着螺旋线来读取盘片上的信息。当激光束照到一个孔时,激光沿着一个方向被反射出来;当激光束照到光滑的表面时,它被反射到另一个方向去了。这很容易进行编码并用来存储信息。剩下的事很容易,仅仅是机械问题了。

与硬盘相比,CD-ROM的速度很慢。尽管一个典型的硬盘的平均寻道时间不到15毫秒,一个快速CD-ROM驱动器要用十分之一秒的时间来寻道。实际的数据传输速率还是相当高的,能达到每秒几百千字节。慢速意味着CD-ROM是不能令人满意地代替硬盘(有些Linux发行版在CD-ROM上提供‘活’文件系统,以至于不必将文件拷贝到硬盘上,使得安装更容易,节省了大量硬盘空间),尽管仍有这个可能。对于安装新的软件,使用CD-ROM是非常好的,因为在安装期间速度并不是最主要的。

有几种方式用来安排CD-ROM上的数据。最流行的方式是按照国际标准ISO 9660。这个标准说明了一个最小文件系统,它甚至比MS-DOS所用的还要粗略。从另一方面来讲,它是如此地小,以至于任何操作系统都可以将其映射入自己的系统中。

对于标准UNIX的使用,ISO 9660是不可用的,所以已经开发出了标准的扩展版,称为Rock Ridge扩展。Rock Ridge允许更长的文件名、符号连接、以及许多其它的好处,使得CD-ROM看上去多少象一个临时UNIX文件系统。更佳的是,一个Rock Ridge文件系统仍然是一个有效的ISO 9660文件系统,使得它对非UNIX系统同样有用。Linux支持ISO 9660以及Rock Ridge扩展这两者;扩展是自动识别和使用的。

然而,文件系统只是战役的一半。许多CD-ROM包含有需要特殊程序才能访问的数据,并且大多数这类程序不能在Linux下运行(很可能除非在dosemu—LinuxMS-DOS模拟器)。

CD-ROM驱动器是通过相应的设备文件来访问的。有几种方法将CD-ROM连接至计算机:通过SCSI、通过声卡、或通过EIDE。所需的硬件叙述已超出了本书范围,但是连接的类型决定了设备文件。详细信息参见XXX(设备列表)。

 

磁带

磁带驱动器使用磁带,同用于乐曲的盒式磁带类似[5]。磁带是顺序连续的,这意味着要想到达它的指定部分,你必须经过这之间的所有部分。一张盘片可以随机地访问,也即,你可以直接跳到盘片的任何地方。磁带的串行访问特征使得它们很慢。

从另一方面讲,磁带制造廉价,因为它们不需要快速。它们也可以做得很长,因此可以容纳大量的数据。这使得磁带非常适合于存档和备份这样的事,这都不需要高速的,但却有低价和大容量的好处。

格式化

格式化(formatting)就是在磁性介质上写上记号,用于标志出磁道和扇区。在格式化之前,磁盘表面的磁信号是杂乱无章的。当格式化后,沿着磁道的轨迹方向带来了一定的次序,并且磁道被分成扇区。实际的细节并不完全如此,但那我们就不管了。重要的是磁盘没有格式化就不能用。

在这,这个术语有些混淆:在MS-DOS中,格式化这个词也同时用于表示创建文件系统的过程(这将在下面讨论)。在其中,两个过程常常合在了一起,尤其是对软盘。当需要加以区别时,实际的格式化被称作低级格式化(low-level-formatting),而创建文件系统被称作高级格式化(high-level formatting)。在UNIX环境中,这两者分别称作格式化和创建文件系统,这也是在本书中的称呼方法。

对于IDE和一些SCSI硬盘来说,格式化早已在出厂前就做好了,不需要重复再做;因此大多数人无需关心它。实际上,对硬盘进行格式化有可能导致硬盘工作不正常,例如,硬盘有可能需要非常特殊的方式进行格式化,以获得自动坏扇区替换的功能。

不管怎么说,需要格式化或能够格式化的磁盘常需要一个特殊的程序,因为不同的硬盘内的格式化逻辑接口是不一样的。格式化用的程序通常或者是在控制器的BIOS中,或者是以MS-DOS程序的形式提供;这两种方式均不适用于Linux

在格式化磁盘时很可能碰到坏点,称作坏块(bad blocks)或坏扇区(bad sectors)。有时这是由驱动器自身来处理的,但即使是这样,如果碰到很多坏的地方,就需要想办法避免使用磁盘坏的部分。处理这样情况的过程是建在文件系统中的;如何增加这方面的信息将在下面叙述。另一种方法是创建只包含磁盘坏区的分区;如果坏区较大的话,这倒是个不错的主意,因为文件系统对付大块坏区有可能出问题。

软盘是用fdformat进行格式化的。软盘设备文件将作为参数给出。例如,下面的命令将在第一个软驱中格式化一张高密度、3.5英寸的软盘:

 

$ fdformat /dev/fd0H1440

Double-sided, 80 tracks, 18 sec/track. Total capacity 1440 kB.

Formatting ... done

Verifying ... done

$

注意,如果你想要使用一个自动识别的设备(例如,/dev/fd0),你必须首先用setfdprm来设置设备的参数。要达到以上同样的目的,就得象下面这样做:

$ setfdprm /dev/fd0 1440/1440

$ fdformat /dev/fd0

Double-sided, 80 tracks, 18 sec/track. Total capacity 1440 kB.

Formatting ... done

Verifying ... done

$

选择符合软盘类型的设备文件来做这事通常是更为方便的。注意,超容量格式化是不明智的。

Fdformat也会对软盘进行验证工作,也即,检查坏块。它将对坏块试着读写几次(你通常可以听到,驱动器的噪声有很大的不同)。如果软盘只是边缘有些损坏(由于磁头脏,有些错误是伪信号),fdformat是不会抱怨的,但是实际错误将取消验证过程。内核将为所发现的每个I/O错误打印出日志消息;这消息将在控制台上显示出来或者,如果使用了syslog,会打印到/usr/log/message文件中。Fdformat自己不会说出出错的地方(人们通常并不关心,因为软盘太便宜了,坏了就丢了算了)。

$ fdformat /dev/fd0H1440

Double-sided, 80 tracks, 18 sec/track. Total capacity 1440 kB.

Formatting ... done

Verifying ... read: Unknown error

$

badblocks命令能用于查找任何磁盘或分区上的坏块(包括软盘)。它并不格式化磁盘,所以它甚至可以用来检查文件系统。下面的例子是检查一张含有两个坏块的3.5英寸软盘。

$ badblocks /dev/fd0H1440 1440

718

719

$

badblocks输出它找到的坏块的块号。许多文件系统可以避免这些坏块。在创建文件系统时会初始化一张已知坏块的列表,并在以后可以对其进行修改。最初寻找坏块的工作可以用命令mkfs来做(它是用于初始化文件系统的),但以后要用badblocks且新的坏块要用fsck加进去。我们将在以后讨论\cmd{mkfs}fsck

许多现代硬盘会自动地注意到坏块,并且会使用特殊预留着的好块来替代它们。这对操作系统来说是看不见的。如果你对它是如何工作的感到好奇的话,这个特性会在磁盘的手册中有。即使是这样的硬盘,如果坏块太多的话,硬盘还是不能用的。

 

分区

一个硬盘可以分成几个区(partitions)。每个分区就如同一个独立的硬盘。这个想法是,如果你有一个硬盘,并且想要在上面安装两个操作系统,你可以将这个硬盘分成两个分区。每个操作系统自由地使用各自的分区而不触及另一个。这样两个操作系统就可以和平地共处于同一个硬盘中。如果没有分区的话,你就得为每个操作系统购买一个硬盘。

软盘是不分区的。这并没有什么技术上的原因,只是因为软盘的容量太小了,因此分区极少使用。CD-ROM盘也常常是不分区的,因为它作为一个大磁盘使用很容易。很少有需要几个操作系统放在一张光盘上的。

 

主引导记录(MBR)、引导扇区以及分区表

硬盘是如何分区的信息存储于硬盘的第一个扇区中(也即,第一张盘片的第一个磁道的第一个扇区)。这第一个扇区就是硬盘的主引导记录(master boot record MBR);当机器首次启动时,BIOS会读入这个扇区。主引导记录中含有一个小程序,用于读分区表、检查哪个分区是活动分区(也即,标志为可启动的),并且读入那个分区的第一个扇区,分区的启动扇区(boot sector(MBR也是一个启动扇区,但它有一个特殊的地位,因此有一个特殊的名字)。这个启动扇区也包括一个小程序,用于读入当前分区操作系统的第一部分(假设它是可启动的),然后开始运行整个操作系统。

分区的方案没有建于硬件中,或者甚至BIOS中。这是许多操作系统都遵守的惯例。但并不是所有的操作系统都是按惯例做的,这是个例外。有些操作系统支持分区,但只在硬盘上占用一个分区,并在此分区上使用自己的内部分区方法。后面这种分区类型能与其它的操作系统和平共处(包括Linux),并且不需要任何特殊的方法。但是不支持分区的操作系统不能在同一个硬盘上与其它操作系统共处。

作为安全预防,将分区表写在一张纸上是个好主意,这样一旦发生破坏,你不会丢失所有的文件。(坏分区可以用fdisk修复)。相关的信息可以用命令fdisk –l给出:

$ fdisk -l /dev/hda

Disk /dev/hda: 15 heads, 57 sectors, 790 cylinders

Units = cylinders of 855 * 512 bytes

Device Boot Begin Start End Blocks Id System

/dev/hda1 1 1 24 10231+ 82 Linux swap

/dev/hda2 25 25 48 10260 83 Linux native

/dev/hda3 49 49 408 153900 83 Linux native

/dev/hda4 409 409 790 163305 5 Extended

/dev/hda5 409 409 744 143611+ 83 Linux native

/dev/hda6 745 745 790 19636+ 83 Linux native

$

扩展与逻辑分区

最初的PC上硬盘的分区方案只允许有4个分区。这在实际使用中很快就变得太小了,部分原因是有些人需要多于4个操作系统(LinuxMS-DOSOS/2MinixFreeBSDNetBSD、或者Windows/NT,等等),而主要原因是有时一个操作系统拥有几个分区是个很好的主意。例如,对Linux来说交换空间通常最好是放置在它自己的分区内,而不是放在主Linux分区中,这是考虑到速度的因素(见下面)。

为克服这个设计问题,发明了扩展分区(extended partitions)。这个诀窍允许主分区再分成子分区。如此划分的主分区就是扩展分区(extended partitions);子分区是逻辑分区(logical partitions)。它们的表现同主[6]分区一样,但是以不同的方式创建的。不存在速度方面的差别。

一个硬盘的分区结构看上去如同图4-2中所示。硬盘被分成三个主分区,第二个主分区再被分成两个逻辑分区。硬盘还有些部分根本没有分区。整个硬盘以及各个主分区都有一个引导扇区。

4-2. 一个简单的硬盘分区

分区类型

分区表(MBR中的以及扩展分区中的)中的每个分区含有一个字节的分区类型识别码。是用于识别使用分区的操作系统,或用于其他用途。目的是为了防止两个操作系统偶然使用了同一个分区。然而,实际上操作系统并不关心分区类型字节;例如,Linux根本不关心它是什么。更糟的是,有些操作系统错误地使用了它;例如,至少在DR-DOS的某些版本中忽略了该字节中非常重要的位,而其它却没有。

并没有标准化机构来指定每个字节值是什么含义,但是某些公认的值的含义见表4-1所示。Linuxfdisk程序也有同样的列表。

4-1。分区类型(取自Linux fdisk程序)。

0

Empty

40

Venix 80286

94

Amoeba BBT

1

DOS 12-bit FAT

51

Novell?

a5

BSD/386

2

XENIX root

52

Microport

b7

BSDI fs

3

XENIX usr

63

GNU HURD

b8

BSDI swap

4

DOS 16-bit f <32M

64

Novell

c7

Syrinx

5

Extended

75

PC/IX

db

CP/M

6

DOS 16-bit >32M

80

Old MINIX

e1

DOS access

7

OS/2 HPFS

81

Linux/MINIX

e3

DOS R/O

8

AIX

82

Linux swap

f2

DOS secondary

9

AIX bootable

83

Linux native

Ff

BBT

a

OS/2 Boot Manag

93

Amoeba

   

 

对硬盘进行分区

有许多程序用于创建和删除分区。大多数操作系统都有自己的,最好要用操作系统自己的程序,以防它可能做些其它程序不能做特别的事。这些程序大多数都称为fdisk,包括Linux系统也是这样称呼的,或者有些相应改变。使用Linuxfdisk的详细信息见man pageCfdisk命令与fdisk相类似,但有一个更好的(全屏幕)用户界面。

当使用IDE硬盘时,启动引导分区(含有启动内核映像文件的分区)必须完全位于头1024柱面以内。这是因为硬盘在启动时是通过BIOS使用的(在系统进入保护模式之前),而BIOS不能处理大于1024的柱面。有时候很可能用到只有部分分区在1024柱面内的启动分区,但只要所有通过BIOS来读取的文件位于头1024个柱面内就行。由于这种安排非常困难,所以这样做是很不利的;你不可能知道什么时候一个内核的更新或者硬盘的整理碎片活动将导致系统不可启动。因此,要确信你的启动分区完全在头1024个柱面以内。

实际上,有些新版的BIOS以及IDE硬盘能够处理大于1024柱面的情况。如果你有这样的系统,你可以不管这个问题;如果你不能非常的确信,就将启动所用的文件放在1024个柱面以内。

每个分区应该有偶数个扇区值,因为Linux系统使用一个1千字节的块大小,也即,两个扇区。一个奇数的扇区值将导致最后一个扇区没有用上。虽然这不会产生任何问题,但是却很不顺眼,并且有些版本的fdisk会对此提出警告。

更改分区的大小通常需要首先备份该分区上的所有你想保存的数据(最好是备份整个硬盘,看情况定),删除这个分区,再创建新分区,接着再恢复所有的数据到新分区上。如果分区是增大的,你可能同时需要调整相邻分区的大小(以及备份和恢复)。

MS-DOS有个程序,叫fips,可以用来调整MS-DOS分区的大小而无需进行备份和恢复操作。但对于其它系统这仍然是必须的。

 

设备文件与分区

每个分区以及扩展分区都有自己的设备文件。这些文件的命名规则是在硬盘名的后面加上分区号,1-4号是主分区(不管那里有多少个主分区)以及5-8是逻辑分区号(不管它是属于那个主分区的)。例如,/dev/hda1是第一个IDE硬盘上的第一个主分区,/dev/sdb7是第二个SCSI硬盘上的第三个扩展分区。XXX(设备列表)中的设备列表给出了更多的信息。

 

文件系统

什么是文件系统?

文件系统(filesystem)是操作系统用以明了磁盘或分区上的文件的一种方法以及数据结构;也即,磁盘上文件组织的方法。这个词也用于指一个用于存储文件的分区或磁盘,或者是指给定文件系统的类型。因此,某人可以说“我有两个文件系统”意思是说他有两个存储文件的分区,或者某人说“扩展文件系统”,意思是说文件系统的类型。

区别对待盘片或分区以及在其上的文件系统是非常重要的。很少程序(很理智地讲,包括创建文件系统的程序)是在磁盘或分区的原始扇区上直接操作的;如果其上已存在一个文件系统,将会被毁坏或受到严重地破坏。大多数程序是在文件系统上操作的,因此不能在无文件系统的分区上工作(或在类型不对的分区上操作)。

在一个分区或磁盘能被用作一个文件系统之前,它需要被初始化过,并且簿记数据结构需已被写入磁盘。这个过程称为制作一个文件系统(making a filesystem)。

大部分UNIX文件系统类型有一个相似的通常结构,尽管在精确的细节方面变化很大。主要概念有超级块(superblock)、i节点(inode)、数据块(data block)、目录块(directory block)、以及间接块(indirection block)。超级块包含整个文件系统的信息,如文件系统的大小(这里的实际信息依赖于是何种文件系统)。一个i节点包括一个文件的所有信息,除了它的名字。名字是和i节点号一起存储于目录中的。一个目录项是由文件名以及表示相应文件的i节点号组成。i节点还包括存储文件中数据的数据块的数量。在i节点中只有容纳几块数据块的空间,然而,如果需要更多的数据块,会动态地为指向数据块的指针分配更多的空间。这些动态分配的块就是间接块;这个名字说明为了找到所需的数据块,必须首先在间接块中查到数据块的号码。

UNIX文件系统通常允许在一个文件中创建一个孔(hole)(这是用lseek来做的;请查看manual page),这意味着,文件系统只是假装在文件的一个特别的地方仅有零个字节,但并没有为文件保留磁盘扇区(这就是说,这个文件将使用更少的磁盘空间)。对于小的二进制文件、Linux共享库文件、一些数据库以及其它一些特殊情况,这事常有的事。(孔是通过在间接块或i节点中存入当作数据块地址的特殊值来实现的。这个特殊的地址表示没有为文件的那个部分分配数据块,因此,文件中就有了一个孔。)

孔是比较有用的。在作者的系统中,简单的测试表明通过孔的使用在大约200MB使用的磁盘空间里能节约4MB的空间。而且,在这个系统中只有相应很少的程序以及并没有数据库文件。

 

各种文件系统

Linux支持几种类型的文件系统。其中重要的几种有:

minix

最老的、认为也是最可靠的,但性能上是很有限的(有时没有标志,文件名最多30个字符)并且容量也是有限的(每个这样的文件系统最多64MB)。

xia

一个minix文件系统的修正版本,降低了对文件名长度以及文件系统大小的限制,但并没有引进新的特性。它并不流行,但据报道工作的很好。

ext2

非常有特色的出自于Linux的文件系统,也是当今最流行的文件系统。它被设计成易于升级的,这样文件系统代码的新版本就不需要重建已存在的文件系统。

ext

ext2的老版本,不是向上兼容的。已不再在安装中使用了,并且大多数人都已转换到了ext2

另外,还支持一些外来的文件系统,使得与其他操作系统交换文件变得更容易了。这些外来的文件系统工作起来如同本地的一样,只是它们缺乏一些通常的UNIX的特征,或者有着奇特的限制或其它古怪的地方。

msdos

MS-DOS的(以及OS/2Windows NTFAT文件系统兼容。

usmdos

是在Linux下对msdos文件系统的扩展,支持长文件名、所有者、权限、连接以及设备文件。这使得一个常规的msdos文件系统能够想Linux的文件系统一样的使用,因此对Linux来说也就无需一个独立的分区了。

Iso9660

标准的CD-ROM文件系统;自动支持允许更长文件名的Rock Ridge扩展文件系统。它是对标准CD-ROM文件系统的扩展。

nfs

一个网络文件系统,允许在许多计算机之间共享一个文件系统,易于这些计算机对文件的访问。

hpfs

OS/2的文件系统。

sysv

SystemV/386,以及Xenix文件系统。

要依具体情况来选择使用文件系统。如果兼容性或其它原因使得需要使用一个非原始的文件系统,那就必须使用其中的一个。如果能自由地选用文件系统的话,那么选用ext2也许是最明知的,因为它有所有的特征并且没有性能上的下降。

还有一种proc文件系统,通常作为/proc目录来访问,它其实完全不是一个真正的文件系统,尽管看起来它很象。proc文件系统使得访问某些内核的数据结构变得很容易,如进程列表(因此还有名字)。它使得这些数据结构看起来很象是一个文件系统,并且能够使用所有通常的文件工具来操作处理。例如,要取得所有进程的一个列表,可以使用命令:

$ ls -l /proc

total 0

dr-xr-xr-x 4 root root 0 Jan 31 20:37 1

dr-xr-xr-x 4 liw users 0 Jan 31 20:37 63

dr-xr-xr-x 4 liw users 0 Jan 31 20:37 94

dr-xr-xr-x 4 liw users 0 Jan 31 20:37 95

dr-xr-xr-x 4 root users 0 Jan 31 20:37 98

dr-xr-xr-x 4 liw users 0 Jan 31 20:37 99

-r--r--r-- 1 root root 0 Jan 31 20:37 devices

-r--r--r-- 1 root root 0 Jan 31 20:37 dma

-r--r--r-- 1 root root 0 Jan 31 20:37 filesystems

-r--r--r-- 1 root root 0 Jan 31 20:37 interrupts

-r-------- 1 root root 8654848 Jan 31 20:37 kcore

-r--r--r-- 1 root root 0 Jan 31 11:50 kmsg

-r--r--r-- 1 root root 0 Jan 31 20:37 ksyms

-r--r--r-- 1 root root 0 Jan 31 11:51 loadavg

-r--r--r-- 1 root root 0 Jan 31 20:37 meminfo

-r--r--r-- 1 root root 0 Jan 31 20:37 modules

dr-xr-xr-x 2 root root 0 Jan 31 20:37 net

dr-xr-xr-x 4 root root 0 Jan 31 20:37 self

-r--r--r-- 1 root root 0 Jan 31 20:37 stat

-r--r--r-- 1 root root 0 Jan 31 20:37 uptime

-r--r--r-- 1 root root 0 Jan 31 20:37 version

$

(尽管这里有些特别的文件是与进程无关的。上面这个例子已简化过)

请注意,尽管是这样,它仍被称为文件系统,虽然proc文件系统的任何部分都与磁盘无关。它仅存在于内核的想象中。无论何时,当有人想查看proc文件系统的任何部分时,内核就会使得该部分好象的确是存在于某个地方的,尽管是这样,它并不是个文件系统。因此,尽管它有一个多兆字节的/proc/kcore文件,它其实不占用任何磁盘空间。

 

应该使用那一种文件系统?

使用同时许多不同文件系统是很少有的。目前,ext2fs是最流行的一个,也可能是最明智的选择了。根据薄记结构的性能、速度、(感知的)可靠性、兼容性以及各种其他原因,选用其他的文件系统是可取的。这需要进行逐步分析才能决定。

 

创建一个文件系统

文件系统是用mkfs命令创建的,也即,初始化的。事实上,每种文件系统类型都有自己独特的创建程序。mkfs只是一个前端程序,它根据所选的文件系统类型来运行适当的程序。类型是用-t fstype选项来选择的。

mkfs调用的程序有些略微不同的命令行界面。共有的以及最重要的选项总结如下;详细信息参见manual pages

-t fstype

选择文件系统的类型。

-c

查找坏块从而初始化坏块列表。

-l filename

从文件中读取坏块列表。

为了在软盘上创建一个ext2文件系统,必须执行以下命令:

$ fdformat -n /dev/fd0H1440

Double-sided, 80 tracks, 18 sec/track. Total capacity 1440 kB.

Formatting ... done

$ badblocks /dev/fd0H1440 1440 $>$ bad-blocks

$ mkfs -t ext2 -l bad-blocks /dev/fd0H1440

mke2fs 0.5a, 5-Apr-94 for EXT2 FS 0.5, 94/03/10

360 inodes, 1440 blocks

72 blocks (5.00%) reserved for the super user

First data block=1

Block size=1024 (log=0)

Fragment size=1024 (log=0)

1 block group

8192 blocks per group, 8192 fragments per group

360 inodes per group

Writing inode tables: done

Writing superblocks and filesystem accounting information: done

$

首先,格式化软盘(-n选项指出无需验证,也即,不进行坏块检查)。然后使用badblocks命令来查找坏块,并将输出重定向到一个文件中,bad-blocks。最后,创建文件系统,并用badblocks找到的坏块来初始化坏块列表。

也可以在mkfs中使用-c选项来替代badblocks命令以及它的输出文件。下面的例子就是这样做的。

$ mkfs -t ext2 -c /dev/fd0H1440

mke2fs 0.5a, 5-Apr-94 for EXT2 FS 0.5, 94/03/10

360 inodes, 1440 blocks

72 blocks (5.00%) reserved for the super user

First data block=1

Block size=1024 (log=0)

Fragment size=1024 (log=0)

1 block group

8192 blocks per group, 8192 fragments per group

360 inodes per group

Checking for bad blocks (read-only test): done

Writing inode tables: done

Writing superblocks and filesystem accounting information: done

$

使用-c选项比分开来使用badblocks命令更为方便,但是badblocks用于检查已有的文件系统是必须的。

在硬盘上或分区上创建文件系统的过程是和在软盘上一样的,只是无需格式化操作。

 

加载与卸载

在使用一个文件系统时,首先必须加载它。然后操作系统会做一系列的薄记作业以确保每件事都工作正常。由于UNIX中的所有文件都在一棵单目录树中,加载操作使得新文件系统的内容看上去象是已加载文件系统子目录中的内容。

例如,图4-3显示了三个独立的文件系统,每一个都有自己的根目录。当后两个文件系统被分别加载到第一个文件系统的/home以及/usr下面时,我们可以获得一棵单目录树,如图4-4中所示。

4-3.三个独立的文件系统。

4-4./home以及/usr已被加载。

可以按以下方法进行加载:

$ mount /dev/hda2 /home

$ mount /dev/hda3 /usr

$

mount命令带有两个参数。第一个是与包含该文件系统的磁盘或分区相关的设备文件。第二个是目录,在该目录下面文件系统将被加载。在执行完上面的命令后,两个文件系统的内容看上去分别象是/home以及/usr目录中的内容。于是,可以说“/dev/hda2加载到了/home”,/usr也是类似的。为了看各个文件系统的内容,只要观察它所加载到的目录的内容,就好象这个目录是别的目录一样。请注意设备文件/dev/hda2和被加载目录/home之间的区别。设备文件给出了访问磁盘上原始数据的能力,而被加载目录给出了访问磁盘上文件的能力。被加载的目录称为加载点(mount point)。

Linux支持许多文件系统类型。mount命令会试图猜测要加载的文件系统的类型。你也可以使用-t fstype选项来直接指定类型;这有时是必须的,因为mount的启发式工作方式并不总是有效的。例如,为了加载一张MS-DOS软盘,你可以用下面的命令:

$ mount –t msdos /dev/fd0 /floppy

$

被加载到的目录并不需要是空的,尽管这个目录必须存在。然后当文件系统加载上来以后,该目录中原来的任何文件就都不可访问了。(但任何已被打开的文件将继续可以访问。从其它目录来的有硬连接的文件也可以用那些硬连接名来访问。)这样做并无害处,甚至很有用处。例如,有些人将/tmp/var/tmp同步起来,使/tmp成为到/var/tmp的一个符号连接。当系统启动时,在/var文件系统被加载之前,根文件系统上的/var/tmp目录先被使用。当/var被加载后,它将使得根文件系统上的/var/tmp目录不可访问。如果/var/tmp在根文件系统上不存在,那么在加载/var之前就不能使用临时文件了。

如果你不会往文件系统上写入任何东西,那么可以使用带-r选项的mount命令来做一个只读加载(readonly mount)。这将使得内核停止任何往文件系统上写的企图,并且不会更新i节点内的文件访问时间。对于只读界质,只读加载方式是必须的,例如,CD-ROM

细心的读者可能已注意到一个微小的逻辑问题。由于第一个文件系统(被称为根文件系统root filesystem,因为它包含根目录)显然不会加载到其它的文件系统上,那么它是如何被加载的呢?好吧,答案是它是被魔术般地加载上去的。[7] 在启动时根文件系统被魔术般地加载上去,并且我们可以始终认为它是已加载的。如果根文件系统不能被加载,系统就启动不了。作为根文件系统被魔术加载的文件系统的名字或是已被编译进内核,或是使用LILOrdev设置的。

通常,根文件系统首先以只读方式加载。然后,启动描述文件将运行fsck来验证它的有效性,并且如果没有问题的话,再重加载成可写的。fsck不能对一个已加载的文件运行,因为当fsck正在运行时,任何对文件系统的改变都会带来麻烦。由于根文件系统在被验证时是已只读方式加载的,所以fsck可以不用担心地修复任何问题,重加载操作将会回写文件系统保存在内存中的任何原数据。

在许多系统中,还有其它一些文件系统应该在系统启动时被自动加载。这些文件系统是在/etc/fstab文件中指定的;文件的详细格式请参见fstabman page。当另加的文件系统被加载时要依靠许多的参数,并且可以由系统管理员来配置;见第六章。

当一个文件系统不再需要被加载时,可以使用umount命令来卸载。[8] umount有一个参数:设备文件名或是加载点。例如,要卸载上个例子的目录,可以使用命令

$ umount /dev/hda2

$ umount /usr

$

如何使用这个命令的更详细的信息请参见man page。要特别强调,一定要卸载一个被加载的软盘,而不能仅仅弹出驱动器中的软盘完事!这是由于磁盘缓冲,在卸载之前数据并不需要马上就写如软盘,所以过早地从驱动器中取走软盘有可能导致软盘的内容乱掉。如果你只是从软盘中读取信息,这还没问题,但如果是写的话,甚至是偶然地,其结果将是灾难性的。

加载与卸载需要超级用户权限,也即,只有root用户能做。原因是如果允许任何用户能够在任何目录上加载软盘的话,那么就很容易创建一张伪装成/bin/sh的特落依木马程序软盘,或任何其它经常被使用的程序。但是,常常需要允许用户能够使用软盘,有几种方法可用:

。给用户root的口令。这显然是极不安全的,但是最简单的解决方法。如果不作安全方面的考虑,这是种方法很好,对于不连网的、个人系统,常常是这样做的。

。使用如sudo这样的程序来允许用户使用加载。这仍然是不安全的,但不用直接给出超级用户的权限。[9]

。让用户使用mtools命令,这是一个维护MS-DOS文件系统的工具包,而无需加载它。这在只使用MS-DOS软盘时可以工作的很好,但是显得很笨拙。

。在/etc/fstab中列出软盘设备文件以及允许它们加载的加载点等参数。

以上最后一种方式可以通过往\fn{/etc/fstab}中加入一行来实现,如下所示:

/dev/fd0 /floppy msdos user,noauto 0 0

各列为:要加载的设备文件、加载的目录、文件系统类型、选项、备份频率(用于dump),以及fsck通行号(指定在启动时文件系统应被检查的顺序;0意味着不用检查)。

Noauto选项阻止当系统启动时自动加载它(也即,它阻止mount –a加载它)。用户选项允许任何用户来加载这个文件系统,并且,由于安全的原因,不允许从这个已加载的文件系统中执行程序(常规的或setuid)以及解释执行设备文件。除了这,任何用户可以用以下命令,加载一张msdos文件系统软盘:

$ mount /floppy

$

软盘能够(当然也是需要的)用相应的命令\cmd{umount}来卸载。

如果你想提供对几种软盘文件系统类型的访问,你需要给出几个加载点。各个加载点的设置可以是不同的。例如,要访问MS-DOS以及ext2的软盘,你可以在/etc/fstab中加入以下两行:

/dev/fd0 /dosfloppy msdos user,noauto 0 0

/dev/fd0 /ext2floppy ext2 user,noauto 0 0

对于MS-DOS文件系统(不仅仅是软盘)来说,你可能想用uidgid以及umask文件系统选项来限制对它的访问,详细叙述参见mountmanual page。如果你不小心,加载了一个任何人都至少有读访问权限的MS-DOS文件系统,是不明智的。

 

使用fsck检查文件系统的完整性

文件系统是种复杂的东西,正因为如此,它们常会含有错误。一个文件系统的正确性和有效性可以用fsck命令来检查。可以用它来修复所发现的小问题,并且在有不可修复的问题时提醒用户注意。幸运的是,实现文件系统的代码能够很有效地进行调试,所以很少真正存在问题的,如果有问题通常也是因为掉电、硬件出错或者操作出错;例如,没有正常关闭系统等。

大多数系统都设置成在启动时自动执行fsck,所以在系统使用前任何错误都可以检测出(并希望也被纠正过来)。使用一个已毁坏的文件系统会使得情况变得更糟:如果数据结构被破坏了,使用这个文件系统会造成更大的破坏,导致更多的数据丢失。然而,在一个大的文件系统上运行fsck需要耗费一段时间,而且如果系统是正常关闭的那么几乎是不可能发生错误的,此时可以使用几种技巧来来跳过对文件系统的检查。第一种是,如果存在文件/etc/fastboot,就不会对文件系统作检查。第二种方法是,ext2文件系统在它的超级块内有一个特殊的标记来指出文件系统在前一次加载后是否正常地卸载。如果标志指出文件系统是正常卸载的(假设正常的卸载就表示文件系统没问题),那么e2fsckfsckext2文件系统版)就不会对文件系统作检查。/etc/fastboot技巧能否工作依赖于系统的启动描述文件,但是每当使用e2fsck命令时就有ext2技巧起作用。而且必须明确地e2fsck命令不带选项。(详细信息参见e2fsckman page。)

只有在启动时自动加载的文件系统才会被自动地检测。手工使用fsck命令来对其它文件系统进行检测,例如,软盘。

如果fsck发现了不可修复的问题,你要么需要有通常文件系统是如何工作的深入的知识以及知道坏文件系统的类型,要么有一个好备份。后一种方法是容易(尽管有时也是乏味的)做到的。前者有时需要朋友、Linux新闻组以及邮件列表或其他的支持源来做到,如果你不知道怎么办的话。有关这方面的事我真想告诉你更多些,但我的教育和经验的匮乏阻碍了我。Theodore T’sodebugfs程序应该是很有用的。

fsck必须对未加载的文件系统运行,绝对不要对已加载的文件系统运行(除了在启动期间对只读的根文件系统)。这是因为它访问磁盘的原始数据,因此能够在操作系统不知情的情况下修改文件系统。这样如果操作系统搞混的话就有可能带来问题。

 

使用badblocks检查磁盘错误

周期性地检查磁盘坏块是个好主意。这是用badblocks命令来做的。它输出一张它找到的所有坏块号的列表。这张列表可以送至fsck命令并记录在文件系统数据结构中使得操作系统不会用这些坏块来存储数据。下面的例子显示出了如何能做到这点。

$ badblocks /dev/fd0H1440 1440 > bad-blocks

$ fsck -t ext2 -l bad-blocks /dev/fd0H1440

Parallelizing fsck version 0.5a (5-Apr-94)

e2fsck 0.5a, 5-Apr-94 for EXT2 FS 0.5, 94/03/10

Pass 1: Checking inodes, blocks, and sizes

Pass 2: Checking directory structure

Pass 3: Checking directory connectivity

Pass 4: Check reference counts.

Pass 5: Checking group summary information.

/dev/fd0H1440: ***** FILE SYSTEM WAS MODIFIED *****

/dev/fd0H1440: 11/360 files, 63/1440 blocks

$

如果badblocks报告一个坏块已被使用,e2fsck将会试着将该块上的数据移到另外的地方去。如果该数据块真的坏得一点也不能用了,而不仅只是边缘有些坏,那么所属的文件就破坏了。

 

整理磁盘碎片

当一个文件被写入磁盘,它不可能总被写进连续的块中。一个文件如果没有被存储于连续的块中,就称为是有碎片的(fragmented)。读有碎片的文件要更长的时间,因为磁盘的读写头要移动更多次。应该尽量避免碎片,尽管在一个有很好的预读缓冲的系统中不是个问题。

ext2文件系统通过把在一个文件中的所有块都集中放在一起(即使它们不能存储于顺序的扇区中)试图使碎片尽可能地少。Ext2文件系统总是有效地分配离文件中其它块最近的自由块给该文件。所以,对于ext2来说,很少需要担心碎片的事。有一个整理ext2文件系统碎片的程序,在参考书目中参见XXXext2-defrag)。

有许多MS-DOS整理碎片的程序,用来在文件系统中移动块以除去碎片。对于其它文件系统,整理碎片的工作需要通过备份文件系统,然后重建该文件系统,并从备份中恢复文件来做到除去碎片。对于所有文件系统来说在做整理碎片工作之前做文件系统的备份是个好主意,因为在整理碎片的过程中有许多事可能出差错。

 

文件系统的通用工具

有许多其它工具对管理文件系统也是很有用的。df用于显示一个或多个文件系统上的空磁盘空间;du用于显示一个目录以及其内所有文件所占用的磁盘空间。这些工具可用于查出浪费磁盘空间的地方。

Sync使得缓冲中未写的块(见第五章中的缓冲一节)写入磁盘。很少需要手工做这事;后台进程update会自动地做这事。在碰到大灾难是它还是很有用的,例如,如果update或它的协助进程bdflush死去了,或者如果你必须立即关闭电源而等不及update来执行。

 

ext2文件系统的通用工具

除了文件系统的创建程序(mke2fs)以及检查程序(e2fsck)可以直接使用或通过文件系统类型独立的前端使用外,ext2文件系统还有其它一些有用工具。

tune2fs用于调整文件系统参数。一些感兴趣的参数有:

。最大加载记数值。当文件系统被加载了太多次时,e2fsck会迫使进行检查操作,即使完整标志已被设置。对于一个用于开发或测试的系统来说,将该数值降低是个好主意。

。检查之间的最长时间。e2fsck也能确定两次检查之间等待的最长时间,即使完整标志已被设置,并且文件系统并没有不时地被加载。然而,这是可以使其不起作用的。

。为root保留的块数。Ext2root保留了一些块,以用于如果文件系统数据满了,在不删除任何东西的情况下,仍能做系统管理的工作。保留值的大小缺省值为百分之5,这对于绝大多数硬盘来说并不浪费。然而,对于软盘来说,是无需保留任何块的。

更多信息请参见tune2fsmanual page

dumpe2fs显示一个ext2文件系统的信息,绝大多数信息来自超级块。图4-5显示出了一个简单的输出结果。其中有些信息是技术上的并且需要对文件系统是如何工作的有个了解(见附录XXX ext2fspaper),但是大多数信息即使对非管理员来说也是容易理解的。

4-5.dumpe2fs的简单输出。

dumpe2fs 0.5b, 11-Mar-95 for EXT2 FS 0.5a, 94/10/23

Filesystem magic number: 0xEF53

Filesystem state: clean

Errors behavior: Continue

Inode count: 360

Block count: 1440

Reserved block count: 72

Free blocks: 1133

Free inodes: 326

First block: 1

Block size: 1024

Fragment size: 1024

Blocks per group: 8192

Fragments per group: 8192

Inodes per group: 360

Last mount time: Tue Aug 8 01:52:52 1995

Last write time: Tue Aug 8 01:53:28 1995

Mount count: 3

Maximum mount count: 20

Last checked: Tue Aug 8 01:06:31 1995

Check interval: 0

Reserved blocks uid: 0 (user root)

Reserved blocks gid: 0 (group root)

Group 0:

Block bitmap at 3, Inode bitmap at 4, Inode table at 5

1133 free blocks, 326 free inodes, 2 directories

Free blocks: 307-1439

Free inodes: 35-360

debugfs是文件系统的调试器(debugger)。它允许对磁盘上的文件系统的数据结构进行直接的访问,因此能用来维修文件系统已破坏但fsck不能自动修复的磁盘。它也因为用于恢复被删除的文件而著称。然而,debugfs极需要你理解你所做的;一次误解可能破坏你的全部数据。

dump以及restore能用于备份一个ext2文件系统。它们是传统UNIX备份工具的ext2的特定版本。有关备份的更多信息请参见第10章。

 

无文件系统的磁盘

不是所有的磁盘或分区被用作文件系统的。例如,交换分区上是没有文件系统的。许多软盘是以模拟磁带驱动器的方式使用的,所以一个tar文件或其它文件是直接写在原始盘片上的,而非文件系统中。Linux启动盘片不含文件系统,只含有原始内核。

不使用文件系统有可以使得磁盘用途更多的好处,因为一个文件系统总有些薄记工作要做。这也使得磁盘更容易兼容于其它系统:例如,tar文件的格式在所有的系统上都是一样的,而文件系统在大多数系统上是不同的。你会很快地习惯于没有文件系统的的磁盘如果你需要的话。可启动的Linux软盘也不必有个文件系统,尽管常常是这样的。

使用原始磁盘的一个理由是做它们的映像文件。例如,如果磁盘含有部分损坏的文件系统,在进行修复它之前做一个完全一样的拷贝是个好主意,从此,你可以再次更多的损坏的部分。这样做的一种方法是使用dd

$ dd if=/dev/fd0H1440 of=floppy-image

2880+0 records in

2880+0 records out

$ dd if=floppy-image of=/dev/fd0H1440

2880+0 records in

2880+0 records out

$

第一个dd作了一个软盘的完全一样的拷贝映像文件floppy-image,第二个dd将映像文件写入软盘。(在第二个命令之前,用户大概已换过磁盘。否则的话这个命令对就很可能没一点用了。)

 

分配磁盘空间

分区的方案

以尽可能好的方法对一个磁盘进行分区并不是件容易的事。更糟糕的是没有普遍正确的方法来进行分区的;会有很多因素要加以考虑。

传统的方法是有一个(相对来说)较小的根(root)文件系统,它包含/bin/etc/dev/lib/tmp以及其它一些用于启动与运行系统的信息。如此,根文件系统(在它自己的分区或磁盘上)是系统启动所需的一切。理由是,如果根文件系统较小且不是工作过重的话,当系统垮掉时它也不会轻易地毁坏,并且你会由此发现修复任何由系统垮掉而造成的问题是非常容易的。然后为目录/usr、用户主目录(常在/home下)、以及交换空间创建独立的分区或使用独立的磁盘。在自己分区中的独立的用户主目录(含有用户文件)使得备份更容易,因为通常不需要备份程序(它们驻留在/usr下)。在一个网络环境中,在几个机器之间共享/usr也是可能的(例如,通过使用NFS),由此减少了几十兆或几百兆乘上机器数量的总的磁盘空间容量。

有许多分区所带来的问题是把总的自由磁盘空间分成了许多小块。现今,当磁盘以及(有希望地)操作系统越来越可靠,许多人更喜欢只有一个含有所有文件的分区。另一方面来讲,备份(以及恢复)一个小的分区是很容易的。

对于一个小容量硬盘(假设你不作内核开发)来讲,最佳的方法很可能是只有一个分区。对于大硬盘来说,有几个大的分区通常是比较好的,只是万一确实出了问题。(注意,这里的‘小’与‘大’是相对来说的;对磁盘空间的需求决定了极限是什么。)

如果你有几个硬盘,你可能希望根文件系统(包括/usr)在一个硬盘上,而用户主目录在另一个上面。

用不同的分区方案作些试验是个好主意(随着时间的过去,而不仅是当第一次安装时)。这需要一些工作量,因为原则上需要你进行几次系统的安装,但这是能够确定你做得正确的唯一方法。

 

空间需求

你所要安装的Linux版本会给出一些针对不同的配置需要多少磁盘空间的指示。分开安装的程序也同样会给出容量的要求。这将帮助你计划硬盘空间的使用,但是你应该为将来所需准备并保留一些额外的空间。

你为用户文件准备的空间大小依赖于你的用户想要作些什么工作。大多数用户会为他们的文件要求尽可能多的硬盘空间。但是,他们所满意的容量是有很大不同的。有些用户只做一些轻微的字处理,只要有几兆字节就会满足,其他做繁重的图象处理的用户将需要几个GB的硬盘空间。

顺便说一句,当比较以千字节或兆字节给出的文件的大小与以兆字节给出的磁盘空间的大小时,需要知道这两者的大小单位略有些不同。有些磁盘生产厂商喜欢称千字节为1000字节、兆字节为1000千字节,而除他们以外的计算机界都使用1024作为因子。因此,我的345MB硬盘其实是一个330MB的硬盘。[10]

 

硬盘空间分配实例

我以前有一个109MB的硬盘。现在我使用一个330MB的硬盘。我将解释怎样以及为什么我这样对这两个硬盘分区。

当我的需求以及我所使用的操作系统改变时,我的109MB硬盘被用许多方法分过区;这里我将解释两种典型的分区方案。首先,我习惯于将MS-DOSLinux放在一起。为了这,我需要约20MB的硬盘空间,或是足够于存放MS-DOS系统、一个C编译器、一些其它的工具、和我正编制的程序以及足够的空闲磁盘空间即可。对于Linux,我有一个10MB的交换区,剩下的79MB作成单个分区用于存放我在Linux下的所有文件。我试验过为root/usr/home分别开设独立的分区,但每个分区总没有足够的空闲磁盘空间。

当我不再需要MS-DOS后,我对硬盘重新分了区,于是我就有了一个12MB的交换区以及又一次把剩余的空间作成了一个单独的文件系统。

我的330MB硬盘被分成了如下几个区:

5MB

Root文件系统

10MB

交换分区

180MB

\fn{/usr}文件系统

120MB

\fn{/home}文件系统

15MB

临时使用分区

临时分区用于那些需要自己的分区的事情,例如,试用不同的Linux发行版本或者用于比较文件系统的速度。当再也需要这个分区时,就将它用作交换空间(我喜欢同时开着许多windows窗口)。

 

Linux增加更多的磁盘空间

Linux增加更多的磁盘空间是很容易的,至少是在硬件都安装妥当之后(硬件的安装不属于本书的讨论范围)。根据需要你可以先进行格式化,然后照上述创建分区和文件系统,并在/etc/fstab文件中加入适当的命令行,使得它可以自动地被加载。

 

节省磁盘空间的一些技巧

节省磁盘空间的最好的技巧是不安装不需要的程序。大多数Linux发行版都有一个只安装部分所含的软件包的选项,通过分析你的需求,你可能会注意到大部分软件包你都是不需要的。这会节省许多的磁盘空间,因为其中有些程序是非常大的。甚至在你的确需要一个特定的软件包或程序时,你也不需要全都安装它。例如,有些随机文档是不必要的,还有些GNU EmacsElisp文件、有些X11的字库文件以及一些编程用的库文件都是不需要的。

如果你不能卸下软件包,你可以用压缩的办法。诸如gzipzip的压缩程序能够压缩(或解压)单个文件或一组文件。gzexe系统能够不可见地[透明地]为用户压缩以及解压执行程序(未使用的程序被压缩,当得到使用时就解压)。正在试验中的DouBle系统能够压缩整个文件系统中的所有文件,而对于使用该文件系统的程序是不可见的[或说是透明的]。(如果你对诸如MS-DOS下的Stacker程序熟悉的话,它们的原理是一样的。)

 

注释

  1. 圆盘是用坚硬的物质做成的,例如,铝合金,硬盘也就从此得名。
  2. BIOS是一些存储于ROM芯片中的内建的软件。除了其它的功能外,它管理启动最初的步骤。
  3. 这些数据是完全虚构的。
  4. 也就是说,盘片内的表面,在塑胶覆盖里面的金属盘。
  5. 当然也是完全不同的。
  6. 不合逻辑吗?
  7. 有关更多的信息,参见内核原代码或内核黑客手册。
  8. 它当然是非加载的,但是n70年代神秘地消失了,并且再也没出现。如果你发现了它,请告知贝尔实验室,NJ
  9. 为了用户的利益,需要好好思考几秒钟。
  10. Sic transit discus mundi