[Kimchi-devel] [PATCH] Choose available address for ide disk

Christy Perez christy at linux.vnet.ibm.com
Thu Apr 10 19:32:48 UTC 2014


Tested-By: Christy Perez <christy at linux.vnet.ibm.com>

I added 3 new CD ROM devices to total 4, and they got the following
addresses:
      <address type='drive' controller='0' bus='1' target='0' unit='1'/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
      <address type='drive' controller='0' bus='1' target='0' unit='0'/>

Without the patch, I get the error "CHVM0019E: Unable to start virtual
machine F19-Remote. Details: internal error: Only 1 ide controller is
supported"
when I try to start the VM.

Two other small comments below...

On Thu, 2014-04-10 at 18:28 +0800, lvroyce at linux.vnet.ibm.com wrote:
> From: Royce Lv <lvroyce at linux.vnet.ibm.com>
> 
> Tested:
>  1.make check
>  2.adding more than 4 cdroms report error
>  3.less than 4 cdroms successful boot and see all cdroms.
>  4.When a vm does not have cdrom, adding succeed.
> 
> Now when just pass source and target type, bus information,
> libvirt may generate another controller for ide disk appending,
> this will be conflict with libvirt's limitation of 1 ide controller.
> This patch choose available bus_id and unit_id for ide disk
> to make sure we can reach the limit of 4 cdroms per vm.
> 
> Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
> ---
>  src/kimchi/i18n.py             |  1 +
>  src/kimchi/model/vmstorages.py | 56 +++++++++++++++++++++++++++++++-----------
>  2 files changed, 43 insertions(+), 14 deletions(-)
> 
> diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
> index 86ab5d6..4ca83d9 100644
> --- a/src/kimchi/i18n.py
> +++ b/src/kimchi/i18n.py
> @@ -230,6 +230,7 @@ messages = {
>      "KCHCDROM0011E": _("Do not support guest CDROM hot plug attachment"),
>      "KCHCDROM0012E": _("Specify type and path to add a new virtual machine disk"),
>      "KCHCDROM0013E": _("Specify path to update virtual machine disk"),
> +    "KCHCDROM0014E": _("Controller type %(type)s limitation %(limit)s reached"),
Kind of a small thing, but with this error, it's not really clear on
what the limit is. Just the number kind of makes it sound like it might
be a return code or something. I suggest "Controller type %(type)s
limitation of %(limit)s devices reached."
> 
>      "KCHREPOS0001E": _("YUM Repository ID must be one word only string."),
>      "KCHREPOS0002E": _("Repository URL must be an http://, ftp:// or file:// URL."),
> diff --git a/src/kimchi/model/vmstorages.py b/src/kimchi/model/vmstorages.py
> index 3b5f99e..b3f22db 100644
> --- a/src/kimchi/model/vmstorages.py
> +++ b/src/kimchi/model/vmstorages.py
> @@ -37,6 +37,16 @@ DEV_TYPE_SRC_ATTR_MAP = {'file': 'file',
>                           'block': 'dev'}
> 
> 
> +def _get_device_xml(dom, dev_name):
> +    # Get VM xml and then devices xml
> +    xml = dom.XMLDesc(0)
> +    devices = objectify.fromstring(xml).devices
> +    disk = devices.xpath("./disk/target[@dev='%s']/.." % dev_name)
> +    if not disk:
> +        return None
> +    return disk[0]
> +
> +
>  def _get_storage_xml(params):
>      src_type = params.get('src_type')
>      disk = E.disk(type=src_type, device=params.get('type'))
> @@ -56,6 +66,12 @@ def _get_storage_xml(params):
>          disk.append(source)
> 
>      disk.append(E.target(dev=params.get('dev'), bus=params.get('bus', 'ide')))
> +    if params.get('address'):
> +        print params['address']
Probably want to take that out.
> +        disk.append(E.address(
> +            type='drive', controller=params['address']['controller'],
> +            bus=params['address']['bus'], target='0',
> +            unit=params['address']['unit']))
>      return ET.tostring(disk)
> 
> 
> @@ -89,6 +105,27 @@ class VMStoragesModel(object):
>      def __init__(self, **kargs):
>          self.conn = kargs['conn']
> 
> +    def _get_available_ide_address(self, vm_name):
> +        dom = VMModel.get_vm(vm_name, self.conn)
> +        disks = self.get_list(vm_name)
> +        valid_id = [('0', '0'), ('0', '1'), ('1', '0'), ('1', '1')]
> +        controller_id = '0'
> +        for dev_name in disks:
> +            disk = _get_device_xml(dom, dev_name)
> +            if disk.target.attrib['bus'] == 'ide':
> +                controller_id = disk.address.attrib['controller']
> +                bus_id = disk.address.attrib['bus']
> +                unit_id = disk.address.attrib['unit']
> +                if (bus_id, unit_id) in valid_id:
> +                    valid_id.remove((bus_id, unit_id))
> +                    continue
> +        if not valid_id:
> +            raise OperationFailed('KCHCDROM0014E', {'type': 'ide', 'limit': 4})
> +        else:
> +            address = {'controller': controller_id,
> +                       'bus': valid_id[0][0], 'unit': valid_id[0][1]}
> +            return dict(address=address)
> +
>      def create(self, vm_name, params):
>          dom = VMModel.get_vm(vm_name, self.conn)
>          if DOM_STATE_MAP[dom.info()[0]] != 'shutoff':
> @@ -109,8 +146,7 @@ class VMStoragesModel(object):
>          path = params['path']
>          params['src_type'] = _check_cdrom_path(path)
> 
> -        # Check if path is an url
> -
> +        params.update(self._get_available_ide_address(vm_name))
>          # Add device to VM
>          dev_xml = _get_storage_xml(params)
>          try:
> @@ -147,19 +183,10 @@ class VMStorageModel(object):
>      def __init__(self, **kargs):
>          self.conn = kargs['conn']
> 
> -    def _get_device_xml(self, vm_name, dev_name):
> -        # Get VM xml and then devices xml
> -        dom = VMModel.get_vm(vm_name, self.conn)
> -        xml = dom.XMLDesc(0)
> -        devices = objectify.fromstring(xml).devices
> -        disk = devices.xpath("./disk/target[@dev='%s']/.." % dev_name)
> -        if not disk:
> -            return None
> -        return disk[0]
> -
>      def lookup(self, vm_name, dev_name):
>          # Retrieve disk xml and format return dict
> -        disk = self._get_device_xml(vm_name, dev_name)
> +        dom = VMModel.get_vm(vm_name, self.conn)
> +        disk = _get_device_xml(dom, dev_name)
>          if disk is None:
>              raise NotFoundError("KCHCDROM0007E", {'dev_name': dev_name,
>                                                    'vm_name': vm_name})
> @@ -188,7 +215,8 @@ class VMStorageModel(object):
> 
>      def delete(self, vm_name, dev_name):
>          # Get storage device xml
> -        disk = self._get_device_xml(vm_name, dev_name)
> +        dom = VMModel.get_vm(vm_name, self.conn)
> +        disk = _get_device_xml(dom, dev_name)
>          if disk is None:
>              raise NotFoundError("KCHCDROM0007E",
>                                  {'dev_name': dev_name,

Regards,


- Christy




More information about the Kimchi-devel mailing list