来自《鸟哥的 Linux 私房菜》,重复只是加深自己的印象。
本篇结构:
- 文件系统的简单操作
- 磁盘的分区、格式化、检验与挂载
- 设置开机挂载
- 内存交换空间(swap)之创建
- 补充
一、文件系统的简单操作
1.1、磁盘与目录的容量
磁盘的整体数据是在 superblock 区块中,但是每个各别文件的容量则在 inode
当中记载的。在命令行下面该如何叫出这几个数据呢?
- df:列出文件系统的整体磁盘使用量;
- du:评估文件系统的磁盘使用量(常用在推估目录所占容量)
1.1.1、 df
df [-ahikHTm] [目录或文件名]
选项与参数:
- -a :列出所有的文件系统,包括系统特有的 /proc 等文件系统;
- -k :以 KBytes 的容量显示各文件系统;
- -m :以 MBytes 的容量显示各文件系统;
- -h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
- -H :以 M=1000K 取代 M=1024K 的进位方式;
- -T :连同该 partition 的 filesystem 名称 (例如 xfs) 也列出;
- -i :不用磁盘容量,而以 inode 的数量来显示
在 Linux 下面如果 df 没有加任何选项,那么默认会将系统内所有的,(不含特殊内存内的文件系统与 swap) 都以 1 KBytes 的容量来列出来!
所输出的结果信息:
- Filesystem:代表该文件系统是在哪个 partition ,所以列出设备名称;
- 1k-blocks:说明下面的数字单位是 1KB!可利用 -h 或 -m 来改变容量;
- Used:顾名思义,就是使用掉的磁盘空间;
- Available:也就是剩下的磁盘空间大小;
- Use%:就是磁盘的使用率啦!如果使用率高达 90% 以上时, 最好需要注意一下了,免得容量不足造成系统问题;
- Mounted on:就是磁盘挂载的目录所在。
范例一:将系统内的所有特殊文件格式及名称都列出来
范例二:将 /etc 下面的可用的磁盘容量以易读的容量格式显示
root@master:~# df -h /etc
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-root 476G 148G 304G 33% /
范例三:将目前各个 partition 当中可用的 inode 数量列出
root@master:~# df -ih
Filesystem Inodes IUsed IFree IUse% Mounted on
udev 7.9M 419 7.9M 1% /dev
tmpfs 7.9M 861 7.9M 1% /run
/dev/mapper/ubuntu--vg-root 31M 402K 30M 2% /
tmpfs 7.9M 4 7.9M 1% /dev/shm
tmpfs 7.9M 4 7.9M 1% /run/lock
tmpfs 7.9M 16 7.9M 1% /sys/fs/cgroup
/dev/sda1 122K 310 122K 1% /boot
tmpfs 7.9M 4 7.9M 1% /run/user/0
tmpfs 7.9M 4 7.9M 1% /run/user/1000
由于 df 主要读取的数据几乎都是针对一整个文件系统,因此读取的范围主要是在 Superblock 内的信息, 所以这个指令显示结果的速度非常的快速!在显示的结果中需要特别留意的是根目录的剩余容量! 因为所有的数据都是由根目录衍生出来的,因此当根目录的剩余容量剩下 0 时,那 Linux 可能就问题很大了。
需要注意的是,如果使用 -a 这个参数时,系统会出现 /proc 这个挂载点,但是里面的东西都是 0 ,不要紧张! /proc 的东西都是 Linux 系统所需要载入的系统数据,而且是挂载在“内存当中”的, 所以当然没有占任何的磁盘空间。
/dev/shm/ 目录,其实是利用内存虚拟出来的磁盘空间,通常是总实体内存的一半!由于是通过内存仿真出来的磁盘,因此你在这个目录下面创建任何数据文件时,存取速度是非常快速的!(在内存内工作) 不过,也由于他是内存仿真出来的,因此这个文件系统的大小在每部主机上都不一样,而且创建的东西在下次开机时就消失了! 因为是在内存中!
1.1.2、du
du [-ahskm] 文件或目录名称
选项与参数:
- -a :列出所有的文件与目录容量,因为默认仅统计目录下面的文件量而已;
- -h :以人们较易读的容量格式 (G/M) 显示;
- -s :列出总量而已,而不列出每个各别的目录占用容量;
- -S :不包括子目录下的总计,与 -s 有点差别。
- -k :以 KBytes 列出容量显示;
- -m :以 MBytes 列出容量显示。
直接输入 du 没有加任何选项时,则 du 会分析“目前所在目录”的文件与目录所占用的磁盘空间。但是,实际显示时,仅会显示目录容量(不含文件),因此 . 目录有很多文件没有被列出来,所以全部的目录相加不会等于 . 的容量。此外,输出的数值数据为 1K 大小的容量单位。加上参数 -a 则可以将文件容量也显示出来。
范例一:检查根目录下面每个目录所占用的容量
du -sm /*
16 /bin
108 /boot
... 省略 ...
du: cannot access '/proc/104399/fd/4': No such file or directory
du: cannot access '/proc/104399/fdinfo/4': No such file or directory
... 省略 ...
1692 /tmp
9607 /usr
41054 /var
这是个很常被使用的功能,利用万用字符 * 来代表每个目录,如果想要检查某个目录下,哪个次目录占用最大的容量,可以用这个方法找出来。至于 /proc 里头会列出一堆“No such file or directory” 的错误,因为是内存内的程序,程序执行结束就会消失,因此会有些目录找不到,是正确的!
与 df 不一样的是,du 这个指令其实会直接到文件系统内去搜寻所有的文件数据,所以指令的运行会执行一小段时间。此外,在默认的情况下,容量的输出是以 KB 来设计的, 如果想要知道目录占了多少 MB ,那么就使用 -m 这个参数即可,如果只想要知道该目录占了多少容量的话,使用 -s 就可以。
至于 -S 这个选项部分,由于 du 默认会将所有文件的大小均列出,因此假设在 /etc 下面使用 du 时, 所有的文件大小,包括 /etc 下面的次目录容量也会被计算一次。然后最终的容量(/etc) 也会加总一次, 因此很多朋友都会误会 du 分析的结果不太对劲。如果想要列出某目录下的全部数据, 或许也可以加上 -S 的选项,减少次目录的加总。
1.2、实体链接与符号链接: ln
1.2.1、Hard Link (实体链接, 硬式链接或实际链接)
- 每个文件都会占用一个 inode ,文件内容由 inode 的记录来指向;
- 想要读取该文件,必须要经过目录记录的文件名来指向到正确的 inode 号码才能读取。
也就是说,其实文件名只与目录有关,但是文件内容则与 inode 有关。那么想一想, 有没有可能有多个文件名对应到同一个 inode 号码呢?有的!那就是 hard link 的由来。
简单说:hard link 只是在某个目录下新增一笔文件名链接到某 inode 号码的关连记录而已。
如图,有个 /root/crontab 是 /etc/crontab 的实体链接,这两个文件名链接到同一个 inode :
使用 hard link 设置链接文件时,磁盘的空间与 inode 的数目都不会改变, hard link 只是在某个目录下的 block 多写入一个关连数据而已,既不会增加 inode 也不会耗用 block 数量(其实还是可能会改变系统的 block 的,那就是当新增这笔数据却刚好将目录的 block 填满时,就可能会新加一个 block 来记录文件名关连性,而导致磁盘空间的变化)。
由图也可知,事实上 hard link 应该仅能在单一文件系统中进行的,应该是不能够跨文件系统,所以 hard link 是有限制的:
- 不能跨 Filesystem;
- 不能 link 目录。
因为如果使用 hard link 链接到目录时, 链接的数据需要连同被链接目录下面的所有数据都创建链接。
1.2.2、Symbolic Link (符号链接,亦即是捷径)
相对于 hard link , Symbolic link 可就好理解多了,基本上, Symbolic link 就是在创建一个独立的文件,而这个文件会让数据的读取指向他 link 的那个文件的文件名!由于只是利用文件来做为指向的动作, 所以,当来源文件被删除之后,symbolic link 的文件会“开不了”, 会一直说“无法打开某文件!”。实际上就是找不到原始“文件名”而已。
如图:
由 1 号 inode 读取到链接文件的内容仅有文件名,根据文件名链接到正确的目录去取得目标文件的 inode , 最终就能够读取到正确的数据了。可以发现的是,如果目标文件(/etc/crontab)被删除了,那么整个环节就会无法继续进行下去, 所以就会发生无法通过链接文件读取的问题了!
这个 Symbolic Link 与 Windows 的捷径可以给他划上等号,由 Symbolic link 所创建的文件为一个独立的新的文件,所以会占用掉 inode 与 block 。
1.2.3、指令
ln [-sf] 来源文件 目标文件
选项与参数:
- -s :如果不加任何参数就进行链接,那就是hard link,至于 -s 就是symbolic link;
- -f :如果 目标文件 存在时,就主动的将目标文件直接移除后再创建!
关于目录的 link 数量:
一个“空目录”里面至少会存在 . 与 .. 这两个目录。那么,当创建一个新目录名称为 /tmp/testing 时,基本上会有三个东西,那就是:
- /tmp/testing
- /tmp/testing/.
- /tmp/testing/..
而其中 /tmp/testing 与 /tmp/testing/. 其实是一样的!都代表该目录,而 /tmp/testing/.. 则代表 /tmp 这个目录。所以说,当创建一个新的目录时, “新的目录的 link 数为 2 ,而上层目录的 link 数则会增加 1。
二、磁盘的分区、格式化、检验与挂载
想要在系统里面新增一颗磁盘时,应该有如下动作需要做:
- 对磁盘进行分区,以创建可用的 partition ;
- 对该 partition 进行格式化 (format),以创建系统可用的 filesystem;
- 若想要仔细一点,则可对刚刚创建好的 filesystem 进行检验;
- 在 Linux 系统上,需要创建挂载点 (亦即是目录),并将他挂载上来。
2.1、观察磁盘分区状态
目前磁盘分区主要有 MBR 以及 GPT 两种格式,这两种格式所使用的分区工具不太一样,因此分区前要去找一下目前系统有的磁盘有哪些, 这些磁盘是 MBR 还是 GPT 等等。
2.1.1、lsblk 列出系统上的所有磁盘列表
lsblk 可以看成“ list block device ”的缩写,就是列出所有储存设备的意思。
lsblk [-dfimpt] [device]
选项与参数:
- -d :仅列出磁盘本身,并不会列出该磁盘的分区数据
- -f :同时列出该磁盘内的文件系统名称
- -i :使用 ASCII 的线段输出,不要使用复杂的编码 (再某些环境下很有用)
- -m :同时输出该设备在 /dev 下面的权限数据 (rwx 的数据)
- -p :列出该设备的完整文件名!而不是仅列出最后的名字而已
- -t :列出该磁盘设备的详细数据,包括磁盘伫列机制、预读写的数据量大小等
范例一:列出本系统下的所有磁盘与磁盘内的分区信息
root@master:/dev# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 500G 0 disk
├─sda1 8:1 0 487M 0 part /boot
├─sda2 8:2 0 1K 0 part
└─sda5 8:5 0 499.5G 0 part
├─ubuntu--vg-root 252:0 0 483.5G 0 lvm /
└─ubuntu--vg-swap_1 252:1 0 16G 0 lvm [SWAP]
sr0 11:0 1 1024M 0 rom
系统主要有个 sr0 以及一个 sda 的设备,而 sda 的设备下面又有三个分区, 其中 sda5 甚至还有因为 LVM 产生的文件系统。
- NAME:就是设备的文件名!会省略 /dev 等前导目录;
- MAJ:MIN:其实核心认识的设备都是通过这两个代码来熟悉的!分别是主要:次要设备代码;
- RM:是否为可卸载设备 (removable device),如光盘、USB 磁盘等等;
- SIZE:当然就是容量;
- RO:是否为只读设备的意思;
- TYPE:是磁盘 (disk)、分区 (partition) 还是只读存储器 (rom) 等输出;
- MOUTPOINT:挂载点!
范例二:仅列出 /dev/sda 设备内的所有数据的完整文件名
root@master:/dev# lsblk -ip /dev/sda
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
/dev/sda 8:0 0 500G 0 disk
|-/dev/sda1 8:1 0 487M 0 part /boot
|-/dev/sda2 8:2 0 1K 0 part
`-/dev/sda5 8:5 0 499.5G 0 part
|-/dev/mapper/ubuntu--vg-root 252:0 0 483.5G 0 lvm /
`-/dev/mapper/ubuntu--vg-swap_1 252:1 0 16G 0 lvm [SWAP]
2.1.2、blkid 列出设备的 UUID 等参数
lsblk 可以使用 -f 也可以来列出文件系统与设备的 UUID 数据。
UUID 是全域单一识别码 (universally unique identifier),Linux 会将系统内所有的设备都给予一个独一无二的识别码, 这个识别码就可以拿来作为挂载或者是使用这个设备/文件系统之用。
root@master:/dev# blkid
/dev/sda1: UUID="4ed77cbc-f446-4918-90ca-4e6b6fc7d97c" TYPE="ext2" PARTUUID="863f83f3-01"
/dev/sda5: UUID="lYIIQX-XyCX-1hpS-bLSR-yXX7-SdqL-6Swqvq" TYPE="LVM2_member" PARTUUID="863f83f3-05"
/dev/mapper/ubuntu--vg-root: UUID="4eb8d680-6565-494a-bf6e-3c15e48eda1b" TYPE="ext4"
/dev/mapper/ubuntu--vg-swap_1: UUID="b2d65ad5-9053-4315-83ae-ddba10e59f57" TYPE="swap"
每一行代表一个文件系统,主要列出设备名称、UUID 名称以及文件系统的类型。
2.1.3、parted 列出磁盘的分区表类型与分区信息
parted device_name print
范例一:列出 /dev/sda 磁盘的相关数据
root@master:/dev# parted /dev/sda print
Model: VMware Virtual disk (scsi) # 磁盘的模块名称(厂商)
Disk /dev/sda: 537GB # 磁盘的总容量
Sector size (logical/physical): 512B/512B # 磁盘的每个逻辑/物理扇区容量
Partition Table: msdos # 分区表的格式 (MBR/GPT)
Disk Flags:
# 下面才是分区数据
Number Start End Size Type File system Flags
1 1049kB 512MB 511MB primary ext2 boot
2 513MB 537GB 536GB extended
5 513MB 537GB 536GB logical lvm
2.2、磁盘分区: gdisk/fdisk
MBR 分区表请使用 fdisk 分区, GPT 分区表请使用 gdisk 分区,否则会分区失败。
所以先通过 lsblk 或 blkid 先找到磁盘,再用 parted /dev/xxx print 来找出内部的分区表类型,之后才用 gdisk 或 fdisk 来操作系统。
2.2.1、gdisk
先看看 gdisk。
gdisk 设备名称
范例:观察该磁盘的分区与相关数据(鸟哥书上的代码,我的设备是 MBR 分区表)
gdisk /dev/vda # 仔细看,不要加上数字喔!
GPT fdisk (gdisk) version 0.8.6
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT. # 找到了 GPT 的分区表!
Command (? for help)# 这里可以让你输入指令动作,可以按问号 (?) 来查看可用指令
Command (? for help): ?
b back up GPT data to a file
c change a partition's name
d delete a partition # 删除一个分区
i show detailed information on a partition
l list known partition types
n add a new partition # 增加一个分区
o create a new empty GUID partition table (GPT)
p print the partition table # 印出分区表 (常用)
q quit without saving changes # 不储存分区就直接离开 gdisk
r recovery and transformation options (experts only)
s sort partitions
t change a partition's type code
v verify disk
w write table to disk and exit # 储存分区操作后离开 gdisk
x extra functionality (experts only)
? print this menu
Command (? for help):
先来看看分区表信息。
Command (? for help): p # 这里可以输出目前磁盘的状态
Disk /dev/vda: 83886080 sectors, 40.0 GiB # 磁盘文件名/扇区数与总容量
Logical sector size: 512 Bytes # 单一扇区大小为 512 Bytes
Disk identifier (GUID): A4C3C813-62AF-4BFE-BAC9-112EBD87A483 # 磁盘的 GPT 识别码
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 83886046
Partitions will be aligned on 2048-sector boundaries
Total free space is 18862013 sectors (9.0 GiB)
Number Start (sector) End (sector) Size Code Name # 下面为完整的分区信息了!
1 2048 6143 2.0 MiB EF02 # 第一个分区数据
2 6144 2103295 1024.0 MiB 0700
3 2103296 65026047 30.0 GiB 8E00
# 分区编号 开始扇区号码 结束扇区号码 容量大小
Command (? for help): q
# 想要不储存离开吗?按下 q 就对了!不要随便按 w 啊!
使用“ p ”可以列出目前这颗磁盘的分区表信息,这个信息的上半部在显示整体磁盘的状态。下半部的分区表信息主要在列出每个分区的个别信息项目。每个项目的意义为:
- Number:分区编号,1 号指的是 /dev/vda1 这样计算;
- Start (sector):每一个分区的开始扇区号码位置;
- End (sector):每一个分区的结束扇区号码位置,与 start 之间可以算出分区的总容量;
- Size:就是分区的容量了;
- Code:在分区内的可能的文件系统类型。Linux 为 8300,swap 为 8200。不过这个项目只是一个提示而已,不见得真的代表此分区内的文件系统;
- Name:文件系统的名称等等。
具体新增分区的操作见《鸟哥的 Linux 私房菜》378 页。
2.2.2、partprobe 更新 Linux 核心的分区表信息
partprobe [-s] # 可以不要加 -s !那么屏幕不会出现信息!
partprobe -s # 不过还是建议加上 -s 比较清晰!
2.2.3、fdisk
虽然 MBR 分区表在未来应该会慢慢的被淘汰,毕竟现在磁盘容量随便都大于 2T 以上了,不过依旧有些旧的系统,以及虚拟机的使用上面,还是有小磁盘存在的空间!这时处理 MBR 分区表, 就得要使用 fdisk。
fdisk 跟 gdisk 使用的方式几乎一样,只是一个使用 ? 作为指令提示数据,一个使用 m 作为提示这样而已。此外,fdisk 有时会使用柱面 (cylinder) 作为分区的最小单位,与 gdisk 默认使用 sector 不太一样。
2.3、磁盘格式化(创建文件系统)
格式化的指令非常的简单,那就是“make filesystem, mkfs” 这个指令!这个指令其实是个综合的指令,他会去调用正确的文件系统格式化工具软件!
我们常听到的“格式化”其实应该称为“创建文件系统 (make filesystem)”才对,使用的指令是 mkfs 。
2.3.1、EXT4 文件系统 mkfs.ext4
想要格式化为 ext4 的传统 Linux 文件系统的话,可以使用 mkfs.ext4 这个指令。
mkfs.ext4 [-b size] [-L label] 设备名称
选项与参数:
- -b :设置 block 的大小,有 1K, 2K, 4K 的容量
- -L :后面接这个设备的标头名称。
范例:将 /dev/vda5 格式化为 ext4 文件系统
mkfs.ext4 /dev/vda5
2.3.2、XFS 文件系统 mkfs.xfs
mkfs.xfs [-b bsize] [-d parms] [-i parms] [-l parms] [-L label] [-f] \
[-r parms] 设备名称
选项与参数:
- 关於单位:下面只要谈到“数值”时,没有加单位则为 Bytes 值,可以用 k,m,g,t,p (小写)等来解释,比较特殊的是 s 这个单位,它指的是 sector 的“个数”;
- -b :后面接的是 block 容量,可由 512 到 64k,不过最大容量限制为 Linux 的 4k ;
- -d :后面接的是重要的 data section 的相关参数值,主要的值有:
- agcount=数值 :设置需要几个储存群组的意思(AG),通常与 CPU 有关;
- agsize=数值 :每个 AG 设置为多少容量的意思,通常 agcount/agsize 只选一个设置即可;
- file :指的是“格式化的设备是个文件而不是个设备”的意思!(例如虚拟磁盘);
- size=数值 :data section 的容量,亦即你可以不将全部的设备容量用完的意思;
- su=数值 :当有 RAID 时,那个 stripe 数值的意思,与下面的 sw 搭配使用;
- sw=数值 :当有 RAID 时,用于储存数据的磁盘数量(须扣除备份碟与备用碟);
- sunit=数值 :与 su 相当,不过单位使用的是“几个 sector(512Bytes大小)”的意思;
- swidth=数值 :就是 su*sw 的数值,但是以“几个 sector(512Bytes大小)”来设置
- -f :如果设备内已经有文件系统,则需要使用这个 -f 来强制格式化才行;
- -i :与 inode 有较相关的设置,主要的设置值有:
- size=数值 :最小是 256Bytes 最大是 2k,一般保留 256 就足够使用了;
- internal=[0|1]:log 设备是否为内置?默认为 1 内置,如果要用外部设备,使用下面设置;
- logdev=device :log 设备为后面接的那个设备上头的意思,需设置 internal=0 才可;
- size=数值 :指定这块登录区的容量,通常最小得要有 512 个 block,大约 2M 以上才行!
- -L :后面接这个文件系统的标头名称 Label name 的意思;
- -r :指定 realtime section 的相关设置值,常见的有:
- extsize=数值 :就是那个重要的 extent 数值,一般不须设置,但有 RAID 时,最好设置与 swidth 的数值相同较佳!最小为 4K 最大为 1G 。
2.3.3、其他文件系统 mkfs
mkfs 其实是个综合指令而已,当使用 mkfs -t xfs 时,它就会跑去找 mkfs.xfs 相关的参数,如果想要知道系统还支持哪种文件系统的格式化功能,直接按 [tabl] 就很清楚。
mkfs[tab][tab]
mkfs mkfs.bfs mkfs.btrfs mkfs.cramfs mkfs.ext2 mkfs.ext3 mkfs.ext4 mkfs.ext4dev mkfs.fat mkfs.minix mkfs.msdos mkfs.ntfs mkfs.vfat mkfs.xfs
2.4、文件系统检验
文件系统运行时会有磁盘与内存数据非同步的状况发生,因此莫名其妙的死机非常可能导致文件系统的错乱。
2.4.1、xfs_repair 处理 XFS 文件系统
xfs_repair [-fnd] 设备名称
选项与参数:
- -f :后面的设备其实是个文件而不是实体设备
- -n :单纯检查并不修改文件系统的任何数据 (检查而已)
- -d :通常用在单人维护模式下面,针对根目录 (/) 进行检查与修复的动作!很危险!不要随便使用
范例一:检查一下刚刚创建的 /dev/vda4 文件系统
[root@study ~]# xfs_repair /dev/vda4
Phase 1 - find and verify superblock...
Phase 2 - using internal log
Phase 3 - for each AG...
Phase 4 - check for duplicate blocks...
Phase 5 - rebuild AG headers and trees...
Phase 6 - check inode connectivity...
Phase 7 - verify and correct link counts...
done
# 共有 7 个重要的检查流程!详细的流程介绍可以 man xfs_repair 即可!
范例二:检查一下系统原本就有的 /dev/centos/home 文件系统
[root@study ~]# xfs_repair /dev/centos/home
xfs_repair: /dev/centos/home contains a mounted filesystem
xfs_repair: /dev/centos/home contains a mounted and writable filesystem
fatal error -- couldn't initialize XFS library
xfs_repair 可以检查/修复文件系统,不过,因为修复文件系统是个很庞大的任务!因此,修复时该文件系统不能被挂载! 所以,检查与修复 /dev/vda4 没啥问题,但是修复/dev/centos/home 这个已经挂载的文件系统时,就出现上述的问题了! 没关系,若可以卸载,卸载后再处理即可。
Linux 系统有个设备无法被卸载,那就是根目录!如果你的根目录有问题怎办?这时得要进入单人维护或救援模式,然后通过 -d 这个选项来处理! 加入 -d 这个选项后,系统会强制检验该设备,检验完毕后就会自动重新开机!
2.4.2、fsck.ext4 处理 EXT4 文件系统
fsck 是个综合指令,如果是针对 ext4 的话,建议直接使用 fsck.ext4 来检测比较妥当。
fsck.ext4 [-pf] [-b superblock] 设备名称
选项与参数:
- -p :当文件系统在修复时,若有需要回复 y 的动作时,自动回复 y 来继续进行修复动作;
- -f :强制检查!一般来说,如果 fsck 没有发现任何 unclean 的旗标,不会主动进入细部检查的,如果您想要强制 fsck 进入细部检查,就得加上 -f 旗标;
- -D :针对文件系统下的目录进行最优化配置;
- -b :后面接 superblock 的位置!一般来说这个选项用不到。但是如果 superblock 因故损毁时,通过这个参数即可利用文件系统内备份的 superblock 来尝试救援。一般来说,superblock 备份在:1K block 放在 8193, 2K block 放在 16384, 4K block 放在 32768。
2.5、文件系统挂载与卸载
进行挂载前,最好先确定几件事:
- 单一文件系统不应该被重复挂载在不同的挂载点(目录)中;
- 单一目录不应该重复挂载多个文件系统;
- 要作为挂载点的目录,理论上应该都是空目录才是。
[root@study ~]# mount -a
[root@study ~]# mount [-l]
[root@study ~]# mount [-t 文件系统] LABEL='' 挂载点
[root@study ~]# mount [-t 文件系统] UUID='' 挂载点 # 鸟哥近期建议用这种方式!
[root@study ~]# mount [-t 文件系统] 设备文件名 挂载点
选项与参数:
-a :依照配置文件 /etc/fstab 的数据将所有未挂载的磁盘都挂载上来;
-l :单纯的输入 mount 会显示目前挂载的信息。加上 -l 可增列 Label 名称;
-t :可以加上文件系统种类来指定欲挂载的类型。常见的 Linux 支持类型有:xfs, ext3, ext4,reiserfs, vfat, iso9660(光盘格式), nfs, cifs, smbfs (后三种为网络文件系统类型);
-n :在默认的情况下,系统会将实际挂载的情况实时写入 /etc/mtab 中,以利其他程序的运行,但在某些情况下(例如单人维护模式)为了避免问题会刻意不写入。此时就得要使用 -n 选项;
-
-o :后面可以接一些挂载时额外加上的参数!比方说帐号、密码、读写权限等:
- async, sync: 此文件系统是否使用同步写入 (sync) 或非同步 (async) 的内存机制默认为 async;
- atime,noatime: 是否修订文件的读取时间(atime)。为了性能,某些时刻可使用 noatime;
- ro, rw: 挂载文件系统成为只读(ro) 或可读写(rw)
- auto, noauto: 允许此 filesystem 被以 mount -a 自动挂载(auto);
- dev, nodev: 是否允许此 filesystem 上,可创建设备文件? dev 为可允许;
- suid, nosuid: 是否允许此 filesystem 含有 suid/sgid 的文件格式?
- exec, noexec: 是否允许此 filesystem 上拥有可执行 binary 文件?
- user, nouser: 是否允许此 filesystem 让任何使用者执行 mount ?一般来说,mount 仅有 root 可以进行,但下达 user 参数,则可让一般 user 也能够对此 partition 进行 mount ;
- defaults: 默认值为:rw, suid, dev, exec, auto, nouser, and async;
- remount: 重新挂载,这在系统出错,或重新更新参数时,很有用!
2.5.1、挂载 xfs/ext4/vfat 等文件系统
范例一:找出 /dev/vda4 的 UUID 后,用该 UUID 来挂载文件系统到 /data/xfs 内
[root@study ~]# blkid /dev/vda4
/dev/vda4: UUID="e0a6af55-26e7-4cb7-a515-826a8bd29e90" TYPE="xfs"
[root@study ~]# mount UUID="e0a6af55-26e7-4cb7-a515-826a8bd29e90" /data/xfs
mount: mount point /data/xfs does not exist # 非正规目录!所以手动创建它!
[root@study ~]# mkdir -p /data/xfs
[root@study ~]# mount UUID="e0a6af55-26e7-4cb7-a515-826a8bd29e90" /data/xfs
[root@study ~]# df /data/xfs
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda4 1038336 32864 1005472 4% /data/xfs
范例二:使用相同的方式,将 /dev/vda5 挂载于 /data/ext4
[root@study ~]# blkid /dev/vda5
/dev/vda5: UUID="899b755b-1da4-4d1d-9b1c-f762adb798e1" TYPE="ext4"
[root@study ~]# mkdir /data/ext4
[root@study ~]# mount UUID="899b755b-1da4-4d1d-9b1c-f762adb798e1" /data/ext4
[root@study ~]# df /data/ext4
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda5 999320 2564 927944 1% /data/ext4
2.5.2、重新挂载根目录与挂载不特定目录
整个目录树最重要的地方就是根目录了,所以根目录根本就不能够被卸载的。如果挂载参数要改变, 或者是根目录出现“只读”状态时,如何重新挂载呢?最可能的处理方式就是重新开机 (reboot)!
不过也可以这样做:
范例:将 / 重新挂载,并加入参数为 rw 与 auto
[root@study ~]# mount -o remount,rw,auto /
另外,也可以利用 mount 来将某个目录挂载到另外一个目录去!这并不是挂载文件系统,而是额外挂载某个目录的方法! 虽然下面的方法也可以使用 symbolic link 来链接,不过在某些不支持符号链接的程序运行中,还是得要通过这样的方法才行。
范例:将 /var 这个目录暂时挂载到 /data/var 下面
[root@study ~]# mkdir /data/var
[root@study ~]# mount --bind /var /data/var
[root@study ~]# ls -lid /var /data/var
16777346 drwxr-xr-x. 22 root root 4096 Jun 15 23:43 /data/var
16777346 drwxr-xr-x. 22 root root 4096 Jun 15 23:43 /var
# 内容完全一模一样啊!因为挂载目录的缘故!
2.6、umount (将设备文件卸载)
umount [-fn] 设备文件名或挂载点
选项与参数:
- -f :强制卸载!可用在类似网络文件系统 (NFS) 无法读取到的情况下;
- -l :立刻卸载文件系统,比 -f 还强;
- -n :不更新 /etc/mtab 情况下卸载。
三、设置开机挂载
但是挂载是临时的,系统重启后需要重新挂载,如果希望下次启动时,自动挂载,需要按照下述操作。
3.1、开机挂载 /etc/fstab 及 /etc/mtab
先查阅一下 /etc/fstab 这个文件的内容。
[root@study ~]# cat /etc/fstab
Device Mount point filesystem parameters dump fsck
/dev/mapper/centos-root / xfs defaults 0 0
UUID=94ac5f77-cb8a-495e-a65b-2ef7442b837c /boot xfs defaults 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
/etc/fstab (filesystem table) 就是将利用 mount 指令进行挂载时, 将所有的选项与参数写入到这个文件中。除此之外, /etc/fstab 还加入了 dump 这个备份用指令的支持! 与开机时是否进行文件系统检验 fsck 等指令有关。
这个文件的内容共有六个字段,各个字段的总结数据与详细数据如下:
[设备/UUID等] [挂载点] [文件系统] [文件系统参数] [dump] [fsck]
第一栏:磁盘设备文件名/UUID/LABEL name:
这个字段可以填写的数据主要有三个项目:
- 文件系统或磁盘的设备文件名,如 /dev/vda2 等
- 文件系统的 UUID 名称,如 UUID=xxx
- 文件系统的 LABEL 名称,例如 LABEL=xxx
第二栏:挂载点 (mount point):
就是挂载的目录。
第三栏:磁盘分区的文件系统:
在手动挂载时可以让系统自动测试挂载,但在这个文件当中我们必须要手动写入文件系统才行! 包括 xfs, ext4, vfat, reiserfs, nfs 等等。
第四栏:文件系统参数:
参数 | 内容意义 |
---|---|
async/sync | 设置磁盘是否以非同步方式运行!默认为 async(性能较佳) |
auto/noauto | 当下达 mount -a 时,此文件系统是否会被主动测试挂载。默认为 auto。 |
rw/ro | 让该分区以可读写或者是只读的型态挂载上来,如果你想要分享的数据 是不给使用者随意变更的, 这里也能够设置为只读。则不论在此文件系 统的文件是否设置 w 权限,都无法写入! |
exec/noexec | 限制在此文件系统内是否可以进行“执行”的工作?如果是纯粹用来储存数 据的目录, 那么可以设置为 noexec 会比较安全。不过,这个参数也不 能随便使用,因为你不知道该目录下是否默认会有可执行文件。举例来 说,如果你将 noexec 设置在 /var ,当某些软件将一些可执行文件放置 于 /var 下时,那就会产生很大的问题! 因此,建议这个 noexec 最多 仅设置于你自订或分享的一般数据目录。 |
user/nouser | 是否允许使用者使用 mount指令来挂载呢?一般而言,我们当然不希望 一般身份的 user 能使用 mount 啰,因为太不安全了,因此这里应该要设 置为 nouser! |
suid/nosuid | 该文件系统是否允许 SUID 的存在?如果不是可执行文件放置目录,也 可以设置为 nosuid 来取消这个功能! |
defaults | 同时具有 rw, suid, dev, exec, auto, nouser, async 等参数。 基本上, 默认情况使用 defaults 设置即可! |
第五栏:能否被 dump 备份指令作用:
dump 是一个用来做为备份的指令,不过现在有太多的备份方案了,所以这个项目可以不要理会!直接输入 0 就好了!
第六栏:是否以 fsck 检验扇区:
早期开机的流程中,会有一段时间去检验本机的文件系统,看看文件系统是否完整
(clean)。 不过这个方式使用的主要是通过 fsck 去做的,我们现在用的 xfs 文件系统就没有办法适用,因为 xfs 会自己进行检验,不需要额外进行这个动作!所以直接填 0 就好了。
例题:假设我们要将 /dev/vda4 每次开机都自动挂载到 /data/xfs ,该如何进行?
# 首先,请用 nano 将下面这一行写入 /etc/fstab 最后面中;
[root@study ~]# nano /etc/fstab
UUID="e0fa7252-b374-4a06-987a-3cb14f415488" /data/xfs xfs defaults 0 0
# 再来看看 /dev/vda4 是否已经挂载,如果挂载了,请务必卸载再说!
[root@study ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda4 1038336 32864 1005472 4% /data/xfs
# 竟然不知道何时被挂载了?赶紧给他卸载先!
# **因为,如果要被挂载的文件系统已经被挂载了(无论挂载在哪个目录),那测试就不会进行喔!**
[root@study ~]# umount /dev/vda4
# 最后测试一下刚刚我们写入 /etc/fstab 的语法有没有错误!这点很重要!因为这个文件如果写错了, 则你的 Linux 很可能将无法顺利开机完成!所以请务必要测试测试!
[root@study ~]# mount -a
[root@study ~]# df /data/xfs
最终有看到 /dev/vda4 被挂载起来的信息才是成功的挂载了!而且以后每次开机都会顺利的将此文件系统挂载起来的!
3.2、特殊设备 loop 挂载
如果有光盘镜像文件,或者是使用文件作为磁盘的方式时,那就得要使用特别的方法来将他挂载起来,不需要烧录!
3.2.1、挂载光盘/DVD镜像文件
如果下载了 Linux 或者是其他所需光盘/DVD的镜像文件后, 难道一定需要烧录成为光盘才能够使用该文件里面的数据吗?当然不是!我们可以通过 loop 设备来挂
载的!
ll -h /tmp/CentOS-7.0-1406-x86_64-DVD.iso
-rw-r--r--. 1 root root 3.9G Jul 7 2014 /tmp/CentOS-7.0-1406-x86_64-DVD.iso
# 看到上面的结果吧!这个文件就是镜像文件,文件非常的大吧!
[root@study ~]# mkdir /data/centos_dvd
[root@study ~]# mount -o loop /tmp/CentOS-7.0-1406-x86_64-DVD.iso /data/centos_dvd
[root@study ~]# df /data/centos_dvd
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop0 4050860 4050860 0 100% /data/centos_dvd
# 就是这个项目! .iso 镜像文件内的所有数据可以在 /data/centos_dvd 看到!
[root@study ~]# ll /data/centos_dvd
total 607
-rw-r--r--. 1 500 502 14 Jul 5 2014 CentOS_BuildTag <==瞧!就是DVD的内容啊!
drwxr-xr-x. 3 500 502 2048 Jul 4 2014 EFI
-rw-r--r--. 1 500 502 611 Jul 5 2014 EULA
-rw-r--r--. 1 500 502 18009 Jul 5 2014 GPL
drwxr-xr-x. 3 500 502 2048 Jul 4 2014 images
.....(下面省略).....
[root@study ~]# umount /data/centos_dvd/
# 测试完成!记得将数据给他卸载!同时这个镜像文件也被鸟哥删除了...测试机容量不够大!
四、内存交换空间(swap)之创建
以前的年代因为内存不足,因此那个可以暂时将内存的程序拿到硬盘中暂放的内存交换空间(swap) 就显的非常的重要! 否则,如果突然间某支程序用掉你大部分的内存,那你的系统恐怕有损毁的情况发生。
一般来说,如果硬件的配备资源足够的话,那么 swap 应该不会被系统所使用到,swap 会被利用到的时刻通常就是实体内存不足的情况了。 CPU 所读取的数据都来自于内存, 那当内存不足的时候,为了让后续的程序可以顺利的运行,因此在内存中暂不使用的程序与数据就会被挪到 swap 中了。 此时内存就会空出来给需要执行的程序载入。由于 swap 是用磁盘来暂时放置内存中的信息,所以用到 swap 时,主机磁盘灯就会开始闪个不停!
4.1、使用实体分区创建swap
创建 swap 分区的方式也是非常的简单的!通过下面几个步骤就搞定:
- 分区:先使用 gdisk 在磁盘中分区出一个分区给系统作为 swap 。由于 Linux 的 gdisk 默认会将分区的 ID 设置为 Linux 的文件系统,所以可能还得要设置一下 system ID。
- 格式化:利用创建 swap 格式的“mkswap 设备文件名”就能够格式化该分区成为 swap 格式。
- 使用:最后将该 swap 设备启动,方法为:“swapon 设备文件名”。
- 观察:最终通过 free 与 swapon -s 这个指令来观察一下内存的用量吧!
具体操作:
- 先进行分区的行为
[root@study ~]# gdisk /dev/vda
Command (? for help): n
Partition number (6-128, default 6):
First sector (34-83886046, default = 69220352) or {+-}size{KMGTP}:
Last sector (69220352-83886046, default = 83886046) or {+-}size{KMGTP}: +512M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 8200
Changed type of partition to 'Linux swap'
Command (? for help): p
Number Start (sector) End (sector) Size Code Name
6 69220352 70268927 512.0 MiB 8200 Linux swap # 重点就是产生这东西!
Command (? for help): w
Do you want to proceed? (Y/N): y
[root@study ~]# partprobe
[root@study ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 252:0 0 40G 0 disk
.....(中间省略).....
`-vda6 252:6 0 512M 0 part # 确定这里是存在的才行!
# 鸟哥有简化输出喔!结果可以看到我们多了一个 /dev/vda6 可以使用于 swap 喔!
- 开始创建 swap 格式
[root@study ~]# mkswap /dev/vda6
Setting up swapspace version 1, size = 524284 KiB
no label, UUID=6b17e4ab-9bf9-43d6-88a0-73ab47855f9d
[root@study ~]# blkid /dev/vda6
/dev/vda6: UUID="6b17e4ab-9bf9-43d6-88a0-73ab47855f9d" TYPE="swap"
# 确定格式化成功!且使用 blkid 确实可以抓到这个设备了喔
- 开始观察与载入看看
[root@study ~]# free
total used free shared buff/cache available
Mem: 1275140 227244 330124 7804 717772 875536 # 实体内存
Swap: 1048572 101340 947232 # swap 相关
# 我有 1275140K 的实体内存,使用 227244K 剩余 330124K ,使用掉的内存有 717772K 用在缓冲/高速缓存的用途中。至于 swap 已经有 1048572K !这样会看了吧?!
[root@study ~]# swapon /dev/vda6
[root@study ~]# free
total used free shared buff/cache available
Mem: 1275140 227940 329256 7804 717944 874752
Swap: 1572856 101260 1471596 <==有看到增加了没?
[root@study ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 1048572 101260 -1
/dev/vda6 partition 524284 0 -2
# 上面列出目前使用的 swap 设备有哪些的意思!
[root@study ~]# nano /etc/fstab
UUID="6b17e4ab-9bf9-43d6-88a0-73ab47855f9d" swap swap defaults 0 0
# 当然要写入配置文件,只不过不是文件系统,所以没有挂载点!第二个字段写入 swap 即可。
4.2、使用文件创建swap
如果是在实体分区无法支持的环境下,此时前一小节提到的 loop 设备创建方法就派的上用场,与实体分区不一样的,这个方法只是利用 dd 去创建一个大文件而已。
- 使用 dd 这个指令来新增一个 128MB 的文件在 /tmp 下面:
[root@study ~]# 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@study ~]# ll -h /tmp/swap
-rw-r--r--. 1 root root 128M Jun 26 17:47 /tmp/swap
# 这个指令的简单意义如下:
# if 是 input file ,输入文件。那个 /dev/zero 是会一直输出 0 的设备!
# of 是 output file ,将一堆零写入到后面接的文件中。
# bs 是每个 block 大小,就像文件系统那样的 block 意义;
# count 则是总共几个 bs 的意思。所以 bs*count 就是这个文件的容量了!
- 使用 mkswap 将 /tmp/swap 这个文件格式化为 swap 的文件格式:
[root@study ~]# mkswap /tmp/swap
Setting up swapspace version 1, size = 131068 KiB
no label, UUID=4746c8ce-3f73-4f83-b883-33b12fa7337c
# 这个指令下达时请“特别小心”,因为下错字符控制,将可能使您的文件系统挂掉!
- 使用 swapon 来将 /tmp/swap 启动:
[root@study ~]# swapon /tmp/swap
[root@study ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 1048572 100380 -1
/dev/vda6 partition 524284 0 -2
/tmp/swap file 131068 0 -3
- 使用 swapoff 关掉 swap file,并设置自动启用:
[root@study ~]# nano /etc/fstab
/tmp/swap swap swap defaults 0 0
# 为何这里不要使用 UUID 呢?这是因为系统仅会查询区块设备 (block device) 不会查询文件!
# 所以,这里千万不要使用 UUID,不然系统会查不到喔!
[root@study ~]# swapoff /tmp/swap /dev/vda6
[root@study ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 1048572 100380 -1
# 确定已经回复到原本的状态了!然后准备来测试!!
[root@study ~]# swapon -a
[root@study ~]# swapon -s
# 最终你又会看正确的三个 swap 出现啰!这也才确定你的 /etc/fstab 设置无误!
swap 在目前的桌面电脑来讲,存在的意义已经不大了!这是因为目前的 x86 主机所含的内存实在都太大了 (一般入门级至少也都有 4GB 了),所以, Linux 系统大概都用不到 swap 这个玩意儿的。不过, 如果是针对服务器或者是工作站这些常年上线的系统来说的话,那么,无论如何,swap 还是需要创建的。
五、补充
5.1、利用 GNU 的 parted 进行分区行为(Optional)
gdisk/fdisk 很快速的将分区切割妥当,不过 gdisk 主要针对 GPT 而 fdisk 主要支持 MBR ,对 GPT 的支持还不够! 所以使用不同的分区时,得要先查询到正确的分区表才能用适合的指令,好麻烦!有没有同时支持的指令呢?有的!那就是 parted。
parted 可以直接在一行命令行就完成分区,是一个非常好用的指令!它常用的语法如下:
parted [设备] [指令 [参数]]
选项与参数:
指令功能:
- 新增分区:mkpart [primary|logical|extended] [ext4|vfat|xfs] 开始 结束
- 显示分区:print
- 删除分区:rm [partition]
范例一:以 parted 列出目前本机的分区表数据
[root@study ~]# parted /dev/vda print
Model: Virtio Block Device (virtblk) <==磁盘接口与型号
Disk /dev/vda: 42.9GB <==磁盘文件名与容量
Sector size (logical/physical): 512B/512B <==每个扇区的大小
Partition Table: gpt <==是 GPT 还是 MBR 分区
Disk Flags: pmbr_boot
Number Start End Size File system Name Flags
1 1049kB 3146kB 2097kB bios_grub
2 3146kB 1077MB 1074MB xfs
3 1077MB 33.3GB 32.2GB lvm
4 33.3GB 34.4GB 1074MB xfs Linux filesystem
5 34.4GB 35.4GB 1074MB ext4 Microsoft basic data
6 35.4GB 36.0GB 537MB linux-swap(v1) Linux swap
[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ]
- Number:这个就是分区的号码!举例来说,1号代表的是 /dev/vda1 的意思;
- Start:分区的起始位置在这颗磁盘的多少 MB 处,他以容量作为单位;
- End:此分区的结束位置在这颗磁盘的多少 MB 处;
- Size:由上述两者的分析,得到这个分区有多少容量;
- File system:分析可能的文件系统类型为何的意思;
- Name:就如同 gdisk 的 System ID 之意。
范例二:将 /dev/sda 这个原本的 MBR 分区表变成 GPT 分区表!(危险!危险!勿乱搞!无法复原!)
[root@study ~]# parted /dev/sda print
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 2148MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos # 确实显示的是 MBR 的 msdos 格式喔!
[root@study ~]# parted /dev/sda mklabel gpt
Warning: The existing disk label on /dev/sda will be destroyed and all data on
this disk will be lost. Do you want to continue?
Yes/No? y
[root@study ~]# parted /dev/sda print
# 你应该就会看到变成 gpt 的模样!只是...后续的分区就全部都死掉了!
范例三:创建一个约为 512MB 容量的分区
[root@study ~]# parted /dev/vda print
.....(前面省略).....
Number Start End Size File system Name Flags
.....(中间省略).....
6 35.4GB 36.0GB 537MB linux-swap(v1) Linux swap # 要先找出来下一个分区的起始点!
[root@study ~]# parted /dev/vda mkpart primary fat32 36.0GB 36.5GB
# 由于新的分区的起始点在前一个分区的后面,所以当然要先找出前面那个分区的 End 位置!
# 然后再请参考 mkpart 的指令功能,就能够处理好相关的动作!
[root@study ~]# parted /dev/vda print
.....(前面省略).....
Number Start End Size File system Name Flags
7 36.0GB 36.5GB 522MB primary
[root@study ~]# partprobe
[root@study ~]# lsblk /dev/vda7
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda7 252:7 0 498M 0 part # 要确定它是真的存在才行!
[root@study ~]# mkfs -t vfat /dev/vda7
[root@study ~]# blkid /dev/vda7
/dev/vda7: SEC_TYPE="msdos" UUID="6032-BF38" TYPE="vfat"
[root@study ~]# nano /etc/fstab
UUID="6032-BF38" /data/win vfat defaults 0 0
[root@study ~]# mkdir /data/win
[root@study ~]# mount -a
[root@study ~]# df /data/win
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda7 509672 0 509672 0% /data/win
事实上,应该使用 gdisk 来处理 GPT 分区就好了!不过,某些特殊时刻,例如要自己写一只脚本,让分区全部一口气创建, 不需要 gdisk 一条一条指令去进行时,那么 parted就非常有效果了!因为他可以直接进行 partition 而不需要跟用户互动!这就是它的最大好处!