Tag Archives: iso

New in nbdkit: Create an ISO image on the fly

nbdkit is the pluggable Network Block Device server that Eric and I wrote. I have submitted a talk to FOSDEM next February about the many weird and wonderful ways you can use nbdkit as a flexible replacement for loopback mounting.

Anyway, new in nbdkit 1.7.6 you can now create ISO 9660 (CD-ROM) disk images on the fly from a directory:

# nbdkit iso /boot params="-JrT"
# nbd-client -b 512 localhost /dev/nbd0
# file -bsL /dev/nbd0
ISO 9660 CD-ROM filesystem data 'CDROM'
# mount /dev/nbd0 /tmp/mnt
# ls /tmp/mnt
# umount /tmp/mnt
# nbd-client -d /dev/nbd0
# killall nbdkit

That ISO wouldn’t actually be bootable, but you could create one (eg. an El Torito ISO) by adding the appropriate extra parameters.

To head off the first question: If you copy files into the directory while nbdkit is running, do they appear in the ISO? Answer: No! This is largely impossible with the way Linux block devices work.


Filed under Uncategorized

Customizing a Windows 7 install ISO

I’m told that if you want to pass additional files to Windows when it is installing, you have to put them on the actual install CD/ISO. However modifying ISOs is a palaver: they are write-once filesystems. The recommended way to modify them — using multisession support — doesn’t work for virtualization because the virtual CD drives don’t support it (nor do quite a few real CD drives).

You can unpack and repack an ISO file like this (and because we’re using libguestfs, root is not required):

$ mkdir /tmp/cd
$ cd /tmp/cd
$ guestfish --ro -a ../win.iso -m /dev/sda tar-out / - | tar xf -
$ mkisofs -o ../new-win.iso [...options...] .

If you add your own files into the /tmp/cd directory between the third and fourth steps then they will appear on the new ISO.

That’s the easy bit. The problem is that the new ISO will not be bootable, so you won’t be able to use it to install Windows from. Making it bootable involves an exploration of the command line options to “mkisofs” and a quick excursion into the ISO format.

It’s a good idea first to find out what format the existing Windows 7 ISO is in. Firstly I mount it up in guestfish to take a look around:

$ guestfish --ro -a ../en_windows_7_enterprise_x64_dvd_x15-70749.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-filesystems
/dev/vda: udf
><fs> mount-ro /dev/vda /
><fs> ll /
total 1164
dr-xr-xr-x  7 4294967295 4294967295    548 Jul 14  2009 .
drwxr-xr-x 20        500        500   4096 Nov  4 14:16 ..
-r-xr-xr-x  1 4294967295 4294967295    122 Jul 14  2009 autorun.inf
dr-xr-xr-x  4 4294967295 4294967295    568 Jul 14  2009 boot
-r-xr-xr-x  1 4294967295 4294967295 383562 Jul 14  2009 bootmgr
-r-xr-xr-x  1 4294967295 4294967295 667712 Jul 14  2009 bootmgr.efi
dr-xr-xr-x  3 4294967295 4294967295    100 Jul 14  2009 efi
-r-xr-xr-x  1 4294967295 4294967295 106760 Jul 14  2009 setup.exe
dr-xr-xr-x 10 4294967295 4294967295  10940 Jul 14  2009 sources
dr-xr-xr-x  5 4294967295 4294967295    200 Jul 14  2009 support
dr-xr-xr-x  3 4294967295 4294967295     92 Jul 14  2009 upgrade
><fs> exit

The format is UDF, the DVD replacement for ISO 9660. There is no obvious “cdboot.img” file which is what we will need in order to boot this thing.

Now look at the same disk with isoinfo:

$ isoinfo -d -i ../en_windows_7_enterprise_x64_dvd_x15-70749.iso
[lots of stuff]
Eltorito validation header:
    Hid 1
    Arch 0 (x86)
    ID 'Microsoft Corporation'
    Key 55 AA
    Eltorito defaultboot header:
        Bootid 88 (bootable)
        Boot media 0 (No Emulation Boot)
        Load segment 0
        Sys type 0
        Nsect 8
        Bootoff 2DE 734

What is interesting is that it’s an El Torito no-emulation bootable disk. The boot image required to boot it is 8 sectors long (“Nsect 8”) starting at sector number 734 (“Bootoff” in decimal).

CD sectors are 2048 bytes, so we can grab the boot image directly:

$ dd if=../en_windows_7_enterprise_x64_dvd_x15-70749.iso \
    of=boot.img bs=2048 count=8 skip=734

Now with all the information collected above, we can (with a great deal of experimentation) come up with a mkisofs command line that makes a bootable image:

$ mkisofs -o ../new-win.iso -b boot.img -no-emul-boot -c BOOT.CAT \
    -iso-level 2 -udf \
    -J -l -D -N -joliet-long -relaxed-filenames .


Filed under Uncategorized

Tip: Use guestfish to look inside an Arch Linux ISO


$ 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
><fs> list-partitions
><fs> vfs-type /dev/vda1
><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


  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

Tip: Ways to extract an ISO without needing root

Many different ways to do this in Linux as it turns out …

Of course I’d prefer you to use guestfish (based on this recipe):

$ guestfish --ro -a cd.iso -m /dev/sda tgz-out / cd.tar.gz

But it’s a bit slow perhaps (40 seconds to extract a 240 MB ISO on my machine). We don’t optimize libguestfs for file copying speed, more for awesome capabilities.

GNOME’s archive tool (file roller) can also open ISO files as non-root, but in fact it doesn’t do it directly, but uses an external program called isoinfo, part of cdrkit. isoinfo can only list files and extract a single file at a time:

$ isoinfo -i cd.iso -l
Directory listing of /
d---------   0    0    0            2048      0 1900 [     26 02]  . 
d---------   0    0    0            2048      0 1900 [     26 02]  .. 
d---------   0    0    0            2048 Feb  6 2010 [     27 02]  AMD64 
----------   0    0    0           61012 Feb  6 2010 [ 121118 00]  BOOT.;1 
----------   0    0    0             624 Feb  6 2010 [ 121148 00]  BOOT.CFG;1 
----------   0    0    0         5622126 Feb  6 2010 [ 121149 00]  NETBSD.;1 
$ isoinfo -i cd.iso -x /BOOT.CFG\;1
banner=Welcome to the NetBSD 5.0.2 installation CD

Amongst the libraries that can read ISO files it’s worth mentioning libarchive and libMirage. libarchive is used by BSD’s tar program, so on BSD tar can directly extract ISO files (and many other formats), which is a neat feature.

If you prefer to mount ISOs using FUSE (and thus still not requiring root), then there are two FUSE modules that can do this. Archivemount is the simplest, merely a small program that connects libarchive and FUSE. However archivemount isn’t packaged for Fedora and I wasn’t able to make it compile. FuseISO is an older package which does complete ISO decoding itself and seems to work as advertised:

$ fuseiso /tmp/cd.iso /tmp/cd
$ cd /tmp/cd
$ ls
amd64  boot  boot.cfg  netbsd


Filed under Uncategorized

Use libguestfs to edit a CD ISO

If you want to install a virtual machine from a CD, but you need to pass extra parameters to the Linux kernel, how can you do it?

Virt-install has an option to pass extra parameters to the kernel, but it doesn’t work with CD images because Linux CDs contain their own boot configuration system called ISOLINUX. Of course you can manually type in the extra parameters at the boot prompt, but that cannot be automated.

I was asked today can we use libguestfs to edit the ISOLINUX configuration inside the ISO directly? My first answer was yes, just do:

guestfish -a boot.iso -m /dev/sda edit /isolinux/isolinux.cfg

Unfortunately this doesn’t work for CD ISOs formatted using the standard ISO9660 filesystem. The kernel driver that guestfish uses is read-only, and you’ll get an error when the edit command tries to save the file. (As an aside, it should just work on UDF-formatted ISOs such as DVD images, but I didn’t try it).

Still, all is not lost and we can use guestfish to make the edit and still not require root. We just have to unpack the ISO, make the edit, and pack it up again, like this:

mkdir /tmp/iso
cd /tmp/iso
guestfish -a ../boot.iso -m /dev/sda tar-out / - | tar xvf -
vi isolinux/isolinux.cfg
mkisofs [flags - see comments] -o ../newboot.iso .


Filed under Uncategorized