Linux磁盘管理

Posted by wsxq2 on 2019-03-19
TAGS:  ddLinux磁盘

本文最后一次编辑时间:2021-08-25 18:08:23 +0800

理论相关

TODO

常用命令

resize2fs

parted

df

df(Disk Free)命令参数功能:检查文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。

语法:

1
df [-ahikHTm] [目录或文件名]

选项与参数:

  • -a: 列出所有的文件系统,包括系统特有的 /proc 等文件系统;
  • -k: 以 KBytes 的容量显示各文件系统;
  • -m: 以 MBytes 的容量显示各文件系统;
  • -h: 以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
  • -H: 以 M=1000K 取代 M=1024K 的进位方式;
  • -T: 显示文件系统类型, 连同该 partition 的 filesystem 名称 (例如 ext3) 也列出;
  • -i: 不用硬盘容量,而以 inode 的数量来显示

常用方法:

1
2
3
df -h
df -Th
df -iah

du

Linux du(Disk Usage)命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的,这里介绍Linux du命令。

语法:

1
du [-ahskm] 文件或目录名称

选项与参数:

  • -a: 列出所有的文件与目录容量,因为默认仅统计目录底下的文件量而已。
  • -h: 以人们较易读的容量格式 (G/M) 显示;
  • -s: 列出总量而已,而不列出每个各别的目录占用容量;
  • -S: 不包括子目录下的总计,与 -s 有点差别。
  • -k: 以 KBytes 列出容量显示;
  • -m: 以 MBytes 列出容量显示;

常用参数:

1
du -sh .

fdisk

fdisk 是 Linux 的磁盘分区表操作工具。

语法:

1
fdisk [-l] 装置名称

选项与参数:

  • -l: 输出后面接的装置所有的分区内容。若仅有 fdisk -l 时, 则系统将会把整个系统内能够搜寻到的装置的分区均列出来。

常用命令: d,m,p,n,t,w,q

mkfs

磁盘格式化命令。磁盘分割完毕后自然就是要进行文件系统的格式化,格式化的命令非常的简单,使用 mkfs(make filesystem) 命令。

语法:

1
mkfs [-t 文件系统格式] 装置文件名

选项与参数:

  • -t: 可以接文件系统格式,例如 ext3, ext2, vfat 等(系统有支持才会生效)

常用命令:mkfs.ext4,mkfs.xfs

e2fsck

fsck

fsck(file system check)用来检查和维护不一致的文件系统。

若系统掉电或磁盘发生问题,可利用fsck命令对文件系统进行检查。

语法:

1
fsck [-t 文件系统] [-ACay] 装置名称

选项与参数:

  • -t: 给定档案系统的型式,若在 /etc/fstab 中已有定义或 kernel 本身已支援的则不需加上此参数
  • -s: 依序一个一个地执行 fsck 的指令来检查
  • -A: 对/etc/fstab 中所有列出来的 分区(partition)做检查
  • -C: 显示完整的检查进度
  • -d: 打印出 e2fsck 的 debug 结果
  • -p: 同时有 -A 条件时,同时有多个 fsck 的检查一起执行
  • -R: 同时有 -A 条件时,省略 / 不检查
  • -V: 详细显示模式
  • -a: 如果检查有错则自动修复
  • -r: 如果检查有错则由使用者回答是否修复
  • -y: 选项指定检测每个文件是自动输入yes,在不确定那些是不正常的时候,可以执行 # fsck -y 全部检查修复。

mount and umount

Linux 的磁盘挂载使用 mount 命令,卸载使用 umount 命令。

磁盘挂载语法:

1
mount [-t 文件系统] [-L Label名] [-o 额外选项] [-n]  装置文件名  挂载点

磁盘卸载命令 umount 语法:

1
umount [-fn] 装置文件名或挂载点

选项与参数:

  • -f: 强制卸除!可用在类似网络文件系统 (NFS) 无法读取到的情况下;
  • -n: 不升级 /etc/mtab 情况下卸除。

lsblk

lsblk(列出块设备)命令用于列出所有可用块设备的信息,但是,它不会列出RAM盘的信息。块设备有硬盘,闪存盘,CD-ROM等等。

lsblk 命令默认情况下将以 「 树状 」 列出所有块设备。在终端输入以下命令:

1
$ lsblk

输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@AbsentM ~]# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 557.9G  0 disk
├─sda1   8:1    0     1M  0 part
├─sda2   8:2    0   500M  0 part /boot
├─sda3   8:3    0 299.4G  0 part
├─sda4   8:4    0     1K  0 part
├─sda5   8:5    0  97.7G  0 part /
├─sda6   8:6    0  97.7G  0 part /var/log
├─sda7   8:7    0  62.5G  0 part [SWAP]
└─sda8   8:8    0   196M  0 part /boot/efi
sdb      8:16   0   200G  0 disk
├─sdb1   8:17   0   150G  0 part /var/lib/cache
└─sdb2   8:18   0    50G  0 part

7 个列的名称解释如下:

  • NAME : 块设备名称。
  • MAJ:MIN : 显示主要和次要设备号。
  • RM : 显示设备是否可移动设备。 RM 值为 1, 表示为可移动设备。
  • SIZE : 列出设备的容量大小信息。
  • RO : 表明设备是否为只读。 RO 值为 0, 表示只读。
  • TYPE : 显示块设备是否是磁盘或磁盘上的一个分区。 disk 表示磁盘,part 表示分区,rom 表示只读存储器。
  • MOUNTPOINT : 显示设备挂载的挂载点。

常用参数:

1
lsblk -ao +FSTYPE,LABEL,UUID,PARTLABEL,PARTUUID,SERIAL,MODEL

blkid

blkid 命令可以显示关于可用块设备的信息,如:设备名称、UUID(文件系统唯一标示符)、Type(文件系统类型)、PARTLABEL、PARTUUID 等信息。

列出几个 blkid 命令支持的可用参数:

  • -o: output format; can be one of: value, device, export or full; (default: full)
  • -s: show specified tag(s) (default show all tags)
  • -t: find device with a specified token (NAME=value pair)
  • -L: convert LABEL to device name
  • -U: convert UUID to device name

dd

介绍

dd是一个Unix和类Unix系统上的命令,主要功能为转换和复制文件。[1]

在Unix上,硬件的设备驱动(如硬盘)和特殊设备文件(如/dev/zero和/dev/random)就像普通文件一样,出现在文件系统中;只要在各自的驱动程序中实现了对应的功能,dd也可以读取自和/或写入到这些文件。这样,dd也可以用在备份硬件的引导扇区、获取一定数量的随机数据等任务中。dd程序也可以在复制时处理数据,例如转换字节序、或在ASCII与EBCDIC编码间互换。[2]

——引用自dd (Unix)维基百科,自由的百科全书

简单地说,dd命令用于将一个位置(可以是磁盘或文件,甚至其它设备)的内容逐字节地复制到另一个位置。该 Linux 命令非常有用,其功能非常强大,但这里我们只涉及它用于磁盘备份与恢复这个方面的功能

简单使用

备份磁盘有效部分(已分区部分,可以通过命令fdisklsblk命令查看):

1
dd if=/dev/sdb  of=multiboot_upan.img bs=64M count=321 status=progress

简单说明一下上面使用的参数:

  • if: input file,输入文件(因为Linux中一切皆文件)
  • of: ouput file,输出文件
  • bs: block size,一次复制的块的大小,据说和速度有一定的关系,但我没感受出来
  • count: 块的数量。count*bs=复制的总大小
  • status: 输出信息的详尽程度。常用的是status=progress,用于输出进度条

更多参数参考man dd

注意,备份太多或太少都不行,太多(如未分区的部分)会占用大量磁盘空间,太少会导致还原失败,所以比有效部分稍微大一点就可以了。还原也很简单:

1
dd if=multiboot_upan.img of=/dev/sdb bs=64M  status=progress

(我突然有点好奇,如果把一个 Windows 系统直接这样备份后在另一台电脑上还原是否可以直接使用(不需要激活)?理论上是可以的,因为它是完全复制了的,除非密钥和硬件绑定了。细细想来,感觉应该是不行)

配合 gzip 命令

正常情况下,你的磁盘的有效部分有多大,那么备份之后的文件就有多大。比如说,我有个 Ubuntu 装在了一个120G的固态硬盘上,但系统本身只有 9G ,且只分了两个区,一个文件系统格式为FAT32大小为 200MB 的ESP分区,一个文件系统格式为ext4的大小为将近120G的用于挂载/的分区,那么使用dd命令后,你生成的备份文件将是 120GB ,而不是 9GB。(这里忘了说swap分区了,不过并不影响)

因此,为了减小备份文件的大小,我们配合 gzip 命令使用:

1
dd bs=512 count=[fdisk命令中最大的end数+1] if=/dev/sda | gzip > backup.img.gz

还原:

1
gzip -dc backup.img.gz | dd of=/dev/sda

注意:gzip命令不会保留原文件,如果想保留原文件,可以使用重定向:

1
gzip < file > file.gz

关于“通过 dd 命令得到的 img 镜像文件”

挂载 img 文件

以 CentOS 为例

映射到 loop 设备
  1. 对于 MBR 磁盘使用如下命令即可:
    1
    
    losetup --find --partscan foo.img
    

    使用如下命令验证:

    1
    
    lsblk
    
  2. 对于 GPT 磁盘使用如下命令:

    1
    2
    
    losetup -f foo.img # 可以使用`losetup`命令验证
    kpartx -av /dev/loop0  
    

    同样使用lsblk命令验证:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    root@master:~# lsblk
    NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda         8:0    0   32G  0 disk
    ├─sda1      8:1    0    1G  0 part /boot
    ├─sda2      8:2    0   29G  0 part /
    └─sda3      8:3    0    2G  0 part [SWAP]
    loop0       7:0    0  710M  0 loop
    ├─loop0p1 253:0    0  200M  0 part
    ├─loop0p2 253:1    0    1M  0 part
    ├─loop0p3 253:2    0    1M  0 part
    └─loop0p4 253:3    0  500M  0 part
    

    也可以使用如下命令验证:

    1
    2
    
    root@master:~# ls /dev/mapper/
    loop0p1  loop0p2  loop0p3  loop0p4
    
挂载
1
mount /dev/mapper/loop0p1 /mnt/usb
卸载 img 文件
1
2
3
umount /dev/mapper/loop0*
kpartx -d /dev/loop0
losetup -D

更多其它的磁盘命令可以参考磁盘管理_Linux命令大全

resize img 文件

按前几节的内容挂载好 img 文件后,执行如下命令:

1
2
3
4
5
6
7
8
for part in /dev/mapper/loop0p*; do
    mount $part /mnt
    dd if=/dev/zero of=/mnt/filler conv=fsync bs=1M
    rm /mnt/filler
    umount /mnt
  done
dd: error writing ‘/mnt/filler’: No space left on device
dd: error writing ‘/mnt/filler’: No space left on device

详情参考: How to resize img file created with dd? - Super User

img 文件格式转换
  1. img to vdi。通过这个可以让u盘中的或者磁盘中的操作系统在虚拟机(我用的Virtual Box)中运行。亲测可行
    1
    
    VBoxManage convertdd dd-image.raw sda.vdi --format VDI
    

    可以使用如下命令查看相关帮助:

    1
    
    VBoxManage convertdd
    
  2. vdi to img。通过这个可以让虚拟机中的操作系统直接复制到u盘中运行。尚未尝试,不知是否可行
    1
    
    VBoxManage clonemedium sda.vdi dd-image.raw --format raw
    

    同样可以使用如下命令查看相关帮助:

    1
    
    VBoxManage clonemedium
    

遇到过的问题

又名踩过的坑

挂载 NTFS 文件系统

对于Ubuntu而言,通常无需手动安装 ntfs-3g(因为默认安装好了)。但是对于CentOS而言需要手动安装 nfs-3g

如果您使用的是CentOS / RHEL,则此软件包来自EPEL,因此,如果您尚未将系统配置为使用EPEL存储库,请运行以下命令。

1
2
3
yum install epel-release -y # ntfs-3g 来自 EPEL
yum install ntfs-3g -y
mount /dev/sda3 /mnt/usb

挂载 HFSPLUS 文件系统(mac OS)

参考 Mount HFS & HFSPLUS (Apple Filesystem Types) - CentOS

  1. 导入 GPG 密钥
    1
    
       rpm --import http://elrepo.org/RPM-GPG-KEY-elrepo.org
    
  2. 安装ELRepo
    1. 对于 CentOS-7:
      1
      
      rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
      
    2. 对于 CentOS-6:

      1
      
      rpm -Uvh https://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
      
  3. 安装kmod-hfs

    1
    
    yum install kmod-hfs
    
  4. 安装kmod-hfsplus

    1
    
    yum install kmod-hfsplus
    
  5. 安装hfsplus-tools

    1
    
    yum install hfsplus-tools
    
  6. 确认安装

    1
    
    rpm -qa | grep hfsplus
    
  7. 挂载
    1
    
    mount /dev/sda2 /mnt/usb
    

How can I monitor disk io?

使用 sysstat 包中sar命令和iostat命令即可

参见 linux - How can I monitor disk io? - Unix & Linux Stack Exchange

扩容分区?

1
2
3
4
# 先进行 VirtualBox 磁盘管理处扩容
sudo parted /dev/sdb resizepart 1 68G # 1代表分区,68G代表目标位置,最好使用 100% 来表达
sudo e2fsck -f /dev/sdb1 # 可选
sudo resize2fs /dev/sdb1 62G

执行上述命令前务必清楚每步的作用、传参的含义等信息,否则后果可能非常严重

2021-08-25 更新:另请参阅 Expanding a Linux disk with gparted (and getting swap out of the way)。该文章讲了一个相当复杂的例子,总结起来就是一句话:gparted无敌

2021-08-25 更新:另外 CentOS 中使用 LVM (逻辑卷管理)可能才是王道

2021-08-25 更新:最近发现日常使用的虚机 master 主盘空间经常不够,老是会浪费时间作手动删除工作,于是决定从根本上解决问题——扩容。但是却被各个问题难住了,下面大致说明经过:

  1. VirtualBox 磁盘管理处扩容到 64 G
  2. 虚机中fdisk -l发现/dev/sda空间依然只有 32 G。谷歌搜索virtualbox disk size not increasing,得到 virtualbox.org • View topic - Increasing disk size not workingVirtualBox Unable to Merge not Enough Free Storage Space - NEXTOFWINDOWS.COM,采用了后者的复制虚机方法解决了此问题
  3. 在复制后的虚机同样在 VirtualBox 磁盘管理处进行了扩容到 64 G 的操作后,进入虚机中fdisk -l发现/dev/sda空间变为了 64 G,即正常了
  4. 执行parted /dev/sda resizepart 2 68G,无任何提示,搜索后执行parted /dev/sda help resizepart发现同样没有输出,因此认为该版本 parted (3.1)不支持此命令
  5. 网上下载 Gparted Live CD 的 ISO 镜像,从该镜像启动,选择命令行界面(即 parted),再执行parted /dev/sda resizepart 2 68G,直接报错,大意是有个 swap 分区夹在中间,无法使用 resizepart 进行大小调整操作
  6. 网上搜索相关教程,发现了这篇文章:Expanding a Linux disk with gparted (and getting swap out of the way),概览后知道使用 gparted 可以进行复杂的分区大小调整
  7. 再次从前述的 Gparted Live CD 镜像启动,选择图形化界面(即 gparted),再根据前面得到的提示,进行分区大小调整,终获成功

get UUID in /etc/fstab?

1
sudo blkid

链接

下面总结了本文中使用的所有链接: