Changes needed for multiple graphics adapters

* src/domain_conf.c src/domain_conf.h: parse and save multiple
  graphics elements instead of one, patch by Pritesh Kothari
* src/qemu_conf.c src/qemu_driver.c: adapt the qemu/kvm driver for
  the new structures, patch by Pritesh Kothari
* src/xend_internal.c src/xm_internal.c: same thing for Xen drivers
Daniel
This commit is contained in:
Daniel Veillard 2009-05-07 07:27:49 +00:00
parent 9f9ce6130d
commit 7ee54d8356
7 changed files with 114 additions and 79 deletions

View File

@ -1,3 +1,11 @@
Thu May 7 09:24:47 CEST 2009 Daniel Veillard <veillard@redhat.com>
* src/domain_conf.c src/domain_conf.h: parse and save multiple
graphics elements instead of one, patch by Pritesh Kothari
* src/qemu_conf.c src/qemu_driver.c: adapt the qemu/kvm driver for
the new structures, patch by Pritesh Kothari
* src/xend_internal.c src/xm_internal.c: same thing for Xen drivers
Thu May 7 09:16:05 CEST 2009 Guido Günther <agx@sigxcpu.org> Thu May 7 09:16:05 CEST 2009 Guido Günther <agx@sigxcpu.org>
* src/lxc_controller.c (main): don't crash when called without * src/lxc_controller.c (main): don't crash when called without

View File

@ -408,7 +408,9 @@ void virDomainDefFree(virDomainDefPtr def)
if (!def) if (!def)
return; return;
virDomainGraphicsDefFree(def->graphics); for (i = 0 ; i < def->ngraphics ; i++)
virDomainGraphicsDefFree(def->graphics[i]);
VIR_FREE(def->graphics);
for (i = 0 ; i < def->ninputs ; i++) for (i = 0 ; i < def->ninputs ; i++)
virDomainInputDefFree(def->inputs[i]); virDomainInputDefFree(def->inputs[i]);
@ -2422,19 +2424,21 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
"%s", _("cannot extract graphics devices")); "%s", _("cannot extract graphics devices"));
goto error; goto error;
} }
if (n > 0) { if (n && VIR_ALLOC_N(def->graphics, n) < 0)
goto no_memory;
for (i = 0 ; i < n ; i++) {
virDomainGraphicsDefPtr graphics = virDomainGraphicsDefParseXML(conn, virDomainGraphicsDefPtr graphics = virDomainGraphicsDefParseXML(conn,
nodes[0], nodes[i],
flags); flags);
if (!graphics) if (!graphics)
goto error; goto error;
def->graphics = graphics; def->graphics[def->ngraphics++] = graphics;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
/* If graphics are enabled, there's an implicit PS2 mouse */ /* If graphics are enabled, there's an implicit PS2 mouse */
if (def->graphics != NULL) { if (def->ngraphics > 0) {
virDomainInputDefPtr input; virDomainInputDefPtr input;
if (VIR_ALLOC(input) < 0) { if (VIR_ALLOC(input) < 0) {
@ -3506,7 +3510,7 @@ char *virDomainDefFormat(virConnectPtr conn,
virDomainInputDefFormat(conn, &buf, def->inputs[n]) < 0) virDomainInputDefFormat(conn, &buf, def->inputs[n]) < 0)
goto cleanup; goto cleanup;
if (def->graphics) { if (def->ngraphics > 0) {
/* If graphics is enabled, add the implicit mouse */ /* If graphics is enabled, add the implicit mouse */
virDomainInputDef autoInput = { virDomainInputDef autoInput = {
VIR_DOMAIN_INPUT_TYPE_MOUSE, VIR_DOMAIN_INPUT_TYPE_MOUSE,
@ -3517,8 +3521,9 @@ char *virDomainDefFormat(virConnectPtr conn,
if (virDomainInputDefFormat(conn, &buf, &autoInput) < 0) if (virDomainInputDefFormat(conn, &buf, &autoInput) < 0)
goto cleanup; goto cleanup;
if (virDomainGraphicsDefFormat(conn, &buf, def, def->graphics, flags) < 0) for (n = 0 ; n < def->ngraphics ; n++)
goto cleanup; if (virDomainGraphicsDefFormat(conn, &buf, def, def->graphics[n], flags) < 0)
goto cleanup;
} }
for (n = 0 ; n < def->nsounds ; n++) for (n = 0 ; n < def->nsounds ; n++)

View File

@ -456,8 +456,8 @@ struct _virDomainDef {
int localtime; int localtime;
/* Only 1 */ int ngraphics;
virDomainGraphicsDefPtr graphics; virDomainGraphicsDefPtr *graphics;
int ndisks; int ndisks;
virDomainDiskDefPtr *disks; virDomainDiskDefPtr *disks;

View File

@ -1348,21 +1348,21 @@ int qemudBuildCommandLine(virConnectPtr conn,
} }
} }
if (def->graphics && if ((def->ngraphics == 1) &&
def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) { def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virBuffer opt = VIR_BUFFER_INITIALIZER; virBuffer opt = VIR_BUFFER_INITIALIZER;
char *optstr; char *optstr;
if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) { if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
if (def->graphics->data.vnc.listenAddr) if (def->graphics[0]->data.vnc.listenAddr)
virBufferAdd(&opt, def->graphics->data.vnc.listenAddr, -1); virBufferAdd(&opt, def->graphics[0]->data.vnc.listenAddr, -1);
else if (driver->vncListen) else if (driver->vncListen)
virBufferAdd(&opt, driver->vncListen, -1); virBufferAdd(&opt, driver->vncListen, -1);
virBufferVSprintf(&opt, ":%d", virBufferVSprintf(&opt, ":%d",
def->graphics->data.vnc.port - 5900); def->graphics[0]->data.vnc.port - 5900);
if (def->graphics->data.vnc.passwd || if (def->graphics[0]->data.vnc.passwd ||
driver->vncPassword) driver->vncPassword)
virBufferAddLit(&opt, ",password"); virBufferAddLit(&opt, ",password");
@ -1387,7 +1387,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
} }
} else { } else {
virBufferVSprintf(&opt, "%d", virBufferVSprintf(&opt, "%d",
def->graphics->data.vnc.port - 5900); def->graphics[0]->data.vnc.port - 5900);
} }
if (virBufferError(&opt)) if (virBufferError(&opt))
goto no_memory; goto no_memory;
@ -1396,22 +1396,22 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ARG_LIT("-vnc"); ADD_ARG_LIT("-vnc");
ADD_ARG(optstr); ADD_ARG(optstr);
if (def->graphics->data.vnc.keymap) { if (def->graphics[0]->data.vnc.keymap) {
ADD_ARG_LIT("-k"); ADD_ARG_LIT("-k");
ADD_ARG_LIT(def->graphics->data.vnc.keymap); ADD_ARG_LIT(def->graphics[0]->data.vnc.keymap);
} }
} else if (def->graphics && } else if ((def->ngraphics == 1) &&
def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
char *xauth = NULL; char *xauth = NULL;
char *display = NULL; char *display = NULL;
if (def->graphics->data.sdl.xauth && if (def->graphics[0]->data.sdl.xauth &&
virAsprintf(&xauth, "XAUTHORITY=%s", virAsprintf(&xauth, "XAUTHORITY=%s",
def->graphics->data.sdl.xauth) < 0) def->graphics[0]->data.sdl.xauth) < 0)
goto no_memory; goto no_memory;
if (def->graphics->data.sdl.display && if (def->graphics[0]->data.sdl.display &&
virAsprintf(&display, "DISPLAY=%s", virAsprintf(&display, "DISPLAY=%s",
def->graphics->data.sdl.display) < 0) { def->graphics[0]->data.sdl.display) < 0) {
VIR_FREE(xauth); VIR_FREE(xauth);
goto no_memory; goto no_memory;
} }
@ -1420,7 +1420,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ENV(xauth); ADD_ENV(xauth);
if (display) if (display)
ADD_ENV(display); ADD_ENV(display);
if (def->graphics->data.sdl.fullscreen) if (def->graphics[0]->data.sdl.fullscreen)
ADD_ARG_LIT("-full-screen"); ADD_ARG_LIT("-full-screen");
} }

View File

@ -1140,13 +1140,13 @@ qemudInitPasswords(virConnectPtr conn,
* for that yet... * for that yet...
*/ */
if (vm->def->graphics && if ((vm->def->ngraphics == 1) &&
vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
(vm->def->graphics->data.vnc.passwd || driver->vncPassword)) { (vm->def->graphics[0]->data.vnc.passwd || driver->vncPassword)) {
if (qemudMonitorCommandExtra(vm, "change vnc password", if (qemudMonitorCommandExtra(vm, "change vnc password",
vm->def->graphics->data.vnc.passwd ? vm->def->graphics[0]->data.vnc.passwd ?
vm->def->graphics->data.vnc.passwd : vm->def->graphics[0]->data.vnc.passwd :
driver->vncPassword, driver->vncPassword,
QEMU_PASSWD_PROMPT, QEMU_PASSWD_PROMPT,
&info) < 0) { &info) < 0) {
@ -1338,16 +1338,16 @@ static int qemudStartVMDaemon(virConnectPtr conn,
driver->securityDriver->domainGenSecurityLabel(conn, vm) < 0) driver->securityDriver->domainGenSecurityLabel(conn, vm) < 0)
return -1; return -1;
if (vm->def->graphics && if ((vm->def->ngraphics == 1) &&
vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
vm->def->graphics->data.vnc.autoport) { vm->def->graphics[0]->data.vnc.autoport) {
int port = qemudNextFreeVNCPort(driver); int port = qemudNextFreeVNCPort(driver);
if (port < 0) { if (port < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("Unable to find an unused VNC port")); "%s", _("Unable to find an unused VNC port"));
goto cleanup; goto cleanup;
} }
vm->def->graphics->data.vnc.port = port; vm->def->graphics[0]->data.vnc.port = port;
} }
if (virFileMakePath(driver->logDir) < 0) { if (virFileMakePath(driver->logDir) < 0) {
@ -1504,10 +1504,10 @@ cleanup:
VIR_FREE(vm->def->seclabel.label); VIR_FREE(vm->def->seclabel.label);
VIR_FREE(vm->def->seclabel.imagelabel); VIR_FREE(vm->def->seclabel.imagelabel);
} }
if (vm->def->graphics && if ((vm->def->ngraphics == 1) &&
vm->def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
vm->def->graphics->data.vnc.autoport) vm->def->graphics[0]->data.vnc.autoport)
vm->def->graphics->data.vnc.port = -1; vm->def->graphics[0]->data.vnc.port = -1;
if (vm->logfile != -1) { if (vm->logfile != -1) {
close(vm->logfile); close(vm->logfile);
vm->logfile = -1; vm->logfile = -1;

View File

@ -2023,7 +2023,11 @@ xenDaemonParseSxprGraphicsOld(virConnectPtr conn,
!(graphics->data.vnc.keymap = strdup(keymap))) !(graphics->data.vnc.keymap = strdup(keymap)))
goto no_memory; goto no_memory;
def->graphics = graphics; if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto no_memory;
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL;
} else if ((tmp = sexpr_fmt_node(root, "domain/image/%s/sdl", hvm ? "hvm" : "linux")) && } else if ((tmp = sexpr_fmt_node(root, "domain/image/%s/sdl", hvm ? "hvm" : "linux")) &&
tmp[0] == '1') { tmp[0] == '1') {
/* Graphics device (HVM, or old (pre-3.0.4) style PV sdl config) */ /* Graphics device (HVM, or old (pre-3.0.4) style PV sdl config) */
@ -2041,7 +2045,11 @@ xenDaemonParseSxprGraphicsOld(virConnectPtr conn,
!(graphics->data.sdl.xauth = strdup(xauth))) !(graphics->data.sdl.xauth = strdup(xauth)))
goto no_memory; goto no_memory;
def->graphics = graphics; if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto no_memory;
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL;
} }
return 0; return 0;
@ -2130,7 +2138,11 @@ xenDaemonParseSxprGraphicsNew(virConnectPtr conn,
goto no_memory; goto no_memory;
} }
def->graphics = graphics; if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto no_memory;
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL;
break; break;
} }
} }
@ -2447,7 +2459,7 @@ xenDaemonParseSxpr(virConnectPtr conn,
goto error; goto error;
/* Graphics device (HVM <= 3.0.4, or PV <= 3.0.3) vnc config */ /* Graphics device (HVM <= 3.0.4, or PV <= 3.0.3) vnc config */
if (!def->graphics && if ((def->ngraphics == 0) &&
xenDaemonParseSxprGraphicsOld(conn, def, root, hvm, xendConfigVersion) < 0) xenDaemonParseSxprGraphicsOld(conn, def, root, hvm, xendConfigVersion) < 0)
goto error; goto error;
@ -5731,8 +5743,9 @@ xenDaemonFormatSxpr(virConnectPtr conn,
/* PV graphics for xen <= 3.0.4, or HVM graphics for xen <= 3.1.0 */ /* PV graphics for xen <= 3.0.4, or HVM graphics for xen <= 3.1.0 */
if ((!hvm && xendConfigVersion < XEND_CONFIG_MIN_VERS_PVFB_NEWCONF) || if ((!hvm && xendConfigVersion < XEND_CONFIG_MIN_VERS_PVFB_NEWCONF) ||
(hvm && xendConfigVersion < 4)) { (hvm && xendConfigVersion < 4)) {
if (def->graphics && if ((def->ngraphics == 1) &&
xenDaemonFormatSxprGraphicsOld(conn, def->graphics, &buf, xendConfigVersion) < 0) xenDaemonFormatSxprGraphicsOld(conn, def->graphics[0],
&buf, xendConfigVersion) < 0)
goto error; goto error;
} }
@ -5756,8 +5769,8 @@ xenDaemonFormatSxpr(virConnectPtr conn,
* or HVM graphics config xen >= 3.0.5 */ * or HVM graphics config xen >= 3.0.5 */
if ((xendConfigVersion >= XEND_CONFIG_MIN_VERS_PVFB_NEWCONF && !hvm) || if ((xendConfigVersion >= XEND_CONFIG_MIN_VERS_PVFB_NEWCONF && !hvm) ||
(xendConfigVersion >= 4 && hvm)) { (xendConfigVersion >= 4 && hvm)) {
if (def->graphics && if ((def->ngraphics == 1) &&
xenDaemonFormatSxprGraphicsNew(conn, def->graphics, &buf) < 0) xenDaemonFormatSxprGraphicsNew(conn, def->graphics[0], &buf) < 0)
goto error; goto error;
} }

View File

@ -1257,7 +1257,10 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
if (xenXMConfigCopyStringOpt(conn, conf, "keymap", &graphics->data.vnc.keymap) < 0) if (xenXMConfigCopyStringOpt(conn, conf, "keymap", &graphics->data.vnc.keymap) < 0)
goto cleanup; goto cleanup;
def->graphics = graphics; if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto no_memory;
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL; graphics = NULL;
} else { } else {
if (xenXMConfigGetBool(conn, conf, "sdl", &val, 0) < 0) if (xenXMConfigGetBool(conn, conf, "sdl", &val, 0) < 0)
@ -1270,7 +1273,10 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
goto cleanup; goto cleanup;
if (xenXMConfigCopyStringOpt(conn, conf, "xauthority", &graphics->data.sdl.xauth) < 0) if (xenXMConfigCopyStringOpt(conn, conf, "xauthority", &graphics->data.sdl.xauth) < 0)
goto cleanup; goto cleanup;
def->graphics = graphics; if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto no_memory;
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL; graphics = NULL;
} }
} }
@ -1339,7 +1345,10 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
nextkey++; nextkey++;
key = nextkey; key = nextkey;
} }
def->graphics = graphics; if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto no_memory;
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL; graphics = NULL;
} }
} }
@ -2305,20 +2314,20 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
} }
} }
if (def->graphics) { if (def->ngraphics == 1) {
if (priv->xendConfigVersion < (hvm ? 4 : XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) { if (priv->xendConfigVersion < (hvm ? 4 : XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) {
if (def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
if (xenXMConfigSetInt(conf, "sdl", 1) < 0) if (xenXMConfigSetInt(conf, "sdl", 1) < 0)
goto no_memory; goto no_memory;
if (xenXMConfigSetInt(conf, "vnc", 0) < 0) if (xenXMConfigSetInt(conf, "vnc", 0) < 0)
goto no_memory; goto no_memory;
if (def->graphics->data.sdl.display && if (def->graphics[0]->data.sdl.display &&
xenXMConfigSetString(conf, "display", xenXMConfigSetString(conf, "display",
def->graphics->data.sdl.display) < 0) def->graphics[0]->data.sdl.display) < 0)
goto no_memory; goto no_memory;
if (def->graphics->data.sdl.xauth && if (def->graphics[0]->data.sdl.xauth &&
xenXMConfigSetString(conf, "xauthority", xenXMConfigSetString(conf, "xauthority",
def->graphics->data.sdl.xauth) < 0) def->graphics[0]->data.sdl.xauth) < 0)
goto no_memory; goto no_memory;
} else { } else {
if (xenXMConfigSetInt(conf, "sdl", 0) < 0) if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
@ -2326,53 +2335,53 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
if (xenXMConfigSetInt(conf, "vnc", 1) < 0) if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
goto no_memory; goto no_memory;
if (xenXMConfigSetInt(conf, "vncunused", if (xenXMConfigSetInt(conf, "vncunused",
def->graphics->data.vnc.autoport ? 1 : 0) < 0) def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
goto no_memory; goto no_memory;
if (!def->graphics->data.vnc.autoport && if (!def->graphics[0]->data.vnc.autoport &&
xenXMConfigSetInt(conf, "vncdisplay", xenXMConfigSetInt(conf, "vncdisplay",
def->graphics->data.vnc.port - 5900) < 0) def->graphics[0]->data.vnc.port - 5900) < 0)
goto no_memory; goto no_memory;
if (def->graphics->data.vnc.listenAddr && if (def->graphics[0]->data.vnc.listenAddr &&
xenXMConfigSetString(conf, "vnclisten", xenXMConfigSetString(conf, "vnclisten",
def->graphics->data.vnc.listenAddr) < 0) def->graphics[0]->data.vnc.listenAddr) < 0)
goto no_memory; goto no_memory;
if (def->graphics->data.vnc.passwd && if (def->graphics[0]->data.vnc.passwd &&
xenXMConfigSetString(conf, "vncpasswd", xenXMConfigSetString(conf, "vncpasswd",
def->graphics->data.vnc.passwd) < 0) def->graphics[0]->data.vnc.passwd) < 0)
goto no_memory; goto no_memory;
if (def->graphics->data.vnc.keymap && if (def->graphics[0]->data.vnc.keymap &&
xenXMConfigSetString(conf, "keymap", xenXMConfigSetString(conf, "keymap",
def->graphics->data.vnc.keymap) < 0) def->graphics[0]->data.vnc.keymap) < 0)
goto no_memory; goto no_memory;
} }
} else { } else {
virConfValuePtr vfb, disp; virConfValuePtr vfb, disp;
char *vfbstr = NULL; char *vfbstr = NULL;
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
if (def->graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
virBufferAddLit(&buf, "type=sdl"); virBufferAddLit(&buf, "type=sdl");
if (def->graphics->data.sdl.display) if (def->graphics[0]->data.sdl.display)
virBufferVSprintf(&buf, ",display=%s", virBufferVSprintf(&buf, ",display=%s",
def->graphics->data.sdl.display); def->graphics[0]->data.sdl.display);
if (def->graphics->data.sdl.xauth) if (def->graphics[0]->data.sdl.xauth)
virBufferVSprintf(&buf, ",xauthority=%s", virBufferVSprintf(&buf, ",xauthority=%s",
def->graphics->data.sdl.xauth); def->graphics[0]->data.sdl.xauth);
} else { } else {
virBufferAddLit(&buf, "type=vnc"); virBufferAddLit(&buf, "type=vnc");
virBufferVSprintf(&buf, ",vncunused=%d", virBufferVSprintf(&buf, ",vncunused=%d",
def->graphics->data.vnc.autoport ? 1 : 0); def->graphics[0]->data.vnc.autoport ? 1 : 0);
if (!def->graphics->data.vnc.autoport) if (!def->graphics[0]->data.vnc.autoport)
virBufferVSprintf(&buf, ",vncdisplay=%d", virBufferVSprintf(&buf, ",vncdisplay=%d",
def->graphics->data.vnc.port - 5900); def->graphics[0]->data.vnc.port - 5900);
if (def->graphics->data.vnc.listenAddr) if (def->graphics[0]->data.vnc.listenAddr)
virBufferVSprintf(&buf, ",vnclisten=%s", virBufferVSprintf(&buf, ",vnclisten=%s",
def->graphics->data.vnc.listenAddr); def->graphics[0]->data.vnc.listenAddr);
if (def->graphics->data.vnc.passwd) if (def->graphics[0]->data.vnc.passwd)
virBufferVSprintf(&buf, ",vncpasswd=%s", virBufferVSprintf(&buf, ",vncpasswd=%s",
def->graphics->data.vnc.passwd); def->graphics[0]->data.vnc.passwd);
if (def->graphics->data.vnc.keymap) if (def->graphics[0]->data.vnc.keymap)
virBufferVSprintf(&buf, ",keymap=%s", virBufferVSprintf(&buf, ",keymap=%s",
def->graphics->data.vnc.keymap); def->graphics[0]->data.vnc.keymap);
} }
if (virBufferError(&buf)) if (virBufferError(&buf))
goto no_memory; goto no_memory;