def attach_volume(self, context, connection_info, instance, mountpoint, disk_bus=None, device_type=None, encryption=None):
    instance_name = instance['name']
    virt_dom = self._lookup_by_name(instance_name)
    disk_dev = mountpoint.rpartition('/')[2]
    bdm = {'device_name': disk_dev, 'disk_bus': disk_bus, 'device_type': device_type}
    data = {}
    if ('data' in connection_info):
        data = connection_info['data']
    if (('logical_block_size' in data) or ('physical_block_size' in data)):
        if ((CONF.libvirt.virt_type != 'kvm') and (CONF.libvirt.virt_type != 'qemu')):
            msg = (_("Volume sets block size, but the current libvirt hypervisor '%s' does not support custom block size") % CONF.libvirt.virt_type)
            raise exception.InvalidHypervisorType(msg)
        if (not self._has_min_version(MIN_LIBVIRT_BLOCKIO_VERSION)):
            ver = '.'.join([str(x) for x in MIN_LIBVIRT_BLOCKIO_VERSION])
            msg = (_("Volume sets block size, but libvirt '%s' or later is required.") % ver)
            raise exception.Invalid(msg)
    disk_info = blockinfo.get_info_from_bdm(CONF.libvirt.virt_type, bdm)
    conf = self._connect_volume(connection_info, disk_info)
    self._set_cache_mode(conf)
    try:
        flags = libvirt.VIR_DOMAIN_AFFECT_CONFIG
        state = LIBVIRT_POWER_STATE[virt_dom.info()[0]]
        if (state in (power_state.RUNNING, power_state.PAUSED)):
            flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
        if ('data' in connection_info):
            connection_info['data']['device_path'] = conf.source_path
        if encryption:
            encryptor = self._get_volume_encryptor(connection_info, encryption)
            encryptor.attach_volume(context, **encryption)
        virt_dom.attachDeviceFlags(conf.to_xml(), flags)
    except Exception as ex:
        if isinstance(ex, libvirt.libvirtError):
            errcode = ex.get_error_code()
            if (errcode == libvirt.VIR_ERR_OPERATION_FAILED):
                self._disconnect_volume(connection_info, disk_dev)
                raise exception.DeviceIsBusy(device=disk_dev)
        with excutils.save_and_reraise_exception():
            self._disconnect_volume(connection_info, disk_dev)
def attach_volume(self, context, connection_info, instance, mountpoint, disk_bus=None, device_type=None, encryption=None):
    instance_name = instance['name']
    virt_dom = self._lookup_by_name(instance_name)
    disk_dev = mountpoint.rpartition('/')[2]
    bdm = {'device_name': disk_dev, 'disk_bus': disk_bus, 'device_type': device_type}
    data = {}
    if ('data' in connection_info):
        data = connection_info['data']
    if (('logical_block_size' in data) or ('physical_block_size' in data)):
        if ((CONF.libvirt.virt_type != 'kvm') and (CONF.libvirt.virt_type != 'qemu')):
            msg = (_("Volume sets block size, but the current libvirt hypervisor '%s' does not support custom block size") % CONF.libvirt.virt_type)
            raise exception.InvalidHypervisorType(msg)
        if (not self._has_min_version(MIN_LIBVIRT_BLOCKIO_VERSION)):
            ver = '.'.join([str(x) for x in MIN_LIBVIRT_BLOCKIO_VERSION])
            msg = (_("Volume sets block size, but libvirt '%s' or later is required.") % ver)
            raise exception.Invalid(msg)
    disk_info = blockinfo.get_info_from_bdm(CONF.libvirt.virt_type, bdm)
    conf = self._connect_volume(connection_info, disk_info)
    self._set_cache_mode(conf)
    try:
        flags = libvirt.VIR_DOMAIN_AFFECT_CONFIG
        state = LIBVIRT_POWER_STATE[virt_dom.info()[0]]
        if (state in (power_state.RUNNING, power_state.PAUSED)):
            flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
        if ('data' in connection_info):
            connection_info['data']['device_path'] = conf.source_path
        if encryption:
            encryptor = self._get_volume_encryptor(connection_info, encryption)
            encryptor.attach_volume(context, **encryption)
        virt_dom.attachDeviceFlags(conf.to_xml(), flags)
    except Exception as ex:
        if isinstance(ex, libvirt.libvirtError):
            errcode = ex.get_error_code()
            if (errcode == libvirt.VIR_ERR_OPERATION_FAILED):
                self._disconnect_volume(connection_info, disk_dev)
                raise exception.DeviceIsBusy(device=disk_dev)
        with excutils.save_and_reraise_exception():
            self._disconnect_volume(connection_info, disk_dev)