Re: [libvirt] [PATCH 2/3] vbox: Read runtime RDP port and handle autoport.

2017-10-17 Thread John Ferlan


On 10/10/2017 05:52 PM, Dawid Zamirski wrote:
> VirutalBox has a IVRDEServerInfo sturcture available that
> gives the effective runtime port that the VM is using when it's
> running. This is useful when the "TCP/Ports" VBox property was set to
> port range (e.g. via autoport = "yes" or via VBoxManage) in which
> case it would be impossible to get the "active" port otherwise.
> ---
>  src/vbox/vbox_common.c|   3 +-
>  src/vbox/vbox_tmpl.c  | 135 
> +-
>  src/vbox/vbox_uniformed_api.h |   2 +-
>  3 files changed, 97 insertions(+), 43 deletions(-)
> 

Is there more than one change going on here?

The removal of VBOX_SESSION_{OPEN|CLOSE} could seemingly be a separately
explained patch...



> diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
> index 92ee37164..d542f2b76 100644
> --- a/src/vbox/vbox_common.c
> +++ b/src/vbox/vbox_common.c
> @@ -3326,7 +3326,8 @@ vboxDumpDisplay(virDomainDefPtr def, vboxDriverPtr 
> data, IMachine *machine)
>  if (VIR_ALLOC(graphics) < 0)
>  goto cleanup;
>  
> -gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, graphics);
> +gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, machine, graphics);
> +gVBoxAPI.UISession.Close(data->vboxSession);
>  
>  graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_RDP;
>  
> diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
> index 8e47d90d6..ff69cf39c 100644
> --- a/src/vbox/vbox_tmpl.c
> +++ b/src/vbox/vbox_tmpl.c
> @@ -144,12 +144,6 @@ if (strUtf16) {\
>(unsigned)(iid)->m3[7]);\
>  }\
>  
> -#define VBOX_SESSION_OPEN(/* unused */ iid_value, /* in */ machine) \
> -machine->vtbl->LockMachine(machine, data->vboxSession, LockType_Write)
> -
> -#define VBOX_SESSION_CLOSE() \
> -data->vboxSession->vtbl->UnlockMachine(data->vboxSession)
> -
>  #define VBOX_IID_INITIALIZER { NULL, true }
>  
>  /* default RDP port range to use for auto-port setting */
> @@ -227,29 +221,6 @@ _vboxIIDFromArrayItem(vboxDriverPtr data, vboxIID *iid,
>  _vboxIIDFromArrayItem(data, iid, array, idx)
>  #define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16)
>  
> -/**
> - * Converts Utf-16 string to int
> - */
> -static int PRUnicharToInt(PCVBOXXPCOM pFuncs, PRUnichar *strUtf16)
> -{
> -char *strUtf8 = NULL;
> -int ret = 0;
> -
> -if (!strUtf16)
> -return -1;
> -
> -pFuncs->pfnUtf16ToUtf8(strUtf16, );
> -if (!strUtf8)
> -return -1;
> -
> -if (virStrToLong_i(strUtf8, NULL, 10, ) < 0)
> -ret = -1;
> -
> -pFuncs->pfnUtf8Free(strUtf8);
> -
> -return ret;
> -}
> -
>  /**
>   * Converts int to Utf-16 string
>   */
> @@ -286,6 +257,56 @@ static virDomainState _vboxConvertState(PRUint32 state)
>  }
>  }
>  
> +static int
> +vboxGetActiveVRDEServerPort(ISession *session, IMachine *machine)
> +{
> +nsresult rc;
> +PRInt32 port = -1;
> +IVRDEServerInfo *vrdeInfo = NULL;
> +IConsole *console = NULL;
> +int locked = 0;
> +
> +rc = machine->vtbl->LockMachine(machine, session, LockType_Shared);
> +if (NS_FAILED(rc)) {
> +VIR_WARN("Could not obtain shared lock on VBox VM, rc=%08x", rc);
> +goto cleanup;

Why not just return -1 here since cleanup wouldn't need to clean up
@console or @vrdeInfo

That way @locked isn't necessary either.

> +} else {
> +locked = 1;
> +}
> +
> +rc = session->vtbl->GetConsole(session, );
> +if (NS_FAILED(rc)) {
> +VIR_WARN("Could not get VBox session console, rc=%08x", rc);
> +goto cleanup;
> +}
> +
> +/* it may be null if VM is not running */
> +if (!console)
> +goto cleanup;
> +
> +rc = console->vtbl->GetVRDEServerInfo(console, );
> +
> +if (NS_FAILED(rc) || !vrdeInfo) {
> +VIR_WARN("Could not get VBox VM VRDEServerInfo, rc=%08x", rc);
> +goto cleanup;
> +}
> +
> +rc = vrdeInfo->vtbl->GetPort(vrdeInfo, );
> +
> +if (NS_FAILED(rc)) {
> +VIR_WARN("Could not read port from VRDEServerInfo, rc=%08x", rc);
> +goto cleanup;
> +}
> +
> + cleanup:
> +VBOX_RELEASE(console);
> +VBOX_RELEASE(vrdeInfo);
> +if (locked)
> +session->vtbl->UnlockMachine(session);
> +
> +return port;
> +}
> +
>  static int
>  _vboxDomainSnapshotRestore(virDomainPtr dom,
>IMachine *machine,
> @@ -326,7 +347,7 @@ _vboxDomainSnapshotRestore(virDomainPtr dom,
>  goto cleanup;
>  }
>  
> -rc = VBOX_SESSION_OPEN(domiid.value, machine);
> +rc = machine->vtbl->LockMachine(machine, data->vboxSession, 
> LockType_Write);
>  #if VBOX_API_VERSION < 500
>  if (NS_SUCCEEDED(rc))
>  rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, 
> );
> @@ -371,7 +392,7 @@ _vboxDomainSnapshotRestore(virDomainPtr dom,
>  #if VBOX_API_VERSION < 500
>  VBOX_RELEASE(console);
>  #endif /*VBOX_API_VERSION < 500*/
> -VBOX_SESSION_CLOSE();
> +

[libvirt] [PATCH 2/3] vbox: Read runtime RDP port and handle autoport.

2017-10-10 Thread Dawid Zamirski
VirutalBox has a IVRDEServerInfo sturcture available that
gives the effective runtime port that the VM is using when it's
running. This is useful when the "TCP/Ports" VBox property was set to
port range (e.g. via autoport = "yes" or via VBoxManage) in which
case it would be impossible to get the "active" port otherwise.
---
 src/vbox/vbox_common.c|   3 +-
 src/vbox/vbox_tmpl.c  | 135 +-
 src/vbox/vbox_uniformed_api.h |   2 +-
 3 files changed, 97 insertions(+), 43 deletions(-)

diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 92ee37164..d542f2b76 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -3326,7 +3326,8 @@ vboxDumpDisplay(virDomainDefPtr def, vboxDriverPtr data, 
IMachine *machine)
 if (VIR_ALLOC(graphics) < 0)
 goto cleanup;
 
-gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, graphics);
+gVBoxAPI.UIVRDEServer.GetPorts(data, VRDEServer, machine, graphics);
+gVBoxAPI.UISession.Close(data->vboxSession);
 
 graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_RDP;
 
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 8e47d90d6..ff69cf39c 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -144,12 +144,6 @@ if (strUtf16) {\
   (unsigned)(iid)->m3[7]);\
 }\
 
-#define VBOX_SESSION_OPEN(/* unused */ iid_value, /* in */ machine) \
-machine->vtbl->LockMachine(machine, data->vboxSession, LockType_Write)
-
-#define VBOX_SESSION_CLOSE() \
-data->vboxSession->vtbl->UnlockMachine(data->vboxSession)
-
 #define VBOX_IID_INITIALIZER { NULL, true }
 
 /* default RDP port range to use for auto-port setting */
@@ -227,29 +221,6 @@ _vboxIIDFromArrayItem(vboxDriverPtr data, vboxIID *iid,
 _vboxIIDFromArrayItem(data, iid, array, idx)
 #define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16)
 
-/**
- * Converts Utf-16 string to int
- */
-static int PRUnicharToInt(PCVBOXXPCOM pFuncs, PRUnichar *strUtf16)
-{
-char *strUtf8 = NULL;
-int ret = 0;
-
-if (!strUtf16)
-return -1;
-
-pFuncs->pfnUtf16ToUtf8(strUtf16, );
-if (!strUtf8)
-return -1;
-
-if (virStrToLong_i(strUtf8, NULL, 10, ) < 0)
-ret = -1;
-
-pFuncs->pfnUtf8Free(strUtf8);
-
-return ret;
-}
-
 /**
  * Converts int to Utf-16 string
  */
@@ -286,6 +257,56 @@ static virDomainState _vboxConvertState(PRUint32 state)
 }
 }
 
+static int
+vboxGetActiveVRDEServerPort(ISession *session, IMachine *machine)
+{
+nsresult rc;
+PRInt32 port = -1;
+IVRDEServerInfo *vrdeInfo = NULL;
+IConsole *console = NULL;
+int locked = 0;
+
+rc = machine->vtbl->LockMachine(machine, session, LockType_Shared);
+if (NS_FAILED(rc)) {
+VIR_WARN("Could not obtain shared lock on VBox VM, rc=%08x", rc);
+goto cleanup;
+} else {
+locked = 1;
+}
+
+rc = session->vtbl->GetConsole(session, );
+if (NS_FAILED(rc)) {
+VIR_WARN("Could not get VBox session console, rc=%08x", rc);
+goto cleanup;
+}
+
+/* it may be null if VM is not running */
+if (!console)
+goto cleanup;
+
+rc = console->vtbl->GetVRDEServerInfo(console, );
+
+if (NS_FAILED(rc) || !vrdeInfo) {
+VIR_WARN("Could not get VBox VM VRDEServerInfo, rc=%08x", rc);
+goto cleanup;
+}
+
+rc = vrdeInfo->vtbl->GetPort(vrdeInfo, );
+
+if (NS_FAILED(rc)) {
+VIR_WARN("Could not read port from VRDEServerInfo, rc=%08x", rc);
+goto cleanup;
+}
+
+ cleanup:
+VBOX_RELEASE(console);
+VBOX_RELEASE(vrdeInfo);
+if (locked)
+session->vtbl->UnlockMachine(session);
+
+return port;
+}
+
 static int
 _vboxDomainSnapshotRestore(virDomainPtr dom,
   IMachine *machine,
@@ -326,7 +347,7 @@ _vboxDomainSnapshotRestore(virDomainPtr dom,
 goto cleanup;
 }
 
-rc = VBOX_SESSION_OPEN(domiid.value, machine);
+rc = machine->vtbl->LockMachine(machine, data->vboxSession, 
LockType_Write);
 #if VBOX_API_VERSION < 500
 if (NS_SUCCEEDED(rc))
 rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, );
@@ -371,7 +392,7 @@ _vboxDomainSnapshotRestore(virDomainPtr dom,
 #if VBOX_API_VERSION < 500
 VBOX_RELEASE(console);
 #endif /*VBOX_API_VERSION < 500*/
-VBOX_SESSION_CLOSE();
+data->vboxSession->vtbl->UnlockMachine(data->vboxSession);
 vboxIIDUnalloc();
 return ret;
 }
@@ -1582,24 +1603,56 @@ _vrdeServerSetEnabled(IVRDEServer *VRDEServer, PRBool 
enabled)
 }
 
 static nsresult
-_vrdeServerGetPorts(vboxDriverPtr data ATTRIBUTE_UNUSED,
-IVRDEServer *VRDEServer, virDomainGraphicsDefPtr graphics)
+_vrdeServerGetPorts(vboxDriverPtr data, IVRDEServer *VRDEServer,
+IMachine *machine, virDomainGraphicsDefPtr graphics)
 {
 nsresult rc;
 PRUnichar *VRDEPortsKey = NULL;
 PRUnichar *VRDEPortsValue = NULL;
+PRInt32 port = -1;
+ssize_t nmatches