使用虚拟机时, 发现想要修改虚拟机中的文件非常麻烦, 需要启动虚拟机, 然后再登录进去修改.

对于已经关闭的虚拟机, 为了修改一个文件而启动, 非常耽误时间.

对于一个无法启动的虚拟机(比如启动文件损坏), 则束手无策.

因此, 掌握在主机中挂载 Guest 的操作系统磁盘, 并修改其中的内容的方法在某些时候会非常有用.

1. 挂载 Guest 操作系统磁盘的方法

挂载 Guest 操作系统磁盘的方法主要有以下3种:

  1. guestfish : 支持lvm, 速度较慢
  2. lomount   : 不支持lvm, 速度快
  3. kpartx    : 支持lvm, 速度快

使用上述3种工具之前, 我先安装了2个 kvm 虚拟机, 都是debian7.6 x86_64, 一个是普通分区, 一个是LVM分区.

2个系统的磁盘在默认路径中

root@debian-:~# ll /var/lib/libvirt/images
total
-rw------- root root Sep : debian7..img
-rw------- root root Sep : debian7.-lvm.img

2. 方法1 - guestfish

2.1 使用 guestfish 对 普通Guest的磁盘进行一些基本的操作

root@debian-:~# apt-get install guestfish            <-- 安装 guestfish 工具包, 中途跳出一个选择画面, 选择no
root@debian-:~# guestfish <-- 进入 guestfish Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems. Type: 'help' for help on commands
'man' to read the manual
'quit' to quit the shell ><fs> add /var/lib/libvirt/images/debian7..img <-- 挂载 debian7.6的系统磁盘(非LVM分区)
><fs> launch <-- 启动Guest, 这里会慢一些, 如果有错误, 参见下面的 *注1*
% ⟦------------------⟧ :
><fs> list-devices <-- 查看 Guest 中的磁盘
/dev/vda ><fs> sfdisk-l /dev/vda <-- 查看 Guest 中的磁盘分区 Disk /dev/vda: cylinders, heads, sectors/track
Units = cylinders of bytes, blocks of bytes, counting from Device Boot Start End #cyls #blocks Id System
/dev/vda1 * + - - Linux <-- 这个应该是根分区 /
/dev/vda2 + - - Extended
/dev/vda3 - Empty
/dev/vda4 - Empty
/dev/vda5 + - - Linux swap / Solaris
/dev/vda6 + - - Linux <-- 这个应该是home分区 /home ><fs> mount /dev/vda6 / <-- 挂载 Guest 操作系统磁盘
><fs> ls / <-- 显示挂载的内容, 就是Guest的 /home
lost+found
wangyubin # Guest磁盘上新建文件
><fs> touch /wangyubin/guestfish <-- Guest的磁盘上新建一个文件
><fs> vi /wangyubin/guestfish <-- 编辑这个文件, 输入 test guestfish # 将Host上的hostname文件上传到Guest的 /home/wangyubin/from-host
><fs> upload /etc/hostname /wangyubin/from-host # 卸载 Guest 的/home分区, 重新挂载Guest的 / 分区
><fs> mounts
/dev/vda6
><fs> umount /dev/vda6
><fs> mount /dev/vda1 /
><fs> ls /
bin
boot
dev
etc
home
initrd.img
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
selinux
srv
sys
tmp
usr
var
vmlinuz # 将 Guest上的 hostname 文件下载到 Host的 /home/from-guest
><fs> download /etc/hostname /home/from-guest # 卸载Guest磁盘, 退出 guestfish
><fs> mounts
/dev/vda1
><fs> umount /dev/vda1
><fs> quit

*注1* guestfish中, launch时出现错误的解决方法:

><fs> launch
febootstrap-supermin-helper: ext2: parent directory not found: /lib: File not found by ext2_lookup
libguestfs: error: external command failed, see earlier error messages
><fs> quit root@debian:~# update-guestfs-appliance

2.2 验证 guestfish 对普通磁盘的修改结果

1. HOST - 验证是否有 Guest的hostname文件, 并且内容正确?

root@debian-:~# cat /home/from-guest      <-- 内容正确, 参见下面cat出的Guest上的hostname
debian
root@debian-:~# cat /etc/hostname <-- Host的hostname内容, 用于验证 from-host的内容
debian-

2. GUEST - 验证是否有新建的文件? 是否有 Host的hostname文件, 并且内容正确?

# virt-manager 启动 guest之后, 登录进去执行以下命令
root@debian:~# ls /home/wangyubin/ <-- 新建的文件和upload的文件都在
from-host guestfish
root@debian:~# cat /home/wangyubin/from-host <-- 内容正确, 参见上面cat出的Host上的hostname
debian-
root@debian:~# cat /home/wangyubin/guestfish <-- 新建的文件内容正确
test guestfish
root@debian:~# cat /etc/hostname <-- Guest的hostname内容, 用于验证 from-guest的内容
debian

2.3 使用 guestfish 对 LVM分区的Guest磁盘进行一些基本的操作

root@debian-:~# guestfish 

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems. Type: 'help' for help on commands
'man' to read the manual
'quit' to quit the shell ><fs> add /var/lib/libvirt/images/debian7.-lvm.img
><fs> launch
><fs> list-devices
/dev/vda
><fs> sfdisk-l /dev/vda Disk /dev/vda: cylinders, heads, sectors/track
Units = cylinders of bytes, blocks of bytes, counting from Device Boot Start End #cyls #blocks Id System
/dev/vda1 * + - - Linux
/dev/vda2 + - - Extended
/dev/vda3 - Empty
/dev/vda4 - Empty
/dev/vda5 + - - 8e Linux LVM <-- 这里看出是LVM ><fs> lvs <-- 查看LVM的逻辑卷
/dev/debian/home
/dev/debian/root
/dev/debian/swap_1 ><fs> mount /dev/debian/home / <-- 挂载 /home 对应的LVM逻辑卷
><fs> ls /
lost+found
wangyubin # Guest磁盘上新建文件 - 步骤同上面普通磁盘
><fs> touch /wangyubin/guestfish-lvm <-- Guest的磁盘上新建一个文件
><fs> vi /wangyubin/guestfish-lvm <-- 编辑这个文件, 输入 test guestfish lvm # 将Host上的hostname文件上传到Guest的 /home/wangyubin/from-host-lvm
><fs> upload /etc/hostname /wangyubin/from-host-lvm # 卸载 Guest 的/home分区, 重新挂载Guest的 / 分区 都是LVM格式
><fs> mounts
/dev/debian/home
><fs> umount /dev/debian/home
><fs> lvs
/dev/debian/home
/dev/debian/root
/dev/debian/swap_1
><fs> mount /dev/debian/root /
><fs> ls /
bin
boot
dev
etc
home
initrd.img
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
selinux
srv
sys
tmp
usr
var
vmlinuz # 将 Guest上的 hostname 文件下载到 Host的 /home/from-guest-lvm
><fs> download /etc/hostname /home/from-guest-lvm # 卸载Guest磁盘, 退出 guestfish
><fs> mounts
/dev/debian/root
><fs> umount /dev/debian/root
><fs> quit

2.4 验证 guestfish 对LVM磁盘的修改结果

1. HOST - 验证是否有 Guest的hostname文件, 并且内容正确?

root@debian-:~# cat /home/from-guest-lvm      <-- 内容正确, 参见下面cat出的Guest上的hostname
debian
root@debian-:~# cat /etc/hostname <-- Host的hostname内容, 用于验证 from-host的内容
debian-

2. GUEST - 验证是否有新建的文件? 是否有 Host的hostname文件, 并且内容正确?

# virt-manager 启动 guest之后, 登录进去执行以下命令
root@debian:~# ls /home/wangyubin/ <-- 新建的文件和upload的文件都在
from-host-lvm guestfish-lvm
root@debian:~# cat /home/wangyubin/from-host-lvm <-- 内容正确, 参见上面cat出的Host上的hostname
debian-
root@debian:~# cat /home/wangyubin/guestfish-lvm <-- 新建的文件内容正确
test guestfish lvm
root@debian:~# cat /etc/hostname <-- Guest的hostname内容, 用于验证 from-guest的内容
debian

3. 方法2 - lomount

lomount是Xen环境下的工具, 挂载Guest的操作系统磁盘时比guestfish要快很多, 但是不支持lvm.

由于没有Xen的环境, 这里就不尝试了.

4. 方法3 - kpartx

首先, 安装 kaprtx

root@debian-:~# apt-get install kpartx

4.1 使用 kpartx 对 普通分区的Guest磁盘进行一些基本的操作

root@debian-:~# kpartx -av /var/lib/libvirt/images/debian7..img
add map loop0p1 (:): linear /dev/loop0 <-- 这个是根分区 /
add map loop0p2 (:): linear /dev/loop0
add map loop0p5 : linear :
add map loop0p6 : linear : <-- 这个是分区 /home # 挂载磁盘
root@debian-:~# mount /dev/mapper/loop0p1 /mnt/ <-- *注2*
root@debian-:~# ll /mnt/
total
drwxr-xr-x root root Sep : bin
drwxr-xr-x root root Sep : boot
drwxr-xr-x root root Sep : dev
drwxr-xr-x root root Sep : etc
drwxr-xr-x root root Sep : home
lrwxrwxrwx root root Sep : initrd.img -> /boot/initrd.img-3.2.--amd64
drwxr-xr-x root root Sep : lib
drwxr-xr-x root root Sep : lib64
drwx------ root root Sep : lost+found
drwxr-xr-x root root Sep : media
drwxr-xr-x root root Jun : mnt
drwxr-xr-x root root Sep : opt
drwxr-xr-x root root Jun : proc
drwx------ root root Sep : root
drwxr-xr-x root root Sep : run
drwxr-xr-x root root Sep : sbin
drwxr-xr-x root root Jun selinux
drwxr-xr-x root root Sep : srv
drwxr-xr-x root root Jul sys
drwxrwxrwt root root Sep : tmp
drwxr-xr-x root root Sep : usr
drwxr-xr-x root root Sep : var
lrwxrwxrwx root root Sep : vmlinuz -> boot/vmlinuz-3.2.--amd64 # 卸载磁盘
root@debian-:~# umount /mnt

*注2* kpartx 可以将Guest的磁盘挂载到主机的某个目录下 (比如上述例子就是 /mnt),

不像 guestfish 只能将Guest的磁盘挂载到 /

因此, 对于 kpartx 来说, 不需要 download 和 upload 命令, 操作 Guest 磁盘中的文件就和挂载了U盘一样.

4.2 使用 kpartx 对 LVM分区的Guest磁盘进行一些基本的操作

root@debian-:~# kpartx -av /var/lib/libvirt/images/debian7.-lvm.img
add map loop1p1 (:): linear /dev/loop1
add map loop1p2 (:): linear /dev/loop1
add map loop1p5 : linear : <-- 这是 lvm 分区 root@debian-:~# vgscan <-- 通过 lvm 相关命令查看 lvm分区信息
Reading all physical volumes. This may take a while...
Found volume group "debian" using metadata type lvm2
root@debian-:~# vgs <-- 通过 lvm 相关命令查看 lvm分区信息
VG #PV #LV #SN Attr VSize VFree
debian wz--n- .76g
root@debian-:~# lvs <-- 通过 lvm 相关命令查看 lvm分区信息
LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert
home debian -wi----- .06g
root debian -wi----- .40g
swap_1 debian -wi----- 300.00m root@debian-:~# vgchange -ay debian <-- 激活lvm分区
logical volume(s) in volume group "debian" now active root@debian-:~# mount /dev/debian/root /mnt/ <-- 挂载 lvm中的根分区 /
root@debian-:~# ll /mnt/
total
drwxr-xr-x root root Sep : bin
drwxr-xr-x root root Sep : boot
drwxr-xr-x root root Sep : dev
drwxr-xr-x root root Sep : etc
drwxr-xr-x root root Sep : home
lrwxrwxrwx root root Sep : initrd.img -> /boot/initrd.img-3.2.--amd64
drwxr-xr-x root root Sep : lib
drwxr-xr-x root root Sep : lib64
drwx------ root root Sep : lost+found
drwxr-xr-x root root Sep : media
drwxr-xr-x root root Jun : mnt
drwxr-xr-x root root Sep : opt
drwxr-xr-x root root Jun : proc
drwx------ root root Sep : root
drwxr-xr-x root root Sep : run
drwxr-xr-x root root Sep : sbin
drwxr-xr-x root root Jun selinux
drwxr-xr-x root root Sep : srv
drwxr-xr-x root root Jul sys
drwxrwxrwt root root Sep : tmp
drwxr-xr-x root root Sep : usr
drwxr-xr-x root root Sep : var
lrwxrwxrwx root root Sep : vmlinuz -> boot/vmlinuz-3.2.--amd64 root@debian-:~# umount /mnt <-- 卸载分区

5. 总结

lomount 由于没有环境, 没有实验.

对于 guestfish 和 kpartx来说, 感觉无论是速度还是易用性上, 都是 kpartx 胜出.

挂载KVM Guest操作系统磁盘的更多相关文章

  1. VMware Linux Guest 增加磁盘无需重启的方法

    摘要     常常需要需要给VMware Linux Guest增加磁盘适配一些测试场景,而又不想花费时间重启Guest,查找文档,发现一种简单的方法,记录一下操作步骤. 操作步骤 1 编辑Linux ...

  2. QEMU命令创建KVM Guest(bridge桥接)

    1. Check QEMU version [root@pqsfc018 ~]# /usr/bin/qemu-system-x86_64 -version QEMU emulator version ...

  3. 在GNU/Linux下使用命令行自动挂载与卸载USB磁盘

    在命令行环境下如果每次都是靠手动敲入mount与umount命令来挂载与卸载USB磁盘是件很麻烦的事情.尤其是mount命令的参数非常多.比如,磁盘的分区类型(vfat.ntfs等),挂载的目录节点, ...

  4. kvm虚拟机扩展磁盘空间

    kvm虚拟机磁盘空间扩展与xen虚拟机磁盘空间扩展思路一致.原因在于xen/kvm默认的虚拟机磁盘格式为raw,所以方式可以通用. raw磁盘格式扩展思路如下 (1) 新添加一块raw格式的磁盘加入到 ...

  5. KVM guest caching modes

    kvm中host和guest各自维护自己的page caches,使得内存中有两份缓存数据.host的缓存为page cache可以理解为读缓存,guest的缓存为disk write cache,可 ...

  6. KVM之XFS磁盘扩容

    1.前言 根据目前我们使用的需求,以前规划的100G磁盘空间不够,这里将演示XFS文件系统的扩容,因为我使用的是KVM所以也会演示KVM的扩容方式. 2.KVM磁盘扩容 扩容前一定要先备份,或者做快照 ...

  7. centos 6.5 x64创建并挂载使用iscsi共享磁盘

    前景摘要:NFS或iSCSI,哪个更好?文件 vs 块NFS使用文件级别的实施,服务器或存储阵列托管整个文件系统,客户到文件系统上读写文件,可以在阵列端对主存储数据进行重复数据删除.iSCSI和FC则 ...

  8. 对VM挂载新加入的磁盘

    在虚拟机配置中增加磁盘后,启动Linux,使用root登录. 首先查看未分区的磁盘,使用下面命令: ## 查看未使用的磁盘 fdisk -l 磁盘/dev/sdb后面没有任何分区,是新挂载的磁盘 输入 ...

  9. CentOS 6U7分区大于2TB的磁盘以及挂载大于16TB分区磁盘的解决方案

    一.内容介绍1.问题描述1).问题一 CentOS 6.x 在格式化大于16TB的ext4分区时,会提示如下错误: mke2fs 1.41.12 (17-May-2010)mkfs.ext4: Siz ...

随机推荐

  1. Spring Cloud Stream如何处理消息重复消费?

    最近收到好几个类似的问题:使用Spring Cloud Stream操作RabbitMQ或Kafka的时候,出现消息重复消费的问题.通过沟通与排查下来主要还是用户对消费组的认识不够.其实,在之前的博文 ...

  2. C#获取某一路径下的所有文件名信息(包括子文件夹)

    前言:初步梳理记录,以后慢慢总结更多的方法... 方法一:使用微软提供的方法:Dicrectory类中的:public static string[] GetFiles(string path, st ...

  3. ASPxGridView中Command列自定义按钮点击事件概要

    其中CustomButtonClick="ButtonClick",e.buttonID可以获取到自定义按钮的id e.visibleIndex获取到行的索引 grdList.Ge ...

  4. SET XACT_ABORT ON是什么?

    避免自己遗忘,在这里做个笔记: SET XACT_ABORT ON:强制事务回滚,如果不加这句的话事务有可能回滚失败.

  5. T-SQL基础(五)之增删改

    在前面的文章中对T-SQL的查询做了基本总结,接下来我们看下SQL中的另外一个常用操作——数据的修改. INSERT INSERT 向数据表中插入数据的基本语句,句式: INSERT INTO tab ...

  6. 第五讲 smart qq poll包处理 以及 私聊 群聊消息收发

    发送 poll包 public static void Login_PostPoll() { try { string url = "http://d1.web2.qq.com/channe ...

  7. SpringBoot简介

    Spring Boot,简单讲就是牺牲项目的自由度来减少配置的复杂度(“契约式编程”思想,SpringBoot自动配置方案的指导思想).约定一套规则,把这些框架都自动配置集成好,从而达到“开箱即用”. ...

  8. TCP连接与释放

    TCP连接的建立 三次握手 TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态. TCP客户进程也是先创建传输控制块TCB,然后向服务器 ...

  9. 封装个 Android 的高斯模糊组件

    本篇文章已授权微信公众号 hongyangAndroid (鸿洋)独家发布 最近基于 Android StackBlur 开源库,根据自己碰到的需求场景,封装了个高斯模糊组件,顺便记录一下. 为什么要 ...

  10. C#反射、方法调用、自动调用方法、根据按钮名称调用方法、C#按钮权限管理

    根据按钮名称,直接调用方法,适用于用户对按钮的操作权限管理. /// <summary> /// 菜单按钮点击事件 /// </summary> void usrMenu1_U ...