20170804 磁盘管理

目录

  • 磁盘结构
  • 磁盘分区
  • 磁盘分区管理
  • 文件系统管理
  • 挂载

一、磁盘结构

(一)设备文件

  • 设备文件:
    linux系统下一切皆文件,设备文件分为块设备和字符设备

  • 块设备:存取单位为“块”,如磁盘

  • 字符设备:存取单位为“字符”,如键盘

  • 设备号码:

    • 主设备号:major number,标识设备类型
    • 次设备号:minor number,标识同类型不同设备
    • 下图红色方框内,逗号前为主设备号表示设备类型,逗号后为次设备号
  • 创建设备文件 mknod
mknod filepath {b | c} m n     // b指块设备,c指字符设备,m指主设备号,n指次设备号

(二)磁盘设备文件命名:/dev/DEV_FILE

  • 物理磁盘/dev/sd,虚拟磁盘/dev/vd

  • 不同磁盘标识:a-z排序,如/dev/sda, /dev/sdb

  • 同磁盘的不同分区标识:数字排序,从1开始,但是并不一定连续编号,视分区方式而定,如/dev/sda1/dev/sda5

(三)磁盘物理概念

  • head:磁头,一张磁盘的两个面需要各配置一个磁头,磁头数等于盘面数

  • track:磁道,磁盘盘面分成许多同心圆,每个同心圆是一个磁道

  • sector: 扇区,磁道被分成长度相等的多个区段为扇区,每个扇区大小512bytes

  • cylinder: 柱面,硬盘上所有盘面上相同位置的磁道组合成的假想的圆柱面

(四)磁盘寻址

  • 磁盘寻址方式:较老的CHS和较新的LBA方式

  • CHS寻址

    • 采用24bit位寻址
    • 其中前10位表示cylinder,中间8位表示head,后面6位表示sector。
    • 最大寻址空间:(2^10) * (2^8) * (2^6) * 512B / (2^30) = 8GB
  • LBA寻址

    • 采用48bit寻址
    • 最大寻址空间128PB
  • 磁盘小于8GB时两种寻址方式均可;当磁盘大于8GB时,必须使用LBA寻址方式。当前硬盘容量远大于8GB,CHS寻址已经基本淘汰。

二、磁盘分区

(一)磁盘分区的优势

  • 优化I/O性能

  • 实现磁盘空间配额限制

  • 提高修复速度

  • 隔离系统和程序

  • 安装多个OS

  • 采用不同文件系统

(二)分区方式:MBR和GPT分区

1. MBR (Master Boot Record) 主引导记录

  • 磁盘的0磁道0扇区被称为MBR,一共512bytes的空间分配如下:

    • 446 bytes: boot loader 引导程序,linux使用grub2
    • 64 bytes: DPT 分区表,每16byte描述一个分区,可以描述四个分区
    • 2 bytes: 55AA,结束标志,表示磁盘有数据
  • 从分区表的容量看,磁盘只能分为四个分区,称为主分区。为了能够分出更多分区,MBR允许建立一个扩展分区,再在扩建分区内创建逻辑分区。扩展分区占据一个主分区位置,分区信息存放在MBR中,从而主分区和扩展分区一共不能超过四个。

  • 逻辑分区的分区信息存放:扩展分区中的每个逻辑分区的0扇区被称为EBR扩展引导记录,其512bytes的空间分配类似于MBR。

    • 446bytes: 未使用
    • 64byte: 分区表,第一个16bytes指向本逻辑分区,第二个16bytes指向下一个逻辑分区,其余两个16bytes尚未使用
    • 2 bytes: 55AA,结束标志
  • BIOS(基本输入输出系统)硬件支持MBR分区方式,使操作系统启动

2. GPT (GUID Partition Table)

  • GUID (Global Unique Identifiers) 全局唯一标识符:GPT分区模式下没有主分区、扩展分区、逻辑分区之分,每个分区以128位的UUID (Universally Unique Identifier) 标识。

  • GPT分区表自动备份在分区头尾,并有CRC校验位

  • GPT分区支持128个分区,使用64位,支持8Z(512Byte/block )64Z (4096Byte/block)

  • UEFI (统一扩展固件接口) 硬件支持GPT分区方式,使操作系统启动

(三)磁盘分区的管理

  • lsblk 列出块设备

  • 磁盘分区管理工具

    • fdisk 创建MBR分区
    • gdisk 创建GPT分区
    • parted 高级分区操作
1、parted 命令使用
  • 语法:parted [选项]... [设备[命令[参数]...]...]

  • 用例

parted /dev/sdb mklabel gpt|msdos        //建立GPT或MBR分区
parted /dev/sdb print                    //显示磁盘分区情况
parted /dev/sdb mkpart primary 1 200     //建立主分区,大小从1M到200M
parted /dev/sdb rm 1                     //删除编号为1的分区
parted -l                                //列出所有块设备分区情况
  • 实验:
    1.将新添加200G的磁盘建立MBR分区表
    命令:parted /dev/sdb mklabel msdos

2.建立主分区1,大小从1M到1024M
命令:parted /dev/sdb mkpart primary 1 1024

3.建立主分区2,大小从1025M到3072M
命令:parted /dev/sdb mkpart primary 1025 3072

4.删除主分区2
命令:parted /dev/sdb rm 2

2、fdisk 命令使用
  • 用法:
fdisk -l [-u] [device...]     //查看分区,使用-u=cylinders选项以柱面为单位查看
#----------------------------------------------------------------------------#
fdisk device                  //管理分区
子命令:
p     //分区列表
t     //更改分区类型
n     //创建新分区
d     //删除分区
v     //校验分区
u     //转换单位
w     //保存并退出
q     //不保存并退出
  • 实验:

1.新加一块100G的磁盘/dev/sdb,分别以扇区和柱面为单位查看磁盘分区信息
命令:

fdisk -l /dev/sdb
fdisk -l -u=cylinders /dev/sdb

2.磁盘分区:第一个主分区500M,第二个主分区10G,扩展分区50G,其中第一个逻辑分区20G,第二个逻辑分区占用扩展分区剩余空间
2.1命令fdisk /dev/sdb后,进入提示页面,输入n代表新建分区:
(1)提示选择分区类型,输入p或者直接回车表示新建主分区;
(2)提示选择分区编号,默认1,回车选择默认设置;
(3)提示分区开始扇区,回车按默认设置;
(4)提示分区结束扇区,输入+500M,代表分区大小500M,回车完成第一个主分区设置。其余分区设置基本类似,按提示操作即可。

2.2分区建立完成后,输入p查看分区列表

3.删除第一个20G逻辑分区,查看分区表发现原第二个逻辑分区的命名有了变化,证明磁盘的命名并不稳定,编写脚本时要特别防止代码中出现硬盘设备名称

4.删除50G扩展分区,发现内部的逻辑分区同时被删除

5.不保存分区设置并退出:输入q即可

  • gdisk用于GPT分区,使用方式和fdisk类似。
3、同步分区表
  • 使用分区工具划分分区后,需要将磁盘上的分区信息同步至内存中

  • 查看内核是否已经识别新的分区:cat /proc/partitions

  • CentOS 6上同步分区 partxkpartx

partx -a /dev/device             //同步增加的分区,-a 增加分区
kpartx -a /dev/device            //同步增加的分区,-f 强制同步分区表
partx -d --nr M-N /dev/device    //同步减少的分区,-d 删除分区,-nr 指明删除分区范围
kpartx -d /dev/device            //同步减少的分区
  • CentOS 5和CentOS 7上同步分区 partprobe
partprobe [/dev/device]     //同步分区

三、文件系统

  • 功能:组织和分配存储设备的空间

  • 查看系统支持的文件系统类型:ls /lib/modules/`uname -r`/kernel/fs

  • 文件系统类型

    • linux:ext2, ext3, ext4, xfs, swap
    • 光盘::iso9660
    • Windows:fat32, exfat, ntfs
    • 网络文件系统:NFS, CIFS
    • RAW:未经处理或未经格式化产生的文件系统
  • 是否支持日志

    • 支持日志:ext3, ext4, xfs
    • 不支持日志:ext2, vfat

四、文件系统管理

(一)创建文件系统 mkfs

  • 语法:
mkfs.fstype /dev/device        //fstype: ext3,ext4,xfs .etc
mkfs -t fstype /dev/device     //fstype: ext3,ext4,xfs .etc
  • mke2fs:ext文件系统专用管理工具,使用mkfs建立ext文件系统自动调用此命令
    选项:
-t {ext2 | ext3 | ext4}     //分区类型
-b {1024 | 2048 | 4096}     //指定块的大小
-L 'LABEL'                  //指定卷标
-j       //相当于-t ext3,mkfs.ext3 = mkfs -t ext3 = mke2fs -j = mke2fs -t ext3
-i #     //一个inode标识多少字节空间,不要小于block大小,格式化后不能更改
-N #     //指定分区中创建多少个inode
-I #      //一个inode记录占用的磁盘空间大小,范围:128至4096,格式化后不能更改
-m #     //为管理人员预留空间占总空间的百分比,默认5%
-O FEATURE      //启用指定特性
-O ^FEATURE     //关闭指定特性
  • 实验:
    现在有三个分区尚未创建文件系统,按以下配置创建:
    (1)/dev/sdb1,ext3分区,卷标"USER";
    (2)/dev/sdb2,ext4分区,块大小2048字节,2048字节/inode;
    (3)/dev/sdb3,ext4分区,预留空间占比2%。
  • 命令:
mkfs.ext3 -L 'USER' /dev/sdb1
mke2fs -t ext4 -b 2048 -i 2048 /dev/sdb2
mkfs -t ext4 -m 2 /dev/sdb3

对/dev/sdb1建立文件系统后,显示的信息中:第一个红框表示卷标设置成功,第二个红框表示默认有5%的分区空间预留给超级用户,第三个红框表示超级块备份到分区的很多地方

对/dev/sdb2建立文件系统后,显示的信息中:红框中的inode数和block数基本相同,这是因为建立文件系统时块大小和每个inode标识块的大小相同。-i选项数值应该大于-b选项值,只有这样产生的inode数才会少于block数。否则,inode数大于block数,多出的inode数就被浪费掉了。

对/dev/sdb3建立文件系统后,显示的信息中:红框中的为超级用户的预留空间为总空间的2%。

(二)管理文件系统

  • blkid 查询块设备属性
blkid -U UUID      //根据指定的UUID查询设备
blkid -L LABLE     //根据指定的LABLE查询设备
  • findfs 查找分区,功能与blkid类似
findfs UUID="uuid"       //根据指定的UUID查询设备
findfs LABEL="label"     //根据指定的LABLE查询设备
  • tune2fs 修改ext文件系统的可修改属性
-l             //查看指定文件系统超级块(superblock)信息
-L 'LABEL'     //修改卷标,也可以使用 e2label /dev/device label 修改
-m #           //修改预留给管理员的空间百分比
-j             //将ext2升级为ext3,即添加日志功能
-O             //文件系统属性启用或禁用,禁用在属性前加^
-o             //调整文件系统的默认挂载选项,禁用在属性前加^
-U UUID        //修改UUID号
  • 实验:将分区/dev/sdb2预留给管理员空间的百分比调至3%,增加卷标"TWO",挂载属性添加acl支持
    命令:
tune2fs -l /dev/sdb2
tune2fs -L 'TWO' -m 3 -o acl /dev/sdb2

首先使用-l选项查看当前文件系统的配置信息,第一个红框表明默认挂载选项为空,第二个红框38556/771120=5%表明为管理员预留的5%空间率。

修改文件系统属性后,再次查看,如图红框中所示:增加了acl挂载选项,为管理员预留的空间率变为23133/771120=3%。

  • dumpe2fs 显示超级块和块组信息
dumpe2fs /dev/device        //显示设备的超级块和块组信息
dumpe2fs -h /dev/device     //只显示设备的超级块信息

(三)文件系统检测和修复

  • 常发生在死机、意外关机之后

  • 文件系统修复必须在未挂载状态下

  • fsck (File System Check) 文件系统修复工具

    • 语法,以下两种格式均可:
      fsck.FS_TYPE [options] /dev/device
      fsck -t FS_TYPE [options] /dev/device

    • 选项:
      -p: 自动修复错误
      -r: 交互式修复错误

  • e2fsck ext文件系统修复工具

e2fsck -y /dev/device     //修复过程自动回答yes 
e2fsck -f /dev/device     //强制检测修复分区,即使分区没问题也执行
  • 实验:修复文件系统
    命令:
dumpe2fs /dev/sdb1 | head -100
dd if=/dev/zero of=/dev/sdb1 bs=1 count=4096
tune2fs -l /dev/sdb1
e2fsck -y /dev/sdb1

首先使用dumpe2fs 命令查看块组信息,如图第2行指明/dev/sdb1分区的主超级块位于块1,下一步考虑破坏块1制造磁盘文件系统损坏

可以看到使用dd命令在对/dev/sdb1分区的前4096字节破坏后,磁盘出现了损坏,提示没有发现有效的系统超级块

可以看到/dev/sdb1修复成功,红框内文件系统状态为clean

五、挂载 mount

  • 挂载:将文件系统与当前目录树中的目录建立联系,从而通过进入目录访问该文件系统

  • 卸载:解除文件系统与被挂载目录的联系关系

  • 被挂载的目录称作挂载点,挂载后目录下的内容将暂时被隐藏,无法被访问

  • 挂载点一般选择空目录,避免目录原内容无法访问的问题

(一)mount 挂载命令

  • 语法:mount [options] device mount_point

  • 分区设备:包含设备文件、UUID、卷标、伪文件系统
    UUID: -U "UUID" 卷标:-L "LABEL"

  • 挂载点:建议使用空目录

  • 选项:

-t vsftype     //指定要挂载设备的文件系统类型,不指明系统会检测文件系统类型
-r     //readonly,只读挂载
-w     //read and write, 读写挂载
-n     //不更新/etc/mtab,mount不可见
-a     //自动挂载所有支持自动挂载的设备(在/etc/fstab文件定义,且挂载选项中有auto功能)
-L 'LABEL'     //以卷标指定挂载设备
-U 'UUID'     //以UUID指定要挂载的设备
-B, --bind     //绑定目录到另一个目录上
  • -o 挂载文件系统的子选项:
async           //异步模式
sync            //同步模式——内存更改时同时写磁盘
atime/noatime   //是否更新文件系统文件和目录的atime时间戳
diratime/nodiratime     //是否更新目录的atime时间戳
auto/noauto     //是否支持自动挂载,即是否支持-a选项
exec/noexec     //是否支持在文件系统上运行应用程序
dev/nodev       //是否支持在此文件系统上使用设备文件
suid/nosuid     //是否支持suid和sgid权限
remount         //重新挂载,经常在给只读文件系统增加写属性时配合-rw选项使用
ro              //只读
rw              //读写
user/nouser     //是否允许普通用户挂载此设备,/etc/fstab使用
acl             //启用此文件系统上的acl功能
loop            //使用loop设备
defaults        //相当于rw, suid, dev, exec, auto, nouser, async, and relatime
  • cat /proc/mounts 查看内核追踪到的所有已挂载设备,mount -n选项的挂载也可以看到

  • 实验:
    按以下要求挂载:
    (1)/dev/sdb1挂在到/mnt/dir1,不更新时间戳
    (2)/dev/sdb2挂在到/mnt/dir2,只读模式,然后不卸载直接改为读写模式
    (3)/dev/sdb3挂在到/mnt/dir3,不支持suid和sgid权限,不更新/etc/mtab
    (4)将/app/file1文件挂载到/mnt/dir4
    (5)将/etc目录挂载到/mnt/dir5
    (6)将/dev/sdb2挂载到/mnt/dir6
    命令:

//first step
mount  -o noatime /dev/sdb1 /mnt/dir1
//second step
mount  -o ro /dev/sdb2 /mnt/dir2
mount -o remount,rw /dev/sdb2 /mnt/dir2
//third step
mount -o nosuid -n /dev/sdb3 /mnt/dir3
//forth step
dd if=/dev/zero of=/app/file1 bs=1M count=500
mkfs -t ext3 /app/file1
mount -o loop /app/file1 /mnt/dir4
//fifth step
mount -B /etc /mnt/dir5
//sixth step
mount  /dev/sdb2 /mnt/dir6
mount  /dev/sdb3 /mnt/dir1

第一步,挂载成功。

第二步,第一次挂载时采用只读模式,导致无法新建文件;重新挂载时改为读写模式,成功新建文件。

第三步,挂载后无论df命令还是mount命令都无法看到/dev/sdb3的挂载信息。

此时,只能从/proc/mounts下才能看到。

将/bin/cat文件拷贝至/mnt/dir3并为其增加suid权限,登录普通用户并尝试访问/etc/shadow文件失败。此时,重新挂载将属性改为suid,再登录普通用户并尝试访问/etc/shadow文件成功。

第四步,使用dd命令创建文件,使用mkfs命令创建文件系统,df结果证明文件也可以挂载。

第五步,mount时使用-B选项成功挂载。此时,发现原目录和挂载点目录下文件完全相同,并且出现了相同文件inode号相同,inode节点数却是1的特殊现象。

第六步,将/dev/sdb2挂载到/mnt/dir6后发现挂载成功,/mnt/dir2和/mnt/dir6都能够访问/dev/sdb2分区内容。将/dev/sdb3挂载到/mnt/dir1后发现挂载成功,但/mnt/dir1访问的是/dev/sdb3分区内容,/dev/sdb1分区内容被隐藏。所以,单个分区可以挂载到不同目录,但不要把几个分区挂载到同一个目录

(二)unmount 卸载命令

  • 卸载前需要确保文件系统没有被进程访问,如果有,需要查询是什么进程访问文件系统,如有必要需要终止占用的进程。

  • 查看挂载情况
    findmnt mount_point | device

  • 查看正在访问文件系统的进程

// 两个命令均可
lsof mount_point
fuser -v mount_point
  • 终止正在访问文件系统的进程
    fuser -km mount_point

  • 卸载
    umount mount_point | device

  • 在有进程访问时卸载分区

在另一个终端用vim访问/mnt/dir1目录内的文件,用lsoffuer -v发现访问程序,使用fuer -km命令强行结束访问分区的vim程序,从而顺利卸载分区。

(三)/etc/fstab 文件

  • /etc/fstab文件用于配置文件系统体系,系统启动时按照此文件的设置挂载文件系统,同时被mount, fsck等工具使用

  • /etc/fstab文件格式:每行定义一个要挂载的文件系统,具体如下

    • 要挂载的文件系统:可以是设备文件、UUID、LABEL和伪文件系统(e.g. proc)
    • 挂载点
    • 文件系统类型
    • 挂载选项:defaults
    • 备份频率:0-不备份;1-每天备份;2-隔一天备份
    • 自检次序:0-不自检;1-首先自检,一般只有根文件系统才会设置
  • 实验:系统启动时自动挂载分区,具体如下:
    (1)/dev/sdb1挂载到/mnt/dir1
    (2)将/app/file1文件挂载到/mnt/dir4
    (3)将/etc目录挂载到/mnt/dir5
    编辑/etc/fstab文件增加如下几行:

UUID=c825e990-eb35-49b1-9f94-72b06786b612     /mnt/dir1             ext3    defaults        0 0
/app/file1                                    /mnt/dir4             ext3    loop            0 0 
/etc                                          /mnt/dir5             none    bind            0 0

通过blkid查看/dev/sdb1的UUID,用于编辑/etc/fstab文件。编辑完成后,重启系统会按照/etc/fstab的设置启动各个分区。当新添加的配置信息的挂载选项中有auto时(default中有auto,直接写loop或者bind也包含default选项),执行mount -a选项会自动挂载/etc/fstab文件有auto选项的新添加条目。

(四)交换分区:系统内存的补充

  • 交换分区设置步骤:

    • 创建交换分区fdisk或文件,注意改变分区类型
    • 使用mkswap命令写入特殊签名
    • /etc/fstab文件中添加条目
    • 使用swapon -a激活交换分区
  • 启用交换分区 swapon [options] [device]

-a              //激活所有交换分区
-p priority     //指定优先级,priority=0~32767,值越大优先级越高
  • 禁用交换分区 swapoff [options] [device]

  • 交换分区优先级:

    • 交换分区优先级值越大优先级越高
    • 系统指定的交换分区优先级从-1开始,每加入一个用户没有指定的交换分区,其优先级减一,故越早加入的系统指定交换分区优先级越高
    • 用户指定的交换分区优先级范围:0-32767,所以任意用户指定的交换分区优先级高于系统指定
    • 调整交换分区优先级用于优化性能,提高存取速度较快的交换分区优先级
  • 实验:交换分区的设置
    命令:

fdisk /dev/sdb5
mkswap /dev/sdb5
vim /etc/fstab
swapon -a
swapoff -a

分区时注意改变作为交换分区的分区system id,通过fdisk工具的t选项将id号由默认83改为82

建立swap分区,通过blkid命令可以看到/dev/sdb5已经成为swap分区

vim编辑/etc/fstab文件,增加条目,内容如下:

UUID=2b29e986-cd2c-435e-9431-6636c834a1e5       swap    swap    defaults        0 0

挂载交换分区成功,查看优先级发现系统默认新添加的交换分区优先级低于旧交换分区

再次编辑/etc/fstab文件,将/dev/sdb5分区的挂载选项增加pri值为10,再次挂载交换分区,此时发现/dev/sdb5的优先级最高

(五)挂载移动介质

  • 访问移动介质前必须挂载

  • 摘除移动介质前必须卸载

  • 挂载点通常在/media和/mnt下

1. 使用光盘
  • 光盘自动挂载目录: /run/media/<user>/<label>

  • 手动挂载: mount /dev/cdrom /mnt

  • 卸载并弹出光盘:eject

  • 创建iso文件:

cp /dev/cdrom filename.iso           //从光盘创建iso文件
mkisofs -r -o filename.iso /path     //将目录下的所有文件打包为iso文件
  • 实验:将CentOS 6.9 两张光盘内容合成为一个iso文件
    命令:
//first step  将光盘1的内容复制到/app/CentOS_6.9_Final_Everything目录下
cp -r /media/CentOS_6.9_Final/ /app/CentOS_6.9_Final_Everything

//second step  将光盘2的内容复制到/app/CentOS_6.9_Final_Everything目录下
cp -r /media/CentOS_6.9_Final/Packages/* /app/CentOS_6.9_Final_Everything/Packages/

//third step  安装mkdvdiso.sh的依赖isomd5sum
yum install isomd5sum

//final step  执行mkdvdiso.sh生成可启动的iso文件
bash mkdvdiso.sh /app/CentOS_6.9_Final_Everything/ /app/CentOS_6.9_x86_64_Final_Everything.iso
2. 挂载USB介质
  • 查看USB设备是否被识别 lsusb

  • USB介质会被内核识别为SCSI设备,设备编号类似/dev/sdb1

  • 自动挂载目录:/run/media/<user>/<label>

  • 手动挂载:mount /dev/sdb1 /mnt

(六) 磁盘管理常用工具

  • free 内存空间状态查询
    free [-m | -g | -h] //-m 以MB为单位,-g 以GB为单位,-h以人类易读方式显示

  • df 文件系统占用等信息查询

df   [options] [files]
-H     //以1000为单位
-h     //以人类易读方式显示
-i     //显示节点号
-T     //显示文件系统类型
  • du 查看目录总体空间占用情况
du [options] dir
-h     //以人类易读方式显示
-s     //显示摘要信息
  • dd 转化并复制文件
    语法:dd if=/path/to/src of=/path/to/dest bs=# count=#
    解释:
if     //从设备文件、文件处输入
of     //输出至文件
bs     //指定输入、输出的块大小
ibs    //一次输入块的大小
obs    //一次输出块的大小
cbs    //一次转化块的大小
skip   //从开头忽略输入的块数
seek   //从开头忽略输出的块数
count  //拷贝记录数

应用:

dd if=/dev/sda of=/tmp/mbr.bak bs=512 count=1          //备份MBR
dd if=/dev/zero of=/dev/sda bs=64 count=1 seek=446     //破坏MBR的分区表
dd if=/dev/sda of=/dev/sdb           //将磁盘/dev/sda整体备份至/sdb/sdb
dd if=/dev/sda of=/path/to/image     //将磁盘/dev/sda整体备份为image文件
dd if=/path/to/image of=/dev/sda     //将image文件恢复至磁盘/dev/sda
dd if=/dev/urandom of=/dev/sda       //用随机数据填充硬盘,可用于销毁数据

推荐阅读更多精彩内容