Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
162efa1a
L
libvirt
项目概览
openeuler
/
libvirt
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
libvirt
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
162efa1a
编写于
9月 02, 2011
作者:
M
Marc-André Lureau
提交者:
Daniel Veillard
9月 02, 2011
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add "redirdev" redirection device
- create a new "redirdev" element for this purpose
上级
fdd14a9d
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
494 addition
and
18 deletion
+494
-18
docs/formatdomain.html.in
docs/formatdomain.html.in
+39
-0
docs/schemas/domain.rng
docs/schemas/domain.rng
+31
-13
src/conf/domain_audit.c
src/conf/domain_audit.c
+65
-0
src/conf/domain_audit.h
src/conf/domain_audit.h
+5
-0
src/conf/domain_conf.c
src/conf/domain_conf.c
+123
-4
src/conf/domain_conf.h
src/conf/domain_conf.h
+24
-0
src/libvirt_private.syms
src/libvirt_private.syms
+3
-0
src/qemu/qemu_command.c
src/qemu/qemu_command.c
+96
-0
src/qemu/qemu_command.h
src/qemu/qemu_command.h
+3
-1
src/qemu/qemu_driver.c
src/qemu/qemu_driver.c
+7
-0
src/qemu/qemu_hotplug.c
src/qemu/qemu_hotplug.c
+43
-0
src/qemu/qemu_hotplug.h
src/qemu/qemu_hotplug.h
+3
-0
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
+8
-0
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
+38
-0
tests/qemuxml2argvtest.c
tests/qemuxml2argvtest.c
+4
-0
tests/qemuxml2xmltest.c
tests/qemuxml2xmltest.c
+2
-0
未找到文件。
docs/formatdomain.html.in
浏览文件 @
162efa1a
...
...
@@ -1387,6 +1387,45 @@
not used by qemu.
</dd>
</dl>
<h4><a
name=
"elementsRedir"
>
Redirected devices
</a></h4>
<p>
USB device redirection through a character device is
supported
<span
class=
"since"
>
since after 0.9.5 (KVM
only)
</span>
:
</p>
<pre>
...
<
devices
>
<
redirdev bus='usb' type='tcp'
>
<
source mode='connect' host='localhost' service='4000'/
>
<
/redirdev
>
<
/devices
>
...
</pre>
<dl>
<dt><code>
redirdev
</code></dt>
<dd>
The
<code>
redirdev
</code>
element is the main container for
describing redirected devices.
<code>
bus
</code>
must be "usb"
for a USB device.
An additional attribute
<code>
type
</code>
is required,
matching one of the
supported
<a
href=
"#elementsConsole"
>
serial device
</a>
types,
to describe the host side of the
tunnel;
<code>
type='tcp'
</code>
or
<code>
type='spicevmc'
</code>
(which uses the usbredir
channel of a
<a
href=
"#elementsGraphics"
>
SPICE graphics
device
</a>
) are typical. Further sub-elements, such
as
<code>
<
source
>
</code>
, may be required according to
the given type, although a
<code>
<
target
>
</code>
sub-element is not required (since the consumer of the
character device is the hypervisor itself, rather than a
device visible in the guest).
</dd>
</dl>
<h4><a
name=
"elementsSmartcard"
>
Smartcard devices
</a></h4>
<p>
...
...
docs/schemas/domain.rng
浏览文件 @
162efa1a
...
...
@@ -1724,21 +1724,25 @@
</element>
</define>
<define
name=
"qemucdevSrcTypeChoice"
>
<choice>
<value>
dev
</value>
<value>
file
</value>
<value>
pipe
</value>
<value>
unix
</value>
<value>
tcp
</value>
<value>
udp
</value>
<value>
null
</value>
<value>
stdio
</value>
<value>
vc
</value>
<value>
pty
</value>
<value>
spicevmc
</value>
</choice>
</define>
<define
name=
"qemucdevSrcType"
>
<attribute
name=
"type"
>
<choice>
<value>
dev
</value>
<value>
file
</value>
<value>
pipe
</value>
<value>
unix
</value>
<value>
tcp
</value>
<value>
udp
</value>
<value>
null
</value>
<value>
stdio
</value>
<value>
vc
</value>
<value>
pty
</value>
<value>
spicevmc
</value>
</choice>
<ref
name=
"qemucdevSrcTypeChoice"
/>
</attribute>
</define>
<define
name=
"qemucdevSrcDef"
>
...
...
@@ -1975,6 +1979,19 @@
</optional>
</element>
</define>
<define
name=
"redirdev"
>
<element
name=
"redirdev"
>
<attribute
name=
"bus"
>
<choice>
<value>
usb
</value>
</choice>
</attribute>
<attribute
name=
"type"
>
<ref
name=
"qemucdevSrcTypeChoice"
/>
</attribute>
<ref
name=
"qemucdevSrcDef"
/>
</element>
</define>
<define
name=
"hostdev"
>
<element
name=
"hostdev"
>
<optional>
...
...
@@ -2139,6 +2156,7 @@
<ref
name=
"channel"
/>
<ref
name=
"smartcard"
/>
<ref
name=
"hub"
/>
<ref
name=
"redirdev"
/>
</choice>
</zeroOrMore>
<optional>
...
...
src/conf/domain_audit.c
浏览文件 @
162efa1a
...
...
@@ -308,6 +308,66 @@ cleanup:
}
/**
* virDomainAuditRedirdev:
* @vm: domain making a change in pass-through host device
* @redirdev: device being attached or removed
* @reason: one of "start", "attach", or "detach"
* @success: true if the device passthrough operation succeeded
*
* Log an audit message about an attempted device passthrough change.
*/
void
virDomainAuditRedirdev
(
virDomainObjPtr
vm
,
virDomainRedirdevDefPtr
redirdev
,
const
char
*
reason
,
bool
success
)
{
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
char
*
vmname
;
char
*
address
;
char
*
device
;
const
char
*
virt
;
virUUIDFormat
(
vm
->
def
->
uuid
,
uuidstr
);
if
(
!
(
vmname
=
virAuditEncode
(
"vm"
,
vm
->
def
->
name
)))
{
VIR_WARN
(
"OOM while encoding audit message"
);
return
;
}
if
(
!
(
virt
=
virDomainVirtTypeToString
(
vm
->
def
->
virtType
)))
{
VIR_WARN
(
"Unexpected virt type %d while encoding audit message"
,
vm
->
def
->
virtType
);
virt
=
"?"
;
}
switch
(
redirdev
->
bus
)
{
case
VIR_DOMAIN_REDIRDEV_BUS_USB
:
if
(
virAsprintf
(
&
address
,
"USB redirdev"
)
<
0
)
{
VIR_WARN
(
"OOM while encoding audit message"
);
goto
cleanup
;
}
default:
VIR_WARN
(
"Unexpected redirdev bus while encoding audit message: %d"
,
redirdev
->
bus
);
goto
cleanup
;
}
if
(
!
(
device
=
virAuditEncode
(
"device"
,
VIR_AUDIT_STR
(
address
))))
{
VIR_WARN
(
"OOM while encoding audit message"
);
goto
cleanup
;
}
VIR_AUDIT
(
VIR_AUDIT_RECORD_RESOURCE
,
success
,
"virt=%s resrc=dev reason=%s %s uuid=%s bus=%s %s"
,
virt
,
reason
,
vmname
,
uuidstr
,
virDomainRedirdevBusTypeToString
(
redirdev
->
bus
),
device
);
cleanup:
VIR_FREE
(
vmname
);
VIR_FREE
(
device
);
VIR_FREE
(
address
);
}
/**
* virDomainAuditCgroup:
* @vm: domain making the cgroups ACL change
...
...
@@ -538,6 +598,11 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)
virDomainAuditHostdev
(
vm
,
hostdev
,
"start"
,
true
);
}
for
(
i
=
0
;
i
<
vm
->
def
->
nredirdevs
;
i
++
)
{
virDomainRedirdevDefPtr
redirdev
=
vm
->
def
->
redirdevs
[
i
];
virDomainAuditRedirdev
(
vm
,
redirdev
,
"start"
,
true
);
}
virDomainAuditMemory
(
vm
,
0
,
vm
->
def
->
mem
.
cur_balloon
,
"start"
,
true
);
virDomainAuditVcpu
(
vm
,
0
,
vm
->
def
->
vcpus
,
"start"
,
true
);
...
...
src/conf/domain_audit.h
浏览文件 @
162efa1a
...
...
@@ -101,5 +101,10 @@ void virDomainAuditVcpu(virDomainObjPtr vm,
void
virDomainAuditSecurityLabel
(
virDomainObjPtr
vm
,
bool
success
)
ATTRIBUTE_NONNULL
(
1
);
void
virDomainAuditRedirdev
(
virDomainObjPtr
vm
,
virDomainRedirdevDefPtr
def
,
const
char
*
reason
,
bool
success
)
ATTRIBUTE_NONNULL
(
1
)
ATTRIBUTE_NONNULL
(
2
)
ATTRIBUTE_NONNULL
(
3
);
#endif
/* __VIR_DOMAIN_AUDIT_H__ */
src/conf/domain_conf.c
浏览文件 @
162efa1a
...
...
@@ -127,7 +127,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
"watchdog"
,
"controller"
,
"graphics"
,
"hub"
)
"hub"
,
"redirdev"
)
VIR_ENUM_IMPL
(
virDomainDeviceAddress
,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
,
"none"
,
...
...
@@ -441,6 +442,9 @@ VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_CRASHED+1,
VIR_ENUM_IMPL
(
virDomainHub
,
VIR_DOMAIN_HUB_TYPE_LAST
,
"usb"
)
VIR_ENUM_IMPL
(
virDomainRedirdevBus
,
VIR_DOMAIN_REDIRDEV_BUS_LAST
,
"usb"
)
#define VIR_DOMAIN_NOSTATE_LAST (VIR_DOMAIN_NOSTATE_UNKNOWN + 1)
VIR_ENUM_IMPL
(
virDomainNostateReason
,
VIR_DOMAIN_NOSTATE_LAST
,
"unknown"
)
...
...
@@ -1013,6 +1017,17 @@ void virDomainHubDefFree(virDomainHubDefPtr def)
VIR_FREE
(
def
);
}
void
virDomainRedirdevDefFree
(
virDomainRedirdevDefPtr
def
)
{
if
(
!
def
)
return
;
virDomainChrSourceDefClear
(
&
def
->
source
.
chr
);
virDomainDeviceInfoClear
(
&
def
->
info
);
VIR_FREE
(
def
);
}
void
virDomainDeviceDefFree
(
virDomainDeviceDefPtr
def
)
{
if
(
!
def
)
...
...
@@ -1052,6 +1067,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
case
VIR_DOMAIN_DEVICE_HUB
:
virDomainHubDefFree
(
def
->
data
.
hub
);
break
;
case
VIR_DOMAIN_DEVICE_REDIRDEV
:
virDomainRedirdevDefFree
(
def
->
data
.
redirdev
);
break
;
}
VIR_FREE
(
def
);
...
...
@@ -5344,7 +5362,6 @@ virDomainHostdevDefParseXML(const xmlNodePtr node,
virBitmapPtr
bootMap
,
unsigned
int
flags
)
{
xmlNodePtr
cur
;
virDomainHostdevDefPtr
def
;
char
*
mode
,
*
type
=
NULL
,
*
managed
=
NULL
;
...
...
@@ -5391,8 +5408,8 @@ virDomainHostdevDefParseXML(const xmlNodePtr node,
if
(
xmlStrEqual
(
cur
->
name
,
BAD_CAST
"source"
))
{
if
(
def
->
mode
==
VIR_DOMAIN_HOSTDEV_MODE_SUBSYS
&&
def
->
source
.
subsys
.
type
==
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB
)
{
if
(
virDomainHostdevSubsysUsbDefParseXML
(
cur
,
def
)
<
0
)
goto
error
;
if
(
virDomainHostdevSubsysUsbDefParseXML
(
cur
,
def
)
<
0
)
goto
error
;
}
if
(
def
->
mode
==
VIR_DOMAIN_HOSTDEV_MODE_SUBSYS
&&
def
->
source
.
subsys
.
type
==
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI
)
{
...
...
@@ -5445,6 +5462,68 @@ error:
}
static
virDomainRedirdevDefPtr
virDomainRedirdevDefParseXML
(
const
xmlNodePtr
node
,
unsigned
int
flags
)
{
xmlNodePtr
cur
;
virDomainRedirdevDefPtr
def
;
char
*
bus
,
*
type
=
NULL
;
if
(
VIR_ALLOC
(
def
)
<
0
)
{
virReportOOMError
();
return
NULL
;
}
bus
=
virXMLPropString
(
node
,
"bus"
);
if
(
bus
)
{
if
((
def
->
bus
=
virDomainRedirdevBusTypeFromString
(
bus
))
<
0
)
{
virDomainReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"unknown redirdev bus '%s'"
),
bus
);
goto
error
;
}
}
else
{
def
->
bus
=
VIR_DOMAIN_REDIRDEV_BUS_USB
;
}
type
=
virXMLPropString
(
node
,
"type"
);
if
(
type
)
{
if
((
def
->
source
.
chr
.
type
=
virDomainChrTypeFromString
(
type
))
<
0
)
{
virDomainReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"unknown redirdev character device type '%s'"
),
type
);
goto
error
;
}
}
else
{
virDomainReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"missing type in redirdev"
));
goto
error
;
}
cur
=
node
->
children
;
while
(
cur
!=
NULL
)
{
if
(
cur
->
type
==
XML_ELEMENT_NODE
)
{
if
(
xmlStrEqual
(
cur
->
name
,
BAD_CAST
"source"
))
{
int
remaining
;
remaining
=
virDomainChrSourceDefParseXML
(
&
def
->
source
.
chr
,
cur
,
flags
);
if
(
remaining
!=
0
)
goto
error
;
}
}
cur
=
cur
->
next
;
}
cleanup:
VIR_FREE
(
bus
);
VIR_FREE
(
type
);
return
def
;
error:
virDomainRedirdevDefFree
(
def
);
def
=
NULL
;
goto
cleanup
;
}
static
int
virDomainLifecycleParseXML
(
xmlXPathContextPtr
ctxt
,
const
char
*
xpath
,
int
*
val
,
...
...
@@ -5650,6 +5729,10 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
dev
->
type
=
VIR_DOMAIN_DEVICE_HUB
;
if
(
!
(
dev
->
data
.
hub
=
virDomainHubDefParseXML
(
node
,
flags
)))
goto
error
;
}
else
if
(
xmlStrEqual
(
node
->
name
,
BAD_CAST
"redirdev"
))
{
dev
->
type
=
VIR_DOMAIN_DEVICE_REDIRDEV
;
if
(
!
(
dev
->
data
.
redirdev
=
virDomainRedirdevDefParseXML
(
node
,
flags
)))
goto
error
;
}
else
{
virDomainReportError
(
VIR_ERR_XML_ERROR
,
"%s"
,
_
(
"unknown device type"
));
...
...
@@ -7069,6 +7152,22 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
}
VIR_FREE
(
nodes
);
/* analysis of the redirected devices */
if
((
n
=
virXPathNodeSet
(
"./devices/redirdev"
,
ctxt
,
&
nodes
))
<
0
)
{
goto
error
;
}
if
(
n
&&
VIR_ALLOC_N
(
def
->
redirdevs
,
n
)
<
0
)
goto
no_memory
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
virDomainRedirdevDefPtr
redirdev
=
virDomainRedirdevDefParseXML
(
nodes
[
i
],
flags
);
if
(
!
redirdev
)
goto
error
;
def
->
redirdevs
[
def
->
nredirdevs
++
]
=
redirdev
;
}
VIR_FREE
(
nodes
);
/* analysis of security label */
if
(
virSecurityLabelDefParseXML
(
def
,
ctxt
,
flags
)
==
-
1
)
goto
error
;
...
...
@@ -10158,6 +10257,22 @@ virDomainHostdevDefFormat(virBufferPtr buf,
return
0
;
}
static
int
virDomainRedirdevDefFormat
(
virBufferPtr
buf
,
virDomainRedirdevDefPtr
def
,
unsigned
int
flags
)
{
const
char
*
bus
;
bus
=
virDomainRedirdevBusTypeToString
(
def
->
bus
);
virBufferAsprintf
(
buf
,
" <redirdev bus='%s'"
,
bus
);
if
(
virDomainChrSourceDefFormat
(
buf
,
&
def
->
source
.
chr
,
false
,
flags
)
<
0
)
return
-
1
;
virBufferAddLit
(
buf
,
" </redirdev>
\n
"
);
return
0
;
}
static
int
virDomainHubDefFormat
(
virBufferPtr
buf
,
...
...
@@ -10592,6 +10707,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if
(
virDomainHostdevDefFormat
(
&
buf
,
def
->
hostdevs
[
n
],
flags
)
<
0
)
goto
cleanup
;
for
(
n
=
0
;
n
<
def
->
nredirdevs
;
n
++
)
if
(
virDomainRedirdevDefFormat
(
&
buf
,
def
->
redirdevs
[
n
],
flags
)
<
0
)
goto
cleanup
;
for
(
n
=
0
;
n
<
def
->
nhubs
;
n
++
)
if
(
virDomainHubDefFormat
(
&
buf
,
def
->
hubs
[
n
],
flags
)
<
0
)
goto
cleanup
;
...
...
src/conf/domain_conf.h
浏览文件 @
162efa1a
...
...
@@ -939,6 +939,23 @@ struct _virDomainHostdevDef {
virDomainDeviceInfo
info
;
/* Guest address */
};
enum
virDomainRedirdevBus
{
VIR_DOMAIN_REDIRDEV_BUS_USB
,
VIR_DOMAIN_REDIRDEV_BUS_LAST
};
typedef
struct
_virDomainRedirdevDef
virDomainRedirdevDef
;
typedef
virDomainRedirdevDef
*
virDomainRedirdevDefPtr
;
struct
_virDomainRedirdevDef
{
int
bus
;
/* enum virDomainRedirdevBus */
union
{
virDomainChrSourceDef
chr
;
}
source
;
virDomainDeviceInfo
info
;
/* Guest address */
};
enum
{
VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO
,
...
...
@@ -979,6 +996,7 @@ enum virDomainDeviceType {
VIR_DOMAIN_DEVICE_CONTROLLER
,
VIR_DOMAIN_DEVICE_GRAPHICS
,
VIR_DOMAIN_DEVICE_HUB
,
VIR_DOMAIN_DEVICE_REDIRDEV
,
VIR_DOMAIN_DEVICE_LAST
,
};
...
...
@@ -1000,6 +1018,7 @@ struct _virDomainDeviceDef {
virDomainWatchdogDefPtr
watchdog
;
virDomainGraphicsDefPtr
graphics
;
virDomainHubDefPtr
hub
;
virDomainRedirdevDefPtr
redirdev
;
}
data
;
};
...
...
@@ -1312,6 +1331,9 @@ struct _virDomainDef {
int
nhostdevs
;
virDomainHostdevDefPtr
*
hostdevs
;
int
nredirdevs
;
virDomainRedirdevDefPtr
*
redirdevs
;
int
nsmartcards
;
virDomainSmartcardDefPtr
*
smartcards
;
...
...
@@ -1479,6 +1501,7 @@ void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
void
virDomainVideoDefFree
(
virDomainVideoDefPtr
def
);
void
virDomainHostdevDefFree
(
virDomainHostdevDefPtr
def
);
void
virDomainHubDefFree
(
virDomainHubDefPtr
def
);
void
virDomainRedirdevDefFree
(
virDomainRedirdevDefPtr
def
);
void
virDomainDeviceDefFree
(
virDomainDeviceDefPtr
def
);
int
virDomainDeviceAddressIsValid
(
virDomainDeviceInfoPtr
info
,
int
type
);
...
...
@@ -1760,6 +1783,7 @@ VIR_ENUM_DECL(virDomainVideo)
VIR_ENUM_DECL
(
virDomainHostdevMode
)
VIR_ENUM_DECL
(
virDomainHostdevSubsys
)
VIR_ENUM_DECL
(
virDomainHub
)
VIR_ENUM_DECL
(
virDomainRedirdevBus
)
VIR_ENUM_DECL
(
virDomainInput
)
VIR_ENUM_DECL
(
virDomainInputBus
)
VIR_ENUM_DECL
(
virDomainGraphics
)
...
...
src/libvirt_private.syms
浏览文件 @
162efa1a
...
...
@@ -219,6 +219,7 @@ virDomainAuditHostdev;
virDomainAuditMemory;
virDomainAuditNet;
virDomainAuditNetDevice;
virDomainAuditRedirdev;
virDomainAuditSecurityLabel;
virDomainAuditStart;
virDomainAuditStop;
...
...
@@ -375,6 +376,8 @@ virDomainObjSetState;
virDomainObjTaint;
virDomainObjUnlock;
virDomainObjUnref;
virDomainRedirdevBusTypeFromString;
virDomainRedirdevBusTypeToString;
virDomainRemoveInactive;
virDomainSaveConfig;
virDomainSaveStatus;
...
...
src/qemu/qemu_command.c
浏览文件 @
162efa1a
...
...
@@ -606,6 +606,33 @@ qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev
}
int
qemuAssignDeviceRedirdevAlias
(
virDomainDefPtr
def
,
virDomainRedirdevDefPtr
redirdev
,
int
idx
)
{
if
(
idx
==
-
1
)
{
int
i
;
idx
=
0
;
for
(
i
=
0
;
i
<
def
->
nredirdevs
;
i
++
)
{
int
thisidx
;
if
((
thisidx
=
qemuDomainDeviceAliasIndex
(
&
def
->
redirdevs
[
i
]
->
info
,
"redir"
))
<
0
)
{
qemuReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"Unable to determine device index for redirected device"
));
return
-
1
;
}
if
(
thisidx
>=
idx
)
idx
=
thisidx
+
1
;
}
}
if
(
virAsprintf
(
&
redirdev
->
info
.
alias
,
"redir%d"
,
idx
)
<
0
)
{
virReportOOMError
();
return
-
1
;
}
return
0
;
}
int
qemuAssignDeviceControllerAlias
(
virDomainControllerDefPtr
controller
)
{
...
...
@@ -653,6 +680,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virBitmapPtr qemuCaps)
if
(
qemuAssignDeviceHostdevAlias
(
def
,
def
->
hostdevs
[
i
],
i
)
<
0
)
return
-
1
;
}
for
(
i
=
0
;
i
<
def
->
nredirdevs
;
i
++
)
{
if
(
qemuAssignDeviceRedirdevAlias
(
def
,
def
->
redirdevs
[
i
],
i
)
<
0
)
return
-
1
;
}
for
(
i
=
0
;
i
<
def
->
nvideos
;
i
++
)
{
if
(
virAsprintf
(
&
def
->
videos
[
i
]
->
info
.
alias
,
"video%d"
,
i
)
<
0
)
goto
no_memory
;
...
...
@@ -2348,6 +2379,45 @@ qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev)
}
char
*
qemuBuildRedirdevDevStr
(
virDomainRedirdevDefPtr
dev
,
virBitmapPtr
qemuCaps
)
{
virBuffer
buf
=
VIR_BUFFER_INITIALIZER
;
if
(
dev
->
bus
!=
VIR_DOMAIN_REDIRDEV_BUS_USB
)
{
qemuReportError
(
VIR_ERR_CONFIG_UNSUPPORTED
,
_
(
"Redirection bus %s is not supported by QEMU"
),
virDomainRedirdevBusTypeToString
(
dev
->
bus
));
goto
error
;
}
if
(
!
qemuCapsGet
(
qemuCaps
,
QEMU_CAPS_USB_REDIR
))
{
qemuReportError
(
VIR_ERR_CONFIG_UNSUPPORTED
,
"%s"
,
_
(
"USB redirection is not supported "
"by this version of QEMU"
));
goto
error
;
}
virBufferAsprintf
(
&
buf
,
"usb-redir,chardev=char%s,id=%s"
,
dev
->
info
.
alias
,
dev
->
info
.
alias
);
if
(
qemuBuildDeviceAddressStr
(
&
buf
,
&
dev
->
info
,
qemuCaps
)
<
0
)
goto
error
;
if
(
virBufferError
(
&
buf
))
{
virReportOOMError
();
goto
error
;
}
return
virBufferContentAndReset
(
&
buf
);
error:
virBufferFreeAndReset
(
&
buf
);
return
NULL
;
}
char
*
qemuBuildUSBHostdevDevStr
(
virDomainHostdevDefPtr
dev
,
virBitmapPtr
qemuCaps
)
...
...
@@ -4839,6 +4909,32 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArgList
(
cmd
,
"-watchdog-action"
,
action
,
NULL
);
}
/* Add redirected devices */
for
(
i
=
0
;
i
<
def
->
nredirdevs
;
i
++
)
{
virDomainRedirdevDefPtr
redirdev
=
def
->
redirdevs
[
i
];
char
*
devstr
;
virCommandAddArg
(
cmd
,
"-chardev"
);
if
(
!
(
devstr
=
qemuBuildChrChardevStr
(
&
redirdev
->
source
.
chr
,
redirdev
->
info
.
alias
,
qemuCaps
)))
{
goto
error
;
}
virCommandAddArg
(
cmd
,
devstr
);
VIR_FREE
(
devstr
);
if
(
!
qemuCapsGet
(
qemuCaps
,
QEMU_CAPS_DEVICE
))
goto
error
;
virCommandAddArg
(
cmd
,
"-device"
);
if
(
!
(
devstr
=
qemuBuildRedirdevDevStr
(
redirdev
,
qemuCaps
)))
goto
error
;
virCommandAddArg
(
cmd
,
devstr
);
VIR_FREE
(
devstr
);
}
/* Add host passthrough hardware */
for
(
i
=
0
;
i
<
def
->
nhostdevs
;
i
++
)
{
virDomainHostdevDefPtr
hostdev
=
def
->
hostdevs
[
i
];
...
...
src/qemu/qemu_command.h
浏览文件 @
162efa1a
...
...
@@ -120,6 +120,7 @@ char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
virBitmapPtr
qemuCaps
);
char
*
qemuBuildHubDevStr
(
virDomainHubDefPtr
dev
,
virBitmapPtr
qemuCaps
);
char
*
qemuBuildRedirdevDevStr
(
virDomainRedirdevDefPtr
dev
,
virBitmapPtr
qemuCaps
);
int
qemuNetworkIfaceConnect
(
virDomainDefPtr
def
,
...
...
@@ -189,8 +190,9 @@ int qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr ad
int
qemuDomainNetVLAN
(
virDomainNetDefPtr
def
);
int
qemuAssignDeviceNetAlias
(
virDomainDefPtr
def
,
virDomainNetDefPtr
net
,
int
idx
);
int
qemuAssignDeviceDiskAlias
(
virDomainDiskDefPtr
def
,
virBitmapPtr
qemuCaps
);
int
qemuAssignDeviceHostdevAlias
(
virDomainDefPtr
def
,
virDomainHostdevDefPtr
net
,
int
idx
);
int
qemuAssignDeviceHostdevAlias
(
virDomainDefPtr
def
,
virDomainHostdevDefPtr
hostdev
,
int
idx
);
int
qemuAssignDeviceControllerAlias
(
virDomainControllerDefPtr
controller
);
int
qemuAssignDeviceRedirdevAlias
(
virDomainDefPtr
def
,
virDomainRedirdevDefPtr
redirdev
,
int
idx
);
int
qemuParseKeywords
(
const
char
*
str
,
...
...
src/qemu/qemu_driver.c
浏览文件 @
162efa1a
...
...
@@ -4978,6 +4978,13 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
dev
->
data
.
hostdev
=
NULL
;
break
;
case
VIR_DOMAIN_DEVICE_REDIRDEV
:
ret
=
qemuDomainAttachRedirdevDevice
(
driver
,
vm
,
dev
->
data
.
redirdev
);
if
(
!
ret
)
dev
->
data
.
redirdev
=
NULL
;
break
;
default:
qemuReportError
(
VIR_ERR_CONFIG_UNSUPPORTED
,
_
(
"device type '%s' cannot be attached"
),
...
...
src/qemu/qemu_hotplug.c
浏览文件 @
162efa1a
...
...
@@ -911,6 +911,49 @@ error:
}
int
qemuDomainAttachRedirdevDevice
(
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainRedirdevDefPtr
redirdev
)
{
int
ret
;
qemuDomainObjPrivatePtr
priv
=
vm
->
privateData
;
char
*
devstr
=
NULL
;
if
(
qemuCapsGet
(
priv
->
qemuCaps
,
QEMU_CAPS_DEVICE
))
{
if
(
qemuAssignDeviceRedirdevAlias
(
vm
->
def
,
redirdev
,
-
1
)
<
0
)
goto
error
;
if
(
!
(
devstr
=
qemuBuildRedirdevDevStr
(
redirdev
,
priv
->
qemuCaps
)))
goto
error
;
}
if
(
VIR_REALLOC_N
(
vm
->
def
->
redirdevs
,
vm
->
def
->
nredirdevs
+
1
)
<
0
)
{
virReportOOMError
();
goto
error
;
}
qemuDomainObjEnterMonitorWithDriver
(
driver
,
vm
);
if
(
qemuCapsGet
(
priv
->
qemuCaps
,
QEMU_CAPS_DEVICE
))
ret
=
qemuMonitorAddDevice
(
priv
->
mon
,
devstr
);
else
goto
error
;
qemuDomainObjExitMonitorWithDriver
(
driver
,
vm
);
virDomainAuditRedirdev
(
vm
,
redirdev
,
"attach"
,
ret
==
0
);
if
(
ret
<
0
)
goto
error
;
vm
->
def
->
redirdevs
[
vm
->
def
->
nredirdevs
++
]
=
redirdev
;
VIR_FREE
(
devstr
);
return
0
;
error:
VIR_FREE
(
devstr
);
return
-
1
;
}
int
qemuDomainAttachHostUsbDevice
(
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainHostdevDefPtr
hostdev
)
...
...
src/qemu/qemu_hotplug.h
浏览文件 @
162efa1a
...
...
@@ -53,6 +53,9 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver,
int
qemuDomainAttachHostUsbDevice
(
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainHostdevDefPtr
hostdev
);
int
qemuDomainAttachRedirdevDevice
(
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainRedirdevDefPtr
hostdev
);
int
qemuDomainAttachHostDevice
(
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainHostdevDefPtr
hostdev
);
...
...
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
0 → 100644
浏览文件 @
162efa1a
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
-device ich9-usb-ehci1,id=usb,bus=pci.0,multifunction=on,addr=0x4.0x7 \
-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,multifunction=on,addr=0x4.0x2 \
-chardev socket,id=charredir0,host=localhost,port=4000 \
-device usb-redir,chardev=charredir0,id=redir0 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
0 → 100644
浏览文件 @
162efa1a
<domain
type=
'qemu'
>
<name>
QEMUGuest1
</name>
<uuid>
c7a5fdbd-edaf-9455-926a-d65c16db1809
</uuid>
<memory>
219136
</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>
<controller
type=
'usb'
index=
'0'
model=
'ich9-ehci1'
>
<address
type=
'pci'
domain=
'0x0000'
bus=
'0x00'
slot=
'0x04'
function=
'0x7'
/>
</controller>
<controller
type=
'usb'
index=
'0'
model=
'ich9-uhci1'
>
<master
startport=
'0'
/>
<address
type=
'pci'
domain=
'0x0000'
bus=
'0x00'
slot=
'0x04'
function=
'0x0'
/>
</controller>
<controller
type=
'usb'
index=
'0'
model=
'ich9-uhci2'
>
<master
startport=
'2'
/>
<address
type=
'pci'
domain=
'0x0000'
bus=
'0x00'
slot=
'0x04'
function=
'0x1'
/>
</controller>
<controller
type=
'usb'
index=
'0'
model=
'ich9-uhci3'
>
<master
startport=
'4'
/>
<address
type=
'pci'
domain=
'0x0000'
bus=
'0x00'
slot=
'0x04'
function=
'0x2'
/>
</controller>
<redirdev
bus=
'usb'
type=
'tcp'
>
<source
mode=
'connect'
host=
'localhost'
service=
'4000'
/>
<protocol
type=
'raw'
/>
</redirdev>
<memballoon
model=
'virtio'
/>
</devices>
</domain>
tests/qemuxml2argvtest.c
浏览文件 @
162efa1a
...
...
@@ -507,6 +507,10 @@ mymain(void)
DO_TEST
(
"usb-ports"
,
false
,
QEMU_CAPS_CHARDEV
,
QEMU_CAPS_DEVICE
,
QEMU_CAPS_USB_HUB
,
QEMU_CAPS_NODEFCONFIG
);
DO_TEST
(
"usb-redir"
,
false
,
QEMU_CAPS_CHARDEV
,
QEMU_CAPS_DEVICE
,
QEMU_CAPS_NODEFCONFIG
,
QEMU_CAPS_PCI_MULTIFUNCTION
,
QEMU_CAPS_USB_HUB
,
QEMU_CAPS_ICH9_USB_EHCI1
,
QEMU_CAPS_USB_REDIR
);
DO_TEST
(
"smbios"
,
false
,
QEMU_CAPS_SMBIOS_TYPE
);
...
...
tests/qemuxml2xmltest.c
浏览文件 @
162efa1a
...
...
@@ -189,6 +189,8 @@ mymain(void)
DO_TEST
(
"lease"
);
DO_TEST
(
"event_idx"
);
DO_TEST
(
"usb-redir"
);
/* These tests generate different XML */
DO_TEST_DIFFERENT
(
"balloon-device-auto"
);
DO_TEST_DIFFERENT
(
"channel-virtio-auto"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录