nbd (mount vm image)

最後更新: 2017-06-02

介紹

 

mount vm image 一般而言有以下目的

 - Troubleshoot a virtual machine that fails to boot.
 - Retrieve files after you've decided to stop using a virtual machine.

目錄

  • nbd server & client
  • KVM VM Instance connect nbd(XML)
  • mount vbox image (vdi) with vdfuse
  • mount vm image with qemu-nbd
  • kpartx
  • guestfish
  • guestmount - FUSE mount utility
  • Modify a single file inside of an image
  • Mount VM Image Example(lvm in image)

 


nbd server & client

 

Version

qemu-nbd -V

qemu-nbd 3.1.0 (Debian 1:3.1+dfsg-8+deb10u8)

Server

可用參數:

  • -t, --persistent     # Don't exit on the last connection
  • --fork                  # Fork off the server process and exit the parent once the server is running.
    ----
  • -p, --port=PORT     # Default: 10809
  • -b, --bind=iface      # Default: 127.0.0.1
    ----
  • -c, --connect=dev
    ----
  • -k, --socket=path
    ----
  • -r, --read-only
    ----
  • -f, --format=fmt     # The block driver for format fmt instead of auto-detecting
                                 # Automatically detecting the format is dangerous for raw images
    ----
  • --cache=cache
    -n, --nocache

 * 一個 Server 只可被 1 個 Client 連上 ! (-e, --shared=num, default 1)

i.e.

# Network (0.0.0.0:10809)

qemu-nbd -t --fork VM-IMAGE.vmdk

# Device

qemu-nbd -t --fork -f raw -t data1.raw -c /dev/nbd1      # raw image 必須加上 "-f raw"

# Unix Socket

qemu-nbd -t --fork -f raw data1.raw -k /var/lib/nbd/1

Client (Server->/dev/nbdN)

nbd-client <IP> [Port] /dev/nbd0

nbd-client -u unix-socket nbd-device         # 對應 Server 的 -k

-d, --disconnect DEV                                # Disconnect the specified nbd device from the server

Opts

-b     Use  a  blocksize of "block size". Default is 1024;

-c, -check     Check whether the specified nbd device is connected.

                    If the device is connected, print the PID of the nbd-client instance that connected it
                    (server 會 fork, 所以 PID 會有所不同)

                    If the device is not connected or does not exist, $?=1

-l     Ask the server for a list of available exports.

-p   nbd-client will immediately try to reconnect an nbd device

       if the connection ever drops unexpectedly due to a lost server

ie.

nbd-client -u /var/lib/nbd/1 /dev/nbd1

 


KVM VM Instance connect nbd(XML)

 

方式1: Network

XML

    <disk type='network' device='disk'>
      <driver name='qemu' type='raw'/>
      <source protocol='nbd'>
        <host name='127.0.0.1' port='10809'/>
      </source>
      <blockio logical_block_size='512' physical_block_size='4096'/>
      <target dev='sdb' bus='scsi'/>
    </disk>

Remark

1) nbd-server 必須 listen 好

方式2: Block device

XML

    <disk type='block' device='disk'>
      <driver name='qemu' type='raw'/>
      <source dev='/dev/nbd0'/>
      <target dev='sdb' bus='scsi'/>
    </disk>

Remark

1) Device disconect 後不可以再連

i.e.

qemu-nbd -t --fork -f raw data2.raw -k /var/lib/nbd/2
nbd-client -u /var/lib/nbd/2 /dev/nbd2
killall qemu-nbd
qemu-nbd -t --fork -f raw data2.raw -k /var/lib/nbd/2

當 KVM Instance 仍在執行時

nbd-client -c /dev/nbd2

27390

 


mount vbox image (vdi) with vdfuse

 

一般而言, 我們可以用以下其一工具去掛載 vdi image

  • virtualbox-ose-fuse
  • qemu-nbd

virtualbox-ose-fuse:

此 package 提供了以下工具

  • /usr/bin/vdfuse

它工作原理是透過 virtualbox 所提供的 API 把 HardDisk image 掛載上.

mount point 上包含了 Image 裡面不同的 partition ~

用它 mount 完後, 我們再 loop mount 它的 partition 到另一 mount point 就可用了 ~

支援格式有 VDI, VMDK, VHD, or raw

應用:

USAGE: vdfuse [options] -f image-file mountpoint

vdfuse -f winxp_sp3-ide8g.vdi /mnt/vboximg/

ls /mnt/vboximg/
EntireDisk  Partition1

mount -o loop /mnt/vboximg/Partition1 /mnt/partition

ls /mnt/partition
AUTOEXEC.BAT  Documents and Settings  ntldr WINDOWS
...........

 


mount vm image with qemu-nbd

 

# Check Version

qemu-nbd  -V                                     <-- Network Block Device Server

qemu-nbd version 0.0.1

載入 kernel module:

modprobe nbd                                    <-- network block device module

/dev/nbd*                                           <-- brw-rw---- 1 root disk 43, 0

使用:

qemu-nbd [OPTIONS] FILE

  • -r, --read-only
  • -n, --nocache
  • -c, --connect=DEV    <---- 把 FILE 看成 DEV
  • -p, --port=PORT       <---- default:10809
  • -b, --bind=IFACE      <---- default: 0.0.0.0
  • -P, --partition=NUM  only expose partition NUM
  • -d, --disconnect

掛載:

qemu-nbd -c /dev/nbd0 <vdi-file>

自動出現了:

ls /dev/nbd0*

nbd0p1  nbd0p2  nbd0p5

 * 當 p1, p2, p5 沒有 auto 出現時, 就要用 partprobe 或 kpartx 了

bind mount:

mount /dev/nbd0p1 /mnt

用完後:

qemu-nbd -d /dev/nbd0

/dev/nbd0 disconnected

 


kpartx

 

reads partition tables on specified device and create device maps over partitions segments detected

-l      # List partition mappings that would be added -a

-d     # Delete partition mappings

-a     # Add partition mappings

-v     # Operate verbosely

i.e.

kpartx -l /dev/nbd0

# Unit: Block
#          Size                Start
nbd0p1 : 0 209713152 /dev/nbd0 2048

# 在 "/dev/mapper/" 內建立了 nbd0p1

kpartx -av /dev/nbd0

mknod

 


guestfish

 

guestfish (libguestfs project) <-- shell

guestfish --rw -a centos63_desktop.img

# touch, chmod, and rm

# This will launch a virtual machine, which will be used to perform all of the file manipulations

><fs> run

><fs> list-filesystems

/dev/vda1: ext4
/dev/vg_centosbase/lv_root: ext4
/dev/vg_centosbase/lv_swap: swap

><fs> mount /dev/vg_centosbase/lv_root /

><fs> rm /etc/udev/rules.d/70-persistent-net.rules

><fs> edit /etc/sysconfig/network-scripts/ifcfg-eth0

><fs> exit

 


guestmount - FUSE mount utility

 

apt-get install guestmount

update-guestfs-appliance

guestmount --version

guestmount 1.18.1

Usage:

guestmount [--options] -a disk.img -i [--ro] mountpoint

i.e.

mkdir /mnt/centos6

guestmount -a centos63_desktop.qcow2 -m /dev/vg_centosbase/lv_root --rw /mnt

  • -a (--add) image
  • -m (--mount) dev               # Mount the named partition or logical volume on the given mountpoint in the guest
                                             # ( 沒有設定時, default mount "/" i.e. "-m /dev/sda1" )
  • --rw                                  # added and mounts are done read-write
  • -i (--inspector)                   # Using "virt-inspector" to inspect the disks, automatically determine what mount fs on VM

mkdir /mnt/centos6

guestmount -a centos6.qcow2 -i --rw /mnt/centos6

# unmount it:

guestunmount /mnt/centos6

 


Modify a single file inside of an image

 

virt-edit -d instance-000000e1 /etc/shadow

 


Mount VM Image Example(lvm in image)

 

  • lvm in raw image
  • lvm in qcow2 image

qcow2 image (qemu-nbd)

modprobe nbd max_part=16              # 即刻有 16 個 /dev/nbd*

qemu-nbd -c /dev/nbd0 image.qcow2

partprobe /dev/nbd0

ls /dev/nbd0*

/dev/nbd0  /dev/nbd0p1  /dev/nbd0p2  /dev/nbd0p3

blkid /dev/nbd0p*

/dev/nbd0p1: UUID="..." TYPE="xfs" PARTUUID="53e68b8c-01"
/dev/nbd0p2: UUID="..." TYPE="xfs" PARTUUID="53e68b8c-02"
/dev/nbd0p3: UUID="..." TYPE="swap" PARTUUID="53e68b8c-03"

mkdir /mnt/tmp;

mount -o ro /dev/nbd0p2 /mnt/tmp

Cleanup:

umount /mnt/tmp

qemu-nbd -d /dev/nbd0

/dev/nbd0 disconnected

lvm inside raw image (losetup)

loop mount

# find an unused loop device

losetup -f

/dev/loop0

losetup /dev/loop0 rhel62.img

kpartx -av /dev/loop0

LVM

vgscan

vgchange -ay

mkdir /mnt/tmp

mount /dev/vg_rhel62x8664/lv_root /mnt/tmp

Cleanup:

umount /mnt/tmp

vgchange -an vg_rhel62x8664

kpartx -d /dev/loop0

losetup -d /dev/loop0

 

 

 

 

 

Creative Commons license icon Creative Commons license icon