3 Linux管理员手册--存贮介质

Linux管理员手册(3)--磁盘和其他存贮介质的使用安装和升级系统时,需要对硬盘做很多工作 。必须在硬盘上做文件系统,使文件能存在其上,并为系统不同的部分保留空间 。
本章说明所有这些初始化工作 。通常,一旦你建立了系统,就不必再做这些工作(除了使用软盘) 。如果你要增加一个新硬盘或更好地调整你的硬盘的使用,那么可能回到这一章 。
管理磁盘的基本任务有:
格式化磁盘 。这为磁盘进入使用做一些工作,比如检查坏扇区 。(现在多数硬盘无须格式化 。)
给硬盘分区,如果想用于互相不干扰的几件事 。分区的一个原因是要在一个硬盘上存不同的操作系统 。另一个原因是将用户文件和系统文件分开,以简化备份并在系统崩溃时有助于保护系统文件 。
在每个磁盘或分区上建立合适类型的文件系统,然后文件就可以在其上产生和存取 。在你建立文件系统前,磁盘对Linux没有意义 。
将不同的文件系统安装起来形成一个单独的树结构,按需要可以自动或手工完成 。(手工安装的文件系统通常还要手工unmount)
5章包括虚拟内存和磁盘cache的信息,使用磁盘应该知道这些 。
本章说明对硬盘、软盘、CDROM和磁带机应该知道什么 。
2种设备
UNIX及Linux,识别2类设备:随机存取的块设备(如磁盘)和字符设备(如磁带和串行线),有些是串行的,有些是随机存取的 。文件系统支持的每种看来是个设备文件 。当读写设备文件时,数据与设备联系 。这样没有必要为存取设备编制特别的程序(程序不直接获取中断或读取串口),例如,发送文件到打印机,只需:
$ cat filename > /dev/lp1
$
文件内容就被打印了(当然,文件必须是打印机能理解的格式) 。当然,因为不应该让多人同时cat文件到同一打印机,一般用特定的程序发送文件去打印(通常是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";更多的信息见ls man页 。
注意即使设备没有安装,一般所有设备文件都存在 。因此有/dev/sda 文件并不意味着你真的有个SCSI硬盘 。有所有的设备文件使安装程序更简单,也易于增加新硬件(无须再为产生新设备的设备文件找出正确的参数) 。

硬盘
本节介绍有关硬盘的术语 。如果你已经知道这些项目和内容,可以跳过本节 。
硬盘包括一到数片盘片platters,其一个或两个面surfaces涂有磁性材料用于记录数据 。每面有一个读写头read-write head用于读写数据 。盘片有一个共同的轴,典型的旋转速度是每分钟3600转,高性能的硬盘转速可能更高 。磁头可沿着盘片的半径移动,磁头移动加上盘片旋转可以使词头存取磁盘表面的任何一个位置 。
处理器(CPU)和实际磁盘通过磁盘控制器disk controller通讯 。这使计算机其他部分不必知道如何使用驱动器,因为不同磁盘的控制器可以做成对计算机其他部分相同的接口 。这样,计算机只要说"嗨,磁盘,给我我要的东西",而不是用一串长而复杂的电信号来移动磁头到正确的位置,并等正确的位置到了磁头下后再做那些不愉快的工作 。(实际上,到控制器的接口仍然很复杂,但比没有好多了 。) 控制器还可以做一些其他的事,比如缓冲,或自动坏扇区替换等 。用电信号控制操作机械部件,
以上只是理解硬件所需的 。还有其他好多工作,比如马达旋转磁盘、移动磁头,但这都与理解硬盘工作原理无关 。
磁盘表面通常被分为同心圆环,叫磁道tracks,磁道又被分为扇区sectors 。用这样分来将磁盘定位,用于为文件定位磁盘空间 。要在硬盘上找到给定的位置,可能?quot;3面5道7扇区" 。通常所有磁道有相同的扇区数,但也有硬盘在外圈磁道放较多的扇区(所有扇区用同样大小的物理空间,这样在较长的外圈磁道可以容纳更多的数据) 。一般一个扇区容纳512字节数据 。磁盘不能处理比一个扇区更小的数据量 。
每个面以相同的方式分为磁道和扇区 。这意味着当一个磁头在某个磁道时,其他磁头也在相应的位置,所有相同位置的磁道组成柱面cylinder 。磁头从一个磁道(柱面)移动到另一个需要花时间,所以将经常要在一起存取的数据(如一个文件)放在一个柱面里 。这改善了性能 。当然不可能完全作到,文件被放在几个相分离的位置叫碎片fragmented 。
磁盘的面(或头,实际是一样的)、柱面、扇区数各不相同,硬盘这些数目叫硬盘参数geometry 。硬盘参数通常存在一个特定的、由电池供电的存储区中,叫CMOS RAM,操作系统在引导启动或驱动器初始化时可以从那里得到硬盘参数 。
不幸的是,BIOS 有一个设计限制,就是不能在CMOS RAM中定义大于1024的磁道数,这对大硬盘来说就太小了 。为了克服这个问题,硬盘控制器在磁盘参数上做了一个欺骗,用地址转换translates the addresses使计算机接受 。例如,一个硬盘可能有8个磁头,2048个磁道,每磁道35个扇区 。其控制器可以对计算机谎称它有16个磁头,1024个磁道,每磁道35个扇区,这样就没有超过磁道数的限制,地址转换将磁头数减半,磁道数加倍后传给硬盘 。实际的算法可能更复杂,因为数量可能不象我们在这里假设的这么好(但这不影响我们理解原理) 。这个转换在操作系统来看产生了错觉,并可能影响操作系统对把所有数据存在相同柱面的企图受到影响 。
转换只是IDE硬盘的问题 。SCSI硬盘使用连续的扇区号(即控制器将连续的扇区好转换成磁头、柱面、扇区的三参数组),对CPU与控制器的通信使用完全不同的方法,因此不会有这个问题 。注意,计算机可能根本不知道一个SCSI硬盘的实际参数 。
由于Linux经常不知道一个硬盘的真正参数,其文件系统也不试图将文件存在一个柱面里 。而是争取给一个文件分配连续编号的山区,这样能得到类似的性能 。对于控制器上有cashe或控制器能自动预取的硬盘,情况将更复杂 。
每个硬盘表现为一个单独的设备文件 。通常只能有2-4个IDE硬盘 。这就是 /dev/hda , /dev/hdb , /dev/hdc , 和 /dev/hdd。SCSI是 /dev/sda , /dev/sdb , 等等 。其他硬盘类型有类似的命名约定,更多的信息见[Anv] 。注意硬盘的设备文件给出整个硬盘的存取,而不是分区(下面讨论的),因此如果不小心可能搞乱分区或数据 。硬盘的设备文件只在存取主引导扇(也将在下面讨论)时使用 。
软盘
软盘的一面或两面涂有和硬盘类似的磁性介质 。软盘自己没有读写头,读写头在驱动器上 。软盘相当于硬盘的一张盘片,但可移动,一个驱动器可以存取不同的软盘,而硬盘则是一个独立的单元 。
如同硬盘,一张软盘也分为磁道和扇区(软盘2面上的相同的磁道组成柱面),但数量要比硬盘少得多 。
软驱通常可以使用几中不同的盘片,例如,一个3.5"软驱可以使用720KB和1.44MB的软盘 。因为软驱操作有些不同,而操作系统必须知道软盘的容量,所以软驱有许多设备文件,每个都与软驱和软盘种类有关 。因此,/dev/fd0H1440 是第一个软驱(fd0),必须是3.5"软驱,使用3.5"高密度软盘(H),容量是1440KB(1440),即普通的3.5"HD软盘 。软盘设备的命名约定见[Anv] 。
软驱的名字是复杂的,因此Linux有一个特定的软驱设备类型,能自动检测软驱中软盘的种类 。它使用不同的软盘类型试图读取新插入的软盘的第一个扇区,直到找到正确的一个 。这自然要求软盘是已经格式化过的 。自动设备叫/dev/fd0 、/dev/fd1 等 。
存取软盘的自动设备的参数可用程序setfdprm 设定 。这可使你使用不是通常容量的软盘,例如有非标准扇区数的软盘,或自动检测由于某种原因失败或适当的设备文件丢失 。
Linux除了所有标准的,还能处理许多非标准的软盘格式 。这有时需要特殊的格式化程序 。我们现在先跳过这些软盘格式,同时你可以查看/etc/fdprm 文件 。它定义了setfdprm 识别的设定 。
操作系统必须知道软驱何时换了软盘,例如,以免使用上一张软盘的cache数据 。不幸的是,当用于此的信号线断了或不好时,当在MSDOS中使用时,这并不总有效 。如果你曾遇到过软驱的这种怪异的问题,可能是这个原因 。解决这个问题的唯一方法是修理软驱 。
CD-ROM
CD-ROM驱动器使用一个光学可读的塑料涂布的盘片 。信息记录在盘片表面 的从中心的边沿的螺旋型小坑上 。驱动器发出一束激光来读盘 。当激光射到小坑上,激光以一种方式反射;当它射到光滑表面上,它以另一种方式反射 。这很容易地编码成bit,组成信息 。其他很容易,不过是机械 。
CD-ROM驱动器比硬盘慢 。典型的硬盘的平均寻道(seek)时间小于15毫秒,而快速的CD-ROM驱动器要花零点几秒 。实际数据传输率则相当快,在数百KB/s 。速度慢使CDROM驱动器不能代替硬盘使用 (有些Linux distributions提供"live" CD-ROM文件系统,使之不必拷贝文件到硬盘,使安装简单并节约了许多硬盘空间),虽然是可能的 。要安装新软件,CD-ROM很好,因为在安装时速度并非最重要的 。
有多种方法在CDROM上安排数据 。最流行的是国际标准化组织定义的ISO9660 。这个标准定义了一个最小的文件系统,甚至比MSDOS更粗糙 。这样,由于它是这么小,所有操作系统都可以将它映射到自己的系统 。
不同UNIX不能使用ISO9660文件系统,因此开发了对这个标准的一个增强,叫Rock Ridge增强 。Rock Ridge允许长文件名、符号连接和许多其他优点,使CD-ROM更象UNIX文件系统 。同时,Rock Ridge文件系统仍然是一个有效的ISO9660文件系统,使非UNIX一样可以使用 。Linux同时支持ISO9660和Rock Ridge增强,增强被自动识别和使用 。
文件系统只是一部分,许多CD-ROM包含的数据需要特定的程序存取,而多数程序不能运行在Linux下 (当然,可能运行在Linux的MSDOS仿真器dosemu下) 。
CD-ROM驱动器通过相关的设备文件存取 。有多种方法将CDROM连接到计算机:SCSI、声卡或EIDE 。要完成这的硬件hacking工作超出了本书的范围,但连接方法决定了设备文件 。指导见[Anv]
磁带
磁带驱动器使用磁带,类似 音乐用的盒带 。磁带是串行的,即如果要得到给定部分的数据,必须经过所有部分 。磁盘可以随机存取,即可以直接跳到磁盘上的某个部分 。串行存取的磁带当然慢了 。
另外一方面,磁带相当便宜,因为无须快速 。也容易做得很长,因此可以容纳大量的数据 。这使磁带很适于如归档、备份等无须高速的、但需要低成本和大容量的事情 。
格式化
格式化在磁介质上写用于标记磁道和扇区的标志的过程 。磁盘格式化前,其磁表面是完成的一块 。格式化后,混沌变为秩序,建立的磁道,划分了扇区 。实际细节并非准确地这样,但重要的是:磁盘不经过格式化是不能使用的 。
这里术语有些模糊:MS-DOS中,格式化(format)这个词还包括了产生文件系统的过程(下面将讨论的) 。这两个过程经常一起使用,尤其是软盘 。当必须区分时,真正的格式化被称为低级格式化low-level formatting,而建立文件系统被成为高级格式化high-level formatting 。在UNIX圈中,这两者叫格式画format和建立文件系统make a filesystem,本书中也这样称 。
IDE硬盘和一些SCSI硬盘实际上厂商已经做了格式化,并无须重复;因为多数人无须关心它 。实际上,格式化硬盘可能反而不好,比如因为硬盘可能需要用特定的方法格式化使坏扇区被自动替换 。
磁盘经常需要特定的程序来格式化,因为驱动器的格式化逻辑的接口每个驱动器都不一样 。格式化程序经常在控制器BIOS上,或用MSDOS程序提供,这都不太容易在Linux中使用 。
格式化中可能会发现磁盘的坏点,叫坏块bad blocks or bad sectors 。这有时由驱动器自己处理 。但有时,如果坏块太多,需要一些工作来避免使用磁盘的这部分 。The logic to do this is built into the filesystem; 下面将说明如何增加这些信息到文件系统 。另外,产生一个只覆盖这些坏的部分的小分区也是一个办法 。如果坏区较大,这可能是个好办法,因为文件系统有时难以处理大量的坏区 。
软盘格式化使用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 也将验证软盘,例如检查坏块 。它在坏块试验几次(你通常能听到,驱动器的噪声很明显) 。If the floppy is only marginally bad (due to dirt on the read/write head, some errors are false signals), fdformat 可能没事,而真正的错误可能退出有效过程 。核心把发现的每个I/O错误打印log信息,送到控制台,或者,如果使用了syslog ,也送到/usr/adm/messages 文件 。fdformat 自己不说明哪里出错(也不必考虑,软盘很便宜,坏了就扔) 。
$ fdformat /dev/fd0H1440
Double-sided, 80 tracks, 18 sec/track. Total capacity 1440 kB.
Formatting ... done
Verifying ... read: Unknown error
$
badblocks 命令可用于查找任何磁盘或分区的坏块(包括软盘) 。它不格式化磁盘,因此可以用于检查存在的文件系统 。下面的例子检查出一张3.5"软盘上的2个坏块:
$ badblocks /dev/fd0H1440 1440
718
719
$
badblocks 输出发现的坏块的块号 。多数文件系统可以避免这样的坏块 。他们维护一个已知的坏块列表,在文件系统建立时初始化,并可以在以后修改 。初始的坏块查找可由mkfs 命令完成(它初始化文件系统),以后可以用badblocks 来检查,新的块可以用fsck 加入 。后面我们将说明mkfs 和fsck。
许多新型的硬盘自动发现坏块,并企图用一个特定的、保护的好块来代替它 。这对操作系统是不可见的 。这种特征应该在硬盘手册的文档中,如果你好奇的话 。但即使这样的硬盘也可能失败,如果坏块数量太大的话,虽然如果这样,那硬盘就基本上不能用了 。
分区
一个硬盘可分为几个分区 。每个分区好象是单独的硬盘 。这样,你如果只有一个硬盘,却想安装2个操作系统,你可以把这个硬盘分为2个分区 。每个操作系统任意使用自己的分区而不干扰另一个 。这种方法,2个操作系统可以在同一硬盘上和平共处 。如果没有分区,你只能为每个操作系统购买一个硬盘 。
软盘不分区 。这没有技术原因,只因为太小,没有必要 。CDROM一般也不分区,因为作为一个大盘更易于使用,而且很少有多操作系统的需要 。
MBR(主引导记录), 启动扇区和分区表
一个硬盘如何分区的信息存在它的第一个扇区(即第一面第一道第一扇区) 。这个第一扇区是硬盘的主引导记录(MBR);这是计算机启动时BIOS读入和启动的扇区 。主引导记录包括一段小程序,读入分区表,检查哪个分区是活动分区(即启动分区),并读入活动分区的第一个扇区:该分区的启动扇区(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 1023182 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 14361183 Linux native
/dev/hda6 745 745 790 1963683 Linux native
$
扩展和逻辑分区
PC硬盘的最初的分区方案只允许4个分区 。实际使用中这太少了,比如有人想装多于4个操作系统 (Linux, MS-DOS, OS/2, Minix, FreeBSD, NetBSD, Windows/NT等),或有时一个操作系统有多个分区更好,例如由于速度的原因,Linux的对换区最好单独使用自己的分区,而不是在主 Linux分区中(下文详述) 。
为克服这个设计问题,发明了扩展分区 。这个方法允许将基本分区分为若干子分区,因而被子分区的基本分区称为扩展分区,而子分区称为逻辑分区,他们的表现类似基本分区 ,但产生方法不同 。他们之间没有速度差别 。
硬盘的分区结构可能类似 。这个硬盘被分为3个基本分区,第二个被分为2个逻辑分区 。部分硬盘根本没有分区 。硬盘是一个整体,每个基本分区有一个启动扇区 。
分区种类
分区表(MBR和扩展分区里都有)中,对每个分区,有一个字节指出分区种类 。这试图确定使用该分区的操作系统,或用于何操作系统 。其目的是避免2个操作系统使用同一分区 。可实际上,操作系统并不真的注意分区种类字节;例如,Linux根本不管它是什么 。较坏的情况是,有些操作系统错误地使用它:例如有些版本的DR-DOS忽略了它的最高位(MSB),而其他一些系统则不是 。
没有一个标准化组织定义分区种类字节每个值的意义,但一些共同接受的值包括在表 4.1中 。相同的列表可以通过Linux的fdisk 命令得到 。
给硬盘分区
有许多产生和删除分区的程序 。许多操作系统自带,最好使用其自带的,除非要做一些它不能作到的 。许多这种程序叫fdisk , 包括Linux, 或其变种 。Linux fdisk 的使用细节可见其Man手册 。cfdisk 命令类似fdisk , 但有更好的用户界面(全屏的) 。
使用IDE硬盘时,启动分区(带可启动核心映象文件的分区)必须全在前1024个柱面内 。这是因为硬盘通过BIOS启动(在系统进入保护模式前),而BIOS不能处理多于1024柱面 。有时也可能使用部分在前1024柱面的启动分区,这要求所有用BIOS读入的文件都在前1024柱面内 。由于这难与安排,因此这是个很差的主意;你不可能知道什么时候核心升级或磁盘碎片整理会导致系统无法启动 。因此,应该确认你的启动分区完全在前1024柱面内 。
事实上,一些新版的BIOS和IDE硬盘可以处理多于1024柱面 。如果你有这样一个系统,你可以忘却这个问题;如果你不能确认,还是把启动分区放在前1024柱面内 。
每个分区拥有一块连续的扇区 。因为Linux文件系统使用1 kB的块,即2个扇区,所以奇数个扇区会导致最后一个扇区不能使用,这不会有什么问题,但不好,有些版本的 fdisk 会对此给出警告 。
改变分区大小一般要求首先备分此分区想保留的所有东西(为防万一,最好备分整个硬盘),然后删除此分区,产生新分区,最后回存所有东西到新分区 。如果是扩大分区,你可能需要调整相邻分区的大小(并备分、回存) 。
由于改变分区大小是如此痛苦,最好一次就确定 。或拥有一个有效而易用的备分系统 。如果你通过无须太多人工干预的介质安装(例如CDROM,而不是软盘),那么开始可以比较容易地玩玩各种设置 。因为你无须备分什么数据,改几次分区大小不会太过痛苦 。
有个MSDOS的程序叫fips , 可以无须备分和回存地改变MSDOS分区的大小, 但对其他文件系统,备分回存还是必须的 。
设备文件和分区
每个分区和扩展分区有自己的设备文件 。这些文件的命名规定是在整个盘的名字加分区号,并约定1-4是基本分区(不管真的有几个基本分区),5-8是逻辑分区(不管它在哪个基本分区中) 。例如,/dev/hda1 是第一个IDE硬盘的第一个基本分区,而/dev/sdb7 是第二个SCSI硬盘的第三个扩展分区 。设备列表 [Anv]给出更详细的信息 。
文件系统
什么是文件系统?
文件系统是操作系统用于明确磁盘或分区上的文件的方法和数据结构;即在磁盘上组织文件的方法 。也指用于存储文件的磁盘或分区,或文件系统种类 。因此,可以说"我有2个文件系统"意思是他有2个分区,一个存文件,或他用 "扩展文件系统",意思是文件系统的种类 。
【3 Linux管理员手册--存贮介质】磁盘或分区和它所包括的文件系统的不同是很重要的 。少数程序(包括最有理由的产生文件系统的程序)直接对磁盘或分区的原始扇区进行操作;这可能破坏一个存在的文件系统 。大部分程序基于文件系统进行操作,在不同种文件系统上不能工作 。
一个分区或磁盘能作为文件系统使用前,需要初始化,并将记录数据结构写到磁盘上 。这个过程就叫建立文件系统 。
大部分UNIX文件系统种类具有类似的通用结构,即使细节有些变化 。其中心概念是超级块superblock, i节点inode, 数据块data block,目录块directory block, 和间接块indirection block 。超级块包括文件系统的总体信息,比如大小(其准确信息依赖文件系统) 。i节点包括除了名字外的一个文件的所有信息,名字与i节点数目一起存在目录中,目录条目包括文件名和文件的i节点数目 。i节点包括几个数据块的数目,用于存储文件的数据 。i节点中只有少量数据块数的空间,如果需要更多,会动态分配指向数据块的指针空间 。这些动态分配的块是间接块;为了找到数据块,这名字指出它必须先找到间接块的号码 。
UNIX文件系统通常允许在文件中产生孔(hole) (用lseek ; 请看手册), 意思是文件系统假装文件中有一个特殊的位置只有0字节,但没有为这文件的这个位置保留实际的磁盘空间(这意味着这个文件将少用一些磁盘空间) 。这对小的二进制文件经常发生,Linux共享库、一些数据库和其他一些特殊情况 。(孔由存储在间接块或i节点中的作为数据块地址的一个特殊值实现,这个特殊地址说明没有为文件的这个部分分配数据块,即,文件中有一个孔 。)
孔有一定的用处 。在笔者的系统中,一个简单的测量工具显示在200MB使用的磁盘空间中,由于孔,节约了大约4MB 。在这个系统中,程序相对较少,没有数据库文件 。有关这个测量工具的细节请看附录 A.
Filesystems galore
Linux支持多种文件系统 。下面是最重要的几个:
minix
最老的,相信是最可靠的,但缺少特色(有些没有时间标记,文件名最长30个字符),能力有局限(每个文件系统最多64MB) 。
xia
minix文件系统的一个修正版本,提升了文件名和文件系统大小的局限,但没有新的特色 。不太流行,但据说工作得很好 。
ext2
最好的Linux自己的文件系统,也是当前最通用的 。其设计易于向上兼容,所以新版的文件系统代码无需重做已有的文件系统 。
ext
ext2的老版,且不向上兼容 。难于用新版安装程序安装,大部分人都改用ext2 。
另外,支持多种其他现存的外围文件系统,很容易与其他外围文件系统交换文件 。这些外围文件系统好象是自己的一样,除了可能缺少一些一般UNIX的特征,或有些不同的局限 。
msdos
与MSDOS、OS/2等的FAT文件系统兼容 。
umsdos
Linux下的扩展msdos文件系统驱动,支持长文件名、所有者、允许权限、连接和设备文件 。允许一个普通的msdos文件系统用于Linux,而无须为Linux建立单独的分区 。
iso9660
标准CDROM文件系统,通用的Rock Ridge增强,允许长文件名 。
nfs
网络文件系统,允许多台计算机之间共享文件系统,易于从所有这些计算机上存取文件 。
hpfs
OS/2文件系统 。
sysv
SystemV/386, Coherent, 和Xenix文件系统 。
根据情况选择文件系统 。如兼容性或其他原因必需使用非Linux文件系统,那就必须用 。如果可以自由选择,可能最明智的选择是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 调用的程序有不同的命令行接口 。最通用和最重要的选项如下,细节请看手册 。
-t fstype
选择文件系统种类 。
-c
查找坏块,初始化坏块列表 。
-l filename
从文件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 初始化 。
-c选项可以与mkfs 一起使用,而无须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 是必要的 。
在硬盘或分区上准备文件系统的过程和软盘是一样的,除了无须格式化 。
Mount和unmount
一个文件系统可以使用之前,必须mount 。操作系统然后做一些记录以确认正常 。因为UNIX所有的文件在一个目录树中,mount操作的结果使新的文件系统的内容好象在某个已经mount的文件系统的一个已经存在的子目录中 。
上面的mount可能使用如下命令:
$ mount /dev/hda2 /home
$ mount /dev/hda3 /usr
$
mount 命令使用2个参数 。第一个是与包括文件系统的磁盘或分区相关的设备文件 。第二个是要mount到的目录 。mount以后,这2个文件系统的内容好象是/home 和/usr 目录 。这样就可以说:/dev/hda2 被mount到 /home , /usr 也同样 。要看每个文件系统,就看其被安装的目录,好象它就是在那里 。注意设备文件的区别,/dev/hda2 , 和安装到的目录/home。设备文件给出硬盘原始内容的存取,安装到的目录给出磁盘上文件的存取 。安装到的目录叫安装点 。
Linux支持许多文件系统 。mount 会试着猜测文件系统种类 。也可以使用-t fstype 选项直接定义种类;这有时是必要的,因为自检测mount 并非总能成功 。例如要mount一个MSDOS软盘,可以用如下命令:
$ mount -t msdos /dev/fd0 /floppy
$
安装点目录不必是空的,但必须存在 。其中的所有文件当文件系统mount后将不可用名字存取(已经打开的文件将继续可存取 。有其他目录硬连接的文件可以通过那些名字存取) 。这没有坏处,反而可能更有用 。例如,有人喜欢将/tmp 和/var/tmp 作为同义,将/tmp 作为/var/tmp 的符号连接 。系统启动时,在/usr 文件系统被mount之前,使用驻留在根文件系统的 /var/tmp 目录 。当/usr 被mount上以后,根文件系统上的/var/tmp 将不可用,如果根文件系统上不存在 /var/tmp ,那么在mount上/var 之前将不可能使用暂存文件 。
如果不打算在一个文件系统上写任何东西,可以使用mount 的-r开关做一个只读mount 。这将使核心停止任何对此文件系统的写要求,也将停止核心的对i节点的文件存取时间的更新 。只读mount对不可写介质是必要的,例如CDROM 。
细心的读者可能已经注意到一个小的逻辑问题 。第一个文件系统(叫根文件系统,因为它包含根目录)如何mount,因为很明显,它不能mount到另一个文件系统? Well, the answer is that it is done by magic. The root filesystem is magically mounted at boot time, and one can rely on it to always be mounted-- 如果根文件系统不能mount,系统将不能启动 。The name of the filesystem that is magically mounted as root 被编译进核心,或用LILO或rdev 设置 。
根文件系统通常先被只读mount 。然后启动手稿运行fsck 校验它的有效性,如果没有问题,将re-mount它,使之可写 。fsck 不能运行于一个已mount的文件系统,因为fsck 运行时,任何文件系统的改变将导致错误 。因为根文件系统在被检查时是只读,fsck 可以无虑地修复任何问题,因为re-mount 操作将刷新文件系统在内存中的所有数据 。
在有其他文件系统的许多系统中,启动时要自动mount,可以在/etc/fstab 文件中定义:文件格式细节请参考fstab 的手册页 。mount特别的文件系统的特别细节依赖于许多因素,可以根据需要由每个管理员设置 。When the chapter on booting is finished, you may read all about it there.
当一个文件系统不需要再mount着,可以用umount . umount 加一个参数unmount它,参数可以是设备文件或安装点 。例如,要unmount上面例子中的目录,可以用:
$ umount /dev/hda2
$ umount /usr
$
要了解使用这个命令的更多的说明,参阅手册 。注意:记住unmount已经mount的软盘,而不能仅仅将软盘弹出软驱!由于磁盘缓冲,在你unmount软盘之前无须回写,因此过早取出软盘将导致内容不正确 。只从软盘上读还不要紧,如果写,就可能发生灾难性的损失 。
mount和umount需要超级拥护特权,即只有root 用户可以做 。原因是:如果任何用户都可以mount软盘到任何目录,那么很容易用软盘做,比如,用特洛伊木马替换/bin/sh , 或者其他常用的程序 。但是允许用户使用软盘经常又是必要的,有几种方法:
给用户root 口令,很明显这对安全不利,但是最简单的方法 。如果没有安全要求,这个方法很好,比如在非网络的、个人系统上 。
使用一个程序比如sudo 允许拥护使用mount 。这同样对安全不利,但没有直接给任何人超级用户特权 。
让用户使用mtools , 这是一个利用MSDOS文件系统的软件包,无须mount 。如果是MSDOS软盘这样做很好,否则不好 。
在/etc/fstab 中用合适的选项列出软驱设备和允许的安装点 。
最后一个选择可以在/etc/fstab 文件中加类似下面的一行来完成:
/dev/fd0 /floppy msdos user,noauto 0 0
各列分别是:要mount的设备文件,要安装到的目录,文件系统类型,选项,备份频率(用于dump ) 和fsck 次序(定义启动时文件系统被检查的次序,0表示不检查) 。
noauto选项使系统启动是不自动mount(即, it stops mount -a from mounting it) 。user允许任何用户mount这个文件系统,并且,由于安全原因,不允许执行程序(normal or setuid) and interpretation of device files from the mounted filesystem 。这样,任何用户都可以用如下命令mount一个msdos文件系统的软盘:
$ mount /floppy
$
软盘可以用相关的umount 被unmount 。
如果想提供多种软盘的存取,需要给出多个安装点 。对每个安装点的设置可以不同 。例如,提供MSDOS和ext2文件系统的存取,可以在/etc/fstab 文件中加如下行:
/dev/fd0 /dosfloppy msdos user,noauto 0 0
/dev/fd0 /ext2floppy ext2 user,noauto 0 0
对于MSDOS文件系统(不仅是软盘),可能需要用uid, gid,和umask 文件系统选项来限制存取权限,请看mount 手册页 。如果不小心,mount一个MS-DOS文件系统将给予任何用户至少是读权限,这可不是一个好主意 。
用fsck检查文件系统完整性
文件系统很复杂,因此易于发生错误 。可以用fsck 命令检查文件系统是否正确和有效 。它可以根据指令修复找到的小错误,并将未修复错误报告用户 。幸运的是,文件系统的代码非常有效,所以根本极少出现问题,并且问题通常原因是电源失败、硬件失败、或操作错误,例如没有正常关闭系统 。
大多数系统设置为启动时自动运行fsck ,因此任何错误将在系统使用前被检测到(并根据希望修正) 。使用有错误的文件系统可能使问题变得更坏:如果数据结构有问题,使用这个文件系统可能使之更糟,导致更多的数据丢失 。当然,在大的文件系统上运行fsck 会花一定的时间,如果系统正常关闭,几乎从不发生错误,因此有一些方法可以不进行检查 。如果文件/etc/fastboot 存在,就不检查 。另外,如果ext2文件系统在超级快中有一个特定的标记告知该文件系统在上次mount后没有正常unmount. 如果标记指出unmount正常完成(假设正常unmount指出没问题),e2fsck (fsck 的ext2文件系统版) 就不检查系统 。/etc/fastboot 是否影响系统依赖于你的启动手稿,但ext2标记则在你使用e2fsck 时发生作用--基于一个e2fsck 选项(参阅e2fsck 手册页)
自动检查只对启动时自动mount的文件系统发生作用 。使用fsck 手工检查其他文件系统,比如软盘 。
如果fsck 发现为修复的问题,你需要深入了解文件系统的一般工作原理和有问题的文件系统的细节,或好的备份 。最后一个办法容易(虽然冗长)安排,如果你自己不知道,有时可以通过朋友、Linux新闻组、电子邮件列表或其他支持源安排 。我很想告诉你更多,但我对这的学习和实践也并不多 。Theodore T"so的debugfs 程序应该有用 。
fsck 只能运行于未mount的文件系统,不要用于已mount的文件系统(除了启动时的只读根文件系统) 。这是因为它存取原始磁盘,在操作系统不知道的情况下修改文件系统 。There will be trouble, if the operating system is confused.
用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 将试着将此块移到其他地方 。如果该块真的坏了,而不是在坏块边缘,文件内容可能丢失 。
Fighting fragmentation
文件写到磁盘时,不一定在连续的块中 。没在连续块中的文件叫碎片 。因为磁盘的读写头回更多地移动,读碎片文件会花较长的时间 。虽然如果有好的读前缓冲系统不会有什么问题,但最好还是避免碎片 。
Ext2文件系统试图使碎片最少,即使不能将一个文件的所有块存在连续扇区中,也尽量靠近 。Ext2通常有效地安排里文件其他块最近的空闲块,因此很少需要关心碎片问题 。Ext2文件系统有一个消除碎片程序,请看参考书目中的 [TV] 。
有许多MSDOS消碎片程序在文件系统中移动块以消除碎片 。其他一些文件系统,消碎片必须通过备份-重产生-回存文件系统来完成 。对于所有文件系统,消碎片应该备份文件系统,因为很多原因可能在消碎片过程中导致错误 。
对所有文件系统的其他工具
一些其他工具对管理文件系统有用 。df (Disk Free)显示一个或多个文件系统的空闲磁盘空间 。du (Disk Usage)显示一个目录和其内的所有文件使用了多少磁盘空间 。这用于发现磁盘空间浪费 。
sync 强制将磁盘缓冲的所有未写块写入磁盘(见 5.6) 。这一般无须手工完成,由守护进程update 自动完成 。这在有些情况下很有用,例如,如果update 或其辅助进程bdflush 死了,或你不能等运行update 必须马上 关闭电源 。
对ext2文件系统的其他工具
除了产生文件系统的mke2fs 和检查文件系统的e2fsck 直接或通过与文件系统类型无关的前端存取外,Ext2文件系统还有几个有用的工具 。
tune2fs 调整文件系统参数 。一些有趣的参数有:
最大mount数 。当文件系统被mount过多少次以后,即使标志是干净的,e2fsck 强制检查 。对用于开发或测试的系统,应该降低这个限制数 。
最大检查间隔 。到达这个间隔时间,即使标志是干净的,e2fsck 强制检查 。如果文件系统不是经常mount,可以不使能这个功能 。
保留给root的块数 。Ext2给root保留一些块,这样如果文件系统满了,还可能无须删除任何东西做系统管理 。保留量确省是5%,这在大多数磁盘上不会造成浪费 。当然,软盘没有理由保留块 。
参阅tune2fs 手册页
dumpe2fs 显示一个ext2文件系统的信息,大部分来源于超级块 。有些输出信息是技术性的,要求对文件系统工作的理解(见附录 ), 但许多即使是一般管理员是也易于理解的 。
debugfs 是一个文件系统调试器 。它允许直接存取磁盘上的文件系统数据结构,可用于修复fsck 不能自动修复的磁盘 。它也可用于恢复被删除的文件 。但是,debugfs 非常要求你理解你所干的事,错误的理解和操作将破坏你的所有数据 。
dump 和restore 可用于备份一个ext2文件系统 。它们是传统UNIX备份工具的ext2版 。关于更有关备份的信息见 9章 。
没有文件系统的磁盘
并非所有磁盘或分区都作为文件系统使用 。例如对换分区,就没有文件系统 。许多软盘作为磁带仿真使用,所以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 , 第二个把映象写到软盘 。(假设用户在第二个命令前换了软盘 。否则这个命令对可能没用 。)
分配磁盘空间
分区概要
用最好的方式给磁盘分区不容易,而且,没有一个通用的正确方法,这包括很多因素 。
传统的方法是有个(相对)小的根文件系统,包括 /bin , /etc , /dev , /lib , /tmp , 和其他系统启动和运行需要的东西 。这种方法,根文件系统(在它自己的分区或硬盘上)是所有系统启动需要的东西 。理由是如果根文件系统小而不常用,系统崩溃时它就不太容易损坏,而且崩溃时也易于修复 。然后给/usr 目录树、用户主目录(经常在/home )、对换空间产生单独的分区或使用单独的硬盘 。分离的用户主目录(存用户文件)在其自己的分区中易于备份,因为一般无须备份程序(/usr 中) 。网络环境中,这样可以使多台计算机共享/usr (例如使用NFS) 这样每台机器可以节约数十、数百兆的磁盘空间 。
多分区的问题是将整个磁盘的空闲空间分割成若干小片 。现在,由于磁盘和操作系统已经很可靠,许多人更倾向与一个分区存所有文件 。当然,这样可能比备份、回存小分区痛苦些 。
对于小硬盘(假设你不做核心开发),最好的方法可能是只要一个分区 。对于大硬盘,分几个大分区可能更好 。尤其在某种情况下出现错误时 。(注意这里说的小和大是相对的,根据你对磁盘空间的需求而言 。)
如果你有多个硬盘,你可能想让根文件系统(包括/usr ) 在一个上,而用户主目录在另一个上 。
最好准备尝试几个不同的分区方案(over time, not just while first installing the system) 。这有些工作量,因为这其实是从头安装系统若干遍,但这是确认正确的唯一方法 。
空间要求
你安装的Linux给出一些对不同配置所需磁盘空间的指示 。单独安装的程序可能也是 。这能帮助你计划你的磁盘使用,但你应该为以后可能的需求保留一些额外空间 。
拥护文件总量基于你的用户希望 。许多人好象想要他们所有可能的文件量,但多多益善 。有些人只有很少的文字处理,也许几兆就够,而有些人可能需要上GB的空间做图象处理 。
顺便说一句,用KB或MB比较文件大小和用MB给出的磁盘空间时,应当注意这2者的可能的不同 。一些硬盘制造商喜欢称1000字节为1KB,1000KB为1MB,而计算机世界的其他地方都以1024为因数 。因此我的MB硬盘实际只是330MB硬盘 。
对换空间在5.5章讨论 。
硬盘分配举例
我原来有个109MB的硬盘,现在我用一个330MB硬盘 。我解释一下我如何分区这些硬盘并说明为什么 。
当我的需要和操作系统变化时,我用不同的方法分区109MB硬盘 。我说明2种方案 。首先,我曾和Linux一起运行MSDOS,为此,我需要大约20MB给MSDOS、C编译器、编辑器、一些其他工具、我工作的程序、和足够的空闲空间 。给Linux开了10MB对换分区,其他79MB作为一个分区给Linux 。我曾试验给出单独的根,/usr , 和/home ,但这样就没有什么空闲空间干什么有趣的事了 。
当我不再需要MSDOS,我重新分区,12MB对换分区,其他是一个单独的文件系统 。
从头分区是为了玩玩要求自己分区的一些东西,例如试试不同的Linux,或比较文件系统的速度 。当没有这些需要后,就把它作为对换区(我喜欢打开好多窗口) 。
给Linux增加更多的磁盘空间
给Linux增加更多的磁盘空间很容易,至少在硬件都安装好后(硬件安装不在本书所述的范围) 。如果需要,先格式化,然后产生分区和上面说过的文件系统,在/etc/fstab 中加入正确的行使之能自动mount 。
节约磁盘空间的提示
节约磁盘空间的最好提示是不要安装不必要的程序 。许多Linux distributions给出安装其所带软件包某些部分的选择,分析你的需求你可能发现好多你并不需要 。这会节约很多磁盘空间,因为许多程序需要很大空间 。即使你需要某部分包或程序,也不一定需要其全部 。例如有些在线文档可能不必要,有些GNU Emacs的Elisp文件, 有些X11的字体,或者有些编程库 。
如果你不能卸装包,你可以压缩 。如gzip 或zip 的压缩程序可以压缩/解压文件或文件群 。gzexe 系统可以对用户透明地压缩/解压程序 (没用的程序被压缩,当被使用时解压) 。实验中的DouBle 系统对程序透明地压缩文件系统中的所有文件 。(如果你熟悉例如Stacker for MS-DOS等产品,原理是一样的 。)