[libvirt] [PATCH v4 8/8] vbox: Implement the driver methods

Daniel P. Berrange berrange at redhat.com
Fri May 13 09:21:06 UTC 2011


On Thu, May 12, 2011 at 06:29:15PM +0200, Michal Privoznik wrote:
> * src/vbox/vbox_tmpl.c: New vboxDomainScreenshot() function
> ---
>  src/vbox/vbox_tmpl.c |  133 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 133 insertions(+), 0 deletions(-)
> 
> diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
> index dc91240..d598bcf 100644
> --- a/src/vbox/vbox_tmpl.c
> +++ b/src/vbox/vbox_tmpl.c
> @@ -36,6 +36,9 @@
>  
>  #include <sys/utsname.h>
>  #include <unistd.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
>  
>  #include "internal.h"
>  #include "datatypes.h"
> @@ -51,6 +54,9 @@
>  #include "nodeinfo.h"
>  #include "logging.h"
>  #include "vbox_driver.h"
> +#include "configmake.h"
> +#include "files.h"
> +#include "fdstream.h"
>  
>  /* This one changes from version to version. */
>  #if VBOX_API_VERSION == 2002
> @@ -8527,6 +8533,129 @@ static char *vboxStorageVolGetPath(virStorageVolPtr vol) {
>      return ret;
>  }
>  
> +#if VBOX_API_VERSION == 4000
> +static char *
> +vboxDomainScreenshot(virDomainPtr dom,
> +                     virStreamPtr st,
> +                     unsigned int screen,
> +                     unsigned int flags ATTRIBUTE_UNUSED)
> +{
> +    VBOX_OBJECT_CHECK(dom->conn, char *, NULL);
> +    IConsole *console = NULL;
> +    vboxIID iid = VBOX_IID_INITIALIZER;
> +    IMachine *machine = NULL;
> +    nsresult rc;
> +    char *tmp;
> +    int tmp_fd = -1;
> +    unsigned int max_screen;
> +
> +    vboxIIDFromUUID(&iid, dom->uuid);
> +    rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
> +    if (NS_FAILED(rc)) {
> +        vboxError(VIR_ERR_NO_DOMAIN, "%s",
> +                  _("no domain with matching uuid"));
> +        return NULL;
> +    }
> +
> +    rc = machine->vtbl->GetMonitorCount(machine, &max_screen);
> +    if (NS_FAILED(rc)) {
> +        vboxError(VIR_ERR_OPERATION_FAILED, "%s",
> +                  _("unable to get monitor count"));
> +        VBOX_RELEASE(machine);
> +        return NULL;
> +    }
> +
> +    if (screen >= max_screen) {
> +        vboxError(VIR_ERR_INVALID_ARG, _("screen ID higher than monitor "
> +                  "count (%d)"), max_screen);
> +        VBOX_RELEASE(machine);
> +        return NULL;
> +    }
> +
> +    if (virAsprintf(&tmp, "%s/cache/libvirt/vbox.screendump.XXXXXX", LOCALSTATEDIR) < 0) {
> +        virReportOOMError();
> +        VBOX_RELEASE(machine);
> +        return NULL;
> +    }
> +
> +    if ((tmp_fd = mkstemp(tmp)) == -1) {
> +        virReportSystemError(errno, _("mkstemp(\"%s\") failed"), tmp);
> +        VIR_FREE(tmp);
> +        VBOX_RELEASE(machine);
> +        return NULL;
> +    }
> +
> +
> +    rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
> +    if (NS_SUCCEEDED(rc)) {
> +        rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
> +        if (NS_SUCCEEDED(rc) && console) {
> +            IDisplay *display = NULL;
> +
> +            console->vtbl->GetDisplay(console, &display);
> +
> +            if (display) {
> +                PRUint32 width, height, bitsPerPixel;
> +                PRUint32 screenDataSize;
> +                PRUint8 *screenData;
> +
> +                rc = display->vtbl->GetScreenResolution(display, screen,
> +                                                        &width, &height,
> +                                                        &bitsPerPixel);
> +
> +                if (NS_FAILED(rc) || !width || !height) {
> +                    vboxError(VIR_ERR_OPERATION_FAILED, "%s",
> +                              _("unable to get screen resolution"));
> +                    goto endjob;
> +                }
> +
> +                rc = display->vtbl->TakeScreenShotPNGToArray(display, screen,
> +                                                             width, height,
> +                                                             &screenDataSize,
> +                                                             &screenData);
> +                if (NS_FAILED(rc)) {
> +                    vboxError(VIR_ERR_OPERATION_FAILED, "%s",
> +                              _("failed to take screenshot"));
> +                    goto endjob;
> +                }
> +
> +                if (safewrite(tmp_fd, (char *) screenData,
> +                              screenDataSize) < 0) {
> +                    virReportSystemError(errno, _("unable to write data "
> +                                                  "to '%s'"), tmp);
> +                    goto endjob;
> +                }
> +
> +                if (VIR_CLOSE(tmp_fd) < 0) {
> +                    virReportSystemError(errno, _("unable to close %s"), tmp);
> +                    goto endjob;
> +                }
> +
> +                if (virFDStreamOpenFile(st, tmp, 0, 0, O_RDONLY, true) < 0) {
> +                    vboxError(VIR_ERR_OPERATION_FAILED, "%s",
> +                              _("unable to open stream"));
> +                    goto endjob;
> +                }
> +
> +                ret = strdup("image/png; charset=binary");


Likewise, drop the '; charset=binary' here

ACK with that change

Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list