- 第8章 Linux磁盘与文件系统管理
- 由于数据量非常庞大,因此鸟哥将一些信息省略输出了,可能与你的屏幕会有点区别。
- 前半部在显示出 supber block 的内容,包括卷标名称(Label)以及inode/block的相关信息。
- 后面则是每个 block group 的个别信息了,你可以看到各区段数据所在的号码。
- 也就是说,基本上所有的数据还是与 block 的号码有关就是了。
- 8.2 文件系统的简单操作
- 在 Linux 下面如果 df 没有加任何参数,那么默认会将系统内所有的
- (不含特殊内存内的文件系统与 swap) 都以 1 KB 的容量来列出来。
- 至于那个 /dev/shm 是与内存有关的挂载。
- 不同于范例一,这里会以 G、M 等容量格式显示出来,比较容易看。
- 系统里面其实还有很多特殊的文件系统存在的。那些比较特殊的文件系统几乎
- 都是在内存当中,例如 /proc 这个挂载点。因此,这些特殊的文件系统
- 都不会占据硬盘空间。
- 这个范例比较有趣一点,在 df 后面加上目录或者是文件时,df
- 会自动分析该目录或文件所在的分区,并将该分区的容量显示出来,
- 所以,你就可以知道某个目录下面还有多少容量可以使用了。
- 这个范例则主要列出可用的 inode 剩余量与总容量。分析一下与范例一的关系,
- 你可以清楚地发现到,通常 inode 的数量剩余都比 block 还要多呢!
- 直接输入 du 没有加任何参数时,则 du 会分析目前所在目录
- 的文件与目录所占用的硬盘空间。但是,实际显示时,仅会显示目录容量(不含文件),
- 因此 . 目录有很多文件没有被列出来,所以全部的目录相加不会等于 . 的容量。
- 此外,输出的数值数据为 1K 大小的容量单位。
- 这是个很常被使用的功能:利用通配符 * 来代表每个目录,
- 如果想要检查某个目录下那个子目录占用最大的容量,可以用这个方法找出来
- 值得注意的是,如果刚才安装好 Linux 时,那么整个系统容量最大的应该是 /usr
- 而 /proc 虽然有列出容量,但是那个容量是在内存中,不占硬盘空间。
- 利用 du 与 df 来检查一下目前的参数,那个 du -sb
- 是计算整个 /tmp 下面有多少 bytes 的啦!
- 即使多了一个文件在 /tmp 下面,整个 inode 与 block 的容量并没有改变。
- 原来是指向同一个 inode ,另外,那个第二列的连接数也会增加!
- passwd-so 指向的 inode number 不同了。这是一个新的文件,这个文件的内容是指向
- passwd 的。passwd-so 的大小是 6bytes ,因为 passwd 共有6个字符之故
- 整个容量与 inode 使用数都改变了。
- 符号连接果然无法打开。另外,如果符号链接的目标文件不存在,
- 其实文件名的部分就会有特殊的颜色显示。
- 设备文件名 开机区否 开始柱面 结束柱面 1KB大小容量 磁盘分区内的系统
- 想要不存储离开吗?按下 q 就对了!不要随便按 w 。
- 练习一:先进入 fdisk 的界面当中去!
- 练习二: 先看看整个分区表的情况是如何
- 练习三: 按下 d 给它删除。
- 因为 /dev/hdc5 是由 /dev/hdc4 所衍生出来的逻辑分区,因此 /dev/hdc4 被删除,
- /dev/hdc5 就自动不见了。最终就会剩下两个分区而已。
- 鸟哥这里仅是做一个练习而已,所以,按下q就能够离开。
- 练习一: 进入 fdisk 的分区软件界面中,并删除所有分区:
- 由于最后仅剩下一个分区,因此系统主动选取这个分区删除。
- 练习二: 开始新增,我们先新增一个主分区,且指定为 4 号看看。
- 这个地方有趣了,我们知道分区是由 n1 到 n2 的柱面号码 (cylinder),
- 但柱面的大小每块磁盘都不相同,这个时候可以填入 +512M 来让系统自动帮我们找出
- 最接近 512M 的那个 cylinder 号码。因为不可能刚好等于 512MB
- 如上所示:这个地方输入的方式有两种:
- (1) 直接输入柱面的号码,你得要自己计算柱面/分区的大小才行;
- (2) 用 +XXM 来输入分区的大小,让系统自己分柱面的号码。
- +与M是必须要有的,XX为数字
- 注意,只有 4 号。1 ~ 3 保留下来了。
- 练习三: 继续新增一个,这次我们新增扩展分区好了!
- 还记得我们在第3章的磁盘分区表曾经谈到过的,扩展分区最好能够包含所有
- 未分区的区间;所以在这个练习中,我们将所有未配置的柱面都给了这个分区。
- 所以在开始/结束柱面的位置上,按下两个[Enter]用默认值即可!
- 如上所示,所有的柱面都在 /dev/hdc1 里面
- 练习四: 这次我们随便新增一个 2GB 的分区看看。
- 这样就新增了 2GB 的分区,且由于是逻辑分区,所以由 5 号开始。
- 鸟哥这里仅是做一个练习而已,所以,按下 q 就能够离开。
- 这样就创建起来我们所需要的 Ext3 文件系统了。
- 按下两个[Tab],会发现 mkfs 支持的文件格式如上所示,可以格式化 vfat 。
- 比较看看,跟上面的范例用默认值的结果有什么不一样的啊?
- 如果没有加上 -f 的参数,则由于这个文件系统不曾出现问题,
- 检查非常快速,若加上 -f 强制检查,才会一项一项显示过程。
- 看起来,真的有挂载!且文件大小为 2GB 左右。
- 除了实际的文件系统外,很多特殊的文件系统(proc/sysfs…)也会被显示出来!
- 值得注意的是,加上-l参数可以列出如上特殊字体的卷标(label)
- 你可以指定 -t iso9660 这个光盘的格式来挂载,也可以让系统自己去测试挂载。
- 所以上述的命令只要做一个就够了,但是目录的创建初次挂载时必须要进行。
- 因为我的光驱使用的是/dev/hdd的IDE接口之故!
- 我们格式化软盘成为 Windows/Linux 可共同使用的 FAT 格式。
- 从上面的特殊字体可得知磁盘的大小以及设备文件名,知道是 /dev/sda1
- 先找一下已经挂载的文件系统,如上所示,特殊字体即为刚才挂载的设备。
- 卷标名称为 vbird_logical 。
- 上面那个 22 与 10 是有意义的,不要随意设置。
- 注意:这个文件可不是一般文件,不可以随便就放在这里。
- 测试完毕之后请删除这个文件,看一下这个文件的类型,是 p 。
- 这块硬盘缓存 (BuffSize)只有 2MB,但使用的是 UDMA5 ,还可以。
- 鸟哥的这台测试机没有很好。这样的速度,实在差强人意。
- Device Mount point filesystem parameters dump fsck
- 上述特殊字体的部分与实际磁盘有关。其他则是虚拟文件系统或
- 与内存交换空间(swap)有关。
- 竟然不知道何时被挂载了,赶紧给他卸载先。
- /dev/hdc6 /mnt/hdc6 ext3 defaults 1 2
- 看到上面的结果吧?这个文件就是镜像文件,文件非常大。
- 就是这个项目。.iso 镜像文件内的所有数据可以在 /mnt/centos_dvd中看到。
- 测试完成,得将数据卸载!
- 这个命令的简单意义如下:
- if 是 input file ,输入文件。那个 /dev/zero 是会一直输出 0 的设备!
- of 是 output file ,将一堆零写入到后面接的文件中。
- bs 是每个 block 大小,就像文件系统那样的 block。
- count 则是总共几个 bs 的意思。
- 此时就将分区表更新了!
- 这个操作很重要的。不要忘记让内核更新分区表。
- 我有 742664KB 的物理内存,使用 684592KB剩余 58072KB,使用掉的内存有
- 43820KB / 497144KB 用在缓冲/快取的用途中。
- 至于 swap 已经存在了 1020088KB 。这样会看了吧?
- 上面列出目前使用的 swap 设备有哪些的意思。
- 这个命令执行时请特别小心,因为弄错字节,将可能使你的文件系统挂掉。
- 8.6 文件系统的特殊查看与操作
- 看到最后一个特殊字体的地方吗?Group0 的 superblock 是由 1 号 block 开始。
- 请参考前面的命令介绍,因为我们的 /dev/hdc7 在 19.2GB 位置结束,
- 所以我们当然要由 19.2GB 位置处继续下一个分区,这样懂了吧?
- 这样就删除了,所以这个命令的执行要特别注意。
- 因为命令一下去就立即生效了,如果写错的话,会欲哭无泪的。
第8章 Linux磁盘与文件系统管理
系统管理员很重要的任务之一就是管理好自己的磁盘文件系统,每个分区不可太大也不能太小,太大会造成磁盘容量的浪费,太小则会产生文件无法存储的困扰。此外,我们在前面几章谈到的文件权限与属性中,这些权限与属性分别记录在文件系统的哪个块内?这就得要谈到文件系统中的inode与block了。在本章我们的重点在于如何制作文件系统,包括分区、格式化与挂载等,是很重要的一个章节。
8.1 认识EXT2文件系统
Linux 最传统的磁盘文件系统(file system)使用的是 EXT2。所以要了解文件系统就得要由认识EXT2 开始。而文件系统是创建在硬盘上面的,因此我们得了解硬盘的物理组成才行。磁盘物理组成的部分我们在第0章谈过了,至于磁盘分区则在第3章谈过了,所以下面只会很快地复习这两部分。重点在于inode、block,还有superblock等文件系统的基本部分。
8.1.1 硬盘组成与分区的复习
由于各项磁盘的物理组成我们在第0章里面就介绍过,同时第3章也谈过分区的概念了,所以这个小节我们就拿之前的重点出来介绍就好了。详细的信息请你回去那两章自行复习。好了,首先说明一下磁盘的物理组成,整块磁盘的组成主要有:
圆形的盘片(主要记录数据的部分);
机械手臂与机械手臂上的磁头(可读写盘片上的数据);
主轴马达,可以转动盘片,让机械手臂的磁头在盘片上读写数据。
从上面我们知道数据存储与读取的重点在于盘片,而盘片上的物理组成则为(假设此磁盘为单盘片,盘片图标请参考图3-1的示意):
扇区(Sector)为最小的物理存储单位,每个扇区为512bytes;
将扇区组成一个圆,那就是柱面(Cylinder),柱面是分区(partition)的最小单位;
第一个扇区最重要,里面有硬盘主引导记录(Masterbootrecord,MBR)及分区表(partition table),其中MBR 占有446bytes,而partition table 则占有64bytes。
各种接口的磁盘在Linux中的文件名分别为:
/dev/sd[a-p][1-15]:为SCSI,SATA,USB,Flash等接口的磁盘文件名;
/dev/hd[a-d][1-63]:为IDE接口的磁盘文件名。
复习完物理组成后,来复习一下磁盘分区吧!所谓的磁盘分区指的是告诉操作系统“我这块磁盘在此分区可以访问的区域是由A柱面到B柱面之间的块”,如此一来操作系统就能够知道它可以在所指定的块内进行文件数据的读/写/查找等操作了。也就是说,磁盘分区意即指定分区的起始与结束柱面就可以。
那么指定分区的柱面范围是记录在哪里?就是第一个扇区的分区表中。但是因为分区表仅有64bytes 而已,因此最多只能记录四条分区的记录,这四条记录我们称为主(primary)分区或扩展(extended)分区,其中扩展分区还可以再分出逻辑分区(logical),而能被格式化的则仅有分区与逻辑分区而已。
最后,我们再将第3章关于分区的定义拿出来说明一下:
主分区与扩展分区最多可以有4个(硬盘的限制);
扩展分区最多只能有一个(操作系统的限制);
逻辑分区是由扩展分区持续分出来的分区;
能够被格式化后作为数据访问的分区为主要分区与逻辑分区,扩展分区无法格式化;
逻辑分区的数量依操作系统而不同,在Linux系统中,IDE硬盘最多有59个逻辑分区(5号到63号),SATA硬盘则有11个逻辑分区(5号到15号)。
8.1.2 文件系统特性
我们都知道磁盘分区完毕后还需要进行格式化(format),之后操作系统才能够使用这个分区。为什么需要进行“格式化”呢?这是因为每种操作系统所设置的文件属性/权限并不相同,为了存放这些文件所需的数据,因此就需要将分区进行格式化,以成为操作系统能够利用的文件系统格式。
由此我们也能够知道,每种操作系统能够使用的文件系统并不相同。举例来说,Windows 98 以前的操作系统主要利用的文件系统是 FAT(或 FAT16),Windows 2000 以后的版本有所谓的 NTFS 文件系统,至于Linux的正规文件系统则为Ext2(Linux second extended file system,Ext2fs)这一个。此外,在默认的情况下,Windows操作系统是不会认识Linux的Ext2。
传统的磁盘与文件系统的应用中,一个分区就是只能够被格式化成为一个文件系统,所以我们可以说一个文件系统就是一个分区。但是由于新技术的利用,例如我们常听到的 LVM 与软磁盘阵列(software raid),这些技术可以将一个分区格式化为多个文件系统(例如 LVM),也能够将多个分区合成一个文件系统(LVM,RAID)所以说,目前我们在格式化时已经不再说成针对分区来格式化了,通常我们可以称呼一个可被挂载的数据为一个文件系统而不是一个分区。
那么文件系统是如何运行的呢?这与操作系统的文件数据有关。较新的操作系统的文件数据除了文件实际内容外,通常含有非常多的属性,例如Linux操作系统的文件权限(rwx)与文件属性(所有者、群组、时间参数等)。文件系统通常会将这两部分的数据分别存放在不同的块,权限与属性放置到inode 中,至于实际数据则放置到data block 块中。另外,还有一个超级块(superblock)会记录整个文件系统的整体信息,包括inode与block的总量、使用量、剩余量等。
每个inode与block都有编号,至于这三个数据的意义可以简略说明如下:
super block:记录此文件系统的整体信息,包括 inode/block 的总量、使用量、剩余量,以及文件系统的格式与相关信息等;
inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block号码;
block:实际记录文件的内容,若文件太大时,会占用多个block。
由于每个inode与block都有编号,而每个文件都会占用一个inode,inode内则有文件数据放置的block号码。因此,我们可以知道的是,如果能够找到文件的inode的话,那么自然就会知道这个文件所放置数据的block号码,当然也就能够读出该文件的实际数据了。这是个比较有效率的做法,因为如此一来我们的磁盘就能够在短时间内读取出全部的数据,读写的性能比较好。
我们将inode与block块用图解来说明一下,如图8-1所示,文件系统先格式化出inode与block的块,假设某一个文件的属性与权限数据是放置到inode4号(下图较小方格内),而这个inode记录了文件数据的实际放置点为2,7,13,15这4个block号码,此时我们的操作系统就能够据此来排列磁盘的阅读顺序,可以一下子将4个block内容读出来。那么数据的读取就如同图8-1所示中的箭头所指定的模样了。
图8-1 inode/block 数据访问示意图
这种数据访问的方法我们称为索引式文件系统(indexed allocation)。那有没有其他的惯用文件系统可以比较一下啊?有的,那就是我们惯用的U盘(闪存),U盘使用的文件系统一般为FAT格式。FAT这种格式的文件系统并没有inode存在,所以FAT没有办法将这个文件的所有block在一开始就读取出来。每个block号码都记录在前一个block当中,它的读取方式如图8-2所示。
图8-2 FAT 文件系统数据访问示意图
图8-2所示中我们假设文件的数据依序写入1->7->4->15号这四个block号码中,但这个文件系统没有办法一口气就知道四个 block 的号码,它得要一个一个地将 block 读出后,才会知道下一个 block 在何处。如果同一个文件数据写入的 block 分散得太过厉害时,则我们的磁盘磁头将无法在磁盘转一圈就读到所有的数据,因此磁盘就会多转好几圈才能完整地读取到这个文件的内容。
经常会听到所谓的“碎片整理”吧?需要碎片整理的原因就是文件写入的 block 太过于离散了,此时文件读取的性能将会变得很差所致。这个时候可以通过碎片整理将同一个文件所属的 block 汇合在一起,这样数据的读取会比较容易。FAT的文件系统需要经常碎片整理一下,那么Ext2是否需要磁盘整理呢?
由于Ext2是索引式文件系统,基本上不太需要经常进行碎片整理的。但是如果文件系统使用太久,经常删除/编辑/新增文件时,那么还是可能会造成文件数据太过于离散的问题,此时或许会需要进行碎片整理一下的。鸟哥倒是没有在Linux操作系统上面进行过Ext2/Ext3文件系统的碎片整理。
8.1.3 Linux 的Ext2文件系统(inode)
在第6章当中我们介绍过Linux的文件除了原有的数据内容外,还含有非常多的权限与属性,这些权限与属性是为了保护每个用户所拥有数据的隐密性。而前一小节我们知道文件系统里面可能含有的 inode/block/super block 等。为什么要谈这个呢?因为标准的 Linux 文件系统 Ext2 就是使用这种inode为基础的文件系统。
而如同前一小节所说的,inode 的内容用于记录文件的权限与相关属性,至于 block 块则是在记录文件的实际内容,而且文件系统一开始就将inode与block规划好了,除非重新格式化(或者利用resize2fs等命令更改文件系统大小),否则inode与block固定后就不再变动。但是如果仔细考虑一下,如果我的文件系统高达数百GB时,那么将所有的inode与block放置在一起将是很不明智的决定,因为inode与block的数量太大时,不容易管理。
因此 Ext2 文件系统在格式化的时候基本上是区分为多个块组(block group)的,每个块组都有独立的inode/block/superblock系统。感觉上就好像我们在当兵时,一个营里面有分成数个连,每个连有自己的联络系统,但最终都向营部回报连上最正确的信息一般。这样分成一群比较好管理。整个来说,Ext2格式化后如图8-3所示。
在整体的规划当中,文件系统最前面有一个启动扇区(boot sector),这个启动扇区可以安装引导装载程序,这是个非常重要的设计,因为如此一来我们就能够将不同的引导装载程序安装到个别的文件系统最前端,而不用覆盖整块硬盘唯一的MBR,这样也才能够制作出多重引导的环境。至于每一个块组的6个主要内容说明如下。
图8-3 EXT2 文件系统示意图 [1]
data block(数据块)
data block 是用来放置文件内容地方,在Ext2 文件系统中所支持的block 大小有1KB,2KB 及4KB三种而已。在格式化时block的大小就固定了,且每个block都有编号,以方便inode的记录。不过要注意的是,由于 block 大小的区别,会导致该文件系统能够支持的最大磁盘容量与最大单一文件容量并不相同。因为block大小而产生的Ext2文件系统限制如表8-1所示 [2]。
表8-1
你需要注意的是,虽然Ext2已经能够支持大于2GB以上的单一文件容量,不过某些应用程序依然使用旧的限制,也就是说,某些程序只能够支持小于2GB以下的文件而已,这就跟文件系统无关了。举例来说,鸟哥在环境工程方面的应用中有一套秀图软件称为PAVE [3],这套软件就无法捉到鸟哥在数值模式仿真后产生的大于2GB以上的文件。害得鸟哥经常还要重跑数值模式。
除此之外Ext2文件系统的block还有什么限制呢?基本限制如下:
原则上,block的大小与数量在格式化完就不能够再改变了(除非重新格式化);
每个block内最多只能够放置一个文件的数据;
承上,如果文件大于block的大小,则一个文件会占用多个block数量;
承上,若文件小于block,则该block的剩余空间就不能够再被使用了(磁盘空间会浪费)。
如上第四点所说,由于每个block仅能容纳一个文件的数据而已,因此如果你的文件都非常小,但是你的block在格式化时却选用最大的4KB时,可能会产生一些空间的浪费。我们以下面的一个简单例题来算一下空间的浪费。
假设你的Ext2文件系统使用4KB的block,而该文件系统中有10000个小文件,每个文件大小均为50bytes,请问此时你的磁盘浪费多少容量?
答:由于Ext2文件系统中一个block仅能容纳一个文件,因此每个block会浪费4096 − 50 = 4046 (bytes),系统中总共有一万个小文件,所有文件容量为:50 x 10000(bytes)= 488.3KB,但此时浪费的容量为:4046 x 10000(bytes)= 38.6MB。想一想,不到 1MB 的总文件容量却浪费将近 40MB的容量,且文件越多将造成越多的磁盘容量浪费。
什么情况会产生上述的状况呢?例如BBS网站的数据。如果BBS上面的数据使用的是纯文本文件来记载每篇留言,而留言内容如果都写上“如题”时,想一想,是否就会产生很多小文件了呢?
好,既然大的 block 可能会产生较严重的磁盘容量浪费,那么我们是否就将 block 大小定为1K即可?这也不妥,因为如果block较小的话,那么大型文件将会占用数量更多的block,而inode也要记录更多的block号码,此时将可能导致文件系统不良的读写性能。
所以我们可以说,在你进行文件系统的格式化之前,请先想好该文件系统预计使用的情况。以鸟哥来说,我的数值模式仿真平台随便一个文件都好几百MB,那么block容量当然选择较大的。至少文件系统就不必记录太多的block号码,读写起来也比较方便。
inodetable(inode表格)
再来讨论一下inode这个玩意儿。如前所述,inode的内容主要记录文件的属性以及该文件实际数据是放置在哪几号block内!基本上,inode记录的文件数据至少有下面这些 [4]:
该文件的访问模式(read/write/excute);
该文件的所有者与组(owner/group);
该文件的大小;
该文件创建或状态改变的时间(ctime);
最近一次的读取时间(atime);
最近修改的时间(mtime);
定义文件特性的标志(flag),如SetUID等;
该文件真正内容的指向(pointer)。
inode的数量与大小也是在格式化时就已经固定了,除此之外inode还有些什么特色呢?
每个inode大小均固定为128bytes;
每个文件都仅会占用一个inode而已;
承上,因此文件系统能够创建的文件数量与inode的数量有关;
系统读取文件时需要先找到inode,并分析inode所记录的权限与用户是否符合,若符合才能够开始实际读取block的内容。
我们简略来分析一下inode/block与文件大小的关系好了。inode要记录的数据非常多,但偏偏又只有128bytes而已,而inode记录一个block号码要花掉4byte,假设我一个文件有400MB且每个block为4KB时,那么至少也要10万条block号码的记录。inode哪有这么多可记录的信息?为此我们的系统很聪明地将inode记录block号码的区域定义为12个直接、一个间接、一个双间接与一个三间接记录区。我们将inode的结构画一下好了,如图8-4所示。
图中最左边为inode本身(128bytes),里面有12个直接指向block号码的对照,这12个记录就能够直接取得block号码。至于所谓的间接就是再拿一个block来当作记录block号码的记录区,如果文件太大时,就会使用间接的block来记录编号。图8-4当中只是间接拿一个block来记录额外的号码而已。同理,如果文件持续长大,那么就会利用所谓的双间接,第一个block仅再指出下一个记录编号的block在哪里,实际记录的在第二个block当中。依此类推,三间接就是利用第三层block来记录编号。
这样子inode能够指定多少个block呢?我们以较小的1KB的block来说明好了,可以指定的情况如下:
12 个直接指向:12 × 1K=12K
由于是直接指向,所以总共可记录12条记录。
间接:256 × 1K=256K
每条block号码的记录会花去4bytes,因此1K的大小能够记录256条记录。
双间接:256 × 256 × 1K = 2 562K
第一层block会指定256个第二层,每个第二层可以指定256个号码。
图8-4 inode 结构示意图 [5]
三间接:256 × 256 × 256 × 1K = 2 56 3 K
第一层block会指定256个第二层,每个第二层可以指定256个第三层,每个第三层可以指定256个号码。
总额:将直接、间接、双间接、三间接加总,得到12+256+256 × 256+256 × 256 × 256(K)=16GB
此时我们知道当文件系统将block格式化为1K大小时,能够容纳的最大文件为16GB,比较一下文件系统限制表的结果可发现是一致的。但这个方法不能用在2K及4K的block大小的计算中,因为大于2K的block将会受到Ext2文件系统本身的限制,所以计算的结果会不太符合之故。
Superblock(超级块)
Superblock是记录整个文件系统相关信息的地方,没有Superblock,就没有这个文件系统了。
它记录的信息主要有:
block与inode的总量;
未使用与已使用的inode/block数量;
block 与inode 的大小(block 为1K,2K,4K,inode 为128 bytes);
文件系统的挂载时间、最近一次写入数据的时间、最近一次检验磁盘(fsck)的时间等文件系统的相关信息;
一个validbit 数值,若此文件系统已被挂载,则valid bit 为0,若未被挂载,则valid bit 为1。
Superblock是非常重要的,因为我们这个文件系统的基本信息都写在这里,
如果 superblock 死掉了,你的文件系统可能就需要花费很多时间去挽救。一般来说, superblock 的大小为 1 024bytes。相关的 superblock 信息我们等一下会以 dumpe2fs 命令来调用出来查看。
此外,每个 block group 都可能含有 superblock。但是我们也说一个文件系统应该仅有一个superblock 而已,那是怎么回事啊?事实上除了第一个 block group 内会含有 superblock 之外,后续的 block group 不一定含有 superblock,而若含有 superblock 则该 superblock 主要是作为第一个 block group 内 superblock 的备份了,这样可以进行 superblock 的救援。
File system Description(文件系统描述说明)
这个区段可以描述每个 block group 的开始与结束的 block 号码,以及说明每个区段(superblock,bitmap,inodemap,data block)分别介于哪一个 block 号码之间。这部分也能够用dumpe2fs来查看的。
block bitmap(块对照表)
如果你想要添加文件时总会用到block。那你要使用哪个block来记录呢?当然是选择“空的block”来记录新文件的数据。那你怎么知道哪个 block 是空的?这就得要通过 block bitmap的辅助了。从 block bitmap 当中可以知道哪些 block 是空的,因此我们的系统就能够很快速地找到可使用的空间来处置文件。
同样,如果你删除某些文件时,那么那些文件原本占用的block号码就得要释放出来,此时在block bitmpap 当中相对应到该 block 号码的标志就得要修改成为“未使用中”。这就是 bitmap的功能。
inode bitmap(inode 对照表)
这个其实与 block bitmap 是类似的功能,只是 block bitmap 记录的是使用与未使用的 block号码,至于 inode bitmap 则是记录使用与未使用的 inode 号码。
了解了文件系统的概念之后,再来当然是查看这个文件系统。刚才谈到的各部分数据都与 block号码有关,每个区段与superblock的信息都可以使用dumpe2fs这个命令来查询的。查询的方法与结果如下:
[root@www ~]# dumpe2fs [-bh] 设备文件名
参数:
-b :列出保留为坏道的部分(一般用不到吧!)
-h :仅列出 superblock 的数据,不会列出其他的区段内容。
范例:找出我的根目录磁盘文件名,并查看文件系统的相关信息
[root@www ~]# df <==这个命令可以调出目前挂载的设备
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hdc2 9920624 3822848 5585708 41% / <==就是这个
/dev/hdc3 4956316 141376 4559108 4% /home
/dev/hdc1 101086 11126 84741 12% /boot
tmpfs 371332 0 371332 0% /dev/shm
[root@www ~]# dumpe2fs /dev/hdc2
dumpe2fs 1.39 (29-May-2006)
Filesystem volume name: /1 <==这个是文件系统的名称(Label)
Filesystem features: has_journal ext_attr resize_inode dir_index
filetype needs_recovery sparse_super large_file
Default mount options: user_xattr acl <==默认挂载的参数
Filesystem state: clean <==这个文件系统是没问题的(clean)
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 2560864 <==inode的总数
Block count: 2560359 <==block的总数
Free blocks: 1524760 <==还有多少个 block 可用
Free inodes: 2411225 <==还有多少个 inode 可用
First block: 0
Block size: 4096 <==每个 block 的大小
Filesystem created: Fri Sep 5 01:49:20 2008
Last mount time: Mon Sep 22 12:09:30 2008
Last write time: Mon Sep 22 12:09:30 2008
Last checked: Fri Sep 5 01:49:20 2008
First inode: 11
Inode size: 128 <==每个 inode 的大小
Journal inode: 8 <==下面这三个与下一小节有关
Journal backup: inode blocks
Journal size: 128M
Group 0: (Blocks 0-32767) <==第一个 data group 内容, 包含 block 的起始、结束号码
Primary superblock at 0, Group descriptors at 1-1 <==超级块在 0 号 block
Reserved GDT blocks at 2-626
Block bitmap at 627 (+627), Inode bitmap at 628 (+628)
Inode table at 629-1641 (+629) <==inode table 所在的 block
0 free blocks, 32405 free inodes, 2 directories <==所有 block 都用完了!
Free blocks:
Free inodes: 12-32416 <==剩余未使用的 inode 号码
Group 1: (Blocks 32768-65535)
….(下面省略)….
由于数据量非常庞大,因此鸟哥将一些信息省略输出了,可能与你的屏幕会有点区别。
前半部在显示出 supber block 的内容,包括卷标名称(Label)以及inode/block的相关信息。
后面则是每个 block group 的个别信息了,你可以看到各区段数据所在的号码。
也就是说,基本上所有的数据还是与 block 的号码有关就是了。
如上所示,利用 dumpe2fs 可以查询到非常多的信息,不过依内容主要可以区分为上半部是superblock 内容,下半部则是每个 blockgroup 的信息了。从上文中我们可以查看到这个/dev/hdc2规划的block为4K,第一个block号码为0号,且blockgroup内的所有信息都以block的号码来表示的。然后在superblock中还有谈到目前这个文件系统的可用block与inode数量。
至于 block group 的内容我们单纯看 Group0 信息好了。从上文中我们可以发现:
Group0所占用的block号码由0到32767号,superblock则在第0号的block块内!
文件系统描述说明在第1号block中。
block bitmap 与 inode bitmap 则在 627 及 628 的 block 号码上。
至于 inodetable 分布于 629~1 641 的 block 号码中。
由于一个inode 用128 bytes,总共有1641–629+1(629本身)=1013个block花在inode table上,每个block的大小为4096 bytes(4KB)。由这些数据可以算出inode的数量共有1013×4 096/128=32416个inode。
这个Group0目前没有可用的block了,但是有剩余32405个inode未被使用。
剩余的inode号码为12号到32416号。
如果你对文件系统的详细信息还有更多想要了解的话,那么请参考本章最后一小节的介绍,否则看到这里对于文件系统基础认知你应该是已经相当足够。下面则是要探讨一下,那么这个文件系统概念与实际的目录树应用有啥关连。
8.1.4 与目录树的关系
由前一小节的介绍我们知道在Linux系统下,每个文件(不管是一般文件还是目录文件)都会占用一个inode,且可依据文件内容的大小来分配多个block给该文件使用。而由第6章的权限说明中我们知道目录的内容在记录文件名,一般文件才是实际记录数据内容的地方。那么目录与文件在Ext2文件系统当中是如何记录数据的呢?基本上可以这样说。
图8-5 目录占用的block记录的数据示意图
目录
当我们在 Linux 下的 ext2 文件系统新建一个目录时,ext2会分配一个inode与至少一块block给该目录。其中,inode记录该目录的相关权限与属性,并可记录分配到的那块block号码;而block则是记录在这个目录下的文件名与该文件名占用的inode号码数据。也就是说目录所占用的block内容在记录如下的信息:
如果想要实际查看 root 目录内的文件所占用的 inode 号码时,可以使用 ls-i 这个参数来处理:
[root@www ~]# ls -li
total 92
654683 -rw———- 1 root root 1474 Sep 4 18:27 anaconda-ks.cfg
648322 -rw-r—r— 1 root root 42304 Sep 4 18:26 install.log
648323 -rw-r—r— 1 root root 5661 Sep 4 18:25 install.log.syslog
由于每个人所使用的计算机并不相同,系统安装时选择的选项与分区都不一样,因此你的环境不可能与我的inode号码一模一样。上面所列出的inode仅是鸟哥的系统所显示的结果而已。而由这个目录的 block结果我们现在就能够知道,当你使用“ll/”时,出现的目录几乎都是1024的倍数,为什么呢?因为每个block的数量都是1K,2K,4K。看一下鸟哥的环境:
[root@www ~]# ll -d / /bin /boot /proc /lost+found /sbin
drwxr-xr-x 23 root root 4096 Sep 22 12:09 / <==一个 4K block
drwxr-xr-x 2 root root 4096 Sep 24 00:07 /bin <==一个 4K block
drwxr-xr-x 4 root root 1024 Sep 4 18:06 /boot <==一个 1K block
drwx——— 2 root root 16384 Sep 5 01:49 /lost+found <==4个 4K block
dr-xr-xr-x 96 root root 0 Sep 22 20:07 /proc <==此目录不占硬盘空间
drwxr-xr-x 2 root root 12288 Sep 5 12:33 /sbin <==3个 4K block
由于鸟哥的根目录/dev/hdc2使用的block大小为4K,因此每个目录几乎都是4K的倍数。其中由于/sbin的内容比较复杂因此占用了3个block,此外,鸟哥的系统中/boot为独立的分区,该分区的block为1K而已,因此该目录就仅占用1024 bytes的大小。至于奇怪的/proc我们在第6章就讲过该目录不占硬盘容量,所以当然耗用的 block就是0。
由上面的结果我们知道目录并不只会占用一个 block 而已,也就是说:在目录下面的文件数如果太多而导致一个 block 无法容纳的下所有的文件名与 inode 对照表时, Linux 会给予该目录多一个 block 来继续记录相关的数据。
文件
当我们在Linux下的ext2新建一个一般文件时,ext2会分配一个inode与相对于该文件大小的block数量给该文件。例如:假设我的一个block为4KB,而我要新建一个100KB的文件,那么linux将分配一个inode与25个block来存储该文件。但同时请注意,由于inode仅有12个直接指向,因此还要多一个block来作为块号码的记录。
目录树读取
好了,经过上面的说明你也应该要很清楚地知道 inode 本身并不记录文件名,文件名的记录是在目录的block当中。因此在第6章文件与目录的权限说明中,我们才会提到新增/删除/重命名文件名与目录的w权限有关的特点。那么因为文件名是记录在目录的block当中,因此当我们要读取某个文件时,就务必会经过目录的inode与block,然后才能够找到那个待读取文件的inode号码,最终才会读到正确的文件的block内的数据。
由于目录树是由根目录开始读起,因此系统通过挂载的信息可以找到挂载点的 inode 号码(通常一个文件系统的最顶层inode号码会由2号开始),此时就能够得到根目录的inode内容,并依据该inode读取根目录的block内的文件名数据,再一层一层地往下读到正确的文件名。
举例来说,如果我想要读取/etc/passwd这个文件时,系统是如何读取的呢?
在鸟哥的系统上面与/etc/passwd有关的目录与文件数据如上所示,该文件的读取流程为(假设读取者身份为vbird这个一般身份用户):
1./的inode
通过挂载点的信息找到/dev/hdc2的inode号码为2的根目录inode,且inode具有的权限让我们可以读取该block的内容(有r与x)。
2./的block
经过上个步骤取得block的号码,并找到该内容有etc/目录的inode号码(1912545)。
3.etc/的inode
读取1912545号inode得知vbird具有r与x的权限,因此可以读取etc/的block内容。
4.etc/的block
经过上个步骤取得block号码,并找到该内容有passwd文件的inode号码(1914888)。
5.passwd的inode
读取1914888号inode得知vbird具有r的权限,因此可以读取passwd的block内容。
6.passwd的block
最后将该block内容的数据读出来。
文件系统大小与磁盘读取性能
另外,关于文件系统的使用效率上,当你的一个文件系统规划得很大时,例如100GB这么大时,由于硬盘上面的数据总是经常变动的,所以,整个文件系统上面的文件通常无法连续写在一起(block 号码不会连续的意思),而是填入式地将数据填入没有被使用的 block 当中。如果文件写入的block真的分得很散,此时就会有所谓的文件数据离散的问题发生了。
如前所述,虽然我们的ext2在inode处已经将该文件所记录的block号码都记上了,所以数据可以一次性读取,但是如果文件真的太过离散,确实还是会发生读取效率低的问题,因为磁头还是得要在整个文件系统中来来去去地频繁读取。那么可以将整个文件系统内的数据全部复制出来,将该文件系统重新格式化,再将数据复制回去即可解决这个问题。
此外,如果文件系统真的太大了,那么当一个文件分别记录在这个文件系统的最前面与最后面的block号码中,此时会造成硬盘的机械手臂移动幅度过大,也会造成数据读取性能低。而且磁头在搜寻整个文件系统时,也会花费比较多的时间。因此,分区的规划并不是越大越好,而是真的要针对你的主机用途来进行规划才行。
8.1.5 Ext2/Ext3文件的访问与日志文件系统的功能
上一小节谈到的仅是读取而已,那么如果是新建一个文件或目录时,我们的 Ext2 是如何处理的呢?这个时候就得要 blockbitmap 及 inode bitmap 的帮忙了。假设我们想要新增一个文件,此时文件系统的行为是:
1.先确定用户对于欲添加文件的目录是否具有w与x的权限,若有的话才能添加。
2.根据inode bitmap 找到没有使用的inode 号码,并将新文件的权限/属性写入。
3.根据block bitmap 找到没有使用中的block 号码,并将实际的数据写入block 中,且更新inode的block指向数据。
4.将刚才写入的inode 与block 数据同步更新inode bitmap 与block bitmap,并更新superblock的内容。
一般来说,我们将inode table与data block称为数据存放区域,至于其他例如super block、block bitmap与inode bitmap 等区段就被称为 metadata(中间数据),因为super block,inode bitmap及block bitmap的数据是经常变动的,每次添加、删除、编辑时都可能会影响到这三个部分的数据,因此才被称为中间数据的。
数据的不一致(Inconsistent)状态
在一般正常的情况下,上述的新增操作当然可以顺利完成。但是如果有个万一怎么办?例如你的文件在写入文件系统时,因为不明原因导致系统中断(例如突然停电、系统内核发生错误等的怪事发生时),所以写入的数据仅有 inode table 及 data block 而已,最后一个同步更新中间数据的步骤并没有做完,此时就会发生 meta data 的内容与实际数据存放区产生不一致的情况了。
既然不一致当然就得要克服。在早期的Ext2文件系统中,如果发生这个问题,那么系统在重新启动的时候,就会通过 Super block 当中记录的 valid bit(是否有挂载)与文件系统的 state (clean与否)等状态来判断是否强制进行数据一致性的检查。若有需要检查时则以e2fsck这支程序来进行的。
不过,这样的检查真的是很费时,因为要针对 meta data 区域与实际数据存放区来进行比对,得要搜寻整个文件系统呢!如果你的文件系统有100GB以上,而且里面的文件数量又多时,系统真忙碌,而且在对Internet提供服务的服务器主机上面,这样的检查真的会造成主机修复时间的拉长,这也就造成后来所谓日志文件系统的兴起了。
日志文件系统(Journaling file system)
为了避免上述提到的文件系统不一致的情况发生,因此我们的前辈们想到一个方式,如果在我们的文件系统当中规划出一个块,该块专门记录写入或修订文件时的步骤,那不就可以简化一致性检查的步骤了?也就是说:
1.预备:当系统要写入一个文件时,会先在日志记录块中记录某个文件准备要写入的信息。
2.实际写入:开始写入文件的权限与数据;开始更新meta data 的数据。
3.结束:完成数据与meta data 的更新后,在日志记录块当中完成该文件的记录。
在这样的程序当中,万一数据的记录过程当中发生了问题,那么我们的系统只要去检查日志记录块就可以知道哪个文件发生了问题,针对该问题来做一致性的检查即可,而不必针对整块文件系统去检查,这样就可以达到快速修复文件系统的能力了。这就是日志式文件最基础的功能。
那么我们的Ext2可达到这样的功能吗?当然可以。就通过Ext3即可。Ext3是Ext2的升级版本,并且可向下兼容Ext2版本呢,目前我们才建议大家可以直接使用Ext3这个文件系统。如果你还记得dumpe2fs输出的信息,可以发现superblock里面含有下面这样的信息:
Journal inode: 8
Journal backup: inode blocks
Journal size: 128M
通过inode8号记录journal块的block指向,而且具有128MB的容量在处理日志呢。这样对于所谓的日志文件系统有没有比较有概念一点呢?如果想要知道为什么Ext3文件系统会更适用于目前的Linux系统,我们可以参考Red Hat公司中首席内核开发者MichaelK.Johnson的话 [6]:
“为什么你想要从Ext2转换到Ext3呢?有四个主要的理由:可利用性、数据完整性、速度及易于转换。”对于可利用性,他指出,这意味着从系统中止到快速重新复原而不是持续地让e2fsck执行长时间的修复。Ext3的日志式条件可以避免数据毁损的可能。他也指出:“除了写入若干数据超过一次时,Ext3往往会较快于Ext2,因为Ext3的日志使硬盘磁头的移动能更有效地进行。”然而或许决定的因素还是在Johnson先生的第四个理由中。
“它是可以轻易的从Ext2更改到Ext3来获得一个强而有力的日志文件系统而不需要重新做格式化”。“那是正确的,为了体验一下Ext3的好处是不需要去做一种长时间的、冗长乏味的且易于产生错误的备份工作及重新格式化的操作”。
8.1.6 Linux 文件系统的操作
我们现在知道了目录树与文件系统的关系了,但是由第0章的内容我们也知道,所有的数据都得要加载到内存后CPU才能够对该数据进行处理。如果你经常编辑一个很大的文件,在编辑的过程中又频繁地要系统来写入磁盘中,由于磁盘写入的速度要比内存慢很多,因此你会经常耗在等待硬盘的写入/读取上。真没效率。
为了解决这个效率的问题,因此我们的Linux使用的方式是通过一个称为异步处理(asynchronously)的方式。所谓的异步处理是这样的:
当系统加载一个文件到内存后,如果该文件没有被改动过,则在内存区段的文件数据会被设置为(clean)的。但如果内存中的文件数据被更改过了(例如你用nano去编辑过这个文件),此时该内存中的数据会被设置为Dirty。此时所有的操作都还在内存中执行,并没有写入到磁盘中。系统会不定时地将内存中设置为 Dirty 的数据写回磁盘,以保持磁盘与内存数据的一致性。你也可以利用第 5 章谈到的sync命令来手动强迫写入磁盘。
我们知道内存的速度要比硬盘快得多,因此如果能够将常用的文件放置到内存当中,这不就会增加系统性能吗?因此我们Linux系统上面文件系统与内存有非常大的关系:
系统会将常用的文件数据放置到主存储器的缓冲区,以加速文件系统的读/写。
承上,因此Linux的物理内存最后都会被用光。这是正常的情况,可加速系统性能。
你可以手动使用sync来强迫内存中设置为Dirty的文件回写到磁盘中。
若正常关机时,关机命令会主动调用sync来将内存的数据回写入磁盘内。
但若不正常关机(如断电、死机或其他不明原因),由于数据尚未回写到磁盘内,因此重新启动后可能会花很多时间在进行磁盘检验,甚至可能导致文件系统的损毁(非磁盘损坏)。
8.1.7 挂载点(mount point)的意义
每个文件系统都有独立的 inode、block、super block 等信息,这个文件系统要能够链接到目录树才能被我们使用。将文件系统与目录树结合的操作我们称为挂载。关于挂载的一些特性我们在第 3章稍微提过,重点是:挂载点一定是目录,该目录为进入该文件系统的入口。因此并不是你有任何文件系统都能使用,必须要“挂载”到目录树的某个目录后,才能够使用该文件系统的。
举例来说,如果你是依据鸟哥的方法安装你的 CentOS 5.x 的话,那么应该会有三个挂载点才是,分别是/,/boot,/home 三个(鸟哥的系统上对应的设备文件名为/dev/hdc2,/dev/hdc1,/dev/hdc3)。那如果查看这三个目录的inode号码时,我们可以发现如下的情况:
[root@www ~]# ls -lid / /boot /home
2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /
2 drwxr-xr-x 4 root root 1024 Sep 4 18:06 /boot
2 drwxr-xr-x 6 root root 4096 Sep 29 02:21 /home
由于文件系统最顶层的目录的inode一般为2号,因此可以发现/,/boot,/home为三个不同的文件系统。(因为每一行的文件属性并不相同,且三个目录的挂载点也均不相同之故。)我们在第7章一开始的路径中曾经提到根目录下的.与..是相同的东西,因为权限是一模一样的。如果从使用文件系统的观点来看,同一个文件系统的某个inode只会对应到一个文件内容而已(因为一个文件占用一个inode的原因),因此我们可以通过判断inode号码来确认不同文件名是否为相同的文件。所以可以这样看:
[root@www ~]# ls -ild / /. /..
2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /
2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /.
2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 /..
上面的信息中由于挂载点均为/,因此三个文件(/,/.,/..)均在同一个文件系统内,而这三个文件的inode号码均为2号,因此这三个文件名都指向同一个inode号码,当然这三个文件的内容也就完全一模一样。也就是说,根目录的上层(/..)就是它自己。
8.1.8 其他Linux 支持的文件系统与VFS
虽然Linux的标准文件系统是ext2,且还有增加了日志功能的ext3,事实上,Linux还有支持很多文件系统格式的,尤其是最近这几年推出了好几种速度很快的日志文件系统,包括SGI的XFS文件系统,可以适用于更小型文件的Reiserfs文件系统,以及Windows的FAT文件系统等,都能够被Linux所支持。常见的支持文件系统有:
传统文件系统:ext2/minix/MS-DOS/FAT(用vfat模块)/iso9660(光盘)等;
日志文件系统:ext3/ReiserFS/Windows'NTFS/IBM'sJFS/SGI'sXFS;
网络文件系统:NFS/SMBFS。
想要知道你的Linux支持的文件系统有哪些,可以查看下面这个目录:
[root@www ~]# ls -l /lib/modules/$(uname -r)/kernel/fs
系统目前已加载到内存中支持的文件系统则有:
[root@www ~]# cat /proc/filesystems
Linux VFS
了解了我们使用的文件系统之后,再来则是要提到,那么Linux的内核又是如何管理这些认识的文件系统呢?其实,整个Linux的系统都是通过一个名为Virtual Filesystem Switch(虚拟文件系统, VFS)的内核功能去读取文件系统的。也就是说,整个Linux认识的文件系统其实都是VFS在进行管理,我们用户并不需要知道每个分区上头的文件系统是什么,VFS会主动帮我们做好读取的操作。
假设你的/使用的是/dev/hda1,用 Ext3,而/home 使用/dev/hda2,用 reiserfs,那么你取用/home/dmtsai/.bashrc 时,有特别指定要用的什么文件系统的模块来读取吗?这个就是 VFS的功能。通过这个VFS的功能来管理所有的文件系统,省去我们需要自行设置读取文件系统的定义。整个VFS可以约略用图8-6来说明。
图8-6 VFS 文件系统的示意图
老实说,文件系统真的不好懂,如果你想要对文件系统有更深入的了解,文末的相关链接 [7]务必要参考参考才好。鸟哥有找了一些数据放置于这里:
Ext2/Ext3 文件系统:http://linux.vbird.org/linux_basic/1 010appendix_B.php
有兴趣的朋友务必要前往参考下才好。
8.2 文件系统的简单操作
稍微了解了文件系统后,再来我们要知道如何查询整体文件系统的总容量与每个目录所占用的容量。此外,前两章谈到的文件类型中尚未讲得很清楚的连接文件(Link file)也会在这一小节当中介绍的。
8.2.1 磁盘与目录的容量:df, du
现在我们知道磁盘的整体数据是在superblock块中,但是每个各别文件的容量则在inode当中记载的。那在命令行界面下面该如何调出这几个数据呢?下面就让我们来谈一谈这两个命令:
df:列出文件系统的整体磁盘使用量;
du:评估文件系统的磁盘使用量(常用于评估目录所占容量)。
df
[root@www ~]# df [-ahikHTm] [目录或文件名]
参数:
-a :列出所有的文件系统,包括系统特有的 /proc 等文件系统;
-k :以 KB的容量显示各文件系统;
-m :以 MB的容量显示各文件系统;
-h :以人们较易阅读的 GB、 MB、 KB等格式自行显示;
-H :以 M=1000K 替代 M=1024K 的进位方式;
-T :连同该分区的文件系统名称 (例如 ext3) 也列出;
-i :不用硬盘容量,而以 inode 的数量来显示。
范例一:将系统内所有的文件系统列出来。
[root@www ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hdc2 9920624 3823112 5585444 41% /
/dev/hdc3 4956316 141376 4559108 4% /home
/dev/hdc1 101086 11126 84741 12% /boot
tmpfs 371332 0 371332 0% /dev/shm
在 Linux 下面如果 df 没有加任何参数,那么默认会将系统内所有的
(不含特殊内存内的文件系统与 swap) 都以 1 KB 的容量来列出来。
至于那个 /dev/shm 是与内存有关的挂载。
范例二:将容量结果以易读的容量格式显示出来
[root@www ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 9.5G 3.7G 5.4G 41% /
/dev/hdc3 4.8G 139M 4.4G 4% /home
/dev/hdc1 99M 11M 83M 12% /boot
tmpfs 363M 0 363M 0% /dev/shm
不同于范例一,这里会以 G、M 等容量格式显示出来,比较容易看。
范例三:将系统内的所有特殊文件格式及名称都列出来
[root@www ~]# df -aT
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/hdc2 ext3 9920624 3823112 5585444 41% /
proc proc 0 0 0 - /proc
sysfs sysfs 0 0 0 - /sys
devpts devpts 0 0 0 - /dev/pts
/dev/hdc3 ext3 4956316 141376 4559108 4% /home
/dev/hdc1 ext3 101086 11126 84741 12% /boot
tmpfs tmpfs 371332 0 371332 0% /dev/shm
none binfmt_misc 0 0 0 - /proc/sys/fs/binfmt_misc
sunrpc rpc_pipefs 0 0 0 - /var/lib/nfs/rpc_pipefs
系统里面其实还有很多特殊的文件系统存在的。那些比较特殊的文件系统几乎
都是在内存当中,例如 /proc 这个挂载点。因此,这些特殊的文件系统
都不会占据硬盘空间。
范例四:将 /etc 下面的可用的磁盘容量以易读的容量格式显示
[root@www ~]# df -h /etc
Filesystem Size Used Avail Use% Mounted on
/dev/hdc2 9.5G 3.7G 5.4G 41% /
这个范例比较有趣一点,在 df 后面加上目录或者是文件时,df
会自动分析该目录或文件所在的分区,并将该分区的容量显示出来,
所以,你就可以知道某个目录下面还有多少容量可以使用了。
范例五:将目前各个分区当中可用的 inode 数量列出
[root@www ~]# df -ih
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/hdc2 2.5M 147K 2.3M 6% /
/dev/hdc3 1.3M 46 1.3M 1% /home
/dev/hdc1 26K 34 26K 1% /boot
tmpfs 91K 1 91K 1% /dev/shm
这个范例则主要列出可用的 inode 剩余量与总容量。分析一下与范例一的关系,
你可以清楚地发现到,通常 inode 的数量剩余都比 block 还要多呢!
先来说明一下范例一所输出的结果信息:
Filesystem:代表该文件系统是在哪个分区,所以列出设备名称。
1k-blocks:说明下面的数字单位是1KB。可利用-h或-m来改变容量。
Used:顾名思义,就是使用掉的硬盘空间啦!
Available:也就是剩下的磁盘空间大小。
Use%:就是磁盘的使用率。如果使用率高达 90%以上时,最好需要注意一下了,免得容量不足造成系统问题。(例如最容易被填满的/var/spool/mail这个放置邮件的磁盘)。
Mountedon:就是磁盘挂载的目录所在(挂载点)。
由于 df 主要读取的数据几乎都是针对整个文件系统,因此读取的范围主要是在 Super block内的信息,所以这个命令显示结果的速度非常快速。在显示的结果中你需要特别留意的是那个根目录的剩余容量,因为我们所有的数据都是由根目录衍生出来的,因此当根目录的剩余容量剩下0时,那你的Linux可能就问题很大了。
说个陈年老笑话,鸟哥还在念书时,别的研究室有个管理 Sun 工作站的研究生发现,他的硬盘明明还有好几GB,但是就是没有办法将光盘内几MB的数据copy进去,他就去跟老板讲说机器坏了。明明才来维护过几天而已为何会坏了。结果他老板就将服务商叫来骂了 2小时左右。
后来,服务商发现原来硬盘的“总空间”还有很多,只是某个分区填满了,偏偏该研究生就是要将数据 copy 去那个分区。后来那个研究生就被命令“再也不许碰 Sun 主机”了。
另外需要注意的是,如果使用-a 这个参数时,系统会出现/proc 这个挂载点,但是里面的东西都是0,不要紧张。/proc的东西都是Linux系统所需要加载的系统数据,而且是挂载在内存当中的,所以当然没有占任何的硬盘空间。
至于那个/dev/shm/目录,其实是利用内存虚拟出来的磁盘空间。由于是通过内存虚拟出来的磁盘,因此你在这个目录下面新建任何数据文件时,访问速度是非常快速的(在内存内工作)。不过,也由于它是内存虚拟出来的,因此这个文件系统的大小在每部主机上都不一样,而且新建的东西在下次开机时就消失了,因为是在内存中。
du
[root@www ~]# du [-ahskm] 文件或目录名称
选项与参数:
-a :列出所有的文件与目录容量,因为默认仅统计目录下面的文件量而已;
-h :以人们较易读的容量格式 (G/M) 显示;
-s :列出总量而已,而不列出每个各别的目录占用容量;
-S :不包括子目录下的总计,与 -s 有点差别;
-k :以 KB列出容量显示;
-m :以 MB列出容量显示。
范例一:列出目前目录下的所有文件容量
[root@www ~]# du
8 ./test4 <==每个目录都会列出来
8 ./test2
….中间省略….
12 ./.gconfd <==包括隐藏文件的目录
220 . <==这个目录(.)所占用的总量
直接输入 du 没有加任何参数时,则 du 会分析目前所在目录
的文件与目录所占用的硬盘空间。但是,实际显示时,仅会显示目录容量(不含文件),
因此 . 目录有很多文件没有被列出来,所以全部的目录相加不会等于 . 的容量。
此外,输出的数值数据为 1K 大小的容量单位。
范例二:同范例一,但是将文件的容量也列出来
[root@www ~]# du -a
12 ./install.log.syslog <==有文件的列表了
8 ./.bash_logout
8 ./test4
8 ./test2
….中间省略….
12 ./.gconfd
220 .
范例三:检查根目录下面每个目录所占用的容量
[root@www ~]# du -sm /*
7 /bin
6 /boot
…..中间省略….
0 /proc
…..中间省略….
1 /tmp
3859 /usr <==系统初期最大就是它了。
77 /var
这是个很常被使用的功能:利用通配符 * 来代表每个目录,
如果想要检查某个目录下那个子目录占用最大的容量,可以用这个方法找出来
值得注意的是,如果刚才安装好 Linux 时,那么整个系统容量最大的应该是 /usr
而 /proc 虽然有列出容量,但是那个容量是在内存中,不占硬盘空间。
与df不一样的是,du这个命令其实会直接到文件系统内去查找所有的文件数据,所以上述第三个范例命令的运行会执行一小段时间。此外,在默认的情况下,大小的输出是以KB来设计的,如果你想要知道目录占了多少MB,那么就使用-m这个参数即可。而如果你只想要知道该目录占了多少容量的话,使用-s就可以。
至于-S这个参数部分,由于du默认会将所有文件的大小均列出,因此假设你在/etc下面使用du时,所有的文件大小,包括/etc下面的子目录容量也会被计算一次。然后最终的容量(/etc)也会加总一次,因此很多朋友都会误会du分析的结果不太对劲。所以,如果想要列出某目录下的全部数据,或许也可以加上-S的参数,减少子目录的计算。
8.2.2 连接文件:ln
关于连接(link)数据,我们在第6章的Linux文件属性及Linux文件种类与扩展名当中提过一些信息,不过当时由于尚未讲到文件系统,因此无法较完整地介绍连接文件。不过在上一小节谈完了文件系统后,我们可以来了解一下连接文件了。
在Linux下面的连接文件有两种,一种是类似Windows的快捷方式功能的文件,可以让你快速连接到目标文件(或目录);另一种则是通过文件系统的inode连接来产生新文件名,而不是产生新文件,这种称为硬连接(hard link)。这两个完全是不一样的东西。现在就分别来介绍。
hard link(硬连接或实际连接)
在前一小节当中,我们知道几件重要的信息,包括:
每个文件都会占用一个inode,文件内容由inode的记录来指向。
想要读取该文件,必须要经过目录记录的文件名来指向到正确的inode号码才能读取。
也就是说,其实文件名只与目录有关,但是文件内容则与 inode 有关。那么想一想,有没有可能有多个文件名对应到同一个inode 号码呢?那就是 hard link 的由来。所以简单地说:hardlink只是在某个目录下新建一条文件名连接到某inode号码的关联记录而已。
举个例子来说,假设我系统有个/root/crontab它是/etc/crontab的实际连接,也就是说这两个文件名连接到同一个inode,自然这两个文件名的所有相关信息都会一模一样(除了文件名之外)。实际的情况可以如下所示:
[root@www ~]# ln /etc/crontab . <==创建实际连接的命令
[root@www ~]# ll -i /etc/crontab /root/crontab
1912701 -rw-r—r— 2 root root 255 Jan 6 2007 /etc/crontab
1912701 -rw-r—r— 2 root root 255 Jan 6 2007 /root/crontab
你可以发现两个文件名都连接到1912701这个inode号码,是否文件的权限、属性完全一样呢?因为这两个“文件名”其实是一模一样的“文件”,而且你也会发现第二个字段由原本的1 变成2 了!那个字段称为“连接”,这个字段的意义为“有多少个文件名连接到这个inode号码”的意思。如果将读取到正确数据的方式画成示意图,就如图8-6所示。
图8-7 实际连接的文件读取示意图
上图的意思是,你可以通过1或2的目录inode指定的block找到两个不同的文件名,而不管使用哪个文件名均可以指到real那个inode去读取到最终数据。那这样有什么好处呢?最大的好处就是“安全”。如图8-7所示中,如果你将任何一个“文件名”删除,其实inode与block都还是存在的。此时你可以通过另一个“文件名”来读取到正确的文件数据。此外,不论你使用哪个“文件名”来编辑,最终的结果都会写入到相同的inode与block中,因此均能进行数据的修改。
一般来说,使用 hard link 设置连接文件时,磁盘的空间与 inode 的数目都不会改变。我们还是由图 8-6 来看,hard link 只是在某个目录下的 block 多写入一个关连数据而已,既不会增加inode也不会耗用block数量。
垄hard link的制作中,其实还是可能会改变系统的 block 的,那就是当你添加这条数据却刚好将目录的 block 填满时,就可能会新加一个 block 来记录文件名关联性,而导致磁盘空间的变化。不过,一般 hard link 所用掉的关联数据量很小,所以通常不会改变 inode与磁盘空间的大小。
由图8-6其实我们也能够知道,事实上hard link应该仅能在单一文件系统中进行的,应该是不能够跨文件系统才对。因为图8-6就是在同一个文件系统上,所以hard link是有限制的:
不能跨文件系统;
不能连接到目录。
不能跨文件系统还好理解,那不能硬连接到目录又是怎么回事呢?这是因为如果使用hard link连接到目录时,连接的数据需要连同被连接目录下面的所有数据都建立连接,举例来说,如果你要将/etc 使用硬连接创建一个/etc_hd 的目录时,那么在/etc_hd 下面的所有文件名同时都与/etc下面的文件名要创建硬连接的,而不是仅连接到/etc_hd与/etc而已。并且,未来如果需要在/etc_hd 下面创建新文件时,连带的,/etc 下面的数据又得要创建一次 hard link,因此造成环境相当大的复杂度。目前 hard link 对于目录暂时还是不支持的。
symbolic link(符号连接,也即是快捷方式)
相对于 hard link,symbolic link 可就好理解多了,基本上,symbolic link 就是在创建一个独立的文件,而这个文件会让数据的读取指向它连接的那个文件的文件名。由于只是利用文件来作为指向的操作,所以,当源文件被删除之后,symbolic link 的文件会“开不了”,会一直说“无法打开某文件”。实际上就是找不到源文件“文件名”而已。
举例来说,我们先创建一个符号连接文件连接到/etc/crontab去看看:
[root@www ~]# ln -s /etc/crontab crontab2
[root@www ~]# ll -i /etc/crontab /root/crontab2
1912701 -rw-r—r— 2 root root 255 Jan 6 2007 /etc/crontab
654687 lrwxrwxrwx 1 root root 12 Oct 22 13:58 /root/crontab2 -> /etc/crontab
由上面的结果我们可以知道两个文件指向不同的inode号码,当然就是两个独立的文件存在。而且连接文件的重要内容就是它会写上目标文件的“文件名”,你可以发现为什么上面连接文件的大小为12bytes呢?因为箭头(->)右边的文件名“/etc/crontab”总共有12个英文,每个英文占用1个byte,所以文件大小就是12bytes了!
关于上述的说明,我们以图8-8来解释。
图8-8 符号链接的文件读取示意图
由1 号inode 读取到连接文件的内容仅有文件名,根据文件名连接到正确的目录去取得目标文件的 inode ,最终就能够读取到正确的数据了。你可以发现的是,如果目标文件(/etc/crontab)被删除了,那么整个环节就会无法继续进行下去,所以就会发生无法通过连接文件读取的问题了。
这里还是得特别留意,这个symbolic link 与Windows 的快捷方式可以划上等号,由symbolic link所创建的文件为一个独立的新的文件,所以会占用掉inode与block。
由上面的说明来看,似乎 hard link 比较安全,因为即使某一个目录下的关联数据被删掉了,也没有关系,只要有任何一个目录下存在着关联数据,那么该文件就不会不见。举上面的例子来说,我的/etc/crontab与/root/crontab指向同一个文件,如果我删除了/etc/crontab这个文件,该删除的操作其实只是将/etc目录下关于crontab的关联数据拿掉而已,crontab所在的inode与block其实都没有被变动。
不过由于 hard link 的限制太多了,包括无法做“目录”的连接,所以在用途上面是比较受限的,反而是 symbolic link 的使用方面较广。实践一下就知道怎么回事了。要制作连接文件就必须要使用ln这个命令。
[root@www ~]# ln [-sf] 源文件 目标文件
参数:
-s :如果不加任何参数就进行连接,那就是hard link,至于 -s 就是symbolic link
-f :如果目标文件存在时,就主动将目标文件直接删除后再创建。
范例一:将 /etc/passwd 复制到 /tmp 下面,并且查看 inode 与 block
[root@www ~]# cd /tmp
[root@www tmp]# cp -a /etc/passwd .
[root@www tmp]# du -sb ; df -i .
18340 . <==先注意一下这里的容量是多少。
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/hdc2 2560864 149738 2411126 6% /
利用 du 与 df 来检查一下目前的参数,那个 du -sb
是计算整个 /tmp 下面有多少 bytes 的啦!
范例二:将 /tmp/passwd 制作 hard link 成为 passwd-hd 文件,并查看文件与容量
[root@www tmp]# ln passwd passwd-hd
[root@www tmp]# du -sb ; df -i .
18340 .
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/hdc2 2560864 149738 2411126 6% /
即使多了一个文件在 /tmp 下面,整个 inode 与 block 的容量并没有改变。
[root@www tmp]# ls -il passwd*
586361 -rw-r—r— 2 root root 1945 Sep 29 02:21 passwd
586361 -rw-r—r— 2 root root 1945 Sep 29 02:21 passwd-hd
原来是指向同一个 inode ,另外,那个第二列的连接数也会增加!
范例三:将 /tmp/passwd 创建一个符号连接
[root@www tmp]# ln -s passwd passwd-so
[root@www tmp]# ls -li passwd*
586361 -rw-r—r— 2 root root 1945 Sep 29 02:21 passwd
586361 -rw-r—r— 2 root root 1945 Sep 29 02:21 passwd-hd
586401 lrwxrwxrwx 1 root root 6 Oct 22 14:18 passwd-so -> passwd
passwd-so 指向的 inode number 不同了。这是一个新的文件,这个文件的内容是指向
passwd 的。passwd-so 的大小是 6bytes ,因为 passwd 共有6个字符之故
[root@www tmp]# du -sb ; df -i .
18346 .
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/hdc2 2560864 149739 2411125 6% /
整个容量与 inode 使用数都改变了。
范例四:删除源文件 passwd ,其他两个文件是否能够开启?
[root@www tmp]# rm passwd
[root@www tmp]# cat passwd-hd
……正常显示完毕!
[root@www tmp]# cat passwd-so
cat: passwd-so: No such file or directory
[root@www tmp]# ll passwd*
-rw-r—r— 1 root root 1945 Sep 29 02:21 passwd-hd
lrwxrwxrwx 1 root root 6 Oct 22 14:18 passwd-so -> passwd
符号连接果然无法打开。另外,如果符号链接的目标文件不存在,
其实文件名的部分就会有特殊的颜色显示。
还记得第6章当中,我们提到的/tmp这个目录是干嘛用的吗?是给大家作为暂存盘用的啊。所以,你会发现,过去我们在进行测试时,都会将数据移动到/tmp下面去练习。因此,有事没事,记得将/tmp下面的一些怪异的数据清一清。
使用ln 如果不加任何参数的话,那么就是 hard link。如同范例二的情况,增加了 hard link 之后,可以发现使用ls-l时,显示的link那一列属性增加。而如果这个时候删掉passwd会发生什么事情呢?passwd -hd 的内容还是会跟原来 passwd 相同,但是 passwd-so 就会找不到该文件。
而如果ln使用-s的参数时,就做成差不多是Windows下面的“快捷方式”的意思。当你修改 Linux 下的symbolic link文件时,则改动的其实是“源文件”,所以不论你的这个源文件被连接到哪里去,只要你修改了连接文件,源文件就跟着变了,以上面为例,由于你使用-s的参数创建一个名为passwd-so的文件,则你修改passwd-so时,其内容与passwd完全相同,并且,当你按下存储之后,被改变的将是passwd这个文件!
此外,如果你做了下面这样的连接:
ln -s /bin /root/bin
那么如果你进入/root/bin这个目录下,该目录其实是/bin这个目录,因为你做了连接文件。所以,如果你进入/root/bin这个刚才创建的连接目录,并且将其中的数据删掉时,/bin里面的数据就通通不见了。这点请千万注意,所以赶紧利用“rm /root/bin”将这个连接文件删除。
基本上,symbolic link 的用途比较广,所以你要特别留意 symbolic link 的用法,将来一定还会经常用到的。
关于目录的连接数量
或许你已经发现了,那就是,当我们以 hard link 进行文件的连接时,可以发现,在 ls −l所显示的第二字段会增1才对,那么请教,如果新建目录时,它默认的连接数量会是多少?让我们来想一想,一个“空目录”里面至少会存在些什么?就是存在.与..这两个目录。那么,当我们创建一个新目录名称为/tmp/testing 时,基本上会有三个东西,那就是:
/tmp/testing
/tmp/testing/.
/tmp/testing/..
而其中/tmp/testing与/tmp/testing/.实际是一样的,都代表该目录,而/tmp/testing/..则代表/tmp这个目录,所以说,当我们新建一个新的目录时,新的目录的连接数为2,而上层目录的连接数则会增加1不信的话,我们来做个测试看看:
[root@www ~]# ls -ld /tmp
drwxrwxrwt 5 root root 4096 Oct 22 14:22 /tmp
[root@www ~]# mkdir /tmp/testing1
[root@www ~]# ls -ld /tmp
drwxrwxrwt 6 root root 4096 Oct 22 14:37 /tmp
[root@www ~]# ls -ld /tmp/testing1
drwxr-xr-x 2 root root 4096 Oct 22 14:37 /tmp/testing1
原本的所谓上层目录/tmp的连接数量由5增加为6,至于新目录/tmp/testing则为2,这样可以理解目录的连接数量的意义了吗?
8.3 磁盘的分区、格式化、检验与挂载
对于一个系统管理者(root)而言,磁盘的管理是相当重要的一环,尤其近来硬盘已经渐渐被当成是消耗品了。如果我们想要在系统里面新增一块硬盘时,应该有哪些动作需要做的呢?
1.对磁盘进行分区,以新建可用的分区。
2.对该分区进行格式化(format),以创建系统可用的文件系统。
3.若想要仔细一点,则可对刚才新建好的文件系统进行检验。
4.在Linux系统上,需要创建挂载点(也即是目录),并将它挂载上来。
在上述的过程当中,还有很多需要考虑的,例如磁盘分区需要定多大、是否需要加入journal的功能、inode 与 block 的数量应该如何规划等的问题。但是这些问题的决定都需要与你的主机用途来加以考虑的。所以,在这个小节里面,鸟哥仅会介绍几个操作而已,更详细的设置,则需要以你未来的经验来参考。
8.3.1 磁盘分区:fdisk
[root@www ~]# fdisk [-l] 设备名称
参数:
-l :输出后面接的设备所有的分区内容。若仅有 fdisk -l 时,
则系统将会把整个系统内能够找到的设备的分区均列出来。
范例:找出你系统中的根目录所在磁盘,并查阅该硬盘内的相关信息
[root@www ~]# df / <==注意:重点在找出磁盘文件名而已
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hdc2 9920624 3823168 5585388 41% /
[root@www ~]# fdisk /dev/hdc <==仔细看,不要加上数字。
The number of cylinders for this disk is set to 5005.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): <==等待你的输入!
由于每个人的环境都不一样,因此每台主机的磁盘数量也不相同。所以你可以先使用df这个命令找出可用磁盘文件名,然后再用fdisk来查阅。在你进入fdisk这个程序的工作界面后,如果你的硬盘太大的话(通常指柱面数量多于1024以上),就会出现如上信息。这个信息仅是在告知你,因为某些旧版的软件与操作系统并无法支持大于 1024 柱面(cylinter)后的扇区使用,不过我们新版的 Linux是没问题。下面继续来看看fdisk内如何操作相关操作。
Command (m for help): m <== 输入 m 后,就会看到下面这些命令介绍
Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition <==删除一个分区
l list known partition types
m print this menu
n add a new partition <==新增一个分区
o create a new empty DOS partition table
p print the partition table <==在屏幕上显示分区表
q quit without saving changes <==不存储,离开fdisk程序
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit <==将刚才的操作写入分区表
x extra functionality (experts only)
老实说,使用fdisk这个程序是完全不需要背命令的。如上所示,你只要按下m就能够看到所有的操作。比较重要的操作在上面已经用底线画出来了,你可以参考。其中比较不一样的是q与w这两个玩意儿,不管你进行了什么操作,只要离开fdisk时按下“q”,那么所有的操作都不会生效!相反,按下“w”就是操作生效的意思。所以,你可以随便玩fdisk,只要离开时按下的是“q”即可。好了,先来看看分区表信息。
Command (m for help): p <== 这里可以输出目前磁盘的状态
Disk /dev/hdc: 41.1 GB, 41174138880 bytes <==这个磁盘的文件名与容量
255 heads, 63 sectors/track, 5005 cylinders <==磁头、扇区与柱面大小
Units = cylinders of 16065 * 512 = 8225280 bytes <==每个柱面的大小
Device Boot Start End Blocks Id System
/dev/hdc1 * 1 13 104391 83 Linux
/dev/hdc2 14 1288 10241437+ 83 Linux
/dev/hdc3 1289 1925 5116702+ 83 Linux
/dev/hdc4 1926 5005 24740100 5 Extended
/dev/hdc5 1926 2052 1020096 82 Linux swap / Solaris
设备文件名 开机区否 开始柱面 结束柱面 1KB大小容量 磁盘分区内的系统
Command (m for help): q
想要不存储离开吗?按下 q 就对了!不要随便按 w 。
使用“p”可以列出目前这块磁盘的分区表信息,这个信息的上半部显示整体磁盘的状态。以鸟哥这块磁盘为例,这个磁盘共有41.1GB左右的容量,共有5005个柱面,每个柱面通过255个磁头在管理读写,每个磁头管理 63 个扇区,而每个扇区的大小均为 512bytes ,因此每个柱面为255 × 63 × 512 = 16065 × 512 = 8225280bytes。
下半部的分区表信息主要列出每个分区的信息项目。每个项目的意义为:
Device:设备文件名,依据不同的磁盘接口/分区位置而变。
Boot:表示是否为开机引导模块,通常Windows系统的C盘需要这模块。
Start,End:表示这个分区在哪个柱面号码之间,可以决定此分区的大小。
Blocks:就是以 1K 为单位的容量。如上所示,/dev/hdc1 大小为 104 391 KB = 102MB。
ID,System:代表这个分区内的文件系统应该是啥。不过这个项目只是一个提示而已,不见得真的代表此分区内的文件系统。
从上文我们可以发现几件事情:
整个磁盘还可以进行额外的分区,因为最大柱面为5005,但只使用到2052号而已;
/dev/hdc5 是由/dev/hdc4 分区出来的,因为/dev/hdc4 为扩展分区,且/dev/hdc5 柱面号码在/dev/hdc4之内。
fdisk还可以直接秀出系统内的所有分区喔!举例来说,鸟哥刚才插入一个U盘到这部Linux系统中,那该如何查看这个磁盘的代号与这个磁盘的分区呢?
范例:查阅目前系统内的所有分区有哪些
[root@www ~]# fdisk -l
Disk /dev/hdc: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hdc1 * 1 13 104391 83 Linux
/dev/hdc2 14 1288 10241437+ 83 Linux
/dev/hdc3 1289 1925 5116702+ 83 Linux
/dev/hdc4 1926 5005 24740100 5 Extended
/dev/hdc5 1926 2052 1020096 82 Linux swap / Solaris
Disk /dev/sda: 8313 MB, 8313110528 bytes
59 heads, 58 sectors/track, 4744 cylinders
Units = cylinders of 3422 * 512 = 1752064 bytes
Device Boot Start End Blocks Id System
/dev/sda1 1 4745 8118260 b W95 FAT32
由上面的信息我们可以看到我有两块磁盘,磁盘文件名为/dev/hdc与/dev/sda,/dev/hdc已经在上面谈过了,至于/dev/sda则有8GB左右的容量,且全部的柱面都已经分区给/dev/sda1,该文件系统应该为Windows的FAT文件系统。这样很容易查阅到分区方面的信息。
这个fdisk只有root才能执行,此外,请注意,使用的“设备文件名”请不要加上数字,因为分区是针对“整个硬盘设备”而不是某个分区呢!所以执行“fdisk /dev/hdc1”就会发生错误。要使用fdisk/dev/hdc才对!那么我们知道可以利用fdisk来查阅硬盘的分区信息外,下面再来说一说进入fdisk之后的几个常做的工作。
再次强调,你可以使用 fdisk 在你的硬盘上面胡乱地进行实际操作,都不要紧,但是请千万记住,不要按下 w。离开的时候按下 q 就万事无妨了。
删除磁盘分区
如果你是按照鸟哥建议的方式去安装你的 CentOS,那么你的磁盘应该会预留一块容量来做练习的。实际练习新增硬盘之前,我们先来玩一玩删除好了,如果想要测试一下如何将你的/dev/hdc全部的分区删除,应该怎么做?
1.fdisk/dev/hdc:先进入fdisk界面。
2.p:先看一下分区的信息,假设要删掉/dev/hdc1。
3.d:这个时候会要你选择一个分区,就选1。
4.w(or)q:按w可存储到磁盘数据表中,并离开fdisk;当然,如果你反悔了,直接按下q就可以取消刚才的删除操作了。
练习一:先进入 fdisk 的界面当中去!
[root@www ~]# fdisk /dev/hdc
练习二: 先看看整个分区表的情况是如何
Command (m for help):p
Disk /dev/hdc: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hdc1 * 1 13 104391 83 Linux
/dev/hdc2 14 1288 10241437+ 83 Linux
/dev/hdc3 1289 1925 5116702+ 83 Linux
/dev/hdc4 1926 5005 24740100 5 Extended
/dev/hdc5 1926 2052 1020096 82 Linux swap / Solaris
练习三: 按下 d 给它删除。
Command (m for help): d
Partition number (1-5): 4
Command (m for help): d
Partition number (1-4): 3
Command (m for help): p
Disk /dev/hdc: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hdc1 * 1 13 104391 83 Linux
/dev/hdc2 14 1288 10241437+ 83 Linux
因为 /dev/hdc5 是由 /dev/hdc4 所衍生出来的逻辑分区,因此 /dev/hdc4 被删除,
/dev/hdc5 就自动不见了。最终就会剩下两个分区而已。
Command (m for help): q
鸟哥这里仅是做一个练习而已,所以,按下q就能够离开。
练习新增磁盘分区
新增磁盘分区有好多种情况,因为新增主分区、扩展分区、逻辑分区的显示结果都不太相同。下面我们先将/dev/hdc全部删除成为干净未分区的磁盘,然后依序新增给大家看看。
练习一: 进入 fdisk 的分区软件界面中,并删除所有分区:
[root@www ~]# fdisk /dev/hdc
Command (m for help): d
Partition number (1-5): 4
Command (m for help): d
Partition number (1-4): 3
Command (m for help): d
Partition number (1-4): 2
Command (m for help): d
Selected partition 1
由于最后仅剩下一个分区,因此系统主动选取这个分区删除。
练习二: 开始新增,我们先新增一个主分区,且指定为 4 号看看。
Command (m for help): n
Command action <==因为是全新磁盘,因此只会问extended/primary而已
e extended
p primary partition (1-4)
p <==选择 Primary 分区
Partition number (1-4): 4 <==设置为 4 号!
First cylinder (1-5005, default 1): <==直接按下[Enter]按键决定。
Using default value 1 <==起始柱面就选用默认值。
Last cylinder or +size or +sizeM or +sizeK (1-5005, default 5005): +512M
这个地方有趣了,我们知道分区是由 n1 到 n2 的柱面号码 (cylinder),
但柱面的大小每块磁盘都不相同,这个时候可以填入 +512M 来让系统自动帮我们找出
最接近 512M 的那个 cylinder 号码。因为不可能刚好等于 512MB
如上所示:这个地方输入的方式有两种:
(1) 直接输入柱面的号码,你得要自己计算柱面/分区的大小才行;
(2) 用 +XXM 来输入分区的大小,让系统自己分柱面的号码。
+与M是必须要有的,XX为数字
Command (m for help): p
Disk /dev/hdc: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hdc4 1 63 506016 83 Linux
注意,只有 4 号。1 ~ 3 保留下来了。
练习三: 继续新增一个,这次我们新增扩展分区好了!
Command (m for help): n
Command action
e extended
p primary partition (1-4)
e <==选择的是 Extended 。
Partition number (1-4): 1
First cylinder (64-5005, default 64): <=[enter]
Using default value 64
Last cylinder or +size or +sizeM or +sizeK (64-5005, default 5005): <=[enter]Using default value 5005
还记得我们在第3章的磁盘分区表曾经谈到过的,扩展分区最好能够包含所有
未分区的区间;所以在这个练习中,我们将所有未配置的柱面都给了这个分区。
所以在开始/结束柱面的位置上,按下两个[Enter]用默认值即可!
Command (m for help): p
Disk /dev/hdc: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hdc1 64 5005 39696615 5 Extended
/dev/hdc4 1 63 506016 83 Linux
如上所示,所有的柱面都在 /dev/hdc1 里面
练习四: 这次我们随便新增一个 2GB 的分区看看。
Command (m for help): n
Command action
l logical ( or over) <==因为已有扩展分区,所以出现逻辑分区
p primary partition (1-4)
p <==玩一下,能否新增主分区
Partition number (1-4): 2
No free sectors available <==肯定不行!因为没有多余的柱面可供配置
Command (m for help): n
Command action
l logical (5 or over)
p primary partition (1-4)
l <==只能使用逻辑分区
First cylinder (64-5005, default 64): <=[enter]
Using default value 64
Last cylinder or +size or +sizeM or +sizeK (64-5005, default 5005): +2048M
Command (m for help): p
Disk /dev/hdc: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hdc1 64 5005 39696615 5 Extended
/dev/hdc4 1 63 506016 83 Linux
/dev/hdc5 64 313 2008093+ 83 Linux
这样就新增了 2GB 的分区,且由于是逻辑分区,所以由 5 号开始。
Command (m for help): q
鸟哥这里仅是做一个练习而已,所以,按下 q 就能够离开。
上面的练习非常重要,注意,不要按下 w,会让你的系统损坏的,上面的一连串练习中,最重要的地方其实就在于创建分区的形式(primary/extended/logical)以及分区的大小了,一般来说新建分区的形式会有下面的数种状况:
1-4号尚有剩余,且系统未有扩展分区:
此时会出现让你挑选Primary/Extended的选项,且你可以指定1~4号间的号码。
1-4号尚有剩余,且系统有扩展分区:
此时会出现让你挑选Primary/Logical的选项;若选择p则你还需要指定1~4号间的号码;若选择l(L的小写)则不需要设置号码,因为系统会自动指定逻辑分区的文件名号码。
1-4没有剩余,且系统有扩展分区:
此时不会让你挑选分区类型,直接会进入logical的分区形式。
请依照你的系统情况,新建一个大约1GB左右的分区,并显示该分区的相关信息。
答:鸟哥的磁盘为/dev/hdc,尚有剩余柱面号码,因此可以这样做:
[root@www ~]# fdisk /dev/hdc
Command (m for help): n
First cylinder (2053-5005, default 2053): <==[enter]
Using default value 2053
Last cylinder or +size or +sizeM or +sizeK (2053-5005, default 5005): +2048M
Command (m for help): p
Disk /dev/hdc: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hdc1 * 1 13 104391 83 Linux
/dev/hdc2 14 1288 10241437+ 83 Linux
/dev/hdc3 1289 1925 5116702+ 83 Linux
/dev/hdc4 1926 5005 24740100 5 Extended
/dev/hdc5 1926 2052 1020096 82 Linux swap / Solaris
/dev/hdc6 2053 2302 2008093+ 83 Linux
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Device or
resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks. <==竟然需要重启才能够生效!我可不要重新启动!
[root@www ~]# partprobe <==强制让内核重新找一次分区表
在这个实践题中,请务必要按下“w”这个操作,因为我们实际上确实要新建这个分区。但请仔细看一下最后的警告消息,因为我们的磁盘无法卸载(因为含有根目录),所以内核无法重新取得分区表信息,因此此时系统会要求我们重新启动(reboot)以更新内核的分区表信息才行。
如上的练习中,最终写入分区表后竟然会让内核无法找到分区表信息。此时你可以直接使用重启来处理,也可以使用GNU推出的工具程序来处置,那就是partprobe这个命令。这个命令的执行很简单,它仅是告知内核必须要读取新的分区表而已,因此并不会在屏幕上出现任何信息才是。这样一来,我们就不需要重启。
操作环境的说明
以 root 的身份进行硬盘的分区时,最好是在单用户维护模式下面比较安全一些,此外,在进行分区的时候,如果该硬盘某个分区还在使用当中,那么很有可能系统内核会无法重载硬盘的分区表,解决的方法就是将该使用中的分区给卸载,然后再重新进入分区一遍,重新写入分区表,那么就可以成功。
注意事项
另外在实践过程中请特别注意,因为SATA硬盘最多能够支持到15号的分区,IDE则可以支持到63号。但目前大家常见的系统都是SATA磁盘,因此在练习的时候千万不要让你的分区超过15号。否则即使你还有剩余的柱面容量,但还是会无法继续进行分区的。
另外需要特别留意的是,fdisk没有办法处理大于2TB以上的磁盘分区。因为虽然Ext3文件系统已经支持达到16TB以上的磁盘,但是分区命令却无法支持。时至今日所有的硬件价格大跌,硬盘也已经达到单块1TB之商,若加上磁盘阵列(RAID),高于2TB的磁盘系统应该会很常见。此时你就得使用parted这个命令了,我们会在本章最后谈一谈这个命令的用法。
8.3.2 磁盘格式化
分区完毕后自然就是要进行文件系统的格式化。格式化的命令非常简单,那就是 mkfs(即 make filesystem之意)这个命令。这个命令其实是个综合的命令,它会去调用正确的文件系统格式化工具软件。
mkfs
[root@www ~]# mkfs [-t文件系统格式]设备文件名
参数:
-t :可以接文件系统格式,例如 ext3, ext2, vfat 等(系统有支持才会生效)
范例一:请将上个小节当中所制作出来的 /dev/hdc6 格式化为 ext3 文件系统
[root@www ~]# mkfs -t ext3 /dev/hdc6
mke2fs 1.39 (29-May-2006)
Filesystem label= <==这里指的是分区的名称(label)
OS type: Linux
Block size=4096(log=2) <==block 的大小设置为 4K
Fragment size=4096 (log=2)
251392 inodes, 502023 blocks <==由此设置决定的inode/block数量
25101 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=515899392
16 block groups
32768 blocks per group, 32768 fragments per group
15712 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912
Writing inode tables: done
Creating journal (8192 blocks): done <==有日志记录
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 34 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
这样就创建起来我们所需要的 Ext3 文件系统了。
[root@www ~]# mkfs[tab][tab]
mkfs mkfs.cramfs mkfs.ext2 mkfs.ext3 mkfs.msdos mkfs.vfat
按下两个[Tab],会发现 mkfs 支持的文件格式如上所示,可以格式化 vfat 。
mkfs 其实是个综合命令而已,事实上如上所示,当我们使用“mkfs –t ext3…”时,系统会去调用mkfs.ext3这个命令来进行格式化的操作。若如同上面所展现的结果,那么这个系统支持的文件系统格式化工具有cramfs,ext2,ext3,msdoc,vfat等,而最常用的应该是ext3,vfat两种。vfat可以用在Windows/Linux共享的U盘。
此时不会让你挑选分区类型,直接会进入logical的分区形式。
将刚才的/dev/hdc6格式化为Windows可读的vfat格式。
答:mkfs-tvfat/dev/hdc6
在格式化为Ext3的范例中,我们可以发现结果里面含有非常多的信息,由于我们没有详细指定文件系统的具体选项,因此系统会使用默认值来进行格式化。其中比较重要的部分为:文件系统的卷标(label)、block的大小以及inode的数量。如果你要指定这些东西,就得要了解一下Ext2/Ext3的公用程序,即mke2fs这个命令。
mke2fs
[root@www ~]# mke2fs [-b block大小] [-i block大小] [-L 卷标] [-cj] 设备
参数:
-b :可以设置每个 block 的大小,目前支持 1024, 2048, 4096 bytes 三种。
-i :多少容量给予一个 inode 呢?
-c :检查磁盘错误,仅下达一次 -c 时,会进行快速读取测试;
如果下达两次 -c -c 的话,会测试读写(read-write)。
-L :后面可以接卷标名称 (label),这个 label 是有用的,e2label命令介绍会谈到。
-j :本来 mke2fs 是 EXT2 ,加上 -j 后,会主动加入 journal 而成为 EXT3。
mke2fs是一个很详细但是很麻烦的命令,因为里面的设置太多了!现在我们进行如下的假设:
这个文件系统的卷标设置为:vbird_logical;
我的block指定为2048大小;
每8192bytes分配一个inode;
构建为journal的Ext3文件系统。
开始格式化/dev/hdc6结果会变成如下所示:
[root@www ~]# mke2fs -j -L "vbird_logical" -b 2048 -i 8192 /dev/hdc6
mke2fs 1.39 (29-May-2006)
Filesystem label=vbird_logical
OS type: Linux
Block size=2048 (log=1)
Fragment size=2048 (log=1)
251968 inodes, 1004046 blocks
50202 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=537919488
62 block groups
16384 blocks per group, 16384 fragments per group
4064 inodes per group
Superblock backups stored on blocks:
16384, 49152, 81920, 114688, 147456, 409600, 442368, 802816
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
比较看看,跟上面的范例用默认值的结果有什么不一样的啊?
其实mke2fs所使用的各项参数也可以用在“mkfs-text3…”后面,因为最终使用的公用程序是相同的,特别要注意的是-b,-i及-j这几个参数,尤其是-j这个参数,当没有指定-j的时候, mke2fs使用ext2为格式化文件格式,若加入-j时,则格式化为ext3这个Journaling的文件系统。
老实说,如果没有特殊需求的话,使用“mkfs -t ext3….”不但容易记忆,而且非常好用。
8.3.3 磁盘检验:fsck,badblocks
由于系统在运行时谁也说不准啥时硬件或者是电源会有问题,所以死机可能是难免的情况(不管是硬件还是软件)。现在我们知道文件系统运行时会有硬盘与内存数据异步的状况发生,因此莫名其妙地死机非常可能导致文件系统的错乱。如果文件系统真的发生错乱的话,那该如何是好?就挽救啊!此时那个好用的 fsck(即 file system check)就得拿来仔细分析一下了。
fsck
[root@www ~]# fsck [-t 文件系统] [-ACay] 设备名称
参数:
-t :如同 mkfs 一样,fsck 也是个综合软件而已,因此我们同样需要指定文件系统。
不过由于现今的 Linux 太聪明了,它会自动通过 super block 去分辨文件系统,
因此通常可以不需要这个参数的。请看后续的范例说明。
-A :依据 /etc/fstab 的内容,将需要的设备扫描一次。/etc/fstab 在下一小节说明,
通常开机过程中就会执行此命令。
-a :自动修复检查到的有问题的扇区,所以你不用一直按 y 。
-y :与 -a 类似,但是某些文件系统仅支持 -y 这个参数。
-C :可以在检验的过程当中使用一个直方图来显示目前的进度!
EXT2/EXT3 的额外参数功能:(e2fsck 这支命令所提供)
-f :强制检查,一般来说,如果 fsck 没有发现任何 unclean 的标志,不会主动进入
细化检查的,如果你想要强制 fsck 进入细化检查,就得加上 -f 标志。
-D :针对文件系统下的目录进行优化配置。
范例一:强制将前面我们新建的 /dev/hdc6 这个设备检验一下!
[root@www ~]# fsck -C -f -t ext3 /dev/hdc6
fsck 1.39 (29-May-2006)
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
vbird_logical: 11/251968 files (9.1% non-contiguous), 36926/1004046 blocks
如果没有加上 -f 的参数,则由于这个文件系统不曾出现问题,
检查非常快速,若加上 -f 强制检查,才会一项一项显示过程。
范例二:查看系统有多少文件系统支持的 fsck 软件
[root@www ~]# fsck[tab][tab]
fsck fsck.cramfs fsck.ext2 fsck.ext3 fsck.msdos fsck.vfat
这是用来检查与修正文件系统错误的命令。注意:通常只有身为 root 且你的文件系统有问题的时候才使用这个命令,否则在正常状况下使用此命令,可能会造成对系统的危害,通常使用这个命令的场合都是在系统出现极大的问题,导致你在Linux开机的时候得进入单用户模式下进行维护的行为时,才必须使用此命令。
另外,如果你怀疑刚才格式化成功的硬盘有问题的时候,也可以使用fsck来检查硬盘。其实就有点像是Windows的scandisk。此外,由于fsck在扫描硬盘的时候,可能会造成部分文件系统的损坏,所以执行fsck时,被检查的分区务必不可挂载到系统上!即是需要在卸载的状态!
不知道你还记不记得第6章的目录配置中我们提过,ext2/ext3文件系统的最顶层(就是挂载点那个目录下面)会存在一个“lost+found”的目录。该目录就是在当你使用 fsck 检查文件系统后,若出现问题时,有问题的数据会被放置到这个目录中。所以理论上这个目录不应该会有任何数据,若系统自动产生数据在里面,那你就得特别注意你的文件系统了。
另外,我们的系统实际执行的fsck命令,其实是调用e2fsck这个软件。可以mane2fsck找到更多的参数辅助。
badblocks
[root@www ~]# badblocks -[svw] 设备名称
参数:
-s :在屏幕上列出进度;
-v :可以在屏幕上看到进度;
-w :使用写入的方式来测试,建议不要使用此参数,尤其是待检查的设备已有文件时!
[root@www ~]# badblocks -sv /dev/hdc6
Checking blocks 0 to 2008093
Checking for bad blocks (read-only test): done
Pass completed, 0 bad blocks found.
刚才谈到的fsck是用来检验文件系统是否出错,至于badblocks则是用来检查硬盘或软盘扇区有没有坏轨的命令。由于这个命令其实可以通过“mke2fs -c 设备文件名”在进行格式化的时候处理磁盘表面的读取测试,因此目前大多不使用这个命令。
8.3.4 磁盘挂载与卸载
我们在本章一开始时的挂载点的意义当中提过挂载点是目录,而这个目录是进入磁盘分区(其实是文件系统)的入口就是了。不过要进行挂载前,你最好先确定几件事:
单一文件系统不应该被重复挂载在不同的挂载点(目录)中;
单一目录不应该重复挂载多个文件系统;
作为挂载点的目录理论上应该都是空目录才是。
尤其是上述的后两点。如果你要用来挂载的目录里面并不是空的,那么挂载了文件系统之后,原目录下的东西就会暂时消失。举个例子来说,假设你的/home原本与根目录(/)在同一个文件系统中,下面原本就有/home/test与/home/vbird两个目录,然后你想要添加新的硬盘,并且直接挂载在/home下面,那么当你挂载上新的分区时,则/home目录显示的是新分区内的数据,至于原先的test与vbird这两个目录就会暂时被隐藏掉了,并不是被覆盖掉,而是暂时隐藏了起来,等到新分区被卸载之后,则/home原本的内容就会再次显示出来。
而要将文件系统挂载到我们的Linux系统上,就要使用mount这个命令,不过,这个命令真的是博大精深。
[root@www ~]# mount -a
[root@www ~]# mount [-l]
[root@www ~]# mount [-t 文件系统] [-L Label名] [-o 额外选项] \
[-n] 设备文件名 挂载点
参数:
-a :依照配置文件 /etc/fstab 的数据将所有未挂载的磁盘都挂载上来。
-l :单纯输入 mount 会显示目前挂载的信息,加上 -l 可增列 Label 名称。
-t :与 mkfs 的参数非常类似的,可以加上文件系统种类来指定欲挂载的类型。
常见的 Linux 支持类型有ext2、ext3、vfat、reiserfs、iso9660(光盘格式)、
nfs、cifs、smbfs(此三种为网络文件系统类型)。
-n :在默认的情况下,系统会将实际挂载的情况实时写入 /etc/mtab 中,以利其他程序
的运行。但在某些情况下(例如单用户维护模式)为了避免问题,会刻意不写入。
此时就得要使用这个 -n 的参数了。
-L :系统除了利用设备文件名 (例如 /dev/hdc6) 之外,还可以利用文件系统的卷标名称
(Label)来进行挂载。最好为你的文件系统取一个独一无二的名称。
-o :后面可以接一些挂载时额外加上的参数,比方说账号、密码、读写权限等:
ro, rw: 挂载文件系统成为只读(ro) 或可读写(rw)。
async, sync: 此文件系统是否使用同步写入 (sync) 或异步 (async) 的
内存机制,请参考文件系统运行方式。默认为 async。
auto, noauto: 允许此分区被以 mount -a 自动挂载(auto)。
dev, nodev: 是否允许此分区上可创建设备文件?dev 为可允许。
suid, nosuid: 是否允许此分区含有 suid/sgid 的文件格式?
exec, noexec: 是否允许此分区上拥有可执行 binary 文件?
user, nouser: 是否允许此分区让任何用户执行 mount ?一般来说,
mount 仅有 root 可以进行,但下达 user 参数,则可让
一般 user 也能够对此分区进行 mount 。
defaults: 默认值为rw, suid, dev, exec, auto, nouser, and async
remount: 重新挂载,这在系统出错,或重新更新参数时,很有用。
会不会觉得光是看这个命令的参数就快要昏倒了?如果有兴趣的话看一下 man mount,那才会真的昏倒的。事实上mount是个很有用的命令,它可以挂载ext3/vfat/nfs等文件系统,由于每种文件系统的数据并不相同,详细的参数自然也就不相同,不过实际应用时却简单。下面介绍几个简单范例先。
挂载Ext2/Ext3文件系统
范例一:用默认的方式将刚才创建的 /dev/hdc6 挂载到 /mnt/hdc6 上面。
[root@www ~]# mkdir /mnt/hdc6
[root@www ~]# mount /dev/hdc6 /mnt/hdc6
[root@www ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
…..中间省略…..
/dev/hdc6 1976312 42072 1833836 3% /mnt/hdc6
看起来,真的有挂载!且文件大小为 2GB 左右。
竟然这么简单,利用“mount 设备文件名挂载点”就能够顺利挂载了。真是方便。为什么可以这么方便呢(甚至不需要使用-t 这个参数)?由于文件系统几乎都有 super block,我们的Linux 可以通过分析 super block 搭配 Linux 自己的驱动程序去测试挂载,如果成功挂载了,就立刻自动使用该类型的文件系统挂载起来。那么系统有没有指定哪些类型的文件系统才需要进行上述的挂载测试呢?主要是参考下面这两个文件:
/etc/filesystems:系统指定的测试挂载文件系统类型;
/proc/filesystems:Linux系统已经加载的文件系统类型。
那我怎么知道我的Linux有没有相关文件系统类型的驱动程序呢?我们Linux支持的文件系统之驱动程序都写在如下的目录中:
/lib/modules/$(uname-r)/kernel/fs/
例如vfat的驱动程序就写在“/lib/modules/$(uname-r)/kernel/fs/vfat/”这个目录下。简单地测试挂载后,接下来让我们检查看看目前已挂载的文件系统状况。
范例二:查看目前已挂载的文件系统,包含各文件系统的Label名称
[root@www ~]# mount -l
/dev/hdc2 on / type ext3 (rw) [/1]
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/hdc3 on /home type ext3 (rw) [/home]
/dev/hdc1 on /boot type ext3 (rw) [/boot]
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
/dev/hdc6 on /mnt/hdc6 type ext3 (rw) [vbird_logical]
除了实际的文件系统外,很多特殊的文件系统(proc/sysfs…)也会被显示出来!
值得注意的是,加上-l参数可以列出如上特殊字体的卷标(label)
这个命令输出的结果可以让我们看到非常多的信息,以/dev/hdc2这个设备来说好了,它的意义是/dev/hdc2是挂载到/目录,文件系统类型为ext3,且挂载为可读写(rw),另外,这个文件系统有卷标,名字(label)为/1。这样,你会解释上文中的最后一行输出结果了吗?自己解释一下先。接下来请拿出你的 CentO SDVD 放入光驱中,并拿 FAT 格式的 U 盘(不要用NTFS的)插入USB接口中,我们来测试挂载一下!
挂载CD或DVD光盘
范例三:将你用来安装 Linux 的 CentOS 原版光盘挂载。
[root@www ~]# mkdir /media/cdrom
[root@www ~]# mount -t iso9660 /dev/cdrom /media/cdrom
[root@www ~]# mount /dev/cdrom /media/cdrom
你可以指定 -t iso9660 这个光盘的格式来挂载,也可以让系统自己去测试挂载。
所以上述的命令只要做一个就够了,但是目录的创建初次挂载时必须要进行。
[root@www ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
…..中间省略…..
/dev/hdd 4493152 4493152 0 100% /media/cdrom
因为我的光驱使用的是/dev/hdd的IDE接口之故!
光驱一旦挂载之后就无法退出光盘,除非你将它卸载才能够退出。从上面的数据你也可以发现,因为是光盘,所以磁盘使用率达到100%,因为你无法直接写入任何数据到光盘当中。另外,其实/dev/cdrom是个连接文件,正确的磁盘文件名得要看你的光驱是什么连接接口的环境。以鸟哥为例,我的光驱接在/dev/hdd 中,所以正确的挂载应该是“mount/dev/hdd/media/cdrom”比较正确。
话说当时年记小 (其实是刚接触 Linux 的那一年),摸 Linux 到处碰壁。连将光驱挂载后,光驱竟然都不让我退片,那个时候难过得要死。解决的方法竟然是重新启动。
格式化与挂载软盘
软盘的格式化可以直接使用mkfs即可。但是软盘也是可以格式化成为ext3或vfat格式的。挂载的时候我们同样使用系统的自动测试挂载即可。如果你有软盘的话(很少人有了吧),请先放置到软盘驱动器当中。下面来测试看看(软盘请勿放置任何数据,且将写保护打开)。
范例四:格式化后挂载软盘到 /media/floppy/ 目录中。
[root@www ~]# mkfs -t vfat /dev/fd0
我们格式化软盘成为 Windows/Linux 可共同使用的 FAT 格式。
[root@www ~]# mkdir /media/floppy
[root@www ~]# mount -t vfat /dev/fd0 /media/floppy
[root@www ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
…..中间省略…..
/dev/fd0 1424 164 1260 12% /media/floppy
与光驱不同的是,你挂载了软盘后竟然还是可以退出软盘。不过,如此一来你的文件系统将会有莫名奇妙的问题发生,整个Linux最重要的就是文件系统,而文件系统是直接挂载到目录树上头,几乎任何命令都会或多或少使用到目录树的数据,因此你当然不可以随意将光盘/软盘拿出来。所以,软盘也请卸载之后再退出,这是很重要的一点。
挂载U盘
请拿出你的U盘并插入Linux主机的USB接口中。注意,你的这个U盘不能够是NTFS的文件系统。接下来让我们测试测试。
范例五:找出你的U盘设备文件名,并挂载到 /mnt/flash 目录中
[root@www ~]# fdisk -l
…..中间省略…..
Disk /dev/sda: 8313 MB, 8313110528 bytes
59 heads, 58 sectors/track, 4744 cylinders
Units = cylinders of 3422 * 512 = 1752064 bytes
Device Boot Start End Blocks Id System
/dev/sda1 1 4745 8118260 b W95 FAT32
从上面的特殊字体可得知磁盘的大小以及设备文件名,知道是 /dev/sda1
[root@www ~]# mkdir /mnt/flash
[root@www ~]# mount -t vfat -o iocharset=cp950 /dev/sda1 /mnt/flash
[root@www ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
…..中间省略…..
/dev/sda1 8102416 4986228 3116188 62% /mnt/flash
如果带有中文文件名的数据,那么可以在挂载时指定一下挂载文件系统所使用的语言。在manmount找到vfat文件格式当中可以使用iocharset来指定语系,而中文语系是cp950,所以也就有了上述的挂载命令选项了。
万一你使用的是可移动硬盘,也就是利用笔记本电脑所做出来的 U 盘时,通常这样的硬盘都使用NTFS格式的。怎办?没关系,可以参考下面这个网站 [8]:
NTFS文件系统官网:Linux-NTFSProject:http://www.linux-ntfs.org/
CentOS 5.x 的相关驱动程序下载页面:http://www.linux-ntfs.org/doku.php?id=redhat:rhel5
将上面提供的驱动程序下载下来并且安装之后,就能够使用NTFS的文件系统了。只是由于文件系统与Linux内核有很大的关系,因此以后如果你的Linux系统有升级(update)时,你就得要重新下载一次相对应的驱动程序版本。
重新挂载根目录与挂载不特定目录
整个目录树最重要的地方就是根目录了,所以根目录根本就不能够被卸载的!问题是,如果你的挂载参数要改变,或者是根目录出现“只读”状态时,如何重新挂载呢?最可能的处理方式就是重新启动。不过你也可以这样做:
范例六:将/重新挂载,并加入参数rw 与 auto
[root@www ~]# mount -o remount,rw,auto/
重点是那个“-o remount,xx”的参数。请注意,要重新挂载(remount)时,这是个非常重要的机制。尤其是当你进入单用户维护模式时,你的根目录常会被系统挂载为只读,这个时候这个命令就太重要了。
另外,我们也可以利用 mount 来将某个目录挂载到另外一个目录去。这并不是挂载文件系统,而是额外挂载某个目录的方法,虽然下面的方法也可以使用symboliclink来连接,不过在某些不支持符号链接的程序运行中,还是得要通过这样的方法才行。
范例七:将 /home 这个目录暂时挂载到 /mnt/home 下面:
[root@www ~]# mkdir /mnt/home
[root@www ~]# mount —bind /home /mnt/home
[root@www ~]# ls -lid /home/ /mnt/home
2 drwxr-xr-x 6 root root 4096 Sep 29 02:21 /home/
2 drwxr-xr-x 6 root root 4096 Sep 29 02:21 /mnt/home
[root@www ~]# mount -l
/home on /mnt/home type none (rw,bind)
看起来,其实两者连接到同一个inode。通过这个mount —bind的功能,你可以将某个目录挂载到其他目录去,而并不是整块文件系统。所以从此进入/mnt/home就是进入/home的意思。
umount(将设备文件卸载)
[root@www ~]# umount [-fn]设备文件名或挂载点
参数:
-f :强制卸载。可用在类似网络文件系统 (NFS) 无法读取到的情况下;
-n :不更新 /etc/mtab 的情况下卸载。
就是直接将已挂载的文件系统卸载即是。卸载之后,可以使用 df 或 mount -l 看看是否还存在目录树中。卸载的方式可以执行设备文件名或挂载点,下面的范例做示范。
范例八:将本章之前自行挂载的文件系统全部卸载:
[root@www ~]# mount
…..前面省略…..
/dev/hdc6 on /mnt/hdc6 type ext3 (rw)
/dev/hdd on /media/cdrom type iso9660 (rw)
/dev/sda1 on /mnt/flash type vfat (rw,iocharset=cp950)
/home on /mnt/home type none (rw,bind)
先找一下已经挂载的文件系统,如上所示,特殊字体即为刚才挂载的设备。
[root@www ~]# umount /dev/hdc6 <==用设备文件名来卸载
[root@www ~]# umount /media/cdrom <==用挂载点来卸载
[root@www ~]# umount /mnt/flash <==因为挂载点比较好记忆
[root@www ~]# umount /dev/fd0 <==用设备文件名较好记
[root@www ~]# umount /mnt/home <==一定要用挂载点。因为挂载的是目录
由于全部卸载了,此时你才可以退出光盘、软盘、U盘等设备。如果你遇到这样的情况:
[root@www ~]# mount /dev/cdrom /media/cdrom
[root@www ~]# cd /media/cdrom
[root@www cdrom]# umount /media/cdrom
umount: /media/cdrom: device is busy
umount: /media/cdrom: device is busy
由于你目前正在/media/cdrom/目录内,也就是说其实你正在使用该文件系统的意思。所以自然无法卸载这个设备!那该如何是好?离开该文件系统的挂载点即可。以上述的案例来说,你可以使用“cd/”回到根目录,就能够卸载/media/cdrom了。
使用Label name 进行挂载的方法
除了磁盘的设备文件名之外,其实我们可以使用文件系统的卷标(label)名称来挂载。举例来说,我们刚才卸载的/dev/hdc6卷标名称是(vbird_logical),你也可以使用dumpe2fs这个命令来查询一下。然后就这样做即可:
范例九:找出 /dev/hdc6 的 label name,并用 label 挂载到 /mnt/hdc6
[root@www ~]# dumpe2fs -h /dev/hdc6
Filesystem volume name: vbird_logical
…..下面省略…..
卷标名称为 vbird_logical 。
[root@www ~]# mount -L "vbird_logical" /mnt/hdc6
这种挂载的方法有一个很大的好处:系统不必知道该文件系统所在的接口与磁盘文件名。更详细的说明我们会在下一小节当中的 e2label 介绍。
8.3.5 磁盘参数修改
某些时刻,你可能会希望修改一下目前文件系统的一些相关信息,举例来说,你可能要修改Labelname,或者是journal的参数,或者是其他硬盘运行时的相关参数(例如DMA启动与否)。这个时候,就得需要下面这些相关的命令功能。
mknod
还记得我们说过,在 Linux 下面所有的设备都以文件来代表,但是那个文件如何代表该设备呢?就是通过文件的major与minor数值来替代。所以,那个major与minor数值是有特殊意义的,不是随意设置的。举例来说,在鸟哥的这个测试机当中,那个用到的磁盘/dev/hdc 的相关设备代码如下:
[root@www ~]# ll /dev/hdc*
brw-r——- 1 root disk 22, 0 Oct 24 15:55 /dev/hdc
brw-r——- 1 root disk 22, 1 Oct 20 08:47 /dev/hdc1
brw-r——- 1 root disk 22, 2 Oct 20 08:47 /dev/hdc2
brw-r——- 1 root disk 22, 3 Oct 20 08:47 /dev/hdc3
brw-r——- 1 root disk 22, 4 Oct 24 16:02 /dev/hdc4
brw-r——- 1 root disk 22, 5 Oct 20 16:46 /dev/hdc5
brw-r——- 1 root disk 22, 6 Oct 25 01:33 /dev/hdc6
上面的22为主设备代码(Major),而0~6则为次设备代码(Minor)。我们的Linux内核认识的设备数据就是通过这两个数值来决定。举例来说,常见的硬盘文件名/dev/hda与/dev/sda设备代码如表8-2所示。
表8-2
如果你想要知道更多内核支持的硬件设备代码(major,minor)请参考官网的连接 [9]:
http://www.kernel.org/pub/linux/docs/device-list/devices.txt
基本上,Linux内核升为2.6版以后,硬件文件名已经都可以被系统自动实时产生了,我们根本不需要手动创建设备文件。不过某些情况下面我们可能还是得要手动处理设备文件的,例如在某些服务被放到特定目录下时(chroot),就需要这样做了。此时这个mknod就得要知道如何操作。
[root@www ~]# mknod 设备文件名 [bcp] [Major] [Minor]
参数:
设备种类:
b :设置设备名称成为一个外部存储设备文件,例如硬盘等;
c :设置设备名称成为一个外部输入设备文件,例如鼠标/键盘等;
p :设置设备名称成为一个 FIFO 文件;
Major :主设备代码;
Minor :次设备代码。
范例一:由上述的介绍我们知道 /dev/hdc10 设备代码 22, 10,请建立并查阅此设备
[root@www ~]# mknod /dev/hdc10 b 22 10
[root@www ~]# ll /dev/hdc10
brw-r—r— 1 root root 22, 10 Oct 26 23:57 /dev/hdc10
上面那个 22 与 10 是有意义的,不要随意设置。
范例二:创建一个 FIFO 文件,文件名为 /tmp/testpipe
[root@www ~]# mknod /tmp/testpipe p
[root@www ~]# ll /tmp/testpipe
prw-r—r— 1 root root 0 Oct 27 00:00 /tmp/testpipe
注意:这个文件可不是一般文件,不可以随便就放在这里。
测试完毕之后请删除这个文件,看一下这个文件的类型,是 p 。
e2label
我们在介绍 mkfs 命令时有谈到设置文件系统卷标(Label)的方法。那如果格式化完毕后想要修改卷标呢?就用这个e2label来修改了。那什么是Label呢?我们拿你曾用过的Windows系统来说明。当你打开资源管理器时,C/D等盘不是都会有个名称吗?那就是label(如果没有设置名称,就会显示“本机磁盘驱动器”的字样)。
这个东西除了有趣且可以让你知道磁盘的内容是什么之外,也会被使用到一些配置文件当中。举例来说,刚才我们聊到的磁盘的挂载时,不就有用到 Label name 来进行挂载吗?目前CentOS 的配置文件,也就是那个/etc/fstab 文件的设置都默认使用 Label name。那这样做有什么好处与缺点呢?
优点:不论磁盘文件名怎么变,不论你将硬盘插在哪个IDE/SATA接口,由于系统是通过Label,所以磁盘插在哪个接口将不会有影响。
缺点:如果插了两块硬盘,刚好两块硬盘的 Label 有重复的,那就惨了,因为系统可能会无法判断哪个磁盘分区才是正确的。
鸟哥一直是个比较“硬派”作风的人,所以我还是比较喜欢直接利用磁盘文件名来挂载。不过,如果没有特殊需求的话,那么利用Label来挂载也成。但是你就不可以随意修改Label的名称了。
[root@www ~]# e2label设备名称 新的Label名称
范例一:将 /dev/hdc6 的卷标改成 my_test 并查看是否修改成功
[root@www ~]# dumpe2fs -h /dev/hdc6
Filesystem volume name: vbird_logical <==原本的卷标名称
…..下面省略…..
[root@www ~]# e2label /dev/hdc6 "my_test"
[root@www ~]# dumpe2fs -h /dev/hdc6
Filesystem volume name: my_test <==改过来啦。
…..下面省略…..
tune2fs
[root@www ~]# tune2fs [-jlL] 设备代号
参数:
-l :类似 dumpe2fs -h 的功能。将 super block 内的数据读出来。
-j :将 ext2 的文件系统转换为 ext3 的文件系统;
-L :类似 e2label 的功能,可以修改文件系统的 Label 。
范例一:列出 /dev/hdc6 的 super block 内容
[root@www ~]# tune2fs -l /dev/hdc6
这个命令的功能其实很广泛,上面鸟哥仅列出很简单的一些参数而已,更多的用法请自行参考 man tune2fs。比较有趣的是,如果你的某个分区原本是 ext2 的文件系统,如果想要将它更新成为ext3文件系统的话,利用tune2fs就可以很简单地转换过来。
hdparm
如果你的硬盘是 IDE 接口的,那么这个命令可以帮助你设置一些高级参数。如果你是使用SATA接口的,那么这个命令就没有多大用途了。另外,目前的Linux系统都已经稍微优化过,所以这个命令最多是用来测试性能,而且建议你不要随便调整硬盘参数,文件系统容易出问题,除非你真的知道你调整的数据是什么。
[root@www ~]# hdparm [-icdmXTt] 设备名称
参数:
-i :将内核检测到的硬盘参数显示出来。
-c :设置 32bit (32位)访问模式。这个 32 位访问模式指的是在硬盘在与
PCI 接口之间传输的模式,而硬盘本身是依旧以 16 位模式在跑的。
默认的情况下,这个设置值都会被打开,建议直接使用 c1 即可。
-d :设置是否启用 DMA 模式,-d1 为启动,-d0 为取消。
-m :设置同步读取多个 sector 的模式。一般来说,设置此模式,可降低系统因为
读取磁盘而损耗的性能。不过,西部数据的硬盘则不怎么建议设置此值。
一般来说,设置为 16/32 是优化,不过,西部数据硬盘建议值则是 4/8 。
这个值的最大值,可以利用 hdparm -i /dev/hda 输出的 MaxMultSect
来设置。一般如果不知道,设置16 是合理的。
-X :设置 UtraDMA 的模式,一般来说,UDMA 的模式值加 64 即为设定值。
并且,硬盘与主板芯片必须要同步,所以,取最小的那个。一般来说:
33MHz DMA mode 0~2 (X64~X66)
66MHz DMA mode 3~4 (X67~X68)
100MHz DMA mode 5 (X69)
如果你的硬盘上面显示的是 UATA 100 以上的,那么设置 X69 也不错。
-T :测试暂存区 cache 的访问性能
-t :测试硬盘的实际访问性能 (较正确)!
范例一:取得我硬盘的最大同步访问 sector 值与目前的 UDMA 模式
[root@www ~]# hdparm -i /dev/hdc
Model=IC35L040AVER07-0, FwRev=ER4OA41A, SerialNo=SX0SXL98406 <==硬盘的厂牌型号
Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>10Mbs }
RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=40
BuffType=DualPortCache, BuffSize=1916kB, MaxMultSect=16, MultSect=16
CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=80418240
IORDY=on/off, tPIO={min:240,w/IORDY:120}, tDMA={min:120,rec:120}
PIO modes: pio0 pio1 pio2 pio3 pio4
DMA modes: mdma0 mdma1 mdma2
UDMA modes: udma0 udma1 udma2 udma3 udma4 udma5 <==有 为目前的值
AdvancedPM=yes: disabled (255) WriteCache=enabled
Drive conforms to: ATA/ATAPI-5 T13 1321D revision 1:
ATA/ATAPI-2 ATA/ATAPI-3 ATA/ATAPI-4 ATA/ATAPI-5
这块硬盘缓存 (BuffSize)只有 2MB,但使用的是 UDMA5 ,还可以。
范例二:由上个范例知道最大 16 位/UDMA 为 mode 5,所以可以设置为:
[root@www ~]# hdparm -d1 -c1 -X69 /dev/hdc
范例三:测试这块硬盘的读取性能
[root@www ~]# hdparm -Tt /dev/hdc
/dev/hdc:
Timing cached reads: 428 MB in 2.00 seconds = 213.50 MB/sec
Timing buffered disk reads: 114 MB in 3.00 seconds = 38.00 MB/sec
鸟哥的这台测试机没有很好。这样的速度,实在差强人意。
如果你是使用 SATA 硬盘的话,这个命令唯一可以做的就是最后面那个测试的功能而已,虽然这样的测试不是很准确,至少是一个可以比较的基准。鸟哥在我的cluster机器上面测试的SATA(/dev/sda)与RAID(/dev/sdb)结果如下,可以提供给你参考。
[root@www ~]# hdparm -Tt /dev/sda /dev/sdb
/dev/sda:
Timing cached reads: 4152 MB in 2.00 seconds = 2075.28 MB/sec
Timing buffered disk reads: 304 MB in 3.01 seconds = 100.91 MB/sec
/dev/sdb:
Timing cached reads: 4072 MB in 2.00 seconds = 2036.31 MB/sec
Timing buffered disk reads: 278 MB in 3.00 seconds = 92.59 MB/sec
8.4 设置开机挂载
手动处理mount不是很人性化,我们总是需要让系统“自动”在开机时进行挂载的。本小节来介绍开机挂载。另外,从FTP服务器下载的镜像文件能否不用刻录就可以读取内容?我们也需要介绍先。
8.4.1 开机挂载/etc/fstab及/etc/mtab
刚才上面说了许多,那么可不可以在开机的时候就将我要的文件系统都挂好呢?这样我就不需要每次进入Linux系统都还要再挂载一次。当然可以,那就直接到/etc/fstab里面去修改就行。不过,在开始说明前,这里要先跟大家说一说系统挂载的一些限制:
根目录/是必须挂载的﹐而且一定要先于其他mount point 被挂载进来。
其他挂载点必须为已新建的目录﹐可任意指定﹐但一定要遵守必需的系统目录架构原则。
所有挂载点在同一时间之内﹐只能挂载一次。
所有分区在同一时间之内﹐只能挂载一次。
如若进行卸载﹐你必须先将工作目录移到挂载点(及其子目录)之外。
让我们直接查阅一下/etc/fstab这个文件的内容。
[root@www ~]# cat /etc/fstab
Device Mount point filesystem parameters dump fsck
LABEL=/1 / ext3 defaults 11
LABEL=/home /home ext3 defaults 12
LABEL=/boot /boot ext3 defaults 12
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
LABEL=SWAP-hdc5 swap swap defaults 0 0
上述特殊字体的部分与实际磁盘有关。其他则是虚拟文件系统或
与内存交换空间(swap)有关。
其实/etc/fstab(file system table)就是将我们利用 mount 命令进行挂载时,将所有的参数写入到这个文件中就可以了。除此之外,/etc/fstab还添加了dump这个备份用的命令支持,与开机时是否进行文件系统检验fsck等命令有关。
这个文件的内容共有六个字段,这六个字段非常重要。你一定要背下来才好。各个字段的详细数据如下:
因为某些 distributions 的/etc/fstab 文件排列方式蛮丑的,虽然每一列之间只要以空格符分开即可,但就是觉得不雅观,所以通常鸟哥就会自己排列整齐,并加上批注符号(就是#),来帮我记住这些信息。
第一列:磁盘设备文件名或该设备的Label
这个字段请填入文件系统的设备文件名。但是由上文我们知道系统默认使用的是Label名称。在鸟哥的这个测试系统中/dev/hdc2 卷标名称为/1,所以上面的“LABEL=/1”也可以被替代成为“/dev/hdc2”的意思。至于Label可以使用dumpe2fs命令来查阅的。
记得有一次有个网友写信给鸟哥,他说,依照e2label的设置去练习修改自己的分区的Label name 之后,却发现,再也无法顺利开机成功!后来才发现,原来他的/etc/fstab 就是以Label name 去挂载的。但是因为在练习的时候,将 Label name 改名字过了,导致在开机的过程当中再也找不到相关的Label name 了。
所以,这里再次强调,利用设备名称(ex>/dev/hda1)来挂载分区时,是被固定死的,所以你的硬盘不可以随意插在任意的插槽,不过它还是有好处的。而使用Label name 来挂载虽然没有插槽方面的问题,不过,你就得要随时注意你的Label name。尤其是新增硬盘的时候。
第二列:挂载点(mount point)
就是挂载点啊!挂载点是什么?一定是目录。
第三列:磁盘分区的文件系统
在手动挂载时可以让系统自动测试挂载,但在这个文件当中我们必须要手动写入文件系统才行。包括ext3,reiserfs,nfs,vfat等。
第四列:文件系统参数
记不记得我们在 mount 这个命令中谈到很多特殊的文件系统参数?还有我们使用过的“-oiocharset=cp950”?这些特殊的参数就是写入在这个字段中。虽然之前在mount中已经提过一次,这里我们利用表8-3所示的方式再整理一下。
表8-3
第五列:能否被dump备份命令作用:
dump是一个用来作为备份的命令(我们会在第25章备份策略中谈到这个命令),我们可以通过fstab指定哪个文件系统必须要进行dump备份。0代表不要做dump备份,1代表要每天进行 dump 的操作,2 也代表其他不定日期的 dump 备份操作,通常这个数值不是 0就是1。
第六列:是否以fsck检验扇区
开机的过程中,系统默认会以fsck检验我们的文件系统是否完整(clean)。不过,某些文件系统是不需要检验的,例如内存交换空间(swap),或者是特殊文件系统,例如/proc 与/sys等。所以,在这个字段中,我们可以设置是否要以 fsck 检验该文件系统。0 是不要检验,1表示最早检验(一般只有根目录会设置为1),2也是要检验,不过1会比较早被检验。一般来说,根目录设置为1,其他的要检验的文件系统都设置为2就好了。
假设我们要将/dev/hdc6每次开机都自动挂载到/mnt/hdc6,该如何进行?
答:首先,请用nano将下面这一行写入/etc/fstab当中;
[root@www ~]# nano /etc/fstab
/dev/hdc6 /mnt/hdc6 ext3 defaults 1 2
再来看看/dev/hdc6是否已经挂载,如果挂载了,请务必卸载再说。
[root@www ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hdc6 1976312 42072 1833836 3% /mnt/hdc6
竟然不知道何时被挂载了,赶紧给他卸载先。
[root@www ~]# umount /dev/hdc6
最后测试一下刚才我们写入/etc/fstab的语法有没有错误。这点很重要,因为这个文件如果写错了,则你的Linux很可能将无法顺利开机完成!所以请务必要测试。
[root@www ~]# mount -a
[root@www ~]# df
最终有看到/dev/hdc6 被挂载起来的信息才是成功挂载了,而且以后每次开机都会顺利将此文件系统挂载起来的。由于这个范例仅是测试而已,请务必回到/etc/fstab当中,将上述这行批注或者是删除掉!
[root@www ~]# nano /etc/fstab
/dev/hdc6 /mnt/hdc6 ext3 defaults 1 2
/etc/fstab是开机时的配置文件,不过,实际文件系统的挂载是记录到/etc/mtab与/proc/mounts这两个文件当中的。每次我们在改动文件系统的挂载时,也会同时更动这两个文件。但是,万一发生你在/etc/fstab中输入的数据有误,导致无法顺利开机成功,而进入单用户维护模式当中,那时候的/可是readonly的状态,当然你就无法修改/etc/fstab,也无法更新/etc/mtab。那怎么办?没关系,可以利用下面这一招:
[root@www ~]# mount -n -o remount,rw /
8.4.2 特殊设备 loop挂载(镜像文件不刻录就挂载使用)
挂载光盘/DVD镜像文件
想象一下如果今天我们下载了Linux或者是其他所需光盘/DVD的镜像文件后,难道一定需要刻录成为光盘才能够使用该文件里面的数据吗?当然不是啦!我们可以通过 loop 设备来挂载的。
那要如何挂载呢?鸟哥将整个 CentOS 5.2 的 DVD 镜像文件挂到测试机上面,然后利用这个文件来挂载给大家参考。
[root@www ~]# ll -h /root/centos 5.2_x86_64.iso
-rw-r—r— 1 root root 4.3G Oct 27 17:34 /root/centos5.2_x86_64.iso
看到上面的结果吧?这个文件就是镜像文件,文件非常大。
[root@www ~]# mkdir /mnt/centos_dvd
[root@www ~]# mount -o loop /root/centos5.2_x86_64.iso /mnt/centos_dvd
[root@www ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/root/centos5.2_x86_64.iso
4493152 4493152 0 100% /mnt/centos_dvd
就是这个项目。.iso 镜像文件内的所有数据可以在 /mnt/centos_dvd中看到。
[root@www ~]# ll /mnt/centos_dvd
total 584
drwxr-xr-x 2 root root 522240 Jun 24 00:57 CentOS <==瞧!就是DVD的内容。
-rw-r—r— 8 root root 212 Nov 21 2007 EULA
-rw-r—r— 8 root root 18009 Nov 21 2007 GPL
drwxr-xr-x 4 root root 2048 Jun 24 00:57 images
…..下面省略…..
[root@www ~]# umount /mnt/centos_dvd/
测试完成,得将数据卸载!
如此一来我们不需要将这个文件刻录成为光盘或者是 DVD 就能够读取内部的数据了。换句话说,你也可以在这个文件内“动手脚”去修改文件。这也是为什么很多镜像文件提供后,还得要提供验证码(MD5)给用户确认该影响文件没有问题。
新建大文件以制作loop设备文件。
想一想,既然能够挂载DVD的镜像文件,那么我能不能制作出一个大文件,然后将这个文件格式化后挂载呢?这是个有趣的操作,而且还能够帮助我们解决很多系统的分区不良的情况。举例来说,如果当初在分区时,你只有分出一个根目录,假设你已经没有多余的空间可以进行额外的分区。偏偏根目录的空间还很大,此时你就能够制作出一个大文件,然后将这个文件挂载。如此一来感觉上你就多了一个分区。用途非常广泛。
下面我们在/home下创建一个512MB左右的大文件,然后将这个大文件格式化并且实际挂载来实践一下。这样你会比较清楚鸟哥在讲什么。
创建大型文件
首先,我们得先有一个大的文件。怎么创建这个大文件呢?在 Linux 下面我们有一个很好用的程序dd!它可以用来创建空的文件。详细的说明请先翻到下一章压缩命令的运用来查阅,这里鸟哥仅作一个简单的范例而已。假设我要创建一个空的文件在/home/loopdev,那可以这样做:
[root@www ~]# dd if=/dev/zero of=/home/loopdev bs=1M count=512
512+0 records in <==读入 512 条数据
512+0 records out <==输出 512 条数据
536870912 bytes (537 MB) copied, 12.3484 seconds, 43.5 MB/s
这个命令的简单意义如下:
if 是 input file ,输入文件。那个 /dev/zero 是会一直输出 0 的设备!
of 是 output file ,将一堆零写入到后面接的文件中。
bs 是每个 block 大小,就像文件系统那样的 block。
count 则是总共几个 bs 的意思。
[root@www ~]# ll -h /home/loopdev
-rw-r—r— 1 root root 512M Oct 28 02:29 /home/loopdev
dd就好像在堆砖块一样,将512块、每块1MB的砖块堆栈成为一个大文件 (/home/loopdev)!最终就会出现一个512MB的文件。
格式化
很简单就创建了一个512MB的文件,接下来当然是格式化了。
[root@www ~]# mkfs -t ext3 /home/loopdev
mke2fs 1.39 (29-May-2006)
/home/loopdev is not a block special device.
Proceed anyway? (y,n) y <==由于不是正常的设备,所以这里会提示你。
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
131072 inodes, 524288 blocks
26214 blocks (5.00%) reserved for the super user
…..以下省略…..
挂载
那要如何挂载啊?利用 mount 的特殊参数,那个-o loop 的参数来处理!
[root@www ~]# mount -o loop /home/loopdev /media/cdrom/
[root@www ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/home/loopdev 507748 18768 462766 4% /media/cdrom
通过这个简单的方法,感觉上你就可以在原本的分区在不改动原有的环境下制作出你想要的分区就是了,尤其是想要玩Linux上面的虚拟机的话,也就是以一台Linux主机再切割成为数个独立的主机系统时,类似VMware这类的软件,在Linux上使用xen这个软件,它就可以配合这种 loop device 的文件类型来进行根目录的挂载,真的非常有用。
8.5 内存交换空间(swap)的构建
还记得在安装Linux之前大家经常会告诉你的话吧?就是安装时一定需要的两个分区。一个是根目录,另外一个就是swap(内存交换空间)。关于内存交换空间的解释在第4章安装Linux内的磁盘分区时有提过,swap的功能就是在应付物理内存不足的情况下所造成的内存扩展记录的功能。
一般来说,如果硬件的配备足够的话,那么swap应该不会被我们的系统所使用到,swap会被利用到的时刻通常就是物理内存不足的情况了。从第 0 章的计算机概论当中,我们知道 CPU 所读取的数据都来自于内存,那当内存不足的时候,为了让后续的程序可以顺利运行,因此在内存中暂不使用的程序与数据就会被挪到swap中了。此时内存就会空出来给需要执行的程序加载。由于swap是用硬盘来暂时放置内存中的信息,所以用到swap时,你的主机硬盘灯就会开始闪个不停。
虽然目前主机的内存都很大,至少都有1GB以上。因此在个人使用上你不设置swap应该也没有什么太大的问题。不过服务器可就不同了,由于你不会知道何时会有大量来自网络的请求,因此你最好能够预留一些swap来缓冲一下系统的内存用量,至少达到“备而不用”的地步。
现在想象一个情况,你已经将系统创建起来了,此时却才发现你没有构建 swap,那该如何是好呢?通过本章上面谈到的方法,你可以使用如下的方式来创建你的swap。
设置一个swap分区
创建一个虚拟内存的文件
不嗌嗦,下面立刻来处理。
8.5.1 使用物理分区构建 swap
新建swap分区的方式也是非常简单。通过下面几个步骤就可搞定:
1.分区:先使用fdisk在你的磁盘中分出一个分区给系统作为swap。由于Linux的fdisk默认会将分区的 ID 设置为 Linux的文件系统,所以你可能还得要设置一下 system ID 就是了。
2.格式化:利用新建swap格式的“mkswap设备文件名”就能够格式化该分区成为swap格式。
3.使用:最后将该swap设备启动,方法为“swapon设备文件名”。
4.查看:最终通过free这个命令来查看一下内存的使用情况。
我们立刻来实践。既然我们还有多余的磁盘空间可以分区,那么让我们继续分出 256MB 的磁盘分区,然后将这个磁盘分区做成swap。
先进行分区的行为。
[root@www ~]# fdisk /dev/hdc
Command (m for help): n
First cylinder (2303-5005, default 2303): <==这里按[Enter]
Using default value 2303
Last cylinder or +size or +sizeM or +sizeK (2303-5005, default 5005): +256M
Command (m for help): p
Device Boot Start End Blocks Id System
…..中间省略…..
/dev/hdc6 2053 2302 2008093+ 83 Linux
/dev/hdc7 2303 2334 257008+ 83 Linux <==新增的选项
Command (m for help): t <==修改系统 ID
Partition number (1-7): 7 <==七号分区
Hex code (type L to list codes): 82 <==改成 swap 的 ID
Changed system type of partition 7 to 82 (Linux swap / Solaris)
Command (m for help): p
Device Boot Start End Blocks Id System
…..中间省略…..
/dev/hdc6 2053 2302 2008093+ 83 Linux
/dev/hdc7 2303 2334 257008+ 82 Linux swap / Solaris
Command (m for help): w
此时就将分区表更新了!
[root@www ~]# partprobe
这个操作很重要的。不要忘记让内核更新分区表。
开始构建swap格式。
[root@www ~]# mkswap /dev/hdc7
Setting up swapspace version 1, size = 263172 kB <==非常快速!
开始查看与加载。
[root@www ~]# free
total used free shared buffers cached
Mem: 742664 684592 58072 0 43820 497144
-/+ buffers/cache: 143628 599036
Swap: 1020088 96 1019992
我有 742664KB 的物理内存,使用 684592KB剩余 58072KB,使用掉的内存有
43820KB / 497144KB 用在缓冲/快取的用途中。
至于 swap 已经存在了 1020088KB 。这样会看了吧?
[root@www ~]# swapon /dev/hdc7
[root@www ~]# free
total used free shared buffers cached
Mem: 742664 684712 57952 0 43872 497180
-/+ buffers/cache: 143660 599004
Swap: 1277088 96 1276992 <==有增加了,看到否?
[root@www ~]# swapon -s
Filename Type Size Used Priority
/dev/hdc5 partition 1020088 96 -1
/dev/hdc7 partition 257000 0 -2
上面列出目前使用的 swap 设备有哪些的意思。
8.5.2 使用文件构建swap
如果是在物理分区无法支持的环境下,此时前一小节提到的loop设备构建方法就派得上用场了。与物理分区不一样的只是利用 dd 去新建一个大文件而已。多说无益,我们就再通过文件新建的方法创建一个128MB的内存交换空间吧。
使用dd这个命令来新增一个128MB的文件在/tmp下面:
[root@www ~]# dd if=/dev/zero of=/tmp/swap bs=1M count=128
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 1.7066 seconds, 78.6 MB/s
[root@www ~]# ll -h /tmp/swap
-rw-r—r— 1 root root 128M Oct 28 15:33 /tmp/swap
这样一个128MB的文件就新建完毕。若忘记上述的各项参数的意义,请回前一小节查阅一下。
使用mkswap将/tmp/swap这个文件格式化为swap的文件格式:
[root@www ~]# mkswap /tmp/swap
Setting up swapspace version 1, size = 134213 kB
这个命令执行时请特别小心,因为弄错字节,将可能使你的文件系统挂掉。
使用swapon来将/tmp/swap启动。
[root@www ~]# free
total used free shared buffers cached
Mem: 742664 450860 291804 0 45584 261284
-/+ buffers/cache: 143992 598672
Swap: 1277088 96 1276992
[root@www ~]# swapon /tmp/swap
[root@www ~]# free
total used free shared buffers cached
Mem: 742664 450860 291804 0 45604 261284
-/+ buffers/cache: 143972 598692
Swap: 1408152 96 1408056
[root@www ~]# swapon -s
Filename Type Size Used Priority
/dev/hdc5 partition 1020088 96 -1
/dev/hdc7 partition 257000 0 -2
/tmp/swap file 131064 0 -3
使用swapoff 关掉swap file
[root@www ~]# swapoff /tmp/swap
[root@www ~]# swapoff /dev/hdc7
[root@www ~]# free
total used free shared buffers cached
Mem: 742664 450860 291804 0 45660 261284
-/+ buffers/cache: 143916 598748
Swap: 1020088 96 1019992 <==回复成最原始的样子了。
8.5.3 swap使用上的限制
说实话,swap 在目前的桌面计算机来讲,存在的意义已经不大,这是因为目前的 x86 主机所含的内存实在都太大了(一般入门级至少也都有 512MB),所以,我们的 Linux 系统大概都用不到 swap。不过,如果是针对服务器或者是工作站这些常年上线的系统来说的话,那么,无论如何,swap 还是需要创建的。
因为swap主要的功能是当物理内存不够时,将某些在内存当中所占的程序暂时移动到swap当中,让物理内存可以被需要的程序来使用。另外,如果你的主机支持电源管理模式,也就是说,你的Linux主机系统可以进入“休眠”模式的话,那么,运行当中的程序状态则会被记录到swap去,以作为“唤醒”主机的状态依据。另外,有某些程序在运行时,本来就会利用swap的特性来存放一些数据段,所以,swap还是需要创建的,只是不需要太大。
不过,swap在被创建时,是有限制的。
在内核2.4.10版本以后,单一swap已经没有2GB的限制了。
但是,最多还是仅能创建32个swap!
而且,由于目前x86_64(64位)最大内存寻址到64GB,因此,swap总量最大也是仅能达64GB就是了。
8.6 文件系统的特殊查看与操作
文件系统实在是非常有趣的东西,鸟哥学了好几年还是很多东西不很懂。在学习的过程中很多朋友在讨论区都有提供一些想法,这些想法将它归纳起来有下面几点可以参考。
8.6.1 boot sector 与super block 的关系
在过去非常多的文章都写到引导装载程序是安装到 super block 内的,但是我们由官方的 How to 文件知道,图 8-3 所示的结果是将可安装开机信息的boot sector(启动扇区)独立出来,并非放置到superblock当中。那么也就是说过去的文章写错了?这其实还是可以讨论的。
经过一些搜寻,鸟哥找到几篇文章(非官方文件)的说明,大多是网友分析的结果。如下所示 [10]:
The Second Extended File System: http://www.nongnu.org/ext2-doc/ext2.html
Rob's ext2 documentation: http://www.landley.net/code/toybox/ext2.html
Life is different blog: ext2 文件系统分析: http://www.qdhedu.com/blog/post/7.html
这几篇文章有几个重点,归纳一下如下:
superblock 的大小为 1024bytes;
superblock 前面需要保留 1024bytes 下来,以让引导装载程序可以安装。
分析上述两点我们知道boot sector应该会占有1024bytes的大小,但是整个文件系统主要是依据block大小来决定的。因此要讨论boot sector与superblock的关系时,不得不将block的大小拿出来讨论。
block为1024bytes(1KB)时:
如果 block 大小刚好是 1024 的话,那么 boot sector与 superblock 各会占用掉一个 block,所以整个文件系统图就会如同图 8-3 所显示的那样,boot sector 是独立于 superblock 外面的.由于鸟哥在基础篇安装的环境中有个/boot 的独立文件系统在/dev/hdc1 中,使用 dumpe2fs 查看的结果有点像下面这样:(如果你是按照鸟哥的教学安装你的CentOS时,可以发现相同的情况。)
[root@www ~]# dumpe2fs /dev/hdc1
dumpe2fs 1.39 (29-May-2006)
Filesystem volume name: /boot
….(中间省略)….
First block: 1
Block size: 1024
….(中间省略)….
Group 0: (Blocks 1-8192)
Primary superblock at 1, Group descriptors at 2-2
Reserved GDT blocks at 3-258
Block bitmap at 259 (+258), Inode bitmap at 260 (+259)
Inode table at 261-511 (+260)
511 free blocks, 1991 free inodes, 2 directories
Free blocks: 5619-6129
Free inodes: 18-2008
看到最后一个特殊字体的地方吗?Group0 的 superblock 是由 1 号 block 开始。
由此我们可以发现 0 号 block 是保留下来的,那就是留给 boot sector 用的。所以整个分区的文件系统分区如图8-9所示。
图8-9 1K block 的boot sector 示意图
block 大于1024 bytes(2K,4K)时:
如果block大于1024的话,那么superblock将会在0号。我们从本章一开始介绍dumpe2fs时的内容来说明一下好了。
[root@www ~]# dumpe2fs /dev/hdc2
dumpe2fs 1.39 (29-May-2006)
….(中间省略)….
Filesystem volume name: /1
….(中间省略)….
Block size: 4096
….(中间省略)….
Group 0: (Blocks 0-32767)
Primary superblock at 0, Group descriptors at 1-1
Reserved GDT blocks at 2-626
Block bitmap at 627 (+627), Inode bitmap at 628 (+628)
Inode table at 629-1641 (+629)
0 free blocks, 32405 free inodes, 2 directories
Free blocks:
Free inodes: 12-32416
我们可以发现 superblock 就在第一个 block(第 0 号)上面。但是 superblock 其实就只有1024bytes。为了怕浪费更多空间,因此第一个 block 内就含有 boot sector 与 superblock。举上面的文字来说明,因为每个block占有4K,因此在第一个block内superblock仅占有1024~2047(由0号起算的话)之间的空间,至于2048bytes以后的空间就真的是保留了。而 0~1023 就保留给 boot sector 来使用,如图 8-9 所示。
因为上述的情况,如果在比较大的block尺寸(size)中,我们可能可以说你能够将引导装载程序安装到superblock所在的 block号码中,就是 0号,但事实上还是安装到启动扇区的保留区域中。所以说,以前的文章说引导装载程序可以安装到superblock内也不能算全错,但比较正确的说法,应该是安装到该文件系统最前面的 1024 bytes 内的区域,就是启动扇区这样比较好。
图8-10 4K block 的boot sector示意图
8.6.2 磁盘空间的浪费问题
我们在前面的block介绍中谈到了一个block只能放置一个文件,因此太多小文件将会浪费非常多的磁盘空间。但你有没有注意到,整个文件系统中包括 superblock、inode table 与其他数据等,其实都会浪费磁盘空间,所以当我们在/dev/hdc6新建起ext3文件系统时,一挂载就立刻有很多空间被用掉了。
另外,不知道你有没有发现到,当你使用ls-l去查询某个目录下的数据时,第一行都会出现一个“total”的字样。其实那就是该目录下的所有数据所占用的实际 block 数量× block 大小的值。我们可以通过ll-s来查看看看上述的意义:
[root@www ~]# ll -s
total 104
8 -rw———- 1 root root 1474 Sep 4 18:27 anaconda-ks.cfg
8 -rw-r—r— 2 root root 255 Jan 6 2007 crontab
4 lrwxrwxrwx 1 root root 12 Oct 22 13:58 crontab2 -> /etc/crontab
48 -rw-r—r— 1 root root 42304 Sep 4 18:26 install.log
12 -rw-r—r— 1 root root 5661 Sep 4 18:25 install.log.syslog
4 -rw-r—r— 1 root root 0 Sep 27 00:25 test1
8 drwxr-xr-x 2 root root 4096 Sep 27 00:25 test2
4 -rw-rw-r— 1 root root 0 Sep 27 00:36 test3
8 drwxrwxr-x 2 root root 4096 Sep 27 00:36 test4
上面的特殊字体部分就是每个文件所使用掉 block 的大小。举例来说,那个 crontab 虽然仅有255bytes,不过它却占用了两个block(每个block为4K),将所有的block汇总就得到104KB那个数值了。如果计算每个文件实际大小的加总结果,其实只有 56.5KB 而已,所以这样就耗费掉好多空间了。
如果想要查询某个目录所占用的所有空间时,那就使用du,不过du如果加上-s这个参数时,还可以依据不同的规范去找出文件系统所消耗的空间。举例来说,我们就来看看/etc/这个目录的空间状态。
[root@www ~]# du -sb /etc
108360494 /etc <==单位是 bytes
[root@www ~]# du -sm /etc
118 /etc <==单位是 KB
使用 byte 去分析时,发现到实际的数据占用约 103.3 MB,但是使用 block 去测试,就发现其实耗用了118MB,此时文件系统就耗费了约15MB。这样看得懂我们在讲的数据了吧?
8.6.3 利用GNU 的parted进行分区行为
虽然你可以使用fdisk很快地将你的分区调整妥当,不过fdisk却无法支持到高于2TB以上的分区。此时就得需要parted来处理了。不要觉得2TB你用不着,现在已经有单块硬盘高达2TB了。如果再搭配主机系统有内置磁盘阵列设备,要使用数个 TB 的单一磁盘设备也不是不可能的。所以,还是得要学一下这个重要的工具parted。
parted可以直接用一行命令行完成分区,是一个非常好用的命令。它的语法如下:
[root@www ~]# parted [设备] [命令 [参数]]
参数:
命令功能:
新增分区:mkpart [primary|logical|extended] [ext3|vfat] 开始 结束
分区表 :print
删除分区:rm [partition]
范例一:以 parted 列出目前本机的分区表资料
[root@www ~]# parted /dev/hdc print
Model: IC35L040AVER07-0 (ide) <==硬盘接口与型号
Disk /dev/hdc: 41.2GB <==磁盘文件名与容量
Sector size (logical/physical): 512B/512B <==每个扇区的大小
Partition Table: msdos <==分区表形式
Number Start End Size Type File system Flags
1 32.3kB 107MB 107MB primary ext3 boot
2 107MB 10.6GB 10.5GB primary ext3
3 10.6GB 15.8GB 5240MB primary ext3
4 15.8GB 41.2GB 25.3GB extended
5 15.8GB 16.9GB 1045MB logical linux-swap
6 16.9GB 18.9GB 2056MB logical ext3
7 18.9GB 19.2GB 263MB logical linux-swap
[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ]
上面是最简单的 parted 命令功能简介,你可以使用“man parted”或者是“parted /dev/hdc helpmkpart”去查询更详细的数据。比较有趣的地方在于分区表的输出。我们将上述的分区表示意拆成六部分来说明:
1.Number:这个就是分区的号码。举例来说,1号代表的是/dev/hdc1的意思。
2.Start:表示起始的柱面位置,它以容量作为单位。
3.End:表示结束的柱面位置。
4.Size:由上述两者的分析,得到这个分区有多少容量。
5.Type:就是分区的类型,有primary,extended,logical等类型。
6.File system:就如同 fdisk 的 System ID。
接下来我们尝试来新建一个全新的分区。因为我们仅剩下逻辑分区可用,所以等一下下面我们选择的会是logical的分区类型。
范例二:新建一个约为 512MB的逻辑分区
[root@www ~]# parted /dev/hdc mkpart logical ext3 19.2GB 19.7GB
请参考前面的命令介绍,因为我们的 /dev/hdc7 在 19.2GB 位置结束,
所以我们当然要由 19.2GB 位置处继续下一个分区,这样懂了吧?
[root@www ~]# parted /dev/hdc print
…..前面省略…..
7 18.9GB 19.2GB 263MB logical linux-swap
8 19.2GB 19.7GB 502MB logical <==就是刚才新建的。
范例三:将刚才新建的第八号磁盘分区删除。
[root@www ~]# parted /dev/hdc rm 8
这样就删除了,所以这个命令的执行要特别注意。
因为命令一下去就立即生效了,如果写错的话,会欲哭无泪的。
关于parted的介绍我们就到这里。除非你有使用到大于2TB以上的磁盘,否则请使用fdisk这个程序来进行分区。
8.7 重点回顾
基本上Linux最主要的文件系统为Ext2,该文件系统内的信息主要有:
superblock:记录此文件系统的整体信息,包括inode/block的总量、使用量、剩余量,以及文件系统的格式与相关信息等。
inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block号码。
block:实际记录文件的内容,若文件太大时,会占用多个block。
Ext2 文件系统的数据访问为索引式文件系统(indexed allocation)。
需要碎片整理的原因就是文件写入的block太过于离散了,此时文件读取的性能将会变得很差所致。这个时候可以通过碎片整理将同一个文件所属的blocks汇集在一起。
Ext2 文件系统主要有 boot sector,superblock,inode bitmap,block bitmap,inode table,data block等六大部分。
data block 是用来放置文件内容数据地方,在 Ext2 文件系统中所支持的 block 大小有 1KB、2KB及4KB三种而已。
inode记录文件的属性/权限等数据,每个inode大小均固定为128bytes;每个文件都仅会占用一个inode而已;因此文件系统能够新建的文件数量与inode的数量有关。
文件的block记录文件的实际数据,目录的block则记录该目录下面文件名与其inode号码的对照表。
日志(journal)文件系统会多出一块记录区,随时记载文件系统的主要活动,可加快系统恢复时间。
Linux文件系统为增加性能,会让主存储器作为大量的磁盘高速缓存。
实际连接只是多了一个文件名对该inode号码的连接而已。
符号连接就类似Windows的快捷方式功能。
磁盘的使用必需要经过分区、格式化与挂载,分别惯用的命令为fdisk、mkfs和mount。
开机自动挂载可参考/etc/fstab 的设置,设置完毕务必使用 mount -a 测试语法正确否。
8.8 本章习题
情境模拟题一
复原本章的各例题练习,本章新增非常多的分区,请将这些分区删除,恢复到原本刚安装好时的状态。
目标:了解到删除分区需要注意的各项信息;
前提:本章的各项范例练习你都必须要做过,才会有/dev/hdc6、/dev/hdc7出现;
需求:熟悉fdisk、umount、swapoff等命令。
由于本章处理完毕后,将会有/dev/hdc6与/dev/hdc7这两个新增的分区,所以请删除掉这两个分区。删除的过程需要注意的是:
1.需先以free/swapon-s/mount等命令查阅,/dev/hdc6,/dev/hdc7不可以被使用,如果有被使用,则你必须要使用 umount 卸载文件系统。如果是内存交换空间,则需使用 swapon -s 找出被使用的分区,再以swapoff去卸载。
2.查看/etc/fstab,该文件不能存在这两个分区。
3.使用“fdisk/dev/hdc”删除,注意,由于是逻辑分区,这些分区一定从 5 号开始连续编号,因此你最好不要从6号删除。否则原本的7号在你删除6号后将会变成6号。因此,你应该由7号删除掉,再删除6号。
情境模拟题二
由于我的系统分区原本不够好,我的用户希望能够独立一个文件系统附挂在/srv/myproject目录下。那你该如何新建新的文件系统,并且让这个文件系统每次开机都能够自动挂载到/srv/myproject上,且该目录是给project这个组共享的,其他人不可具有任何权限,且该文件系统具有5GB的容量。
目标:理解文件系统的构建、自动挂载文件系统与选项开发必须要的权限;
前提:你需要进行过第7章的情境模拟才可以继续本章;
需求:本章的所有概念必须要清楚!
那就让我们开始来处理这个流程。
1.首先,我们必须要使用 fdisk /dev/hdc 来创建新的分区,由于本章之前范例的分区已经在上一个练习中删除,因此你应该会多出一个/dev/hdc6 才对:“fdisk /dev/hdc”,然后按下 n,按下[Enter]选择默认的起始柱面,按下“+5000M”新建5GB的磁盘分区,可以多按一次p看看是否正确,若无问题则按下w写入分区表。
2.避免重新启动,因此使用partprobe强制内核更新分区表;如果屏幕出现类似:“end_request:I/O error dev fd0,sector 0”的错误时,不要担心。这个说明的是“找不到软盘”,我们本来就没有软盘,所以这个错误是可以忽略的。
3.新建完毕后,开始进行格式化的操作如下:“mkfs -t ext3 /dev/hdc6 ”,这样就 OK 了!
4.开始新建挂载点,利用“mkdir /srv/myproject”来新建即可。
5.编写自动挂载的配置文件“nano /etc/fstab”,在这个文件最下面新增一行,内容如下:
/dev/hdc6 /srv/myproject ext3 defaults 1 2。
6.测试自动挂载:“ mount -a”,然后使用“df”查看有无挂载即可!
7.设置最后的权限,使用“chgrp project /srv/myproject”以及“chmod 2770 /srv/myproject ”即可。
简答题部分
如果由于你的主机磁盘容量不够大,你想要增加一块新磁盘,并将该磁盘全部分区成单一分区,且将该分区挂载到/home目录,你该如何处置?
如果扇区/dev/hda3有问题,偏偏它是被挂载上的,请问我要如何修理此扇区?
我们经常说,开机的时候发现硬盘有问题,请问,这个问题的产生是文件系统的损坏还是硬盘的损坏?
当我有两个文件,分别是 file1 与 file2,这两个文件互为 hard link 的文件,请问,若我将 file1 删除,然后再以类似vi的方式重新新建一个名为file1的文件,则file2的内容是否会被改动?