Tag Archives: virt-list-filesystems

Notes on producing a minimal, compressed filesystem

You can save the minimal, compressed filesystem from a guest in a way that lets you reconstruct that filesystem (or guest) later very quickly. I’m writing an experimental tool called virt-builder which will make this automatic, but here’s how to make the minimal, compressed filesystem manually.

I’m starting here with a freshly installed Fedora 13 i686 guest. Firstly we see what filesystems it contains:

$ virt-list-filesystems -al /dev/vg_pin/TmpF13
/dev/sda1 ext4
/dev/vg_virtbuilder/lv_root ext4
/dev/vg_virtbuilder/lv_swap swap

We have a boot partition (/dev/sda1), a root filesystem (/dev/vg_virtbuilder/lv_root), and a swap partition. We can just ignore swap since it doesn’t contain any information and we can reconstruct it at will.

There is also some extra information “hidden” in the disk and not in a partition, namely the boot sector, partition table, and (maybe) GRUB stages. For this guest just the boot sector is interesting, other guests may have a boot loader located between the boot sector and the first partition. I’m going to ignore these for now, although virt-builder will need to restore this in order to make a bootable guest.

Let’s grab the boot and root partitions using guestfish:

$ guestfish --ro -i -a /dev/vg_pin/TmpF13 \
    download /dev/sda1 fedora-13-i686-boot.img
$ guestfish --progress --ro -i -a /dev/vg_pin/TmpF13 \
    download /dev/vg_virtbuilder/lv_root fedora-13-i686-root.img
 100% ⟦▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉⟧ 00:00

The boot partition is small enough that I’m just going to leave it as it is for now. But I need to shrink the root filesystem. The reason is that I might want to restore this to a different-sized, possibly smaller guest than the one I just created. There is only about 2GB of data in the root filesystem, but as an ext4 filesystem it is taking up about 6GB of space. The resize2fs command has a handy -M option which makes this very simple:

$ e2fsck -f fedora-13-i686-root.img
e2fsck 1.41.12 (17-May-2010)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Fedora-13-i686-L: 91151/368640 files (0.1% non-contiguous), 531701/1458176 blocks
$ resize2fs -M fedora-13-i686-root.img
resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on fedora-13-i686-root.img to 520344 (4k) blocks.
The filesystem on fedora-13-i686-root.img is now 520344 blocks long.

Note that new size: 520344 x 4k blocks = 2081376k. We can therefore truncate the file down to the new size without any loss of information:

$ truncate -s 2081376k fedora-13-i686-root.img
$ ls -lh
total 2.5G
-rw-rw-r--. 1 rjones rjones 500M Oct 30 10:21 fedora-13-i686-boot.img
-rw-rw-r--. 1 rjones rjones 2.0G Oct 30 10:30 fedora-13-i686-root.img

I haven’t finished yet. I now need to compress both filesystems so I have something small(ish) and portable. I performed some tests, and xz was the clear winner in terms of final compressed size, although it does take a very long time to run with the -9 option.

$ xz -9 *.img
$ ls -lh
total 652M
-rw-rw-r--. 1 rjones rjones 250M Oct 30 10:21 fedora-13-i686-boot.img.xz
-rw-rw-r--. 1 rjones rjones 403M Oct 30 10:30 fedora-13-i686-root.img.xz

From the two files above, plus the boot sector stuff that I glossed over, it is possible to reconstruct a Fedora 13 VM of any dimensions quickly (in about 1 minute 15 seconds on my machine). Note the comments are not part of the command, and the guest is fully bootable:

guestfish -x -- \
# create a disk image of any size
  alloc test.img 10G : \
  run : \
# create the partitions
  part-init /dev/sda mbr : \
  part-add /dev/sda primary 2048 1026047 : \
  part-add /dev/sda primary 1026048 -64 : \
# upload the boot loader
  upload fedora-13-i686-grub.img /dev/sda : \
# upload the boot partition
  upload <( xzcat fedora-13-i686-boot.img.xz ) /dev/sda1 : \
# create the logical volumes for root and swap
  pvcreate /dev/sda2 : \
  vgcreate vg_virtbuilder /dev/sda2 : \
  lvcreate lv_swap vg_virtbuilder 512 : \
  lvcreate lv_root vg_virtbuilder 256 : \
  lvresize-free /dev/vg_virtbuilder/lv_root 100 : \
# make fresh swap
  mkswap /dev/vg_virtbuilder/lv_swap : \
# upload and resize the root filesystem
  upload <( xzcat fedora-13-i686-root.img.xz ) /dev/vg_virtbuilder/lv_root : \
  resize2fs /dev/vg_virtbuilder/lv_root

2 Comments

Filed under Uncategorized

New in guestfish 1.5.15: “list-filesystems”

Previously if you used guestfish on an unknown disk image you had to use several commands to examine the disk (video demonstration). In the new development version guestfish 1.5.15 it’s easier, just use the list-filesystems command like this:

$ guestfish -a disk.img --ro

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for a list of commands
      'man' to read the manual
      'quit' to quit the shell

><fs> run
><fs> list-filesystems
/dev/vda1: ext2
/dev/debian5x64/home: ext3
/dev/debian5x64/root: ext3
/dev/debian5x64/swap_1: swap
/dev/debian5x64/tmp: ext3
/dev/debian5x64/usr: ext3
/dev/debian5x64/var: ext3

and straight away from this you know what you could mount, for example:

><fs> mount-options "" /dev/debian5x64/home /
><fs> ll /
total 28
drwxr-xr-x  4 root root  4096 May 14  2009 .
drwxr-xr-x 20  500  500  4096 Sep 15 20:17 ..
drwx------  2 root root 16384 May 14  2009 lost+found
drwxr-xr-x  7 1000 1000  4096 Oct  9  2009 rjones
><fs> !mkdir /tmp/rjones
><fs> copy-out /rjones /tmp/rjones

Leave a comment

Filed under Uncategorized

Tip: Use guestfish to look inside an Arch Linux ISO

Simples!

$ guestfish --ro -a archlinux-2010.05-core-x86_64.iso

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for a list of commands
      'man' to read the manual
      'quit' to quit the shell

><fs> run
><fs> list-devices
/dev/vda
><fs> list-partitions
/dev/vda1
><fs> vfs-type /dev/vda1
udf
><fs> mkmountpoint /iso
><fs> mkmountpoint /root
><fs> mount /dev/vda1 /iso
><fs> ll /iso
total 334378
dr-xr-xr-x 3 root root       296 May 16 15:00 .
drwxr-xr-x 4 root root      4096 Sep 13 19:14 ..
dr-xr-xr-x 3 root root       556 May 16 14:53 boot
-r--r--r-- 1 root root 179900416 May 16 15:00 core-pkgs.sqfs
-r--r--r-- 1 root root       454 May 16 15:00 isomounts
-r--r--r-- 1 root root      8192 May 16 14:55 overlay.sqfs
-r--r--r-- 1 root root 162484224 May 16 14:55 root-image.sqfs
><fs> mount-loop /iso/root-image.sqfs /root
><fs> ll /root
total 5
drwxr-xr-x 20 root root  302 May 16 14:51 .
drwxr-xr-x  4 root root 4096 Sep 13 19:14 ..
-rw-r--r--  1 root root   11 May 16 14:51 .arch-chroot
drwxr-xr-x  2 root root 1158 May 16 14:51 bin
drwxr-xr-x  4 root root   82 May 16 14:51 boot
drwxr-xr-x  2 root root   54 May 16 14:50 dev
drwxr-xr-x 33 root root 1715 May 16 14:51 etc
drwxr-xr-x  2 root root    3 Feb 26  2010 home
drwxr-xr-x  8 root root 3486 May 16 14:51 lib
drwxr-xr-x  2 root root   63 Apr 16 12:51 lib64
drwxr-xr-x  5 root root   46 Feb 26  2010 media
drwxr-xr-x  2 root root    3 Feb 26  2010 mnt
drwxr-xr-x  2 root root    3 Feb 26  2010 opt
drwxr-xr-x  2 root root    3 May 16 14:42 proc
drwxr-x---  2 root root    3 Feb 26  2010 root
drwxr-xr-x  2 root root 3251 May 16 14:51 sbin
drwxr-xr-x  4 root root   38 Feb 26  2010 srv
drwxr-xr-x  2 root root    3 May 16 14:42 sys
drwxrwxrwt  2 root root    3 May 16 14:51 tmp
drwxr-xr-x  9 root root  149 May 16 14:50 usr
drwxr-xr-x 13 root root  159 May 16 14:51 var

Explanation:

  1. guestfish --ro -a foo.iso opens “foo.iso” (or any disk image) read only.
  2. list-devices and list-partitions are ways to see what there is in a disk image. You can also use virt-list-filesystems.
  3. vfs-type looks at a partition or other device and tells us what sort of filesystem it contains. UDF is the format used by DVDs.
  4. Install CDs typically contained nested filesystems, nested squashfs filesystems in this case, so we use mkmountpoint to create some more mountpoints (because we can’t just mount everything on the root mountpoint).
  5. mount mounts the first partition.
  6. mount-loop loopback mounts the root-image squashfs filesystem from the file.

Previously and previously.

1 Comment

Filed under Uncategorized

guestfish -i, that’s i for “inspector” not “interactive”

I wrote this FAQ entry today …


  • What’s the deal with guestfish -i?
  • Why does virt-cat only work on a real VM image, but virt-df works on any disk image?
  • What does “no root device found in this operating system image” mean?

These questions are all related at a fundamental level which may not be immediately obvious.

At the libguestfs API and guestfish level, a “disk image” is just a pile of partitions and filesystems.

In contrast, when the virtual machine boots, it mounts those filesystems into a consistent hierarchy such as:

 /          (/dev/sda2)
 |
 +-- /boot  (/dev/sda1)
 |
 +-- /home  (/dev/vg_external/Homes)
 |
 +-- /usr   (/dev/vg_os/lv_usr)
 |
 +-- /var   (/dev/vg_os/lv_var)

(or drive letters on Windows).

The libguestfs API however knows nothing about how filesystems are mounted. In general, a disk image that we just made up might not contain an operating system or “mountpoints” at all.

Nevertheless, users expect some tools (like virt-cat) to work with VM paths:

virt-cat fedora.img /var/log/messages

How does virt-cat know that /var is a separate partition?

The trick is a large external program called virt-inspector. Virt-inspector contains all sorts of tests and heuristics, so it can take a disk image about which nothing is known beforehand and work out both what it is, and how filesystems would be mounted.

Some tools, such as virt-cat, virt-edit, virt-ls and virt-tar use the same virt-inspector code to map VM paths. Other tools, such as virt-df and virt-list-filesystems operate entirely at the raw “big pile of filesystems” level of the libguestfs API, and don’t use virt-inspector code.

guestfish is in an interesting middle ground. If you use the -a and -m command line options, then you have to tell guestfish exactly how to add disk images and where to mount partitions. This is the raw API level.

However there is also a guestfish -i (for “inspector”) mode. In this mode, guestfish runs virt-inspector, and then (if successful) virt-inspector runs guestfish a second time with the correct -a and -m options. This is much slower, but usually simpler for the user. They can just do this and it all works:

guestfish -i SomeLibvirtGuest

The error “no root device found in this operating system image” is related to this. It means virt-inspector was unable to locate an operating system within the disk image you gave it. You might see this from programs like virt-cat if you try to run them on something which is just a disk image, not a virtual machine.

2 Comments

Filed under Uncategorized

Tip: extract a filesystem from a disk image

You’ve got a partitioned disk image, how do you pull out of that just the filesystem(s)? It’s easy with libguestfs tools:

$ virt-list-filesystems -al disk.img
/dev/sda1 ext4
/dev/vg_f12x32/lv_root ext4
/dev/vg_f12x32/lv_swap swap
$ virt-cat disk.img /dev/sda1 > boot.fs
$ file boot.fs
boot.fs: Linux rev 1.0 ext4 filesystem data (extents) (huge files)
$ virt-cat disk.img /dev/vg_f12x32/lv_root > root.fs

You can also use guestfish to examine the filesystem image:

$ guestfish -a boot.fs -m /dev/sda

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for help with commands
      'quit' to quit the shell

><fs> ll /
total 15941
dr-xr-xr-x.  5 root root     1024 Mar  8 19:37 .
dr-xr-xr-x  19 root root        0 Mar  8 13:40 ..
-rw-r--r--.  1 root root  1486532 Nov  7 21:38 System.map-2.6.31.5-127.fc12.i686.PAE
-rw-r--r--.  1 root root   103788 Nov  7 21:38 config-2.6.31.5-127.fc12.i686.PAE
drwxr-xr-x.  3 root root     1024 Mar  8 19:12 efi
drwxr-xr-x.  2 root root     1024 Mar  8 19:49 grub
-rw-r--r--.  1 root root 11253019 Mar  8 19:39 initramfs-2.6.31.5-127.fc12.i686.PAE.img
drwx------.  2 root root    12288 Mar  8 18:45 lost+found
-rwxr-xr-x.  1 root root  3454368 Nov  7 21:38 vmlinuz-2.6.31.5-127.fc12.i686.PAE

><fs> cat /grub/grub.conf 
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/mapper/vg_f12x32-lv_root
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=0
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Fedora (2.6.31.5-127.fc12.i686.PAE)
	root (hd0,0)
	kernel /vmlinuz-2.6.31.5-127.fc12.i686.PAE ro root=/dev/mapper/vg_f12x32-lv_root  LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=uk rhgb quiet
	initrd /initramfs-2.6.31.5-127.fc12.i686.PAE.img

><fs>

1 Comment

Filed under Uncategorized

New tool: virt-list-filesystems

$ virt-list-filesystems Debian5x64.img
/dev/debian5x64/home
/dev/debian5x64/root
/dev/debian5x64/tmp
/dev/debian5x64/usr
/dev/debian5x64/var
/dev/sda1

You can also augment this tool with the -a and -l options. The -a option tells it to list swap partitions too. The -l option tells it to show the filesystem type on each partition that was found:

$ virt-list-filesystems -a -l Fedora12.img
/dev/sda1 ext4
/dev/vg_f12x64/lv_root ext4
/dev/vg_f12x64/lv_swap swap

While this is a fairly simple tool, the use case comes from a user who asked me how I knew what filesystems could be mounted using the guestmount command. The answer is that you don’t know, unless you know something about the guest, or you interactively examine the guest using guestfish, or just use this new tool.

Leave a comment

Filed under Uncategorized