Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 252535 Details for
Bug 335932
app-emulation/libvirt: please add qemu-kvm-spice support
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
spice PATCH for libvirt-0.8.5
spice-libvirt-0.8.5.tar (text/plain), 90.00 KB, created by
fkhp
on 2010-10-30 03:34:36 UTC
(
hide
)
Description:
spice PATCH for libvirt-0.8.5
Filename:
MIME Type:
Creator:
fkhp
Created:
2010-10-30 03:34:36 UTC
Size:
90.00 KB
patch
obsolete
>files/01-qxl-xml.patch0000644000000000000000000000415511440167350013525 0ustar rootroot* src/qemu_conf.c: Add dummy entry in enumeration >* docs/schemas/domain.rng: Add 'qxl' as a type for the <video> tag >* src/domain_conf.c, src/domain_conf.h: Add QXL to video type > enumerations >--- > docs/schemas/domain.rng | 1 + > src/conf/domain_conf.c | 3 ++- > src/conf/domain_conf.h | 1 + > src/qemu/qemu_conf.c | 3 ++- > 4 files changed, 6 insertions(+), 2 deletions(-) > >diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng >index c877a35..bf3759e 100644 >--- a/docs/schemas/domain.rng >+++ b/docs/schemas/domain.rng >@@ -1050,6 +1050,7 @@ > <value>vmvga</value> > <value>xen</value> > <value>vbox</value> >+ <value>qxl</value> > </choice> > </attribute> > <optional> >diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c >index 2de838b..a10ef66 100644 >--- a/src/conf/domain_conf.c >+++ b/src/conf/domain_conf.c >@@ -199,7 +199,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, > "cirrus", > "vmvga", > "xen", >- "vbox") >+ "vbox", >+ "qxl") > > VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST, > "mouse", >diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h >index 82f2d15..afd143d 100644 >--- a/src/conf/domain_conf.h >+++ b/src/conf/domain_conf.h >@@ -442,6 +442,7 @@ enum virDomainVideoType { > VIR_DOMAIN_VIDEO_TYPE_VMVGA, > VIR_DOMAIN_VIDEO_TYPE_XEN, > VIR_DOMAIN_VIDEO_TYPE_VBOX, >+ VIR_DOMAIN_VIDEO_TYPE_QXL, > > VIR_DOMAIN_VIDEO_TYPE_LAST > }; >diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c >index 6557b2f..767e168 100644 >--- a/src/qemu/qemu_conf.c >+++ b/src/qemu/qemu_conf.c >@@ -92,7 +92,8 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, > "cirrus", > "vmware", > "", /* no arg needed for xen */ >- "" /* don't support vbox */); >+ "", /* don't support vbox */ >+ "", /* Not implemented QXL yet */); > > int qemudLoadDriverConfig(struct qemud_driver *driver, > const char *filename) { >-- >1.6.6.1 >files/02-spice-graphics.patch0000644000000000000000000001642711440372210015023 0ustar rootroot* docs/schemas/domain.rng: Define the SPICE <graphics> schema >* src/domain_conf.h, src/domain_conf.c: Add parsing and formatting > for SPICE graphics config >* src/qemu_conf.c: Complain about unsupported graphics types >--- > docs/schemas/domain.rng | 38 ++++++++++++++++++++++ > src/conf/domain_conf.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++- > src/conf/domain_conf.h | 9 +++++ > src/qemu/qemu_conf.c | 11 ++++++- > 4 files changed, 136 insertions(+), 2 deletions(-) > >diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng >index bf3759e..edd0b7c 100644 >--- a/docs/schemas/domain.rng >+++ b/docs/schemas/domain.rng >@@ -977,6 +977,44 @@ > </group> > <group> > <attribute name="type"> >+ <value>spice</value> >+ </attribute> >+ <optional> >+ <attribute name="port"> >+ <ref name="PortNumber"/> >+ </attribute> >+ </optional> >+ <optional> >+ <attribute name="tlsPort"> >+ <ref name="PortNumber"/> >+ </attribute> >+ </optional> >+ <optional> >+ <attribute name="autoport"> >+ <choice> >+ <value>yes</value> >+ <value>no</value> >+ </choice> >+ </attribute> >+ </optional> >+ <optional> >+ <attribute name="listen"> >+ <ref name="addrIP"/> >+ </attribute> >+ </optional> >+ <optional> >+ <attribute name="passwd"> >+ <text/> >+ </attribute> >+ </optional> >+ <optional> >+ <attribute name="keymap"> >+ <text/> >+ </attribute> >+ </optional> >+ </group> >+ <group> >+ <attribute name="type"> > <value>rdp</value> > </attribute> > <optional> >diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c >index a10ef66..b25c622 100644 >--- a/src/conf/domain_conf.c >+++ b/src/conf/domain_conf.c >@@ -215,7 +215,8 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TYPE_LAST, > "sdl", > "vnc", > "rdp", >- "desktop") >+ "desktop", >+ "spice") > > VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST, > "subsystem", >@@ -397,6 +398,12 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) > case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: > VIR_FREE(def->data.desktop.display); > break; >+ >+ case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: >+ VIR_FREE(def->data.spice.listenAddr); >+ VIR_FREE(def->data.spice.keymap); >+ VIR_FREE(def->data.spice.passwd); >+ break; > } > > VIR_FREE(def); >@@ -2849,6 +2856,50 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { > def->data.desktop.fullscreen = 0; > > def->data.desktop.display = virXMLPropString(node, "display"); >+ } else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { >+ char *port = virXMLPropString(node, "port"); >+ char *tlsPort; >+ char *autoport; >+ >+ if (port) { >+ if (virStrToLong_i(port, NULL, 10, &def->data.spice.port) < 0) { >+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, >+ _("cannot parse spice port %s"), port); >+ VIR_FREE(port); >+ goto error; >+ } >+ VIR_FREE(port); >+ } else { >+ def->data.spice.port = 5900; >+ } >+ >+ tlsPort = virXMLPropString(node, "tlsPort"); >+ if (tlsPort) { >+ if (virStrToLong_i(tlsPort, NULL, 10, &def->data.spice.tlsPort) < 0) { >+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, >+ _("cannot parse spice tlsPort %s"), tlsPort); >+ VIR_FREE(tlsPort); >+ goto error; >+ } >+ VIR_FREE(tlsPort); >+ } else { >+ def->data.spice.tlsPort = 0; >+ } >+ >+ if ((autoport = virXMLPropString(node, "autoport")) != NULL) { >+ if (STREQ(autoport, "yes")) { >+ if (flags & VIR_DOMAIN_XML_INACTIVE) { >+ def->data.spice.port = 0; >+ def->data.spice.tlsPort = 0; >+ } >+ def->data.spice.autoport = 1; >+ } >+ VIR_FREE(autoport); >+ } >+ >+ def->data.spice.listenAddr = virXMLPropString(node, "listen"); >+ def->data.spice.passwd = virXMLPropString(node, "passwd"); >+ def->data.spice.keymap = virXMLPropString(node, "keymap"); > } > > cleanup: >@@ -5653,6 +5704,33 @@ virDomainGraphicsDefFormat(virBufferPtr buf, > > break; > >+ case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: >+ if (def->data.spice.port) >+ virBufferVSprintf(buf, " port='%d'", >+ def->data.spice.port); >+ >+ if (def->data.spice.tlsPort) >+ virBufferVSprintf(buf, " tlsPort='%d'", >+ def->data.spice.tlsPort); >+ >+ virBufferVSprintf(buf, " autoport='%s'", >+ def->data.spice.autoport ? "yes" : "no"); >+ >+ if (def->data.spice.listenAddr) >+ virBufferVSprintf(buf, " listen='%s'", >+ def->data.spice.listenAddr); >+ >+ if (def->data.spice.keymap) >+ virBufferEscapeString(buf, " keymap='%s'", >+ def->data.spice.keymap); >+ >+ if (def->data.spice.passwd && >+ (flags & VIR_DOMAIN_XML_SECURE)) >+ virBufferEscapeString(buf, " passwd='%s'", >+ def->data.spice.passwd); >+ >+ break; >+ > } > > virBufferAddLit(buf, "/>\n"); >diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h >index afd143d..cda1d98 100644 >--- a/src/conf/domain_conf.h >+++ b/src/conf/domain_conf.h >@@ -472,6 +472,7 @@ enum virDomainGraphicsType { > VIR_DOMAIN_GRAPHICS_TYPE_VNC, > VIR_DOMAIN_GRAPHICS_TYPE_RDP, > VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP, >+ VIR_DOMAIN_GRAPHICS_TYPE_SPICE, > > VIR_DOMAIN_GRAPHICS_TYPE_LAST, > }; >@@ -504,6 +505,14 @@ struct _virDomainGraphicsDef { > char *display; > unsigned int fullscreen :1; > } desktop; >+ struct { >+ int port; >+ int tlsPort; >+ char *listenAddr; >+ char *keymap; >+ char *passwd; >+ unsigned int autoport :1; >+ } spice; > } data; > }; > >diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c >index 767e168..84b7067 100644 >--- a/src/qemu/qemu_conf.c >+++ b/src/qemu/qemu_conf.c >@@ -4737,15 +4737,13 @@ > ADD_ARG_LIT("-sdl"); >- >- } else if ((def->ngraphics == 1)) { >- qemuReportError(VIR_ERR_INTERNAL_ERROR, >- _("unsupported graphics type '%s'"), >- virDomainGraphicsTypeToString(def->graphics[0]->type)); >+ } else if ((def->ngraphics)) { >+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, >+ "%s", _("unsupported graphics output requested")); > goto error; > } > > if (def->nvideos) { > if (def->nvideos > 1) { >- qemuReportError(VIR_ERR_INTERNAL_ERROR, >+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, > "%s", _("only one video card is currently supported")); > goto error; > } >files/03-fix-conf.patch0000644000000000000000000000261311440205531013625 0ustar rootroot* src/qemu/qemu_conf.c: Report VIR_ERR_CONFIG_UNSUPPORTED for > unsupported video adapters >--- > src/qemu/qemu_conf.c | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > >diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c >index 84b7067..b922907 100644 >--- a/src/qemu/qemu_conf.c >+++ b/src/qemu/qemu_conf.c >@@ -4423,7 +4423,7 @@ int qemudBuildCommandLine(virConnectPtr conn, > } else { > const char *vgastr = qemuVideoTypeToString(def->videos[0]->type); > if (!vgastr || STREQ(vgastr, "")) { >- qemuReportError(VIR_ERR_INTERNAL_ERROR, >+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, > _("video type %s is not supported with QEMU"), > virDomainVideoTypeToString(def->videos[0]->type)); > goto error; >@@ -4449,8 +4449,8 @@ int qemudBuildCommandLine(virConnectPtr conn, > break; > > default: >- qemuReportError(VIR_ERR_INTERNAL_ERROR, >- _("video type %s is not supported with QEMU"), >+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, >+ _("video type %s is not supported with this QEMU"), > virDomainVideoTypeToString(def->videos[0]->type)); > goto error; > } >-- >1.6.6.1 >files/04-imp-qxl-drv.patch0000644000000000000000000004431411462705423014312 0ustar rootroot* src/qemu/qemu_conf.h: Flag for QXL support >* src/qemu/qemu_conf.c: Probe for '-vga qxl' support and implement it >* tests/qemuhelptest.c, tests/qemuhelpdata/qemu-kvm-0.12.1-rhel6: Test > case for '-vga qxl' probing. Currently broken. >* tests/qemuxml2argvtest.c, tests/qemuxml2xmltest.c, > tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args, > tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml: Test > case for generating spice args with RHEL6 kvm >--- > src/qemu/qemu_conf.c | 15 ++- > src/qemu/qemu_conf.h | 1 + > tests/qemuhelpdata/qemu-kvm-0.12.1-rhel6 | 212 ++++++++++++++++++++ > tests/qemuhelptest.c | 28 +++ > .../qemuxml2argv-graphics-spice-rhel6.args | 1 + > .../qemuxml2argv-graphics-spice-rhel6.xml | 27 +++ > tests/qemuxml2argvtest.c | 10 + > tests/qemuxml2xmltest.c | 1 + > 8 files changed, 293 insertions(+), 2 deletions(-) > create mode 100644 tests/qemuhelpdata/qemu-kvm-0.12.1-rhel6 > create mode 100644 >tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml > >diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c >index b922907..d59b0e9 100644 >--- a/src/qemu/qemu_conf.c >+++ b/src/qemu/qemu_conf.c >@@ -93,7 +93,7 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, > "vmware", > "", /* no arg needed for xen */ > "", /* don't support vbox */ >- "", /* Not implemented QXL yet */); >+ "qxl"); > > int qemudLoadDriverConfig(struct qemud_driver *driver, > const char *filename) { >@@ -1143,8 +1143,12 @@ static unsigned long long qemudComputeCmdFlags(const char *help, > if (strstr(help, "format=")) > flags |= QEMUD_CMD_FLAG_DRIVE_FORMAT; > } >- if (strstr(help, "-vga") && !strstr(help, "-std-vga")) >+ if (strstr(help, "-vga") && !strstr(help, "-std-vga")) { > flags |= QEMUD_CMD_FLAG_VGA; >+ >+ if (strstr(help, "|qxl")) >+ flags |= QEMUD_CMD_FLAG_VGA_QXL; >+ } > if (strstr(help, "boot=on")) > flags |= QEMUD_CMD_FLAG_DRIVE_BOOT; > if (strstr(help, "serial=s")) >@@ -4421,6 +4425,13 @@ int qemudBuildCommandLine(virConnectPtr conn, > if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_XEN) { > /* nothing - vga has no effect on Xen pvfb */ > } else { >+ if ((def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL) && >+ !(qemuCmdFlags & QEMUD_CMD_FLAG_VGA_QXL)) { >+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", >+ _("This QEMU does not support QXL graphics adapters")); >+ goto error; >+ } >+ > const char *vgastr = qemuVideoTypeToString(def->videos[0]->type); > if (!vgastr || STREQ(vgastr, "")) { > qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, >diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h >index e0666cb..5321955 100644 >--- a/src/qemu/qemu_conf.h >+++ b/src/qemu/qemu_conf.h >@@ -92,6 +92,7 @@ > QEMUD_CMD_FLAG_NESTING = (1LL << 41), /* -enable-nesting (SVM/VMX) */ > QEMUD_CMD_FLAG_NAME_PROCESS = (1LL << 42), /* Is -name process= available */ > QEMUD_CMD_FLAG_DRIVE_READONLY = (1LL << 43), /* -drive readonly=on|off */ >+ QEMUD_CMD_FLAG_VGA_QXL = (1LL << 44), /* The 'qxl' arg for '-vga' */ > }; > > /* Main driver state */ >diff --git a/tests/qemuhelpdata/qemu-kvm-0.12.1-rhel6 >b/tests/qemuhelpdata/qemu-kvm-0.12.1-rhel6 >new file mode 100644 >index 0000000..db54f6b >--- /dev/null >+++ b/tests/qemuhelpdata/qemu-kvm-0.12.1-rhel6 >@@ -0,0 +1,212 @@ >+QEMU PC emulator version 0.12.1 (qemu-kvm-0.12.1.2), Copyright (c) 2003-2008 Fabrice Bellard >+usage: qemu [options] [disk_image] >+ >+'disk_image' is a raw hard image image for IDE hard disk 0 >+ >+Standard options: >+-h or -help display this help and exit >+-version display version information and exit >+-M machine select emulated machine (-M ? for list) >+-cpu cpu select CPU (-cpu ? for list) >+-smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets] >+ set the number of CPUs to 'n' [default=1] >+ maxcpus= maximum number of total cpus, including >+ offline CPUs for hotplug etc. >+ cores= number of CPU cores on one socket >+ threads= number of threads on one CPU core >+ sockets= number of discrete sockets in the system >+-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node] >+-fda/-fdb file use 'file' as floppy disk 0/1 image >+-hda/-hdb file use 'file' as IDE hard disk 0/1 image >+-hdc/-hdd file use 'file' as IDE hard disk 2/3 image >+-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master) >+-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i] >+ [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off] >+ [,cache=writethrough|writeback|none][,format=f][,serial=s] >+ [,addr=A][,id=name][,aio=threads|native] >+ [,boot=on|off] >+ use 'file' as a drive image >+-set group.id.arg=value >+ set <arg> parameter for item <id> of type <group> >+ i.e. -set drive.$id.file=/path/to/image >+-global driver.property=value >+ set a global default for a driver property >+-mtdblock file use 'file' as on-board Flash memory image >+-sd file use 'file' as SecureDigital card image >+-pflash file use 'file' as a parallel flash image >+-boot [order=drives][,once=drives][,menu=on|off] >+ 'drives': floppy (a), hard disk (c), CD-ROM (d), network (n) >+-snapshot write to temporary files instead of disk image files >+-m megs set virtual RAM size to megs MB [default=128] >+-k language use keyboard layout (for example 'fr' for French) >+-audio-help print list of audio drivers and their options >+-soundhw c1,... enable audio support >+ and only specified sound cards (comma separated list) >+ use -soundhw ? to get the list of supported cards >+ use -soundhw all to enable all of them >+-usb enable the USB driver (will be the default soon) >+-usbdevice name add the host or guest USB device 'name' >+-device driver[,options] add device >+-name string1[,process=string2] set the name of the guest >+ string1 sets the window title and string2 the process name (on Linux) >+-uuid %08x-%04x-%04x-%04x-%012x >+ specify machine UUID >+ >+Display options: >+-nographic disable graphical output and redirect serial I/Os to console >+-spice <args> use spice >+-portrait rotate graphical output 90 deg left (only PXA LCD) >+-vga [std|cirrus|vmware|xenfb|qxl|none] >+ select video card type >+-full-screen start in full screen >+-vnc display start a VNC server on display >+ >+i386 target only: >+-win2k-hack use it when installing Windows 2000 to avoid a disk full bug >+-no-fd-bootchk disable boot signature checking for floppy disks >+-no-acpi disable ACPI >+-no-hpet disable HPET >+-balloon none disable balloon device >+-balloon virtio[,addr=str] >+ enable virtio balloon device (default) >+-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,data=file1[:file2]...] >+ ACPI table description >+-smbios file=binary >+ Load SMBIOS entry from binary file >+-smbios type=0[,vendor=str][,version=str][,date=str][,release=%d.%d] >+ Specify SMBIOS type 0 fields >+-smbios type=1[,manufacturer=str][,product=str][,version=str][,serial=str] >+ [,uuid=uuid][,sku=str][,family=str] >+ Specify SMBIOS type 1 fields >+ >+Network options: >+-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v] >+ create a new Network Interface Card and connect it to VLAN 'n' >+-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n] >+ [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f] >+ [,hostfwd=rule][,guestfwd=rule][,smb=dir[,smbserver=addr]] >+ connect the user mode network stack to VLAN 'n', configure its >+ DHCP server and enabled optional services >+-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h] >+ connect the host TAP network interface to VLAN 'n' and use the >+ network scripts 'file' (default=/etc/qemu-ifup) >+ and 'dfile' (default=/etc/qemu-ifdown); >+ use '[down]script=no' to disable script execution; >+ use 'fd=h' to connect to an already opened TAP interface >+ use 'sndbuf=nbytes' to limit the size of the send buffer; the >+ default of 'sndbuf=1048576' can be disabled using 'sndbuf=0' >+ use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag; use >+ vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition >+ use vhost=on to enable experimental in kernel accelerator >+ use 'vhostfd=h' to connect to an already opened vhost net device >+-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port] >+ connect the vlan 'n' to another VLAN using a socket connection >+-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port] >+ connect the vlan 'n' to multicast maddr and port >+-net dump[,vlan=n][,file=f][,len=n] >+ dump traffic on vlan 'n' to file 'f' (max n bytes per packet) >+-net none use it alone to have zero network devices; if no -net option >+ is provided, the default is '-net nic -net user' >+-netdev [user|tap|socket],id=str[,option][,option][,...] >+ >+Character device options: >+-chardev null,id=id >+-chardev socket,id=id[,host=host],port=host[,to=to][,ipv4][,ipv6][,nodelay] >+ [,server][,nowait][,telnet] (tcp) >+-chardev socket,id=id,path=path[,server][,nowait][,telnet] (unix) >+-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr] >+ [,localport=localport][,ipv4][,ipv6] >+-chardev msmouse,id=id >+-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]] >+-chardev file,id=id,path=path >+-chardev pipe,id=id,path=path >+-chardev pty,id=id >+-chardev stdio,id=id >+-chardev tty,id=id,path=path >+-chardev parport,id=id,path=path >+ >+Bluetooth(R) options: >+-bt hci,null dumb bluetooth HCI - doesn't respond to commands >+-bt hci,host[:id] >+ use host's HCI with the given name >+-bt hci[,vlan=n] >+ emulate a standard HCI in virtual scatternet 'n' >+-bt vhci[,vlan=n] >+ add host computer to virtual scatternet 'n' using VHCI >+-bt device:dev[,vlan=n] >+ emulate a bluetooth device 'dev' in scatternet 'n' >+ >+Linux/Multiboot boot specific: >+-kernel bzImage use 'bzImage' as kernel image >+-append cmdline use 'cmdline' as kernel command line >+-initrd file use 'file' as initial ram disk >+ >+Debug/Expert options: >+-serial dev redirect the serial port to char device 'dev' >+-parallel dev redirect the parallel port to char device 'dev' >+-monitor dev redirect the monitor to char device 'dev' >+-qmp dev like -monitor but opens in 'control' mode. >+-mon chardev=[name][,mode=readline|control][,default] >+-pidfile file write PID to 'file' >+-singlestep always run in singlestep mode >+-S freeze CPU at startup (use 'c' to start execution) >+-gdb dev wait for gdb connection on 'dev' >+-s shorthand for -gdb tcp::1234 >+-d item1,... output log to /tmp/qemu.log (use -d ? for a list of log items) >+-hdachs c,h,s[,t] >+ force hard disk 0 physical geometry and the optional BIOS >+ translation (t=none or lba) (usually qemu can guess them) >+-L path set the directory for the BIOS, VGA BIOS and keymaps >+-bios file set the filename for the BIOS >+-enable-kvm enable KVM full virtualization support >+-no-reboot exit instead of rebooting >+-no-shutdown stop before shutdown >+-loadvm [tag|id] >+ start right away with a saved state (loadvm in monitor) >+-daemonize daemonize QEMU after initializing >+-option-rom rom load a file, rom, into the option ROM space >+-clock force the use of the given methods for timer alarm. >+ To see what timers are available use -clock ? >+-rtc [base=utc|localtime|date][,clock=host|vm][,driftfix=none|slew] >+ set the RTC base and clock, enable drift fix for clock ticks >+-icount [N|auto] >+ enable virtual instruction counter with 2^N clock ticks per >+ instruction >+-watchdog i6300esb|ib700 >+ enable virtual hardware watchdog [default=none] >+-watchdog-action reset|shutdown|poweroff|pause|debug|none >+ action when watchdog fires [default=reset] >+-echr chr set terminal escape character instead of ctrl-a >+-virtioconsole c >+ set virtio console >+-show-cursor show cursor >+-tb-size n set TB size >+-incoming p prepare for incoming migration, listen on port p >+-nodefaults don't create default devices. >+-chroot dir Chroot to dir just before starting the VM. >+-runas user Change to user id user just before starting the VM. >+-readconfig <file> >+-writeconfig <file> >+ read/write config file >+-no-kvm disable KVM hardware virtualization >+-no-kvm-irqchip disable KVM kernel mode PIC/IOAPIC/LAPIC >+-no-kvm-pit disable KVM kernel mode PIT >+-no-kvm-pit-reinjection disable KVM kernel mode PIT interrupt reinjection >+-pcidevice host=bus:dev.func[,dma=none][,name=string] >+ expose a PCI device to the guest OS. >+ dma=none: don't perform any dma translations (default is to use an iommu) >+ 'string' is used in log output. >+-enable-nesting enable support for running a VM inside the VM (AMD only) >+-nvram FILE provide ia64 nvram contents >+-tdf enable guest time drift compensation >+-kvm-shadow-memory MEGABYTES >+ allocate MEGABYTES for kvm mmu shadowing >+-mem-path FILE provide backing storage for guest RAM >+-mem-prealloc preallocate guest memory (use with -mempath) >+ >+During emulation, the following keys are useful: >+ctrl-alt-f toggle full screen >+ctrl-alt-n switch to virtual console 'n' >+ctrl-alt toggle mouse and keyboard grab >+ >+When using -nographic, press 'ctrl-a h' to get some help. >diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c >index b8c4b91..8dc49f0 100644 >--- a/tests/qemuhelptest.c >+++ b/tests/qemuhelptest.c >@@ -310,7 +310,8 @@ > QEMUD_CMD_FLAG_TDF | > QEMUD_CMD_FLAG_BOOT_MENU | > QEMUD_CMD_FLAG_NESTING | >- QEMUD_CMD_FLAG_NAME_PROCESS, >+ QEMUD_CMD_FLAG_NAME_PROCESS | >+ QEMUD_CMD_FLAG_VGA_QXL, > 12003, 1, 0); > > return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >new file mode 100644 >index 0000000..94cd90e >--- /dev/null >+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >@@ -0,0 +1 @@ >+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -vga qxl -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >new file mode 100644 >index 0000000..031a622 >--- /dev/null >+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >@@ -0,0 +1,27 @@ >+<domain type='qemu'> >+ <name>QEMUGuest1</name> >+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> >+ <memory>219200</memory> >+ <currentMemory>219200</currentMemory> >+ <vcpu>1</vcpu> >+ <os> >+ <type arch='i686' machine='pc'>hvm</type> >+ <boot dev='hd'/> >+ </os> >+ <clock offset='utc'/> >+ <on_poweroff>destroy</on_poweroff> >+ <on_reboot>restart</on_reboot> >+ <on_crash>destroy</on_crash> >+ <devices> >+ <emulator>/usr/bin/qemu</emulator> >+ <disk type='block' device='disk'> >+ <source dev='/dev/HostVG/QEMUGuest1'/> >+ <target dev='hda' bus='ide'/> >+ <address type='drive' controller='0' bus='0' unit='0'/> >+ </disk> >+ <controller type='ide' index='0'/> >+ <video> >+ <model type='qxl' vram='65536' heads='1'/> >+ </video> >+ </devices> >+</domain> >diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c >index 9e4d5bf..2e960d1 100644 >--- a/tests/qemuxml2argvtest.c >+++ b/tests/qemuxml2argvtest.c >@@ -14,6 +14,7 @@ > # include "testutils.h" > # include "qemu/qemu_conf.h" > # include "datatypes.h" >+# include "virterror_internal.h" > > # include "testutilsqemu.h" > >@@ -39,6 +40,8 @@ static int testCompareXMLToArgvFiles(const char *xml, > virDomainChrDef monitor_chr; > virConnectPtr conn; > >+ virResetLastError(); >+ > if (!(conn = virGetConnect())) > goto fail; > >@@ -125,6 +128,9 @@ static int testCompareXMLToArgvFiles(const char *xml, > ret = 0; > > fail: >+ if (ret != 0 && virGetLastError()) >+ virDispatchError(conn); >+ > free(log); > free(actualargv); > if (argv) { >@@ -289,6 +295,9 @@ mymain(int argc, char **argv) > DO_TEST("graphics-sdl", 0, false); > DO_TEST("graphics-sdl-fullscreen", 0, false); > DO_TEST("nographics-vga", QEMUD_CMD_FLAG_VGA, false); >+ DO_TEST("graphics-spice-rhel6", >+ QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_VGA_QXL | >+ QEMUD_CMD_FLAG_DEVICE, false); > DO_TEST("input-usbmouse", 0, false); > DO_TEST("input-usbtablet", 0, false); > DO_TEST("input-xen", QEMUD_CMD_FLAG_DOMID, true); >diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c >index 1ac6edc..60f60c7 100644 >--- a/tests/qemuxml2xmltest.c >+++ b/tests/qemuxml2xmltest.c >@@ -110,6 +110,7 @@ mymain(int argc, char **argv) > DO_TEST("graphics-vnc-tls"); > DO_TEST("graphics-sdl"); > DO_TEST("graphics-sdl-fullscreen"); >+ DO_TEST("graphics-spice-rhel6"); > DO_TEST("input-usbmouse"); > DO_TEST("input-usbtablet"); > DO_TEST("input-xen"); >-- >1.6.6.1 >files/05-implement-spice-graphics.patch0000644000000000000000000001413411462704722017022 0ustar rootroot* src/qemu_conf.c, src/qemu_conf.h: Add SPICE flag. Check for > -spice availability. Format -spice arg for command line >* qemuhelptest.c: Add SPICE flag >* qemuxml2argvdata/qemuxml2argv-graphics-spice.args: Add <graphics> > for spice >* qemuxml2argvdata/qemuxml2argv-graphics-spice.xml: Add -spice arg >* qemuxml2argvtest.c: Add SPICE flag >--- > src/qemu/qemu_conf.c | 36 ++++++++++++++++++++ > src/qemu/qemu_conf.h | 1 + > tests/qemuhelptest.c | 3 +- > .../qemuxml2argv-graphics-spice-rhel6.args | 2 +- > .../qemuxml2argv-graphics-spice-rhel6.xml | 2 + > tests/qemuxml2argvtest.c | 2 +- > 6 files changed, 43 insertions(+), 3 deletions(-) > >diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c >index d59b0e9..e4a5985 100644 >--- a/src/qemu/qemu_conf.c >+++ b/src/qemu/qemu_conf.c >@@ -1149,6 +1149,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help, > if (strstr(help, "|qxl")) > flags |= QEMUD_CMD_FLAG_VGA_QXL; > } >+ if (strstr(help, "-spice")) >+ flags |= QEMUD_CMD_FLAG_SPICE; > if (strstr(help, "boot=on")) > flags |= QEMUD_CMD_FLAG_DRIVE_BOOT; > if (strstr(help, "serial=s")) >@@ -4409,6 +4411,40 @@ int qemudBuildCommandLine(virConnectPtr conn, > * default, since the default changes :-( */ > if (qemuCmdFlags & QEMUD_CMD_FLAG_SDL) > ADD_ARG_LIT("-sdl"); >+ } else if ((def->ngraphics == 1) && >+ def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { >+ virBuffer opt = VIR_BUFFER_INITIALIZER; >+ char *optstr; >+ >+ if (!(qemuCmdFlags & QEMUD_CMD_FLAG_SPICE)) { >+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", >+ _("spice graphics are not supported with this QEMU")); >+ goto error; >+ } >+ >+ virBufferVSprintf(&opt, "port=%u", def->graphics[0]->data.spice.port); >+ >+ if (def->graphics[0]->data.spice.tlsPort) >+ virBufferVSprintf(&opt, ",tls-port=%u", def->graphics[0]->data.spice.tlsPort); >+ >+ if (def->graphics[0]->data.spice.listenAddr) >+ virBufferVSprintf(&opt, ",addr=%s", def->graphics[0]->data.spice.listenAddr); >+ >+ if (virBufferError(&opt)) >+ goto no_memory; >+ >+ optstr = virBufferContentAndReset(&opt); >+ >+ ADD_ARG_LIT("-spice"); >+ ADD_ARG(optstr); >+ if (def->graphics[0]->data.spice.keymap) { >+ ADD_ARG_LIT("-k"); >+ ADD_ARG_LIT(def->graphics[0]->data.spice.keymap); >+ } >+ /* SPICE includes native support for tunnelling audio, so we >+ * set the audio backend to point at SPICE's own driver >+ */ >+ ADD_ENV_LIT("QEMU_AUDIO_DRV=spice"); > } else if ((def->ngraphics)) { > qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, > "%s", _("unsupported graphics output requested")); >diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h >index 5321955..2d169bd 100644 >--- a/src/qemu/qemu_conf.h >+++ b/src/qemu/qemu_conf.h >@@ -89,6 +89,7 @@ enum qemud_cmd_flags { > QEMUD_CMD_FLAG_NAME_PROCESS = (1LL << 42), /* Is -name process= available */ > QEMUD_CMD_FLAG_DRIVE_READONLY = (1LL << 43), /* -drive readonly=on|off */ > QEMUD_CMD_FLAG_VGA_QXL = (1LL << 44), /* The 'qxl' arg for '-vga' */ >+ QEMUD_CMD_FLAG_SPICE = (1LL << 41), /* Is -spice avail (RHEL-6 custom) */ > }; > > /* Main driver state */ >diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c >index 8dc49f0..f57fc51 100644 >--- a/tests/qemuhelptest.c >+++ b/tests/qemuhelptest.c >@@ -271,7 +271,8 @@ mymain(int argc, char **argv) > QEMUD_CMD_FLAG_BOOT_MENU | > QEMUD_CMD_FLAG_NESTING | > QEMUD_CMD_FLAG_NAME_PROCESS | >- QEMUD_CMD_FLAG_VGA_QXL, >+ QEMUD_CMD_FLAG_VGA_QXL | >+ QEMUD_CMD_FLAG_SPICE, > 12003, 1, 0); > > return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >index 94cd90e..8d195e5 100644 >--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >@@ -1 +1 @@ >-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -vga qxl -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 >+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1 -vga qxl -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >index 031a622..08dfb26 100644 >--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >@@ -20,6 +20,8 @@ > <address type='drive' controller='0' bus='0' unit='0'/> > </disk> > <controller type='ide' index='0'/> >+ <input type='mouse' bus='ps2'/> >+ <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'/> > <video> > <model type='qxl' vram='65536' heads='1'/> > </video> >diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c >index 2e960d1..5e46dca 100644 >--- a/tests/qemuxml2argvtest.c >+++ b/tests/qemuxml2argvtest.c >@@ -297,7 +297,7 @@ mymain(int argc, char **argv) > DO_TEST("nographics-vga", QEMUD_CMD_FLAG_VGA, false); > DO_TEST("graphics-spice-rhel6", > QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_VGA_QXL | >- QEMUD_CMD_FLAG_DEVICE, false); >+ QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_SPICE, false); > DO_TEST("input-usbmouse", 0, false); > DO_TEST("input-usbtablet", 0, false); > DO_TEST("input-xen", QEMUD_CMD_FLAG_DOMID, true); >1.6.6.1 >files/06-auto-port-spice.patch0000644000000000000000000000507411440335614015164 0ustar rootroot* src/qemu/qemu_driver.c: Allocate the TCP ports for SPICE > before starting guest >--- > src/qemu/qemu_driver.c | 36 ++++++++++++++++++++++++------------ > 1 files changed, 24 insertions(+), 12 deletions(-) > >diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c >index df1d435..2aa39c1 100644 >--- a/src/qemu/qemu_driver.c >+++ b/src/qemu/qemu_driver.c >@@ -2911,10 +2911,10 @@ > return ret; > } > >-static int qemudNextFreeVNCPort(struct qemud_driver *driver) { >+static int qemudNextFreePort(struct qemud_driver *driver, int startPort) { > int i; > >- for (i = QEMU_VNC_PORT_MIN; i < QEMU_VNC_PORT_MAX; i++) { >+ for (i = startPort ; i < 65535 ; i++) { > int fd; > int reuse = 1; > struct sockaddr_in addr; >@@ -3200,17 +3200,29 @@ static int qemudStartVMDaemon(virConnectPtr conn, > DEBUG0("Ensuring no historical cgroup is lying around"); > qemuRemoveCgroup(driver, vm, 1); > >- if ((vm->def->ngraphics == 1) && >- vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && >- vm->def->graphics[0]->data.vnc.autoport) { >- DEBUG0("Determining VNC port"); >- int port = qemudNextFreeVNCPort(driver); >- if (port < 0) { >- qemuReportError(VIR_ERR_INTERNAL_ERROR, >- "%s", _("Unable to find an unused VNC port")); >- goto cleanup; >+ if (vm->def->ngraphics == 1) { >+ if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && >+ vm->def->graphics[0]->data.vnc.autoport) { >+ int port = qemudNextFreePort(driver, 5900); >+ if (port < 0) { >+ qemuReportError(VIR_ERR_INTERNAL_ERROR, >+ "%s", _("Unable to find an unused VNC port")); >+ goto cleanup; >+ } >+ vm->def->graphics[0]->data.vnc.port = port; >+ } else if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE && >+ vm->def->graphics[0]->data.spice.autoport) { >+ int port = qemudNextFreePort(driver, 5900); >+ int tlsPort = port == -1 ? -1 : qemudNextFreePort(driver, port + 1); >+ if (port < 0 || tlsPort < 0) { >+ qemuReportError(VIR_ERR_INTERNAL_ERROR, >+ "%s", _("Unable to find an unused SPICE ports")); >+ goto cleanup; >+ } >+ >+ vm->def->graphics[0]->data.spice.port = port; >+ vm->def->graphics[0]->data.spice.tlsPort = tlsPort; > } >- vm->def->graphics[0]->data.vnc.port = port; > } > > if (virFileMakePath(driver->logDir) != 0) { >-- >1.6.6.1 >files/07-spice-conf.patch0000644000000000000000000002302611462707172014163 0ustar rootroot* src/qemu/qemu.conf: Add spice_listen, spice_tls, > spice_tls_x509_cert_dir & spice_password config params >* src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Parsing of > spice config parameters and updating -spice arg generation > to use them >* tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args, > tests/qemuxml2argvtest.c: Expand test case to cover driver > level configuration >--- > src/qemu/qemu.conf | 40 +++++++++++++ > src/qemu/qemu_conf.c | 62 +++++++++++++++++++- > src/qemu/qemu_conf.h | 4 + > src/qemu/qemu_driver.c | 15 ++++- > .../qemuxml2argv-graphics-spice-rhel6.args | 2 +- > tests/qemuxml2argvtest.c | 7 ++- > 6 files changed, 124 insertions(+), 6 deletions(-) > >diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf >index 3da332f..980dc8b 100644 >--- a/src/qemu/qemu.conf >+++ b/src/qemu/qemu.conf >@@ -80,6 +80,46 @@ > > > >+# SPICE is configured to listen on 127.0.0.1 by default. >+# To make it listen on all public interfaces, uncomment >+# this next option. >+# >+# NB, strong recommendation to enable TLS + x509 certificate >+# verification when allowing public access >+# >+# spice_listen = "0.0.0.0" >+ >+ >+# Enable use of TLS encryption on the SPICE server. >+# >+# It is necessary to setup CA and issue a server certificate >+# before enabling this. >+# >+# spice_tls = 1 >+ >+ >+# Use of TLS requires that x509 certificates be issued. The >+# default it to keep them in /etc/pki/libvirt-spice. This directory >+# must contain >+# >+# ca-cert.pem - the CA master certificate >+# server-cert.pem - the server certificate signed with ca-cert.pem >+# server-key.pem - the server private key >+# >+# This option allows the certificate directory to be changed >+# >+# spice_tls_x509_cert_dir = "/etc/pki/libvirt-spice" >+ >+ >+# The default SPICE password. This parameter is only used if the >+# per-domain XML config does not already provide a password. To >+# allow access without passwords, leave this commented out. An >+# empty string will still enable passwords, but be rejected by >+# QEMU effectively preventing any use of SPICE. Obviously change >+# this example here before you set this >+# >+# spice_password = "XYZ12345" >+ > > # The default security driver is SELinux. If SELinux is disabled > # on the host, then the security driver will automatically disable >diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c >index e4a5985..ca251a3 100644 >--- a/src/qemu/qemu_conf.c >+++ b/src/qemu/qemu_conf.c >@@ -115,6 +115,15 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, > return -1; > } > >+ if (!(driver->spiceListen = strdup("127.0.0.1"))) { >+ virReportOOMError(); >+ return -1; >+ } >+ if (!(driver->spiceTLSx509certdir = strdup(SYSCONF_DIR "/pki/libvirt-spice"))) { >+ virReportOOMError(); >+ return -1; >+ } >+ > #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R > /* For privileged driver, try and find hugepage mount automatically. > * Non-privileged driver requires admin to create a dir for the >@@ -213,6 +222,43 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, > } > } > >+ p = virConfGetValue (conf, "spice_tls"); >+ CHECK_TYPE ("spice_tls", VIR_CONF_LONG); >+ if (p) driver->spiceTLS = p->l; >+ >+ p = virConfGetValue (conf, "spice_tls_x509_cert_dir"); >+ CHECK_TYPE ("spice_tls_x509_cert_dir", VIR_CONF_STRING); >+ if (p && p->str) { >+ VIR_FREE(driver->spiceTLSx509certdir); >+ if (!(driver->spiceTLSx509certdir = strdup(p->str))) { >+ virReportOOMError(); >+ virConfFree(conf); >+ return -1; >+ } >+ } >+ >+ p = virConfGetValue (conf, "spice_listen"); >+ CHECK_TYPE ("spice_listen", VIR_CONF_STRING); >+ if (p && p->str) { >+ VIR_FREE(driver->spiceListen); >+ if (!(driver->spiceListen = strdup(p->str))) { >+ virReportOOMError(); >+ virConfFree(conf); >+ return -1; >+ } >+ } >+ >+ p = virConfGetValue (conf, "spice_password"); >+ CHECK_TYPE ("spice_password", VIR_CONF_STRING); >+ if (p && p->str) { >+ VIR_FREE(driver->spicePassword); >+ if (!(driver->spicePassword = strdup(p->str))) { >+ virReportOOMError(); >+ virConfFree(conf); >+ return -1; >+ } >+ } >+ > p = virConfGetValue (conf, "user"); > CHECK_TYPE ("user", VIR_CONF_STRING); > if (!(user = strdup(p && p->str ? p->str : QEMU_USER))) { >@@ -4424,11 +4470,25 @@ int qemudBuildCommandLine(virConnectPtr conn, > > virBufferVSprintf(&opt, "port=%u", def->graphics[0]->data.spice.port); > >- if (def->graphics[0]->data.spice.tlsPort) >+ if (driver->spiceTLS && def->graphics[0]->data.spice.tlsPort != -1) > virBufferVSprintf(&opt, ",tls-port=%u", def->graphics[0]->data.spice.tlsPort); > > if (def->graphics[0]->data.spice.listenAddr) > virBufferVSprintf(&opt, ",addr=%s", def->graphics[0]->data.spice.listenAddr); >+ else if (driver->spiceListen) >+ virBufferVSprintf(&opt, ",addr=%s", driver->spiceListen); >+ >+ /* In the password case we set it via monitor command, to avoid >+ * making it visible on CLI, so there's no use of password=XXX >+ * in this bit of the code */ >+ if (!def->graphics[0]->data.spice.passwd && >+ !driver->spicePassword) >+ virBufferAddLit(&opt, ",disable-ticketing"); >+ >+ if (driver->spiceTLS) >+ virBufferVSprintf(&opt, ",x509-dir=%s", >+ driver->spiceTLSx509certdir); >+ > > if (virBufferError(&opt)) > goto no_memory; >diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h >index 2d169bd..bf18102 100644 >--- a/src/qemu/qemu_conf.h >+++ b/src/qemu/qemu_conf.h >@@ -131,6 +131,10 @@ struct qemud_driver { > char *vncListen; > char *vncPassword; > char *vncSASLdir; >+ unsigned int spiceTLS : 1; >+ char *spiceTLSx509certdir; >+ char *spiceListen; >+ char *spicePassword; > char *hugetlbfs_mount; > char *hugepage_path; > >diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c >index 2aa39c1..f290172 100644 >--- a/src/qemu/qemu_driver.c >+++ b/src/qemu/qemu_driver.c >@@ -3213,13 +3213,22 @@ static int qemudStartVMDaemon(virConnectPtr conn, > } else if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE && > vm->def->graphics[0]->data.spice.autoport) { > int port = qemudNextFreePort(driver, 5900); >- int tlsPort = port == -1 ? -1 : qemudNextFreePort(driver, port + 1); >- if (port < 0 || tlsPort < 0) { >+ int tlsPort = -1; >+ if (port < 0) { > qemuReportError(VIR_ERR_INTERNAL_ERROR, >- "%s", _("Unable to find an unused SPICE ports")); >+ "%s", _("Unable to find an unused SPICE port")); > goto cleanup; > } > >+ if (driver->spiceTLS) { >+ tlsPort = qemudNextFreePort(driver, port + 1); >+ if (tlsPort < 0) { >+ qemuReportError(VIR_ERR_INTERNAL_ERROR, >+ "%s", _("Unable to find an unused SPICE TLS port")); >+ goto cleanup; >+ } >+ } >+ > vm->def->graphics[0]->data.spice.port = port; > vm->def->graphics[0]->data.spice.tlsPort = tlsPort; > } >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >index 8d195e5..e412fdb 100644 >--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >@@ -1 +1 @@ >-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1 -vga qxl -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 >+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,x509-dir=/etc/pki/libvirt-spice -vga qxl -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 >diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c >index 5e46dca..10bf4b1 100644 >--- a/tests/qemuxml2argvtest.c >+++ b/tests/qemuxml2argvtest.c > return EXIT_FAILURE; > if ((driver.hugepage_path = strdup("/dev/hugepages/libvirt/qemu")) == NULL) > return EXIT_FAILURE; >+ driver.spiceTLS = 1; >+ if (!(driver.spiceTLSx509certdir = strdup("/etc/pki/libvirt-spice"))) >+ return EXIT_FAILURE; >+ if (!(driver.spicePassword = strdup("123456"))) >+ return EXIT_FAILURE; > > # define DO_TEST_FULL(name, extraFlags, migrateFrom, expectError) \ > do { \ >@@ -220,6 +220,11 @@ > return EXIT_FAILURE; > if ((driver.hugepage_path = strdup("/dev/hugepages/libvirt/qemu")) == NULL) > return EXIT_FAILURE; >+ driver.spiceTLS = 1; >+ if (!(driver.spiceTLSx509certdir = strdup("/etc/pki/libvirt-spice"))) >+ return EXIT_FAILURE; >+ if (!(driver.spicePassword = strdup("123456"))) >+ return EXIT_FAILURE; > > # define DO_TEST_FULL(name, extraFlags, migrateFrom, expectError) \ > do { \ >-- >1.6.6.1 >files/08-password-expire.patch0000644000000000000000000004330311440326325015263 0ustar rootroot* src/conf/domain_conf.h: Pull passwd out into separate struct > virDomainGraphicsAuthDef to allow sharing between VNC & SPICE >* src/conf/domain_conf.c: Add parsing/formatting of new passwdValidTo > argument >* src/opennebula/one_conf.c, src/qemu/qemu_conf.c, src/qemu/qemu_driver.c, > src/xen/xend_internal.c, src/xen/xm_internal.c: Update for changed > struct containing VNC password >--- > src/conf/domain_conf.c | 102 +++++++++++++++++++++++++++++++++++++++----- > src/conf/domain_conf.h | 13 +++++- > src/esx/esx_vmx.c | 6 +- > src/opennebula/one_conf.c | 4 +- > src/qemu/qemu_conf.c | 4 +- > src/qemu/qemu_driver.c | 20 ++++---- > src/xen/xend_internal.c | 12 +++--- > src/xen/xm_internal.c | 12 +++--- > 8 files changed, 130 insertions(+), 43 deletions(-) > >diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c >index b25c622..eee78b1 100644 >--- a/src/conf/domain_conf.c >+++ b/src/conf/domain_conf.c >@@ -374,6 +374,17 @@ virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms, > > #endif /* !PROXY */ > >+static void >+virDomainGraphicsAuthDefClear(virDomainGraphicsAuthDefPtr def) >+{ >+ if (!def) >+ return; >+ >+ VIR_FREE(def->passwd); >+ >+ /* Don't free def */ >+} >+ > void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) > { > if (!def) >@@ -383,7 +394,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) > case VIR_DOMAIN_GRAPHICS_TYPE_VNC: > VIR_FREE(def->data.vnc.listenAddr); > VIR_FREE(def->data.vnc.keymap); >- VIR_FREE(def->data.vnc.passwd); >+ virDomainGraphicsAuthDefClear(&def->data.vnc.auth); > break; > > case VIR_DOMAIN_GRAPHICS_TYPE_SDL: >@@ -402,7 +413,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) > case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: > VIR_FREE(def->data.spice.listenAddr); > VIR_FREE(def->data.spice.keymap); >- VIR_FREE(def->data.spice.passwd); >+ virDomainGraphicsAuthDefClear(&def->data.spice.auth); > break; > } > >@@ -2715,6 +2726,56 @@ error: > goto cleanup; > } > >+ >+static int >+virDomainGraphicsAuthDefParseXML(xmlNodePtr node, virDomainGraphicsAuthDefPtr def) >+{ >+ char *validTo = NULL; >+ >+ def->passwd = virXMLPropString(node, "passwd"); >+ >+ if (!def->passwd) >+ return 0; >+ >+ validTo = virXMLPropString(node, "passwdValidTo"); >+ if (validTo) { >+ char *tmp; >+ struct tm tm; >+ memset(&tm, 0, sizeof(tm)); >+ /* Expect: YYYY-MM-DDTHH:MM:SS (%d-%d-%dT%d:%d:%d) eg 2010-11-28T14:29:01 */ >+ if (/* year */ >+ virStrToLong_i(validTo, &tmp, 10, &tm.tm_year) < 0 || *tmp != '-' || >+ /* month */ >+ virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_mon) < 0 || *tmp != '-' || >+ /* day */ >+ virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_mday) < 0 || *tmp != 'T' || >+ /* hour */ >+ virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_hour) < 0 || *tmp != ':' || >+ /* minute */ >+ virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_min) < 0 || *tmp != ':' || >+ /* second */ >+ virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_sec) < 0 || *tmp != '\0') { >+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, >+ _("cannot parse password validity time '%s', expect YYYY-MM-DDTHH:MM:SS"), >+ validTo); >+ VIR_FREE(validTo); >+ VIR_FREE(def->passwd); >+ return -1; >+ } >+ VIR_FREE(validTo); >+ >+ tm.tm_year -= 1900; /* Human epoch starts at 0 BC, not 1900BC */ >+ tm.tm_mon--; /* Humans start months at 1, computers at 0 */ >+ >+ /* XXX this is broken it needs to be UTC not localtime */ >+ def->validTo = timegm(&tm); >+ def->expires = 1; >+ } >+ >+ return 0; >+} >+ >+ > /* Parse the XML definition for a graphics device */ > static virDomainGraphicsDefPtr > virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { >@@ -2773,8 +2834,10 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { > } > > def->data.vnc.listenAddr = virXMLPropString(node, "listen"); >- def->data.vnc.passwd = virXMLPropString(node, "passwd"); > def->data.vnc.keymap = virXMLPropString(node, "keymap"); >+ >+ if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth) < 0) >+ goto error; > } else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { > char *fullscreen = virXMLPropString(node, "fullscreen"); > >@@ -2898,8 +2961,9 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { > } > > def->data.spice.listenAddr = virXMLPropString(node, "listen"); >- def->data.spice.passwd = virXMLPropString(node, "passwd"); > def->data.spice.keymap = virXMLPropString(node, "keymap"); >+ if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth) < 0) >+ goto error; > } > > cleanup: >@@ -5618,6 +5682,24 @@ virDomainTimerDefFormat(virBufferPtr buf, > return 0; > } > >+static void >+virDomainGraphicsAuthDefFormatAttr(virBufferPtr buf, >+ virDomainGraphicsAuthDefPtr def) >+{ >+ if (!def->passwd) >+ return; >+ >+ virBufferEscapeString(buf, " passwd='%s'", >+ def->passwd); >+ if (def->expires) { >+ char strbuf[100]; >+ struct tm tmbuf, *tm; >+ tm = gmtime_r(&def->validTo, &tmbuf); >+ strftime(strbuf, sizeof(strbuf), "%Y-%m-%dT%H:%M:%S", tm); >+ virBufferVSprintf(buf, " passwdValidTo='%s'", strbuf); >+ } >+} >+ > static int > virDomainGraphicsDefFormat(virBufferPtr buf, > virDomainGraphicsDefPtr def, >@@ -5653,10 +5735,8 @@ virDomainGraphicsDefFormat(virBufferPtr buf, > virBufferEscapeString(buf, " keymap='%s'", > def->data.vnc.keymap); > >- if (def->data.vnc.passwd && >- (flags & VIR_DOMAIN_XML_SECURE)) >- virBufferEscapeString(buf, " passwd='%s'", >- def->data.vnc.passwd); >+ if (flags & VIR_DOMAIN_XML_SECURE) >+ virDomainGraphicsAuthDefFormatAttr(buf, &def->data.vnc.auth); > > break; > >@@ -5724,10 +5804,8 @@ virDomainGraphicsDefFormat(virBufferPtr buf, > virBufferEscapeString(buf, " keymap='%s'", > def->data.spice.keymap); > >- if (def->data.spice.passwd && >- (flags & VIR_DOMAIN_XML_SECURE)) >- virBufferEscapeString(buf, " passwd='%s'", >- def->data.spice.passwd); >+ if (flags & VIR_DOMAIN_XML_SECURE) >+ virDomainGraphicsAuthDefFormatAttr(buf, &def->data.spice.auth); > > break; > >diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h >index cda1d98..bbd7e84 100644 >--- a/src/conf/domain_conf.h >+++ b/src/conf/domain_conf.h >@@ -477,6 +477,15 @@ enum virDomainGraphicsType { > VIR_DOMAIN_GRAPHICS_TYPE_LAST, > }; > >+typedef struct _virDomainGraphicsAuthDef virDomainGraphicsAuthDef; >+typedef virDomainGraphicsAuthDef *virDomainGraphicsAuthDefPtr; >+struct _virDomainGraphicsAuthDef { >+ char *passwd; >+ unsigned int expires: 1; /* Whether there is an expiry time set */ >+ time_t validTo; /* seconds since epoch */ >+}; >+ >+ > typedef struct _virDomainGraphicsDef virDomainGraphicsDef; > typedef virDomainGraphicsDef *virDomainGraphicsDefPtr; > struct _virDomainGraphicsDef { >@@ -487,7 +496,7 @@ struct _virDomainGraphicsDef { > unsigned int autoport :1; > char *listenAddr; > char *keymap; >- char *passwd; >+ virDomainGraphicsAuthDef auth; > } vnc; > struct { > char *display; >@@ -510,7 +519,7 @@ struct _virDomainGraphicsDef { > int tlsPort; > char *listenAddr; > char *keymap; >- char *passwd; >+ virDomainGraphicsAuthDef auth; > unsigned int autoport :1; > } spice; > } data; >diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c >index c965e00..f7de901 100644 >--- a/src/esx/esx_vmx.c >+++ b/src/esx/esx_vmx.c >@@ -1635,7 +1635,7 @@ esxVMX_ParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def) > esxUtil_GetConfigString(conf, "RemoteDisplay.vnc.keymap", > &(*def)->data.vnc.keymap, true) < 0 || > esxUtil_GetConfigString(conf, "RemoteDisplay.vnc.password", >- &(*def)->data.vnc.passwd, true) < 0) { >+ &(*def)->data.vnc.auth.passwd, 1) < 0) { > goto failure; > } > >@@ -2979,9 +2979,9 @@ esxVMX_FormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer) > def->data.vnc.keymap); > } > >- if (def->data.vnc.passwd != NULL) { >+ if (def->data.vnc.auth.passwd != NULL) { > virBufferVSprintf(buffer, "RemoteDisplay.vnc.password = \"%s\"\n", >- def->data.vnc.passwd); >+ def->data.vnc.auth.passwd); > } > > return 0; >diff --git a/src/opennebula/one_conf.c b/src/opennebula/one_conf.c >index 029d475..b76a1ac 100644 >--- a/src/opennebula/one_conf.c >+++ b/src/opennebula/one_conf.c >@@ -259,9 +259,9 @@ char* xmlOneTemplate(virDomainDefPtr def) > virBufferVSprintf(&buf,",\n port = \"%d\"", > def->graphics[i]->data.vnc.port); > >- if (def->graphics[i]->data.vnc.passwd != NULL) >+ if (def->graphics[i]->data.vnc.auth.passwd != NULL) > virBufferVSprintf(&buf,",\n passwd = \"%s\"", >- def->graphics[i]->data.vnc.passwd); >+ def->graphics[i]->data.vnc.auth.passwd); > > virBufferAddLit(&buf," ]\n"); > >diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c >index ca251a3..f4a6c99 100644 >--- a/src/qemu/qemu_conf.c >+++ b/src/qemu/qemu_conf.c >@@ -4375,7 +4375,7 @@ int qemudBuildCommandLine(virConnectPtr conn, > virBufferVSprintf(&opt, ":%d", > def->graphics[0]->data.vnc.port - 5900); > >- if (def->graphics[0]->data.vnc.passwd || >+ if (def->graphics[0]->data.vnc.auth.passwd || > driver->vncPassword) > virBufferAddLit(&opt, ",password"); > >@@ -4481,7 +4481,7 @@ int qemudBuildCommandLine(virConnectPtr conn, > /* In the password case we set it via monitor command, to avoid > * making it visible on CLI, so there's no use of password=XXX > * in this bit of the code */ >- if (!def->graphics[0]->data.spice.passwd && >+ if (!def->graphics[0]->data.spice.auth.passwd && > !driver->spicePassword) > virBufferAddLit(&opt, ",disable-ticketing"); > >diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c >index f290172..013d85d 100644 >--- a/src/qemu/qemu_driver.c >+++ b/src/qemu/qemu_driver.c >@@ -2191,12 +2191,12 @@ qemuInitPasswords(virConnectPtr conn, > > if ((vm->def->ngraphics == 1) && > vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && >- (vm->def->graphics[0]->data.vnc.passwd || driver->vncPassword)) { >+ (vm->def->graphics[0]->data.vnc.auth.passwd || driver->vncPassword)) { > > qemuDomainObjEnterMonitorWithDriver(driver, vm); > ret = qemuMonitorSetVNCPassword(priv->mon, >- vm->def->graphics[0]->data.vnc.passwd ? >- vm->def->graphics[0]->data.vnc.passwd : >+ vm->def->graphics[0]->data.vnc.auth.passwd ? >+ vm->def->graphics[0]->data.vnc.auth.passwd : > driver->vncPassword); > qemuDomainObjExitMonitorWithDriver(driver, vm); > } >@@ -7611,19 +7611,19 @@ qemuDomainChangeGraphics(struct qemud_driver *driver, > return -1; > } > >- if (STRNEQ_NULLABLE(olddev->data.vnc.passwd, dev->data.vnc.passwd)) { >- VIR_DEBUG("Updating password on VNC server %p %p", dev->data.vnc.passwd, driver->vncPassword); >+ if (STRNEQ_NULLABLE(olddev->data.vnc.auth.passwd, dev->data.vnc.auth.passwd)) { >+ VIR_DEBUG("Updating password on VNC server %p %p", dev->data.vnc.auth.passwd, driver->vncPassword); > qemuDomainObjEnterMonitorWithDriver(driver, vm); > ret = qemuMonitorSetVNCPassword(priv->mon, >- dev->data.vnc.passwd ? >- dev->data.vnc.passwd : >+ dev->data.vnc.auth.passwd ? >+ dev->data.vnc.auth.passwd : > driver->vncPassword); > qemuDomainObjExitMonitorWithDriver(driver, vm); > > /* Steal the new dev's char * reference */ >- VIR_FREE(olddev->data.vnc.passwd); >- olddev->data.vnc.passwd = dev->data.vnc.passwd; >- dev->data.vnc.passwd = NULL; >+ VIR_FREE(olddev->data.vnc.auth.passwd); >+ olddev->data.vnc.auth.passwd = dev->data.vnc.auth.passwd; >+ dev->data.vnc.auth.passwd = NULL; > } else { > ret = 0; > } >diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c >index c4e73b7..b7138fe 100644 >--- a/src/xen/xend_internal.c >+++ b/src/xen/xend_internal.c >@@ -2007,7 +2007,7 @@ xenDaemonParseSxprGraphicsOld(virConnectPtr conn, > goto no_memory; > > if (vncPasswd && >- !(graphics->data.vnc.passwd = strdup(vncPasswd))) >+ !(graphics->data.vnc.auth.passwd = strdup(vncPasswd))) > goto no_memory; > > if (keymap && >@@ -2129,7 +2129,7 @@ xenDaemonParseSxprGraphicsNew(virConnectPtr conn, > goto no_memory; > > if (vncPasswd && >- !(graphics->data.vnc.passwd = strdup(vncPasswd))) >+ !(graphics->data.vnc.auth.passwd = strdup(vncPasswd))) > goto no_memory; > > if (keymap && >@@ -5336,8 +5336,8 @@ xenDaemonFormatSxprGraphicsNew(virDomainGraphicsDefPtr def, > > if (def->data.vnc.listenAddr) > virBufferVSprintf(buf, "(vnclisten '%s')", def->data.vnc.listenAddr); >- if (def->data.vnc.passwd) >- virBufferVSprintf(buf, "(vncpasswd '%s')", def->data.vnc.passwd); >+ if (def->data.vnc.auth.passwd) >+ virBufferVSprintf(buf, "(vncpasswd '%s')", def->data.vnc.auth.passwd); > if (def->data.vnc.keymap) > virBufferVSprintf(buf, "(keymap '%s')", def->data.vnc.keymap); > } >@@ -5379,8 +5379,8 @@ xenDaemonFormatSxprGraphicsOld(virDomainGraphicsDefPtr def, > > if (def->data.vnc.listenAddr) > virBufferVSprintf(buf, "(vnclisten '%s')", def->data.vnc.listenAddr); >- if (def->data.vnc.passwd) >- virBufferVSprintf(buf, "(vncpasswd '%s')", def->data.vnc.passwd); >+ if (def->data.vnc.auth.passwd) >+ virBufferVSprintf(buf, "(vncpasswd '%s')", def->data.vnc.auth.passwd); > if (def->data.vnc.keymap) > virBufferVSprintf(buf, "(keymap '%s')", def->data.vnc.keymap); > >diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c >index a7a09a0..554fe40 100644 >--- a/src/xen/xm_internal.c >+++ b/src/xen/xm_internal.c >@@ -1298,7 +1298,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { > } > if (xenXMConfigCopyStringOpt(conf, "vnclisten", &graphics->data.vnc.listenAddr) < 0) > goto cleanup; >- if (xenXMConfigCopyStringOpt(conf, "vncpasswd", &graphics->data.vnc.passwd) < 0) >+ if (xenXMConfigCopyStringOpt(conf, "vncpasswd", &graphics->data.vnc.auth.passwd) < 0) > goto cleanup; > if (xenXMConfigCopyStringOpt(conf, "keymap", &graphics->data.vnc.keymap) < 0) > goto cleanup; >@@ -1370,7 +1370,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { > if (!(graphics->data.vnc.listenAddr = strdup(key + 10))) > goto no_memory; > } else if (STRPREFIX(key, "vncpasswd=")) { >- if (!(graphics->data.vnc.passwd = strdup(key + 10))) >+ if (!(graphics->data.vnc.auth.passwd = strdup(key + 10))) > goto no_memory; > } else if (STRPREFIX(key, "keymap=")) { > if (!(graphics->data.vnc.keymap = strdup(key + 7))) >@@ -2436,9 +2436,9 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, > xenXMConfigSetString(conf, "vnclisten", > def->graphics[0]->data.vnc.listenAddr) < 0) > goto no_memory; >- if (def->graphics[0]->data.vnc.passwd && >+ if (def->graphics[0]->data.vnc.auth.passwd && > xenXMConfigSetString(conf, "vncpasswd", >- def->graphics[0]->data.vnc.passwd) < 0) >+ def->graphics[0]->data.vnc.auth.passwd) < 0) > goto no_memory; > if (def->graphics[0]->data.vnc.keymap && > xenXMConfigSetString(conf, "keymap", >@@ -2467,9 +2467,9 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, > if (def->graphics[0]->data.vnc.listenAddr) > virBufferVSprintf(&buf, ",vnclisten=%s", > def->graphics[0]->data.vnc.listenAddr); >- if (def->graphics[0]->data.vnc.passwd) >+ if (def->graphics[0]->data.vnc.auth.passwd) > virBufferVSprintf(&buf, ",vncpasswd=%s", >- def->graphics[0]->data.vnc.passwd); >+ def->graphics[0]->data.vnc.auth.passwd); > if (def->graphics[0]->data.vnc.keymap) > virBufferVSprintf(&buf, ",keymap=%s", > def->graphics[0]->data.vnc.keymap); >-- >1.6.6.1 >files/09-multi-qxl.patch0000644000000000000000000001127411440333270014063 0ustar rootroot* src/qemu/qemu_conf.c: Support multiple QXL video cards >--- > src/qemu/qemu_conf.c | 64 +++++++++++++++++-- > .../qemuxml2argv-graphics-spice-rhel6.args | 2 +- > .../qemuxml2argv-graphics-spice-rhel6.xml | 3 + > 3 files changed, 61 insertions(+), 8 deletions(-) > >diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c >index f4a6c99..78778ef 100644 >--- a/src/qemu/qemu_conf.c >+++ b/src/qemu/qemu_conf.c >@@ -2922,6 +2922,36 @@ error: > } > > >+static char * >+qemuBuildVideoDevStr(virDomainVideoDefPtr video) >+{ >+ virBuffer buf = VIR_BUFFER_INITIALIZER; >+ const char *model = qemuVideoTypeToString(video->type); >+ >+ if (!model) { >+ qemuReportError(VIR_ERR_INTERNAL_ERROR, >+ "%s", _("invalid video model")); >+ goto error; >+ } >+ >+ virBufferVSprintf(&buf, "%s", model); >+ virBufferVSprintf(&buf, ",id=%s", video->info.alias); >+ if (qemuBuildDeviceAddressStr(&buf, &video->info) < 0) >+ goto error; >+ >+ if (virBufferError(&buf)) { >+ virReportOOMError(); >+ goto error; >+ } >+ >+ return virBufferContentAndReset(&buf); >+ >+error: >+ virBufferFreeAndReset(&buf); >+ return NULL; >+} >+ >+ > char * > qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev) > { >@@ -4510,14 +4540,8 @@ int qemudBuildCommandLine(virConnectPtr conn, > "%s", _("unsupported graphics output requested")); > goto error; > } > >- if (def->nvideos) { >- if (def->nvideos > 1) { >- qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, >- "%s", _("only one video card is currently supported")); >- goto error; >- } >- >+ if (def->nvideos > 0) { > if (qemuCmdFlags & QEMUD_CMD_FLAG_VGA) { > if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_XEN) { > /* nothing - vga has no effect on Xen pvfb */ >@@ -4562,6 +4586,32 @@ int qemudBuildCommandLine(virConnectPtr conn, > goto error; > } > } >+ >+ if (def->nvideos > 1) { >+ if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { >+ for (i = 1 ; i < def->nvideos ; i++) { >+ char *str; >+ if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) { >+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, >+ _("video type %s is only valid as primary video card"), >+ virDomainVideoTypeToString(def->videos[0]->type)); >+ goto error; >+ } >+ >+ ADD_ARG_LIT("-device"); >+ >+ if (!(str = qemuBuildVideoDevStr(def->videos[i]))) >+ goto error; >+ >+ ADD_ARG(str); >+ } >+ } else { >+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, >+ "%s", _("only one video card is currently supported")); >+ goto error; >+ } >+ } >+ > } else { > /* If we have -device, then we set -nodefault already */ > if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) && >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >index e412fdb..44809b0 100644 >--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >@@ -1 +1 @@ >-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,x509-dir=/etc/pki/libvirt-spice -vga qxl -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 >+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,x509-dir=/etc/pki/libvirt-spice -vga qxl -device qxl,id=video1,bus=pci.0,addr=0x4 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >index 08dfb26..6fe9a60 100644 >--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >@@ -25,5 +25,8 @@ > <video> > <model type='qxl' vram='65536' heads='1'/> > </video> >+ <video> >+ <model type='qxl' vram='65536' heads='1'/> >+ </video> > </devices> > </domain> >-- >1.6.6.1 >files/10-spice-security.patch0000644000000000000000000002571311462707627015111 0ustar rootroot* src/conf/domain_conf.c, src/conf/domain_conf.h, > src/libvirt_private.syms: Add XML syntax for specifying per > channel security options for spice;. >* src/qemu/qemu_conf.c: Configure channel security with spice >--- > docs/schemas/domain.rng | 21 ++++++ > src/conf/domain_conf.c | 75 +++++++++++++++++++- > src/conf/domain_conf.h | 21 ++++++ > src/libvirt_private.syms | 4 + > src/qemu/qemu_conf.c | 13 ++++ > .../qemuxml2argv-graphics-spice-rhel6.args | 2 +- > .../qemuxml2argv-graphics-spice-rhel6.xml | 5 +- > 7 files changed, 138 insertions(+), 3 deletions(-) > >diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng >index edd0b7c..17d7b88 100644 >--- a/docs/schemas/domain.rng >+++ b/docs/schemas/domain.rng >@@ -1012,6 +1012,27 @@ > <text/> > </attribute> > </optional> >+ <zeroOrMore> >+ <element name="channel"> >+ <attribute name="name"> >+ <choice> >+ <value>main</value> >+ <value>display</value> >+ <value>inputs</value> >+ <value>cursor</value> >+ <value>playback</value> >+ <value>record</value> >+ </choice> >+ </attribute> >+ <attribute name="mode"> >+ <choice> >+ <value>any</value> >+ <value>secure</value> >+ <value>insecure</value> >+ </choice> >+ </attribute> >+ </element> >+ </zeroOrMore> > </group> > <group> > <attribute name="type"> >diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c >index eee78b1..ffc446f 100644 >--- a/src/conf/domain_conf.c >+++ b/src/conf/domain_conf.c >@@ -218,6 +218,21 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TYPE_LAST, > "desktop", > "spice") > >+VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelName, >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST, >+ "main", >+ "display", >+ "inputs", >+ "cursor", >+ "playback", >+ "record"); >+ >+VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelMode, >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_LAST, >+ "any", >+ "secure", >+ "insecure"); >+ > VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST, > "subsystem", > "capabilities") >@@ -2920,6 +2935,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { > > def->data.desktop.display = virXMLPropString(node, "display"); > } else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { >+ xmlNodePtr cur; > char *port = virXMLPropString(node, "port"); > char *tlsPort; > char *autoport; >@@ -2964,6 +2980,40 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { > def->data.spice.keymap = virXMLPropString(node, "keymap"); > if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth) < 0) > goto error; >+ >+ cur = node->children; >+ while (cur != NULL) { >+ if (cur->type == XML_ELEMENT_NODE) { >+ if (xmlStrEqual(cur->name, BAD_CAST "channel")) { >+ const char *name, *mode; >+ int nameval, modeval; >+ name = virXMLPropString(cur, "name"); >+ mode = virXMLPropString(cur, "mode"); >+ >+ if (!name || !mode) { >+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", >+ _("spice channel missing name/mode")); >+ goto error; >+ } >+ >+ if ((nameval = virDomainGraphicsSpiceChannelNameTypeFromString(name)) < 0) { >+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, >+ _("unknown spice channel name %s"), >+ name); >+ goto error; >+ } >+ if ((modeval = virDomainGraphicsSpiceChannelModeTypeFromString(mode)) < 0) { >+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, >+ _("unknown spice channel mode %s"), >+ mode); >+ goto error; >+ } >+ >+ def->data.spice.channels[nameval] = modeval; >+ } >+ } >+ cur = cur->next; >+ } > } > > cleanup: >@@ -5706,6 +5756,8 @@ virDomainGraphicsDefFormat(virBufferPtr buf, > int flags) > { > const char *type = virDomainGraphicsTypeToString(def->type); >+ int children = 0; >+ int i; > > if (!type) { > virDomainReportError(VIR_ERR_INTERNAL_ERROR, >@@ -5811,7 +5863,28 @@ virDomainGraphicsDefFormat(virBufferPtr buf, > > } > >- virBufferAddLit(buf, "/>\n"); >+ if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { >+ for (i = 0 ; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST ; i++) { >+ int mode = def->data.spice.channels[i]; >+ if (mode == VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY) >+ continue; >+ >+ if (!children) { >+ virBufferAddLit(buf, ">\n"); >+ children = 1; >+ } >+ >+ virBufferVSprintf(buf, " <channel name='%s' mode='%s'/>\n", >+ virDomainGraphicsSpiceChannelNameTypeToString(i), >+ virDomainGraphicsSpiceChannelModeTypeToString(mode)); >+ } >+ } >+ >+ if (children) { >+ virBufferAddLit(buf, " </graphics>\n"); >+ } else { >+ virBufferAddLit(buf, "/>\n"); >+ } > > return 0; > } >diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h >index bbd7e84..d7ea1e0 100644 >--- a/src/conf/domain_conf.h >+++ b/src/conf/domain_conf.h >@@ -485,6 +485,24 @@ struct _virDomainGraphicsAuthDef { > time_t validTo; /* seconds since epoch */ > }; > >+enum virDomainGraphicsSpiceChannelName { >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MAIN, >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_DISPLAY, >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_INPUT, >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_CURSOR, >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_PLAYBACK, >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_RECORD, >+ >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST >+}; >+ >+enum virDomainGraphicsSpiceChannelMode { >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY, >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE, >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE, >+ >+ VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_LAST >+}; > > typedef struct _virDomainGraphicsDef virDomainGraphicsDef; > typedef virDomainGraphicsDef *virDomainGraphicsDefPtr; >@@ -521,6 +539,7 @@ struct _virDomainGraphicsDef { > char *keymap; > virDomainGraphicsAuthDef auth; > unsigned int autoport :1; >+ int channels[VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST]; > } spice; > } data; > }; >@@ -1103,6 +1122,8 @@ VIR_ENUM_DECL(virDomainHostdevSubsys) > VIR_ENUM_DECL(virDomainInput) > VIR_ENUM_DECL(virDomainInputBus) > VIR_ENUM_DECL(virDomainGraphics) >+VIR_ENUM_DECL(virDomainGraphicsSpiceChannelName) >+VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode) > /* from libvirt.h */ > VIR_ENUM_DECL(virDomainState) > VIR_ENUM_DECL(virDomainSeclabel) >diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms >index 7950bcd..f1a91f7 100644 >--- a/src/libvirt_private.syms >+++ b/src/libvirt_private.syms >@@ -146,6 +146,10 @@ virDomainGetRootFilesystem; > virDomainGraphicsDefFree; > virDomainGraphicsTypeFromString; > virDomainGraphicsTypeToString; >+virDomainGraphicsSpiceChannelNameTypeFromString; >+virDomainGraphicsSpiceChannelNameTypeToString; >+virDomainGraphicsSpiceChannelModeTypeFromString; >+virDomainGraphicsSpiceChannelModeTypeToString; > virDomainHostdevDefFree; > virDomainHostdevModeTypeToString; > virDomainHostdevSubsysTypeToString; >diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c >index 78778ef..31214b1 100644 >--- a/src/qemu/qemu_conf.c >+++ b/src/qemu/qemu_conf.c >@@ -4519,6 +4519,19 @@ int qemudBuildCommandLine(virConnectPtr conn, > virBufferVSprintf(&opt, ",x509-dir=%s", > driver->spiceTLSx509certdir); > >+ for (i = 0 ; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST ; i++) { >+ int mode = def->graphics[0]->data.spice.channels[i]; >+ switch (mode) { >+ case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE: >+ virBufferVSprintf(&opt, ",tls-channel=%s", >+ virDomainGraphicsSpiceChannelNameTypeToString(i)); >+ break; >+ case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE: >+ virBufferVSprintf(&opt, ",plaintext-channel=%s", >+ virDomainGraphicsSpiceChannelNameTypeToString(i)); >+ break; >+ } >+ } > > if (virBufferError(&opt)) > goto no_memory; >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >index 44809b0..87b8c06 100644 >--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.args >@@ -1 +1 @@ >-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,x509-dir=/etc/pki/libvirt-spice -vga qxl -device qxl,id=video1,bus=pci.0,addr=0x4 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 >+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,x509-dir=/etc/pki/libvirt-spice,tls-channel=main,plaintext-channel=inputs -vga qxl -device qxl,id=video1,bus=pci.0,addr=0x4 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >index 6fe9a60..bdce04b 100644 >--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-rhel6.xml >@@ -21,7 +21,10 @@ > </disk> > <controller type='ide' index='0'/> > <input type='mouse' bus='ps2'/> >- <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'/> >+ <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'> >+ <channel name='main' mode='secure'/> >+ <channel name='inputs' mode='insecure'/> >+ </graphics> > <video> > <model type='qxl' vram='65536' heads='1'/> > </video> >-- >1.6.6.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 335932
:
245937
| 252535 |
252629