[libvirt] [PATCH] ESX: Change disk selection for datastore detection.

In order to register a new virtual machine the ESX driver needs to upload a VMX file to a datastore. Try to put this file beside the main VMDK file of the virtual machine. Change the disk selection for datastore detection to choose the first file-based harddisk instead of just the first disk. The first disk may be a CDROM disk and ISO images are normaly not located in the virtual machine's directory. * src/esx/esx_driver.c: change disk selection for datastore detection --- src/esx/esx_driver.c | 44 +++++++++++++++++++++++++++++++++----------- 1 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index e063b46..a0efa5d 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -2410,6 +2410,8 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED) esxPrivate *priv = (esxPrivate *)conn->privateData; virDomainDefPtr def = NULL; char *vmx = NULL; + int i; + virDomainDiskDefPtr disk = NULL; esxVI_ObjectContent *virtualMachine = NULL; char *datastoreName = NULL; char *directoryName = NULL; @@ -2458,31 +2460,51 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED) goto failure; } - /* Build VMX datastore URL */ + /* + * Build VMX datastore URL. Use the source of the first file-based harddisk + * to deduce the datastore and path for the VMX file. Don't just use the + * first disk, because it may be CDROM disk and ISO images are normaly not + * located in the virtual machine's directory. This approach to deduce the + * datastore isn't perfect but should work in the majority of cases. + */ if (def->ndisks < 1) { ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "Domain XML doesn't contain a disk, cannot deduce datastore " - "and path for VMX file"); + "Domain XML doesn't contain any disks, cannot deduce " + "datastore and path for VMX file"); goto failure; } - if (def->disks[0]->src == NULL) { + for (i = 0; i < def->ndisks; ++i) { + if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK && + def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_FILE) { + disk = def->disks[i]; + break; + } + } + + if (disk == NULL) { ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "First disk has no source, cannot deduce datastore and path " - "for VMX file"); + "Domain XML doesn't contain any file-based harddisks, " + "cannot deduce datastore and path for VMX file"); goto failure; } - if (esxUtil_ParseDatastoreRelatedPath(conn, def->disks[0]->src, - &datastoreName, &directoryName, - &fileName) < 0) { + if (disk->src == NULL) { + ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "First file-based harddisk has no source, cannot deduce " + "datastore and path for VMX file"); + goto failure; + } + + if (esxUtil_ParseDatastoreRelatedPath(conn, disk->src, &datastoreName, + &directoryName, &fileName) < 0) { goto failure; } if (! virFileHasSuffix(fileName, ".vmdk")) { ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "Expecting source of first disk '%s' to be a VMDK image", - def->disks[0]->src); + "Expecting source '%s' of first file-based harddisk to be a " + "VMDK image", disk->src); goto failure; } -- 1.6.0.4

On Wed, Oct 28, 2009 at 09:08:56PM +0100, Matthias Bolte wrote:
In order to register a new virtual machine the ESX driver needs to upload a VMX file to a datastore. Try to put this file beside the main VMDK file of the virtual machine. Change the disk selection for datastore detection to choose the first file-based harddisk instead of just the first disk. The first disk may be a CDROM disk and ISO images are normaly not located in the virtual machine's directory.
Is there anything you can do in the case of a VM without any disks besides reporting the error ? It might be needed if someone creates a disk-less VM - eg so they can use iSCSI or NFS based root filesystem
* src/esx/esx_driver.c: change disk selection for datastore detection --- src/esx/esx_driver.c | 44 +++++++++++++++++++++++++++++++++----------- 1 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index e063b46..a0efa5d 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -2410,6 +2410,8 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED) esxPrivate *priv = (esxPrivate *)conn->privateData; virDomainDefPtr def = NULL; char *vmx = NULL; + int i; + virDomainDiskDefPtr disk = NULL; esxVI_ObjectContent *virtualMachine = NULL; char *datastoreName = NULL; char *directoryName = NULL; @@ -2458,31 +2460,51 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED) goto failure; }
- /* Build VMX datastore URL */ + /* + * Build VMX datastore URL. Use the source of the first file-based harddisk + * to deduce the datastore and path for the VMX file. Don't just use the + * first disk, because it may be CDROM disk and ISO images are normaly not + * located in the virtual machine's directory. This approach to deduce the + * datastore isn't perfect but should work in the majority of cases. + */ if (def->ndisks < 1) { ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "Domain XML doesn't contain a disk, cannot deduce datastore " - "and path for VMX file"); + "Domain XML doesn't contain any disks, cannot deduce " + "datastore and path for VMX file"); goto failure; }
- if (def->disks[0]->src == NULL) { + for (i = 0; i < def->ndisks; ++i) { + if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK && + def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_FILE) { + disk = def->disks[i]; + break; + } + } + + if (disk == NULL) { ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "First disk has no source, cannot deduce datastore and path " - "for VMX file"); + "Domain XML doesn't contain any file-based harddisks, " + "cannot deduce datastore and path for VMX file"); goto failure; }
- if (esxUtil_ParseDatastoreRelatedPath(conn, def->disks[0]->src, - &datastoreName, &directoryName, - &fileName) < 0) { + if (disk->src == NULL) { + ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "First file-based harddisk has no source, cannot deduce " + "datastore and path for VMX file"); + goto failure; + } + + if (esxUtil_ParseDatastoreRelatedPath(conn, disk->src, &datastoreName, + &directoryName, &fileName) < 0) { goto failure; }
if (! virFileHasSuffix(fileName, ".vmdk")) { ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "Expecting source of first disk '%s' to be a VMDK image", - def->disks[0]->src); + "Expecting source '%s' of first file-based harddisk to be a " + "VMDK image", disk->src); goto failure; }
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

2009/10/28 Daniel P. Berrange <berrange@redhat.com>:
On Wed, Oct 28, 2009 at 09:08:56PM +0100, Matthias Bolte wrote:
In order to register a new virtual machine the ESX driver needs to upload a VMX file to a datastore. Try to put this file beside the main VMDK file of the virtual machine. Change the disk selection for datastore detection to choose the first file-based harddisk instead of just the first disk. The first disk may be a CDROM disk and ISO images are normaly not located in the virtual machine's directory.
Is there anything you can do in the case of a VM without any disks besides reporting the error ? It might be needed if someone creates a disk-less VM - eg so they can use iSCSI or NFS based root filesystem
The current domain XML format has no place to specify where to put the VMX file, so I try to deduce the path from the disk file paths. Yes this doesn't work for disk-less VM's. One could add a new element to the domain XML that specifies the datastore path for the VMX file. Matthias
participants (2)
-
Daniel P. Berrange
-
Matthias Bolte