On Wed, Sep 28, 2011 at 06:37:17PM +0100, Daniel P. Berrange wrote: > We do have a historical syntax from Xen paravirt which lets us call out > to a helper at boot time, namely the "<bootloader>" element. With Xen > this is typically something like pygrub, or pxegrub, which does some > work and writes out a kernel+initrd into temporary files, and prints > the file paths + any kernel args on stdout. > > We could just wire up this concept in KVM too without any real trouble, > and then we could have guestfs-bootloader script todo the magic setup The attached scripts show how it would work, and furthermore they show that it really does work. The first script is the bootloader script. This creates the libguestfs appliance (3 files called /tmp/kernel, /tmp/initrd and /tmp/root). At the moment, no caching of the appliance is implemented, but that is easy to add. The second script shows the sort of changes we would make to the guestfs_add_domain API in order to run the appliance from libvirt. It's a Ruby script that creates a transient domain, booting from the appliance created in step 1, with the correct virtio-serial port etc. It then tells libguestfs to connect to the virtio-serial socket. Finally it issues some libguestfs commands to create a filesystem, so you can tell that it is actually talking to the libguestfs daemon. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://et.redhat.com/~rjones/virt-top
#!/bin/bash - set -e rm -f /tmp/kernel /tmp/initrd /tmp/root # XXX Checksumming and caching not done yet. febootstrap-supermin-helper --verbose -f ext2 \ /usr/lib*/guestfs/supermin.d $(uname -m) \ /tmp/kernel /tmp/initrd /tmp/root echo "bootstrap OK"
#!/usr/bin/ruby # Assumes you have run ./bootstrap to create the /tmp/kernel, # /tmp/initrd and appliance disk (/tmp/root) require 'libvirt' require 'guestfs' # Create a dummy disk for libguestfs to edit. File.open("/tmp/disk.img", "w") { |f| f.seek(500*1024*1024); f.write("\0") } xml = <<EOF <domain type='kvm'> <name>guestfs_test0</name> <memory>500000</memory> <currentMemory>500000</currentMemory> <vcpu>1</vcpu> <os> <type arch='x86_64'>hvm</type> <kernel>/tmp/kernel</kernel> <initrd>/tmp/initrd</initrd> <cmdline>panic=1 console=ttyS0 udevtimeout=300 no_timer_check acpi=off printk.time=1 cgroup_disable=memory selinux=0 guestfs_verbose=1 TERM=xterm</cmdline> </os> <features> <apic/> <pae/> </features> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>destroy</on_reboot> <on_crash>destroy</on_crash> <devices> <!-- this is the disk we are editing --> <disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='/tmp/disk.img'/> <target dev='vda' bus='virtio'/> </disk> <!-- the appliance disk, must be added last --> <disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='/tmp/root'/> <target dev='vdb' bus='virtio'/> </disk> <!-- virtio serial to talk to the guest --> <channel type='unix'> <source mode='bind' path='/tmp/socket'/> <target type='virtio' name='org.libguestfs.channel.0'/> </channel> <!-- XXX console? --> <console type='pty'> <target port='0'/> </console> </devices> </domain> EOF begin File.delete("/tmp/socket") rescue Exception end # Run the guest, locally for now. conn = Libvirt::open('qemu:///session') # 2 == autodestroy, so the domain is killed when conn is closed dom = conn.create_domain_xml(xml, 2) # Run libguestfs and try to connect to the socket. g = Guestfs::Guestfs.new() g.set_attach_method("unix:/tmp/socket") g.set_trace(1) g.launch() # Send a message to the daemon to check we're talking to it OK. r = g.echo_daemon(["one", "two", "three"]) if r != "one two three" raise "bad response from daemon" end # Do some disk operations on /tmp/disk.img. g.part_disk("/dev/sda", "mbr") g.mkfs("ext3", "/dev/sda1") g.mount_options("", "/dev/sda1", "/") g.write("/hello_world.txt", "hello from libvirt") # Close everything. Transient guest should go away. g.close() conn.close() puts "create test run OK" puts "/tmp/disk.img should be a complete disk image"
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list