Commit ef261a24 authored by Benziane Chakib's avatar Benziane Chakib
Browse files

Added export_vm method in KvmHypervisor using dd nc and pipes to transfer a vm

parent 475f20cf
Loading
Loading
Loading
Loading
+54 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ Two entites belong to this module: a Kvm hypervisor or a Kvm virtual machine
from libvirtwrapper import *
from exceptions import *
import subprocess
import hashlib


class KvmHypervisor(LibvirtHypervisor):
@@ -116,6 +117,58 @@ class KvmHypervisor(LibvirtHypervisor):
        result = p.communicate()
        return result

    def export_vm(self, name, target, port):
        '''
        Migrates the given vm (name) to (target) hypervisor which is already
        waiting for the migration

        :param name: the name of the vm
        :type name: :class:`str`
        :param target: the destination hypervisor
        :type target: :class:`str`
        :param port: the port on the destination to use for the transfer
        :type port: :class:`str`
        '''
        # We will be using subprocess to pipe the volume using dd  in a netcat 
        # connection to the destination
        # We send a hash of the volume before so that the target can checksum
        # and validate integrity.
        # This algorithm is just a proof of concept of the cold migration
        # process it is likely that it does not anticipates some problems

        buff = 1024 * 1024 * 10   #10 Mo
        path = [vm.get_disk_path() for vm in self._vm_list 
                                    if vm.get_name() == name].pop()
        dd_cmd = ['dd', 'if=%s' % path]
        
        dd_process = subprocess.Popen(dd_cmd, bufsize=-1,
                                    stdout=subprocess.PIPE)
        nc_process = subprocess.Popen(['nc', target, port],
                                    bufsize=-1,
                                    stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
        #We send dd output to nc
        dd_out = dd_process.stdout
        nc_in = nc_process.stdin
        m = hashlib.md5()
        print 'going to pipe loop'
        try:
            read = dd_out.read(buff)
        except Exception as err:
            raise IOError('error while reading dd process output %s' % err)
        try:
            while len(read) != 0:
                print len(read)
                m.update(read)
                nc_in.write(read)
                nc_in.flush()
                read = dd_out.read(buff)
        except Exception as err:
            raise IOError('Error occured while writing to nc process %s' % err)
        nc_in.close()
        print m.hexdigest()

    def get_network_conf(self):
        raise NotImplementedError