从磁盘映像中挂载或提取指定的 LVM 逻辑卷

2009-10-22

前面提到了如何从磁盘映像中挂载或提取指定分区,现在我们再看看如何从含有 LVM 分区的映像中挂载或提取指定的逻辑卷(LV)。由于 LVM 分区内部有自己的盘区(PE)分配方法,因此逻辑卷在映像中并不一定是物理连续的,不能通过找到其偏移地址直接挂载。不过只要本地系统安装了 LVM 支持,就可以使用 LVM 自带的实用工具完成硬盘映像中逻辑卷的挂载。

首先查看一下本地系统已经挂载过的物理卷(PV)、卷组(VG)和逻辑卷。我们看到,系统已经安装并激活了 VolGroup01 卷组。事实上 VolGroup01 中的 LogVol00 是本地系统的根分区,LogVol01 是交换分区。

[root@centos CentOS]# pvscan
  PV /dev/sda2   VG VolGroup01   lvm2 [136.00 GB / 0    free]
  Total: 1 [136.00 GB] / in use: 1 [136.00 GB] / in no VG: 0 [0   ]
[root@centos CentOS]# vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "VolGroup01" using metadata type lvm2
[root@centos CentOS]# lvscan
  ACTIVE            '/dev/VolGroup01/LogVol00' [134.06 GB] inherit
  ACTIVE            '/dev/VolGroup01/LogVol01' [1.94 GB] inherit

实验使用的 centos5-2-gnome.img 是一个安装了 CentOS 并通过 LVM 管理磁盘的映像文件。使用 fdisk 命令查看其分区结构,其中 centos5-2-gnome.img2 是 LVM 分区,fdisk 不能提供 LVM 的详细信息。

[root@centos CentOS]# fdisk -l -u centos5-2-gnome.img
last_lba(): I don't know how to handle files with mode 81a4
You must set cylinders.
You can do this from the extra functions menu.

Disk centos5-2-gnome.img: 0 MB, 0 bytes
255 heads, 63 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes

      Device Boot      Start         End      Blocks   Id  System
centos5-2-gnome.img1   *          63      208844      104391   83  Linux
centos5-2-gnome.img2          208845     8385929     4088542+  8e  Linux LVM

使用 Linux 的 loop 设备控制命令——losetup:首先用 -f 参数查找一个空闲的 loop 节点;然后通过 -o 参数指定 LVM 分区在映像中的偏移量(参考 fdisk 的输出),将其挂载在空闲的 loop 节点上;最后使用 -a 参数确认挂载成功。

[root@centos CentOS]# losetup -f
/dev/loop4
[root@centos CentOS]# losetup -o $((208845*512)) /dev/loop4 centos5-2-gnome.img
[root@centos CentOS]# losetup -a
...
/dev/loop4: [fd00]:26706086 (centos5-2-gnome.img), offset 106928640

再一次查看系统中存在的 LVM 设施。我们看到,映像中的 VolGroup00 卷组已被扫描到,其中有 LogVol00、LogVol01 两个未激活的分区。

[root@centos CentOS]# pvscan
  PV /dev/loop4   VG VolGroup00   lvm2 [3.88 GB / 0    free]
  PV /dev/sda2    VG VolGroup01   lvm2 [136.00 GB / 0    free]
  Total: 2 [139.88 GB] / in use: 2 [139.88 GB] / in no VG: 0 [0   ]
[root@centos CentOS]# vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "VolGroup00" using metadata type lvm2
  Found volume group "VolGroup01" using metadata type lvm2
[root@centos CentOS]# lvscan
  inactive          '/dev/VolGroup00/LogVol00' [2.91 GB] inherit
  inactive          '/dev/VolGroup00/LogVol01' [992.00 MB] inherit
  ACTIVE            '/dev/VolGroup01/LogVol00' [134.06 GB] inherit
  ACTIVE            '/dev/VolGroup01/LogVol01' [1.94 GB] inherit

这个例子中,映像中的卷组与本地已挂载的卷组名称不同,不会出现歧义。但如果映像中的卷组恰与本地已挂载的卷组重名,则可以使用 vgrename 命令修改映像中的卷组名称。

[root@centos CentOS]# vgrename --help
  vgrename: Rename a volume group

vgrename
  [-A|--autobackup y|n]
  [-d|--debug]
  [-h|--help]
  [-t|--test]
  [-v|--verbose]
  [--version]
  OldVolumeGroupPath NewVolumeGroupPath |
  OldVolumeGroupName NewVolumeGroupName

使用 vgchange 命令激活 VolGroup00 卷组,再次查看逻辑卷的状态,LogVol00、LogVol01 已经可用。

[root@centos CentOS]# vgchange -ay VolGroup00
  2 logical volume(s) in volume group "VolGroup00" now active
[root@centos CentOS]# lvscan
  ACTIVE            '/dev/VolGroup00/LogVol00' [2.91 GB] inherit
  ACTIVE            '/dev/VolGroup00/LogVol01' [992.00 MB] inherit
  ACTIVE            '/dev/VolGroup01/LogVol00' [134.06 GB] inherit
  ACTIVE            '/dev/VolGroup01/LogVol01' [1.94 GB] inherit

现在便可以使用 lvscan 输出的逻辑卷设备文件名来挂载对应的文件系统了。

[root@centos CentOS]# mount /dev/VolGroup00/LogVol00 ./part/
[root@centos CentOS]# ls ./part/
bin  boot  dev  etc  home  lib  lost+found  media  misc  mnt
net  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
[root@centos CentOS]# umount ./part/

如果要提取其中的分区,也可以直接对逻辑卷设备文件或 /dev/mapper/ 下对应的设备文件操作。

[root@centos CentOS]# dd if=/dev/VolGroup00/LogVol00 of=LogVol00.img
6094848+0 records in
6094848+0 records out
3120562176 bytes (3.1 GB) copied, 113.93 seconds, 27.4 MB/s

试挂载提取出来的分区。

[root@centos CentOS]# mount -o loop LogVol00.img ./part/
[root@centos CentOS]# ls ./part/
bin  boot  dev  etc  home  lib  lost+found  media  misc  mnt
net  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
[root@centos CentOS]# umount ./part/

卸载文件系统之后,别忘了卸载卷组和 loop 节点。

[root@centos CentOS]# vgchange -an VolGroup00
  0 logical volume(s) in volume group "VolGroup00" now active
[root@centos CentOS]# losetup -d /dev/loop4