[libvirt] [PATCH] esx: Add VNC support

Daniel P. Berrange berrange at redhat.com
Sun Jan 17 13:03:55 UTC 2010


On Sat, Jan 16, 2010 at 03:22:19PM +0100, Matthias Bolte wrote:
> * src/conf/domain_conf.c: add defaults for the video device
> * src/esx/esx_vmx.[ch]: add VNC support to the VMX handling
> * tests/vmx2xmltest.c, tests/xml2vmxtest.c: add tests for the VNC support
> ---
>  src/conf/domain_conf.c                     |    5 +
>  src/esx/esx_vmx.c                          |  146 +++++++++++++++++++++++++++-
>  src/esx/esx_vmx.h                          |    6 +
>  tests/vmx2xmldata/vmx2xml-graphics-vnc.vmx |    6 +
>  tests/vmx2xmldata/vmx2xml-graphics-vnc.xml |   17 +++
>  tests/vmx2xmltest.c                        |    4 +-
>  tests/xml2vmxdata/xml2vmx-graphics-vnc.vmx |   11 ++
>  tests/xml2vmxdata/xml2vmx-graphics-vnc.xml |   11 ++
>  tests/xml2vmxtest.c                        |    2 +
>  9 files changed, 203 insertions(+), 5 deletions(-)
>  create mode 100644 tests/vmx2xmldata/vmx2xml-graphics-vnc.vmx
>  create mode 100644 tests/vmx2xmldata/vmx2xml-graphics-vnc.xml
>  create mode 100644 tests/xml2vmxdata/xml2vmx-graphics-vnc.vmx
>  create mode 100644 tests/xml2vmxdata/xml2vmx-graphics-vnc.xml
> 
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 126e7e1..5c427fb 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -2490,6 +2490,8 @@ virDomainVideoDefaultRAM(virDomainDefPtr def,
>      case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
>          if (def->virtType == VIR_DOMAIN_VIRT_VBOX)
>              return 8 * 1024;
> +        else if (def->virtType == VIR_DOMAIN_VIRT_VMWARE)
> +            return 4 * 1024;
>          else
>              return 9 * 1024;
>          break;
> @@ -2523,6 +2525,9 @@ virDomainVideoDefaultType(virDomainDefPtr def)
>      case VIR_DOMAIN_VIRT_VBOX:
>          return VIR_DOMAIN_VIDEO_TYPE_VBOX;
>  
> +    case VIR_DOMAIN_VIRT_VMWARE:
> +        return VIR_DOMAIN_VIDEO_TYPE_VMVGA;
> +
>      default:
>          return -1;
>      }
> diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c
> index 8e016df..777a60a 100644
> --- a/src/esx/esx_vmx.c
> +++ b/src/esx/esx_vmx.c
> @@ -731,7 +731,7 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
>      char *guestOS = NULL;
>      int controller;
>      int port;
> -    int present;
> +    int present; // boolean
>      char *scsi_virtualDev = NULL;
>      int id;
>  
> @@ -967,7 +967,20 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
>      def->localtime*/
>  
>      /* def:graphics */
> -    /* FIXME */
> +    if (VIR_ALLOC_N(def->graphics, 1) < 0) {
> +        virReportOOMError(NULL);
> +        goto failure;
> +    }
> +
> +    def->ngraphics = 0;
> +
> +    if (esxVMX_ParseVNC(conf, &def->graphics[def->ngraphics]) < 0) {
> +        goto failure;
> +    }
> +
> +    if (def->graphics[def->ngraphics] != NULL) {
> +        ++def->ngraphics;
> +    }
>  
>      /* def:disks: 4 * 15 scsi + 2 * 2 ide + 2 floppy = 66 */
>      if (VIR_ALLOC_N(def->disks, 66) < 0) {
> @@ -1155,6 +1168,70 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
>  
>  
>  int
> +esxVMX_ParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def)
> +{
> +    int enabled = 0; // boolean
> +    long long port = 0;
> +
> +    if (def == NULL || *def != NULL) {
> +        ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
> +        return -1;
> +    }
> +
> +    if (esxUtil_GetConfigBoolean(conf, "RemoteDisplay.vnc.enabled",
> +                                 &enabled, 0, 1) < 0) {
> +        return -1;
> +    }
> +
> +    if (! enabled) {
> +        return 0;
> +    }
> +
> +    if (VIR_ALLOC(*def) < 0) {
> +        virReportOOMError(NULL);
> +        goto failure;
> +    }
> +
> +    (*def)->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
> +
> +    if (esxUtil_GetConfigLong(conf, "RemoteDisplay.vnc.port",
> +                              &port, -1, 1) < 0 ||
> +        esxUtil_GetConfigString(conf, "RemoteDisplay.vnc.ip",
> +                                &(*def)->data.vnc.listenAddr, 1) < 0 ||
> +        esxUtil_GetConfigString(conf, "RemoteDisplay.vnc.keymap",
> +                                &(*def)->data.vnc.keymap, 1) < 0 ||
> +        esxUtil_GetConfigString(conf, "RemoteDisplay.vnc.password",
> +                                &(*def)->data.vnc.passwd, 1) < 0) {
> +        goto failure;
> +    }
> +
> +    if (port < 0) {
> +        VIR_WARN0("VNC is enabled but VMX entry 'RemoteDisplay.vnc.port' "
> +                  "is missing, the VNC port is unknown");
> +
> +        (*def)->data.vnc.port = 0;
> +        (*def)->data.vnc.autoport = 1;
> +    } else {
> +        if (port < 5900 || port > 5964) {
> +            VIR_WARN("VNC port %lld it out of [5900..5964] range", port);
> +        }
> +
> +        (*def)->data.vnc.port = port;
> +        (*def)->data.vnc.autoport = 0;
> +    }
> +
> +    return 0;
> +
> +  failure:
> +    virDomainGraphicsDefFree(*def);
> +    *def = NULL;
> +
> +    return -1;
> +}
> +
> +
> +
> +int
>  esxVMX_ParseSCSIController(virConfPtr conf, int controller, int *present,
>                             char **virtualDev)
>  {
> @@ -2195,7 +2272,7 @@ esxVMX_FormatConfig(esxVI_Context *ctx, virDomainDefPtr def,
>                            (int)(def->memory / 1024));
>      }
>  
> -    /* vmx:numvcpus -> def:vcpus */
> +    /* def:vcpus -> vmx:numvcpus */
>      if (def->vcpus <= 0 || (def->vcpus % 2 != 0 && def->vcpus != 1)) {
>          ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
>                    "Expecting domain XML entry 'vcpu' to be an unsigned "
> @@ -2241,6 +2318,24 @@ esxVMX_FormatConfig(esxVI_Context *ctx, virDomainDefPtr def,
>          virBufferAddLit(&buffer, "\"\n");
>      }
>  
> +    /* def:graphics */
> +    for (i = 0; i < def->ngraphics; ++i) {
> +        switch (def->graphics[i]->type) {
> +          case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
> +            if (esxVMX_FormatVNC(def->graphics[i], &buffer) < 0) {
> +                goto failure;
> +            }
> +
> +            break;
> +
> +          default:
> +            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
> +                      "Unsupported graphics type '%s'",
> +                      virDomainGraphicsTypeToString(def->graphics[i]->type));
> +            goto failure;
> +        }
> +    }
> +
>      /* def:disks */
>      int scsi_present[4] = { 0, 0, 0, 0 };
>      char *scsi_virtualDev[4] = { NULL, NULL, NULL, NULL };
> @@ -2285,7 +2380,7 @@ esxVMX_FormatConfig(esxVI_Context *ctx, virDomainDefPtr def,
>  
>            default:
>              ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
> -                      "Unsuppotred disk device type '%s'",
> +                      "Unsupported disk device type '%s'",
>                        virDomainDiskDeviceTypeToString(def->disks[i]->device));
>              goto failure;
>          }
> @@ -2341,6 +2436,49 @@ esxVMX_FormatConfig(esxVI_Context *ctx, virDomainDefPtr def,
>  
>  
>  int
> +esxVMX_FormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer)
> +{
> +    if (def->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
> +        ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "Invalid argument");
> +        return -1;
> +    }
> +
> +    virBufferVSprintf(buffer, "RemoteDisplay.vnc.enabled = \"true\"\n");
> +
> +    if (def->data.vnc.autoport) {
> +        VIR_WARN0("VNC autoport is enabled, but the automatically assigned "
> +                  "VNC port cannot be read back");
> +    } else {
> +        if (def->data.vnc.port < 5900 || def->data.vnc.port > 5964) {
> +            VIR_WARN("VNC port %d it out of [5900..5964] range",
> +                     def->data.vnc.port);
> +        }
> +
> +        virBufferVSprintf(buffer, "RemoteDisplay.vnc.port = \"%d\"\n",
> +                          def->data.vnc.port);
> +    }
> +
> +    if (def->data.vnc.listenAddr != NULL) {
> +        virBufferVSprintf(buffer, "RemoteDisplay.vnc.ip = \"%s\"\n",
> +                          def->data.vnc.listenAddr);
> +    }
> +
> +    if (def->data.vnc.keymap != NULL) {
> +        virBufferVSprintf(buffer, "RemoteDisplay.vnc.keymap = \"%s\"\n",
> +                          def->data.vnc.keymap);
> +    }
> +
> +    if (def->data.vnc.passwd != NULL) {
> +        virBufferVSprintf(buffer, "RemoteDisplay.vnc.password = \"%s\"\n",
> +                          def->data.vnc.passwd);
> +    }
> +
> +    return 0;
> +}
> +
> +
> +
> +int
>  esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
>                        virBufferPtr buffer)
>  {
> diff --git a/src/esx/esx_vmx.h b/src/esx/esx_vmx.h
> index 325005e..6193409 100644
> --- a/src/esx/esx_vmx.h
> +++ b/src/esx/esx_vmx.h
> @@ -61,6 +61,9 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
>                     esxVI_APIVersion apiVersion);
>  
>  int
> +esxVMX_ParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def);
> +
> +int
>  esxVMX_ParseSCSIController(virConfPtr conf, int controller, int *present,
>                             char **virtualDev);
>  
> @@ -96,6 +99,9 @@ esxVMX_FormatConfig(esxVI_Context *ctx, virDomainDefPtr def,
>                      esxVI_APIVersion apiVersion);
>  
>  int
> +esxVMX_FormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer);
> +
> +int
>  esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
>                        virBufferPtr buffer);
>  
> diff --git a/tests/vmx2xmldata/vmx2xml-graphics-vnc.vmx b/tests/vmx2xmldata/vmx2xml-graphics-vnc.vmx
> new file mode 100644
> index 0000000..bd3e55f
> --- /dev/null
> +++ b/tests/vmx2xmldata/vmx2xml-graphics-vnc.vmx
> @@ -0,0 +1,6 @@
> +config.version = "8"
> +virtualHW.version = "4"
> +RemoteDisplay.vnc.enabled = "true"
> +RemoteDisplay.vnc.port = "5903"
> +RemoteDisplay.vnc.keymap = "de"
> +RemoteDisplay.vnc.password = "password"
> diff --git a/tests/vmx2xmldata/vmx2xml-graphics-vnc.xml b/tests/vmx2xmldata/vmx2xml-graphics-vnc.xml
> new file mode 100644
> index 0000000..159324d
> --- /dev/null
> +++ b/tests/vmx2xmldata/vmx2xml-graphics-vnc.xml
> @@ -0,0 +1,17 @@
> +<domain type='vmware'>
> +  <uuid>00000000-0000-0000-0000-000000000000</uuid>
> +  <memory>32768</memory>
> +  <currentMemory>32768</currentMemory>
> +  <vcpu>1</vcpu>
> +  <os>
> +    <type arch='i686'>hvm</type>
> +  </os>
> +  <clock offset='utc'/>
> +  <on_poweroff>destroy</on_poweroff>
> +  <on_reboot>restart</on_reboot>
> +  <on_crash>destroy</on_crash>
> +  <devices>
> +    <input type='mouse' bus='ps2'/>
> +    <graphics type='vnc' port='5903' autoport='no' keymap='de' passwd='password'/>
> +  </devices>
> +</domain>
> diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c
> index b83f23f..8ea0b12 100644
> --- a/tests/vmx2xmltest.c
> +++ b/tests/vmx2xmltest.c
> @@ -42,7 +42,7 @@ testCompareFiles(const char *vmx, const char *xml, esxVI_APIVersion apiVersion)
>          goto failure;
>      }
>  
> -    formatted = virDomainDefFormat(NULL, def, 0);
> +    formatted = virDomainDefFormat(NULL, def, VIR_DOMAIN_XML_SECURE);
>  
>      if (formatted == NULL) {
>          goto failure;
> @@ -120,6 +120,8 @@ mymain(int argc, char **argv)
>      DO_TEST("minimal", "minimal", esxVI_APIVersion_25);
>      DO_TEST("minimal-64bit", "minimal-64bit", esxVI_APIVersion_25);
>  
> +    DO_TEST("graphics-vnc", "graphics-vnc", esxVI_APIVersion_25);
> +
>      DO_TEST("scsi-buslogic", "scsi-buslogic", esxVI_APIVersion_25);
>      DO_TEST("scsi-writethrough", "scsi-writethrough", esxVI_APIVersion_25);
>  
> diff --git a/tests/xml2vmxdata/xml2vmx-graphics-vnc.vmx b/tests/xml2vmxdata/xml2vmx-graphics-vnc.vmx
> new file mode 100644
> index 0000000..b4966b5
> --- /dev/null
> +++ b/tests/xml2vmxdata/xml2vmx-graphics-vnc.vmx
> @@ -0,0 +1,11 @@
> +config.version = "8"
> +virtualHW.version = "4"
> +guestOS = "other"
> +uuid.bios = "56 4d 9b ef ac d9 b4 e0-c8 f0 ae a8 b9 10 35 15"
> +displayName = "minimal"
> +memsize = "4"
> +numvcpus = "1"
> +RemoteDisplay.vnc.enabled = "true"
> +RemoteDisplay.vnc.port = "5903"
> +RemoteDisplay.vnc.keymap = "de"
> +RemoteDisplay.vnc.password = "password"
> diff --git a/tests/xml2vmxdata/xml2vmx-graphics-vnc.xml b/tests/xml2vmxdata/xml2vmx-graphics-vnc.xml
> new file mode 100644
> index 0000000..400dcdd
> --- /dev/null
> +++ b/tests/xml2vmxdata/xml2vmx-graphics-vnc.xml
> @@ -0,0 +1,11 @@
> +<domain type='vmware'>
> +  <name>minimal</name>
> +  <uuid>564d9bef-acd9-b4e0-c8f0-aea8b9103515</uuid>
> +  <memory>4096</memory>
> +  <os>
> +    <type>hvm</type>
> +  </os>
> +  <devices>
> +    <graphics type='vnc' port='5903' autoport='no' keymap='de' passwd='password'/>
> +  </devices>
> +</domain>
> diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c
> index dfaca02..530dd2a 100644
> --- a/tests/xml2vmxtest.c
> +++ b/tests/xml2vmxtest.c
> @@ -173,6 +173,8 @@ mymain(int argc, char **argv)
>      DO_TEST("minimal", "minimal", esxVI_APIVersion_25);
>      DO_TEST("minimal-64bit", "minimal-64bit", esxVI_APIVersion_25);
>  
> +    DO_TEST("graphics-vnc", "graphics-vnc", esxVI_APIVersion_25);
> +
>      DO_TEST("scsi-buslogic", "scsi-buslogic", esxVI_APIVersion_25);
>      DO_TEST("scsi-writethrough", "scsi-writethrough", esxVI_APIVersion_25);
>  
> -- 

ACK, this is nice - it sould mean that you can connect to ESX guest consoles
in virt-manager now


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 :|




More information about the libvir-list mailing list