Commit 725d63bc authored by Anael Beutot's avatar Anael Beutot
Browse files

Prevent fd leakage by opening new libvirt connections in child.

parent 9ad928d3
Loading
Loading
Loading
Loading
+31 −17
Original line number Diff line number Diff line
@@ -339,14 +339,6 @@ class Handler(HostHandler):
            logger.exception('Cannot find domain %s on hypervisor for live'
                             ' migration', name)
            raise
        try:
            dest_virt_con = libvirt.open(
                'qemu+tcp://127.0.0.1:%d/system' % remote_virt_port)
        except libvirt.libvirtError:
            logger.exception('Cannot connect to remote libvirt for live'
                             ' migrating vm %s', name)
            raise


        # we open a new connection to libvirt and fork because sometimes libvirt
        # python binding, while doing a operation,
@@ -356,14 +348,6 @@ class Handler(HostHandler):
        # libvirt connection for the migration and fork, the migration operation
        # in itself is handled by the child while other threads can be scheduled

        # create a new libvirt connection dedicated to migration
        try:
            new_con = libvirt.open('qemu:///system')
            domain = new_con.lookupByUUIDString(vm.uuid)
        except libvirt.libvirtError:
            logger.exception('Cannot connect to libvirt')
            raise

        try:
            pid = os.fork()
        except OSError:
@@ -373,6 +357,29 @@ class Handler(HostHandler):
        if pid == 0:
            # child
            # FIXME we should close all unused fds
            # create a new libvirt connection dedicated to migration
            try:
                new_con = libvirt.open('qemu:///system')
                domain = new_con.lookupByUUIDString(vm.uuid)
            except libvirt.libvirtError:
                sys.stderr.write('Cannot connect to libvirt\n')
                os._exit(4)
            except:
                # error
                # TODO print traceback
                os._exit(2)
            try:
                dest_virt_con = libvirt.open(
                    'qemu+tcp://127.0.0.1:%d/system' % remote_virt_port)
            except libvirt.libvirtError:
                sys.stderr.write('Cannot connect to remote libvirt for live'
                                 ' migrating vm %s', name)
                os._exit(5)
            except:
                # error
                # TODO print traceback
                os._exit(2)

            try:
                if unsafe:
                    # VIR_MIGRATE_UNSAFE is not defined for libvirt < 0.9.11
@@ -398,6 +405,7 @@ class Handler(HostHandler):
            else:
                os._exit(0)
            finally:
                new_con.close()
                dest_virt_con.close()
        else:
            # watch for migration status every second
@@ -437,7 +445,13 @@ class Handler(HostHandler):
                    logger.error('Migration timeout for vm %s', name)
                    raise VMMigrationError('Timeout')
                else:
                    if status != 0:
                    if status == 4:
                        raise VMMigrationError('Cannot open new connection to'
                                               ' libvirt')
                    elif status == 5:
                        raise VMMigrationError('Cannot open connection to'
                                               ' remote libvirt')
                    elif status != 0:
                        # error
                        logger.error('Libvirt error while live migrating vm %s',
                                     name)