Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
ea960fb7
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ea960fb7
编写于
12月 04, 2008
作者:
D
Daniel P. Berrange
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Merge all return paths from QEMU driver APIs
上级
8492cd20
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
668 addition
and
549 deletion
+668
-549
ChangeLog
ChangeLog
+4
-0
src/qemu_driver.c
src/qemu_driver.c
+664
-549
未找到文件。
ChangeLog
浏览文件 @
ea960fb7
Thu Dec 4 21:01:41 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
* src/qemu_driver.c: Merge all return paths from driver APIs
Thu Dec 4 21:00:41 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
Thu Dec 4 21:00:41 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
* src/test.c: Stub out node device APIs to avoid activating
* src/test.c: Stub out node device APIs to avoid activating
...
...
src/qemu_driver.c
浏览文件 @
ea960fb7
...
@@ -1074,7 +1074,7 @@ static int qemudDispatchVMFailure(struct qemud_driver *driver, virDomainObjPtr v
...
@@ -1074,7 +1074,7 @@ static int qemudDispatchVMFailure(struct qemud_driver *driver, virDomainObjPtr v
static
void
static
void
qemudDispatchVMEvent
(
int
watch
,
int
fd
,
int
events
,
void
*
opaque
)
{
qemudDispatchVMEvent
(
int
watch
,
int
fd
,
int
events
,
void
*
opaque
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
opaque
;
struct
qemud_driver
*
driver
=
opaque
;
virDomainObjPtr
vm
=
NULL
;
virDomainObjPtr
vm
=
NULL
;
unsigned
int
i
;
unsigned
int
i
;
...
@@ -1236,7 +1236,7 @@ static virDrvOpenStatus qemudOpen(virConnectPtr conn,
...
@@ -1236,7 +1236,7 @@ static virDrvOpenStatus qemudOpen(virConnectPtr conn,
}
}
static
int
qemudClose
(
virConnectPtr
conn
)
{
static
int
qemudClose
(
virConnectPtr
conn
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
/* Get rid of callbacks registered for this conn */
/* Get rid of callbacks registered for this conn */
virDomainEventCallbackListRemoveConn
(
conn
,
driver
->
domainEventCallbacks
);
virDomainEventCallbackListRemoveConn
(
conn
,
driver
->
domainEventCallbacks
);
...
@@ -1308,14 +1308,12 @@ static int qemudGetNodeInfo(virConnectPtr conn,
...
@@ -1308,14 +1308,12 @@ static int qemudGetNodeInfo(virConnectPtr conn,
static
char
*
qemudGetCapabilities
(
virConnectPtr
conn
)
{
static
char
*
qemudGetCapabilities
(
virConnectPtr
conn
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
char
*
xml
;
char
*
xml
;
if
((
xml
=
virCapabilitiesFormatXML
(
driver
->
caps
))
==
NULL
)
{
if
((
xml
=
virCapabilitiesFormatXML
(
driver
->
caps
))
==
NULL
)
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
"%s"
,
_
(
"failed to allocate space for capabilities support"
));
"%s"
,
_
(
"failed to allocate space for capabilities support"
));
return
NULL
;
}
return
xml
;
return
xml
;
}
}
...
@@ -1329,11 +1327,12 @@ qemudNodeGetCellsFreeMemory(virConnectPtr conn,
...
@@ -1329,11 +1327,12 @@ qemudNodeGetCellsFreeMemory(virConnectPtr conn,
int
maxCells
)
int
maxCells
)
{
{
int
n
,
lastCell
,
numCells
;
int
n
,
lastCell
,
numCells
;
int
ret
=
-
1
;
if
(
numa_available
()
<
0
)
{
if
(
numa_available
()
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"NUMA not supported on this host"
));
"%s"
,
_
(
"NUMA not supported on this host"
));
return
-
1
;
goto
cleanup
;
}
}
lastCell
=
startCell
+
maxCells
-
1
;
lastCell
=
startCell
+
maxCells
-
1
;
if
(
lastCell
>
numa_max_node
())
if
(
lastCell
>
numa_max_node
())
...
@@ -1344,22 +1343,26 @@ qemudNodeGetCellsFreeMemory(virConnectPtr conn,
...
@@ -1344,22 +1343,26 @@ qemudNodeGetCellsFreeMemory(virConnectPtr conn,
if
(
numa_node_size64
(
n
,
&
mem
)
<
0
)
{
if
(
numa_node_size64
(
n
,
&
mem
)
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"Failed to query NUMA free memory"
));
"%s"
,
_
(
"Failed to query NUMA free memory"
));
return
-
1
;
goto
cleanup
;
}
}
freeMems
[
numCells
++
]
=
mem
;
freeMems
[
numCells
++
]
=
mem
;
}
}
return
numCells
;
ret
=
numCells
;
cleanup:
return
ret
;
}
}
static
unsigned
long
long
static
unsigned
long
long
qemudNodeGetFreeMemory
(
virConnectPtr
conn
)
qemudNodeGetFreeMemory
(
virConnectPtr
conn
)
{
{
unsigned
long
long
freeMem
=
0
;
unsigned
long
long
freeMem
=
-
1
;
int
n
;
int
n
;
if
(
numa_available
()
<
0
)
{
if
(
numa_available
()
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"NUMA not supported on this host"
));
"%s"
,
_
(
"NUMA not supported on this host"
));
return
-
1
;
goto
cleanup
;
}
}
for
(
n
=
0
;
n
<=
numa_max_node
()
;
n
++
)
{
for
(
n
=
0
;
n
<=
numa_max_node
()
;
n
++
)
{
...
@@ -1367,11 +1370,12 @@ qemudNodeGetFreeMemory (virConnectPtr conn)
...
@@ -1367,11 +1370,12 @@ qemudNodeGetFreeMemory (virConnectPtr conn)
if
(
numa_node_size64
(
n
,
&
mem
)
<
0
)
{
if
(
numa_node_size64
(
n
,
&
mem
)
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"Failed to query NUMA free memory"
));
"%s"
,
_
(
"Failed to query NUMA free memory"
));
return
-
1
;
goto
cleanup
;
}
}
freeMem
+=
mem
;
freeMem
+=
mem
;
}
}
cleanup:
return
freeMem
;
return
freeMem
;
}
}
...
@@ -1415,57 +1419,72 @@ static int qemudGetProcessInfo(unsigned long long *cpuTime, int pid) {
...
@@ -1415,57 +1419,72 @@ static int qemudGetProcessInfo(unsigned long long *cpuTime, int pid) {
static
virDomainPtr
qemudDomainLookupByID
(
virConnectPtr
conn
,
static
virDomainPtr
qemudDomainLookupByID
(
virConnectPtr
conn
,
int
id
)
{
int
id
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
id
);
virDomainObjPtr
vm
;
virDomainPtr
dom
;
virDomainPtr
dom
=
NULL
;
vm
=
virDomainFindByID
(
&
driver
->
domains
,
id
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_DOMAIN
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_DOMAIN
,
NULL
);
return
NULL
;
goto
cleanup
;
}
}
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
cleanup:
return
dom
;
return
dom
;
}
}
static
virDomainPtr
qemudDomainLookupByUUID
(
virConnectPtr
conn
,
static
virDomainPtr
qemudDomainLookupByUUID
(
virConnectPtr
conn
,
const
unsigned
char
*
uuid
)
{
const
unsigned
char
*
uuid
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
uuid
)
;
virDomainObjPtr
vm
;
virDomainPtr
dom
;
virDomainPtr
dom
=
NULL
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_DOMAIN
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_DOMAIN
,
NULL
);
return
NULL
;
goto
cleanup
;
}
}
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
cleanup:
return
dom
;
return
dom
;
}
}
static
virDomainPtr
qemudDomainLookupByName
(
virConnectPtr
conn
,
static
virDomainPtr
qemudDomainLookupByName
(
virConnectPtr
conn
,
const
char
*
name
)
{
const
char
*
name
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByName
(
&
driver
->
domains
,
name
)
;
virDomainObjPtr
vm
;
virDomainPtr
dom
;
virDomainPtr
dom
=
NULL
;
vm
=
virDomainFindByName
(
&
driver
->
domains
,
name
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_DOMAIN
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_DOMAIN
,
NULL
);
return
NULL
;
goto
cleanup
;
}
}
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
cleanup:
return
dom
;
return
dom
;
}
}
static
int
qemudGetVersion
(
virConnectPtr
conn
,
unsigned
long
*
version
)
{
static
int
qemudGetVersion
(
virConnectPtr
conn
,
unsigned
long
*
version
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
int
ret
=
-
1
;
if
(
qemudExtractVersion
(
conn
,
driver
)
<
0
)
if
(
qemudExtractVersion
(
conn
,
driver
)
<
0
)
return
-
1
;
goto
cleanup
;
*
version
=
qemu_driver
->
qemuVersion
;
*
version
=
qemu_driver
->
qemuVersion
;
return
0
;
ret
=
0
;
cleanup:
return
ret
;
}
}
static
char
*
static
char
*
...
@@ -1491,7 +1510,7 @@ qemudGetHostname (virConnectPtr conn)
...
@@ -1491,7 +1510,7 @@ qemudGetHostname (virConnectPtr conn)
}
}
static
int
qemudListDomains
(
virConnectPtr
conn
,
int
*
ids
,
int
nids
)
{
static
int
qemudListDomains
(
virConnectPtr
conn
,
int
*
ids
,
int
nids
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
int
got
=
0
,
i
;
int
got
=
0
,
i
;
for
(
i
=
0
;
i
<
driver
->
domains
.
count
&&
got
<
nids
;
i
++
)
for
(
i
=
0
;
i
<
driver
->
domains
.
count
&&
got
<
nids
;
i
++
)
...
@@ -1501,7 +1520,7 @@ static int qemudListDomains(virConnectPtr conn, int *ids, int nids) {
...
@@ -1501,7 +1520,7 @@ static int qemudListDomains(virConnectPtr conn, int *ids, int nids) {
return
got
;
return
got
;
}
}
static
int
qemudNumDomains
(
virConnectPtr
conn
)
{
static
int
qemudNumDomains
(
virConnectPtr
conn
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
int
n
=
0
,
i
;
int
n
=
0
,
i
;
for
(
i
=
0
;
i
<
driver
->
domains
.
count
;
i
++
)
for
(
i
=
0
;
i
<
driver
->
domains
.
count
;
i
++
)
...
@@ -1512,21 +1531,20 @@ static int qemudNumDomains(virConnectPtr conn) {
...
@@ -1512,21 +1531,20 @@ static int qemudNumDomains(virConnectPtr conn) {
}
}
static
virDomainPtr
qemudDomainCreate
(
virConnectPtr
conn
,
const
char
*
xml
,
static
virDomainPtr
qemudDomainCreate
(
virConnectPtr
conn
,
const
char
*
xml
,
unsigned
int
flags
ATTRIBUTE_UNUSED
)
{
unsigned
int
flags
ATTRIBUTE_UNUSED
)
{
struct
qemud_driver
*
driver
=
conn
->
privateData
;
virDomainDefPtr
def
;
virDomainDefPtr
def
;
virDomainObjPtr
vm
;
virDomainObjPtr
vm
;
virDomainPtr
dom
;
virDomainPtr
dom
=
NULL
;
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
if
(
!
(
def
=
virDomainDefParseString
(
conn
,
driver
->
caps
,
xml
)))
if
(
!
(
def
=
virDomainDefParseString
(
conn
,
driver
->
caps
,
xml
)))
return
NULL
;
goto
cleanup
;
vm
=
virDomainFindByName
(
&
driver
->
domains
,
def
->
name
);
vm
=
virDomainFindByName
(
&
driver
->
domains
,
def
->
name
);
if
(
vm
)
{
if
(
vm
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"domain '%s' is already defined"
),
_
(
"domain '%s' is already defined"
),
def
->
name
);
def
->
name
);
virDomainDefFree
(
def
);
goto
cleanup
;
return
NULL
;
}
}
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
def
->
uuid
);
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
def
->
uuid
);
if
(
vm
)
{
if
(
vm
)
{
...
@@ -1536,21 +1554,20 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
...
@@ -1536,21 +1554,20 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"domain with uuid '%s' is already defined"
),
_
(
"domain with uuid '%s' is already defined"
),
uuidstr
);
uuidstr
);
virDomainDefFree
(
def
);
goto
cleanup
;
return
NULL
;
}
}
if
(
!
(
vm
=
virDomainAssignDef
(
conn
,
if
(
!
(
vm
=
virDomainAssignDef
(
conn
,
&
driver
->
domains
,
&
driver
->
domains
,
def
)))
{
def
)))
virDomainDefFree
(
def
)
;
goto
cleanup
;
return
NULL
;
}
def
=
NULL
;
if
(
qemudStartVMDaemon
(
conn
,
driver
,
vm
,
NULL
)
<
0
)
{
if
(
qemudStartVMDaemon
(
conn
,
driver
,
vm
,
NULL
)
<
0
)
{
virDomainRemoveInactive
(
&
driver
->
domains
,
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
vm
);
return
NULL
;
goto
cleanup
;
}
}
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
VIR_DOMAIN_EVENT_STARTED
,
VIR_DOMAIN_EVENT_STARTED
,
...
@@ -1558,30 +1575,35 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
...
@@ -1558,30 +1575,35 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
cleanup:
virDomainDefFree
(
def
);
return
dom
;
return
dom
;
}
}
static
int
qemudDomainSuspend
(
virDomainPtr
dom
)
{
static
int
qemudDomainSuspend
(
virDomainPtr
dom
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
char
*
info
;
char
*
info
;
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
virDomainObjPtr
vm
;
int
ret
=
-
1
;
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
return
-
1
;
goto
cleanup
;
}
}
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"domain is not running"
));
"%s"
,
_
(
"domain is not running"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
vm
->
state
==
VIR_DOMAIN_PAUSED
)
if
(
vm
->
state
!=
VIR_DOMAIN_PAUSED
)
{
return
0
;
if
(
qemudMonitorCommand
(
driver
,
vm
,
"stop"
,
&
info
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
"stop"
,
&
info
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"suspend operation failed"
));
"%s"
,
_
(
"suspend operation failed"
));
return
-
1
;
goto
cleanup
;
}
}
vm
->
state
=
VIR_DOMAIN_PAUSED
;
vm
->
state
=
VIR_DOMAIN_PAUSED
;
qemudDebug
(
"Reply %s"
,
info
);
qemudDebug
(
"Reply %s"
,
info
);
...
@@ -1589,30 +1611,36 @@ static int qemudDomainSuspend(virDomainPtr dom) {
...
@@ -1589,30 +1611,36 @@ static int qemudDomainSuspend(virDomainPtr dom) {
VIR_DOMAIN_EVENT_SUSPENDED
,
VIR_DOMAIN_EVENT_SUSPENDED
,
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
);
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
);
VIR_FREE
(
info
);
VIR_FREE
(
info
);
return
0
;
}
ret
=
0
;
cleanup:
return
ret
;
}
}
static
int
qemudDomainResume
(
virDomainPtr
dom
)
{
static
int
qemudDomainResume
(
virDomainPtr
dom
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
char
*
info
;
char
*
info
;
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
virDomainObjPtr
vm
;
int
ret
=
-
1
;
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
_
(
"no domain with matching id %d"
),
dom
->
id
);
return
-
1
;
goto
cleanup
;
}
}
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"domain is not running"
));
"%s"
,
_
(
"domain is not running"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
vm
->
state
==
VIR_DOMAIN_RUNNING
)
if
(
vm
->
state
==
VIR_DOMAIN_PAUSED
)
{
return
0
;
if
(
qemudMonitorCommand
(
driver
,
vm
,
"cont"
,
&
info
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
"cont"
,
&
info
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"resume operation failed"
));
"%s"
,
_
(
"resume operation failed"
));
return
-
1
;
goto
cleanup
;
}
}
vm
->
state
=
VIR_DOMAIN_RUNNING
;
vm
->
state
=
VIR_DOMAIN_RUNNING
;
qemudDebug
(
"Reply %s"
,
info
);
qemudDebug
(
"Reply %s"
,
info
);
...
@@ -1620,40 +1648,51 @@ static int qemudDomainResume(virDomainPtr dom) {
...
@@ -1620,40 +1648,51 @@ static int qemudDomainResume(virDomainPtr dom) {
VIR_DOMAIN_EVENT_RESUMED
,
VIR_DOMAIN_EVENT_RESUMED
,
VIR_DOMAIN_EVENT_RESUMED_UNPAUSED
);
VIR_DOMAIN_EVENT_RESUMED_UNPAUSED
);
VIR_FREE
(
info
);
VIR_FREE
(
info
);
return
0
;
}
ret
=
0
;
cleanup:
return
ret
;
}
}
static
int
qemudDomainShutdown
(
virDomainPtr
dom
)
{
static
int
qemudDomainShutdown
(
virDomainPtr
dom
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
)
;
virDomainObjPtr
vm
;
char
*
info
;
char
*
info
;
int
ret
=
-
1
;
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
_
(
"no domain with matching id %d"
),
dom
->
id
);
return
-
1
;
goto
cleanup
;
}
}
if
(
qemudMonitorCommand
(
driver
,
vm
,
"system_powerdown"
,
&
info
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
"system_powerdown"
,
&
info
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"shutdown operation failed"
));
"%s"
,
_
(
"shutdown operation failed"
));
return
-
1
;
goto
cleanup
;
}
}
VIR_FREE
(
info
);
VIR_FREE
(
info
);
return
0
;
ret
=
0
;
cleanup:
return
ret
;
}
}
static
int
qemudDomainDestroy
(
virDomainPtr
dom
)
{
static
int
qemudDomainDestroy
(
virDomainPtr
dom
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
virDomainObjPtr
vm
;
int
ret
=
-
1
;
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
_
(
"no domain with matching id %d"
),
dom
->
id
);
return
-
1
;
goto
cleanup
;
}
}
qemudShutdownVMDaemon
(
dom
->
conn
,
driver
,
vm
);
qemudShutdownVMDaemon
(
dom
->
conn
,
driver
,
vm
);
...
@@ -1663,106 +1702,128 @@ static int qemudDomainDestroy(virDomainPtr dom) {
...
@@ -1663,106 +1702,128 @@ static int qemudDomainDestroy(virDomainPtr dom) {
if
(
!
vm
->
persistent
)
if
(
!
vm
->
persistent
)
virDomainRemoveInactive
(
&
driver
->
domains
,
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
vm
);
return
0
;
ret
=
0
;
cleanup:
return
ret
;
}
}
static
char
*
qemudDomainGetOSType
(
virDomainPtr
dom
)
{
static
char
*
qemudDomainGetOSType
(
virDomainPtr
dom
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
char
*
type
;
char
*
type
=
NULL
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
NULL
;
goto
cleanup
;
}
}
if
(
!
(
type
=
strdup
(
vm
->
def
->
os
.
type
)))
{
if
(
!
(
type
=
strdup
(
vm
->
def
->
os
.
type
)))
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_MEMORY
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_MEMORY
,
"%s"
,
_
(
"failed to allocate space for ostype"
));
"%s"
,
_
(
"failed to allocate space for ostype"
));
return
NULL
;
}
cleanup:
return
type
;
return
type
;
}
}
/* Returns max memory in kb, 0 if error */
/* Returns max memory in kb, 0 if error */
static
unsigned
long
qemudDomainGetMaxMemory
(
virDomainPtr
dom
)
{
static
unsigned
long
qemudDomainGetMaxMemory
(
virDomainPtr
dom
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
virDomainObjPtr
vm
;
unsigned
long
ret
=
0
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
return
0
;
goto
cleanup
;
}
}
return
vm
->
def
->
maxmem
;
ret
=
vm
->
def
->
maxmem
;
cleanup:
return
ret
;
}
}
static
int
qemudDomainSetMaxMemory
(
virDomainPtr
dom
,
unsigned
long
newmax
)
{
static
int
qemudDomainSetMaxMemory
(
virDomainPtr
dom
,
unsigned
long
newmax
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
virDomainObjPtr
vm
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
return
-
1
;
goto
cleanup
;
}
}
if
(
newmax
<
vm
->
def
->
memory
)
{
if
(
newmax
<
vm
->
def
->
memory
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"cannot set max memory lower than current memory"
));
"%s"
,
_
(
"cannot set max memory lower than current memory"
));
return
-
1
;
goto
cleanup
;
;
}
}
vm
->
def
->
maxmem
=
newmax
;
vm
->
def
->
maxmem
=
newmax
;
return
0
;
ret
=
0
;
cleanup:
return
ret
;
}
}
static
int
qemudDomainSetMemory
(
virDomainPtr
dom
,
unsigned
long
newmem
)
{
static
int
qemudDomainSetMemory
(
virDomainPtr
dom
,
unsigned
long
newmem
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
virDomainObjPtr
vm
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
return
-
1
;
goto
cleanup
;
}
}
if
(
virDomainIsActive
(
vm
))
{
if
(
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"cannot set memory of an active domain"
));
"%s"
,
_
(
"cannot set memory of an active domain"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
newmem
>
vm
->
def
->
maxmem
)
{
if
(
newmem
>
vm
->
def
->
maxmem
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"cannot set memory higher than max memory"
));
"%s"
,
_
(
"cannot set memory higher than max memory"
));
return
-
1
;
goto
cleanup
;
}
}
vm
->
def
->
memory
=
newmem
;
vm
->
def
->
memory
=
newmem
;
return
0
;
ret
=
0
;
cleanup:
return
ret
;
}
}
static
int
qemudDomainGetInfo
(
virDomainPtr
dom
,
static
int
qemudDomainGetInfo
(
virDomainPtr
dom
,
virDomainInfoPtr
info
)
{
virDomainInfoPtr
info
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
virDomainObjPtr
vm
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
goto
cleanup
;
}
}
info
->
state
=
vm
->
state
;
info
->
state
=
vm
->
state
;
...
@@ -1772,14 +1833,17 @@ static int qemudDomainGetInfo(virDomainPtr dom,
...
@@ -1772,14 +1833,17 @@ static int qemudDomainGetInfo(virDomainPtr dom,
}
else
{
}
else
{
if
(
qemudGetProcessInfo
(
&
(
info
->
cpuTime
),
vm
->
pid
)
<
0
)
{
if
(
qemudGetProcessInfo
(
&
(
info
->
cpuTime
),
vm
->
pid
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
(
"cannot read cputime for domain"
));
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
(
"cannot read cputime for domain"
));
return
-
1
;
goto
cleanup
;
}
}
}
}
info
->
maxMem
=
vm
->
def
->
maxmem
;
info
->
maxMem
=
vm
->
def
->
maxmem
;
info
->
memory
=
vm
->
def
->
memory
;
info
->
memory
=
vm
->
def
->
memory
;
info
->
nrVirtCpu
=
vm
->
def
->
vcpus
;
info
->
nrVirtCpu
=
vm
->
def
->
vcpus
;
return
0
;
ret
=
0
;
cleanup:
return
ret
;
}
}
...
@@ -1878,28 +1942,32 @@ struct qemud_save_header {
...
@@ -1878,28 +1942,32 @@ struct qemud_save_header {
static
int
qemudDomainSave
(
virDomainPtr
dom
,
static
int
qemudDomainSave
(
virDomainPtr
dom
,
const
char
*
path
)
{
const
char
*
path
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
virDomainObjPtr
vm
;
char
*
command
,
*
info
;
char
*
command
=
NULL
;
int
fd
;
char
*
info
=
NULL
;
char
*
safe_path
;
int
fd
=
-
1
;
char
*
xml
;
char
*
safe_path
=
NULL
;
char
*
xml
=
NULL
;
struct
qemud_save_header
header
;
struct
qemud_save_header
header
;
int
ret
=
-
1
;
memset
(
&
header
,
0
,
sizeof
(
header
));
memset
(
&
header
,
0
,
sizeof
(
header
));
memcpy
(
header
.
magic
,
QEMUD_SAVE_MAGIC
,
sizeof
(
header
.
magic
));
memcpy
(
header
.
magic
,
QEMUD_SAVE_MAGIC
,
sizeof
(
header
.
magic
));
header
.
version
=
QEMUD_SAVE_VERSION
;
header
.
version
=
QEMUD_SAVE_VERSION
;
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
_
(
"no domain with matching id %d"
),
dom
->
id
);
return
-
1
;
goto
cleanup
;
}
}
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"domain is not running"
));
"%s"
,
_
(
"domain is not running"
));
return
-
1
;
goto
cleanup
;
}
}
/* Pause */
/* Pause */
...
@@ -1908,7 +1976,7 @@ static int qemudDomainSave(virDomainPtr dom,
...
@@ -1908,7 +1976,7 @@ static int qemudDomainSave(virDomainPtr dom,
if
(
qemudDomainSuspend
(
dom
)
!=
0
)
{
if
(
qemudDomainSuspend
(
dom
)
!=
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to pause domain"
));
"%s"
,
_
(
"failed to pause domain"
));
return
-
1
;
goto
cleanup
;
}
}
}
}
...
@@ -1917,7 +1985,7 @@ static int qemudDomainSave(virDomainPtr dom,
...
@@ -1917,7 +1985,7 @@ static int qemudDomainSave(virDomainPtr dom,
if
(
!
xml
)
{
if
(
!
xml
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to get domain xml"
));
"%s"
,
_
(
"failed to get domain xml"
));
return
-
1
;
goto
cleanup
;
}
}
header
.
xml_len
=
strlen
(
xml
)
+
1
;
header
.
xml_len
=
strlen
(
xml
)
+
1
;
...
@@ -1925,51 +1993,49 @@ static int qemudDomainSave(virDomainPtr dom,
...
@@ -1925,51 +1993,49 @@ static int qemudDomainSave(virDomainPtr dom,
if
((
fd
=
open
(
path
,
O_CREAT
|
O_TRUNC
|
O_WRONLY
,
S_IRUSR
|
S_IWUSR
))
<
0
)
{
if
((
fd
=
open
(
path
,
O_CREAT
|
O_TRUNC
|
O_WRONLY
,
S_IRUSR
|
S_IWUSR
))
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"failed to create '%s'"
),
path
);
_
(
"failed to create '%s'"
),
path
);
VIR_FREE
(
xml
);
goto
cleanup
;
return
-
1
;
}
}
if
(
safewrite
(
fd
,
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
{
if
(
safewrite
(
fd
,
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to write save header"
));
"%s"
,
_
(
"failed to write save header"
));
close
(
fd
);
VIR_FREE
(
xml
);
return
-
1
;
return
-
1
;
}
}
if
(
safewrite
(
fd
,
xml
,
header
.
xml_len
)
!=
header
.
xml_len
)
{
if
(
safewrite
(
fd
,
xml
,
header
.
xml_len
)
!=
header
.
xml_len
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to write xml"
));
"%s"
,
_
(
"failed to write xml"
));
close
(
fd
);
goto
cleanup
;
VIR_FREE
(
xml
);
return
-
1
;
}
}
close
(
fd
);
if
(
close
(
fd
)
<
0
)
{
VIR_FREE
(
xml
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"unable to save file %s %s"
),
path
,
strerror
(
errno
));
goto
cleanup
;
}
fd
=
-
1
;
/* Migrate to file */
/* Migrate to file */
safe_path
=
qemudEscapeShellArg
(
path
);
safe_path
=
qemudEscapeShellArg
(
path
);
if
(
!
safe_path
)
{
if
(
!
safe_path
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"out of memory"
));
"%s"
,
_
(
"out of memory"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
asprintf
(
&
command
,
"migrate
\"
exec:"
if
(
asprintf
(
&
command
,
"migrate
\"
exec:"
"dd of='%s' oflag=append conv=notrunc 2>/dev/null"
"dd of='%s' oflag=append conv=notrunc 2>/dev/null"
"
\"
"
,
safe_path
)
==
-
1
)
{
"
\"
"
,
safe_path
)
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"out of memory"
));
"%s"
,
_
(
"out of memory"
));
VIR_FREE
(
safe_path
)
;
command
=
NULL
;
return
-
1
;
goto
cleanup
;
}
}
free
(
safe_path
);
if
(
qemudMonitorCommand
(
driver
,
vm
,
command
,
&
info
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
command
,
&
info
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"migrate operation failed"
));
"%s"
,
_
(
"migrate operation failed"
));
VIR_FREE
(
command
);
goto
cleanup
;
return
-
1
;
}
}
DEBUG
(
"migrate reply: %s"
,
info
);
DEBUG
(
"migrate reply: %s"
,
info
);
...
@@ -1980,14 +2046,9 @@ static int qemudDomainSave(virDomainPtr dom,
...
@@ -1980,14 +2046,9 @@ static int qemudDomainSave(virDomainPtr dom,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
"%s"
,
_
(
"'migrate' not supported by this qemu"
));
_
(
"'migrate' not supported by this qemu"
));
VIR_FREE
(
info
);
goto
cleanup
;
VIR_FREE
(
command
);
return
-
1
;
}
}
VIR_FREE
(
info
);
VIR_FREE
(
command
);
/* Shut it down */
/* Shut it down */
qemudShutdownVMDaemon
(
dom
->
conn
,
driver
,
vm
);
qemudShutdownVMDaemon
(
dom
->
conn
,
driver
,
vm
);
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
...
@@ -1996,45 +2057,62 @@ static int qemudDomainSave(virDomainPtr dom,
...
@@ -1996,45 +2057,62 @@ static int qemudDomainSave(virDomainPtr dom,
if
(
!
vm
->
persistent
)
if
(
!
vm
->
persistent
)
virDomainRemoveInactive
(
&
driver
->
domains
,
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
vm
);
return
0
;
ret
=
0
;
cleanup:
if
(
fd
!=
-
1
)
close
(
fd
);
VIR_FREE
(
xml
);
VIR_FREE
(
safe_path
);
VIR_FREE
(
command
);
VIR_FREE
(
info
);
if
(
ret
!=
0
)
unlink
(
path
);
return
ret
;
}
}
static
int
qemudDomainSetVcpus
(
virDomainPtr
dom
,
unsigned
int
nvcpus
)
{
static
int
qemudDomainSetVcpus
(
virDomainPtr
dom
,
unsigned
int
nvcpus
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
int
max
;
int
max
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
return
-
1
;
goto
cleanup
;
}
}
if
(
virDomainIsActive
(
vm
))
{
if
(
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"cannot change vcpu count of an active domain"
));
_
(
"cannot change vcpu count of an active domain"
));
return
-
1
;
goto
cleanup
;
}
}
if
((
max
=
qemudDomainGetMaxVcpus
(
dom
))
<
0
)
{
if
((
max
=
qemudDomainGetMaxVcpus
(
dom
))
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"could not determine max vcpus for the domain"
));
_
(
"could not determine max vcpus for the domain"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
nvcpus
>
max
)
{
if
(
nvcpus
>
max
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
_
(
"requested vcpus is greater than max allowable"
_
(
"requested vcpus is greater than max allowable"
" vcpus for the domain: %d > %d"
),
nvcpus
,
max
);
" vcpus for the domain: %d > %d"
),
nvcpus
,
max
);
return
-
1
;
goto
cleanup
;
}
}
vm
->
def
->
vcpus
=
nvcpus
;
vm
->
def
->
vcpus
=
nvcpus
;
return
0
;
ret
=
0
;
cleanup:
return
ret
;
}
}
...
@@ -2044,27 +2122,29 @@ qemudDomainPinVcpu(virDomainPtr dom,
...
@@ -2044,27 +2122,29 @@ qemudDomainPinVcpu(virDomainPtr dom,
unsigned
int
vcpu
,
unsigned
int
vcpu
,
unsigned
char
*
cpumap
,
unsigned
char
*
cpumap
,
int
maplen
)
{
int
maplen
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
cpu_set_t
mask
;
cpu_set_t
mask
;
int
i
,
maxcpu
;
int
i
,
maxcpu
;
virNodeInfo
nodeinfo
;
virNodeInfo
nodeinfo
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"cannot pin vcpus on an inactive domain"
));
"%s"
,
_
(
"cannot pin vcpus on an inactive domain"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
vcpu
>
(
vm
->
nvcpupids
-
1
))
{
if
(
vcpu
>
(
vm
->
nvcpupids
-
1
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
_
(
"vcpu number out of range %d > %d"
),
_
(
"vcpu number out of range %d > %d"
),
vcpu
,
vm
->
nvcpupids
);
vcpu
,
vm
->
nvcpupids
);
return
-
1
;
goto
cleanup
;
}
}
if
(
virNodeInfoPopulate
(
dom
->
conn
,
&
nodeinfo
)
<
0
)
if
(
virNodeInfoPopulate
(
dom
->
conn
,
&
nodeinfo
)
<
0
)
return
-
1
;
goto
cleanup
;
maxcpu
=
maplen
*
8
;
maxcpu
=
maplen
*
8
;
if
(
maxcpu
>
nodeinfo
.
cpus
)
if
(
maxcpu
>
nodeinfo
.
cpus
)
...
@@ -2080,15 +2160,17 @@ qemudDomainPinVcpu(virDomainPtr dom,
...
@@ -2080,15 +2160,17 @@ qemudDomainPinVcpu(virDomainPtr dom,
if
(
sched_setaffinity
(
vm
->
vcpupids
[
vcpu
],
sizeof
(
mask
),
&
mask
)
<
0
)
{
if
(
sched_setaffinity
(
vm
->
vcpupids
[
vcpu
],
sizeof
(
mask
),
&
mask
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
_
(
"cannot set affinity: %s"
),
strerror
(
errno
));
_
(
"cannot set affinity: %s"
),
strerror
(
errno
));
return
-
1
;
goto
cleanup
;
}
}
}
else
{
}
else
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"cpu affinity is not supported"
));
"%s"
,
_
(
"cpu affinity is not supported"
));
return
-
1
;
goto
cleanup
;
}
}
ret
=
0
;
return
0
;
cleanup:
return
ret
;
}
}
static
int
static
int
...
@@ -2097,19 +2179,21 @@ qemudDomainGetVcpus(virDomainPtr dom,
...
@@ -2097,19 +2179,21 @@ qemudDomainGetVcpus(virDomainPtr dom,
int
maxinfo
,
int
maxinfo
,
unsigned
char
*
cpumaps
,
unsigned
char
*
cpumaps
,
int
maplen
)
{
int
maplen
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
virNodeInfo
nodeinfo
;
virNodeInfo
nodeinfo
;
int
i
,
v
,
maxcpu
;
int
i
,
v
,
maxcpu
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"cannot pin vcpus on an inactive domain"
));
"%s"
,
_
(
"cannot pin vcpus on an inactive domain"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
virNodeInfoPopulate
(
dom
->
conn
,
&
nodeinfo
)
<
0
)
if
(
virNodeInfoPopulate
(
dom
->
conn
,
&
nodeinfo
)
<
0
)
return
-
1
;
goto
cleanup
;
maxcpu
=
maplen
*
8
;
maxcpu
=
maplen
*
8
;
if
(
maxcpu
>
nodeinfo
.
cpus
)
if
(
maxcpu
>
nodeinfo
.
cpus
)
...
@@ -2119,9 +2203,7 @@ qemudDomainGetVcpus(virDomainPtr dom,
...
@@ -2119,9 +2203,7 @@ qemudDomainGetVcpus(virDomainPtr dom,
if
(
maxinfo
>
vm
->
nvcpupids
)
if
(
maxinfo
>
vm
->
nvcpupids
)
maxinfo
=
vm
->
nvcpupids
;
maxinfo
=
vm
->
nvcpupids
;
if
(
maxinfo
<
1
)
if
(
maxinfo
>=
1
)
{
return
0
;
if
(
info
!=
NULL
)
{
if
(
info
!=
NULL
)
{
memset
(
info
,
0
,
sizeof
(
*
info
)
*
maxinfo
);
memset
(
info
,
0
,
sizeof
(
*
info
)
*
maxinfo
);
for
(
i
=
0
;
i
<
maxinfo
;
i
++
)
{
for
(
i
=
0
;
i
<
maxinfo
;
i
++
)
{
...
@@ -2142,7 +2224,7 @@ qemudDomainGetVcpus(virDomainPtr dom,
...
@@ -2142,7 +2224,7 @@ qemudDomainGetVcpus(virDomainPtr dom,
if
(
sched_getaffinity
(
vm
->
vcpupids
[
v
],
sizeof
(
mask
),
&
mask
)
<
0
)
{
if
(
sched_getaffinity
(
vm
->
vcpupids
[
v
],
sizeof
(
mask
),
&
mask
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
_
(
"cannot get affinity: %s"
),
strerror
(
errno
));
_
(
"cannot get affinity: %s"
),
strerror
(
errno
));
return
-
1
;
goto
cleanup
;
}
}
for
(
i
=
0
;
i
<
maxcpu
;
i
++
)
for
(
i
=
0
;
i
<
maxcpu
;
i
++
)
...
@@ -2152,108 +2234,102 @@ qemudDomainGetVcpus(virDomainPtr dom,
...
@@ -2152,108 +2234,102 @@ qemudDomainGetVcpus(virDomainPtr dom,
}
else
{
}
else
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"cpu affinity is not available"
));
"%s"
,
_
(
"cpu affinity is not available"
));
return
-
1
;
goto
cleanup
;
}
}
}
}
}
ret
=
maxinfo
;
return
maxinfo
;
cleanup:
return
ret
;
}
}
#endif
/* HAVE_SCHED_GETAFFINITY */
#endif
/* HAVE_SCHED_GETAFFINITY */
static
int
qemudDomainGetMaxVcpus
(
virDomainPtr
dom
)
{
static
int
qemudDomainGetMaxVcpus
(
virDomainPtr
dom
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
const
char
*
type
;
const
char
*
type
;
int
ret
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
return
-
1
;
goto
cleanup
;
}
}
if
(
!
(
type
=
virDomainVirtTypeToString
(
vm
->
def
->
virtType
)))
{
if
(
!
(
type
=
virDomainVirtTypeToString
(
vm
->
def
->
virtType
)))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"unknown virt type in domain definition '%d'"
),
_
(
"unknown virt type in domain definition '%d'"
),
vm
->
def
->
virtType
);
vm
->
def
->
virtType
);
return
-
1
;
goto
cleanup
;
}
}
if
((
ret
=
qemudGetMaxVCPUs
(
dom
->
conn
,
type
))
<
0
)
{
ret
=
qemudGetMaxVCPUs
(
dom
->
conn
,
type
);
return
-
1
;
}
cleanup:
return
ret
;
return
ret
;
}
}
static
int
qemudDomainRestore
(
virConnectPtr
conn
,
static
int
qemudDomainRestore
(
virConnectPtr
conn
,
const
char
*
path
)
{
const
char
*
path
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
virDomainDefPtr
def
;
virDomainDefPtr
def
=
NULL
;
virDomainObjPtr
vm
;
virDomainObjPtr
vm
;
int
fd
;
int
fd
=
-
1
;
int
ret
;
int
ret
=
-
1
;
char
*
xml
;
char
*
xml
=
NULL
;
struct
qemud_save_header
header
;
struct
qemud_save_header
header
;
/* Verify the header and read the XML */
/* Verify the header and read the XML */
if
((
fd
=
open
(
path
,
O_RDONLY
))
<
0
)
{
if
((
fd
=
open
(
path
,
O_RDONLY
))
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"cannot read domain image"
));
"%s"
,
_
(
"cannot read domain image"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
saferead
(
fd
,
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
{
if
(
saferead
(
fd
,
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to read qemu header"
));
"%s"
,
_
(
"failed to read qemu header"
));
close
(
fd
);
goto
cleanup
;
return
-
1
;
}
}
if
(
memcmp
(
header
.
magic
,
QEMUD_SAVE_MAGIC
,
sizeof
(
header
.
magic
))
!=
0
)
{
if
(
memcmp
(
header
.
magic
,
QEMUD_SAVE_MAGIC
,
sizeof
(
header
.
magic
))
!=
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"image magic is incorrect"
));
"%s"
,
_
(
"image magic is incorrect"
));
close
(
fd
);
goto
cleanup
;
return
-
1
;
}
}
if
(
header
.
version
>
QEMUD_SAVE_VERSION
)
{
if
(
header
.
version
>
QEMUD_SAVE_VERSION
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"image version is not supported (%d > %d)"
),
_
(
"image version is not supported (%d > %d)"
),
header
.
version
,
QEMUD_SAVE_VERSION
);
header
.
version
,
QEMUD_SAVE_VERSION
);
close
(
fd
);
goto
cleanup
;
return
-
1
;
}
}
if
(
VIR_ALLOC_N
(
xml
,
header
.
xml_len
)
<
0
)
{
if
(
VIR_ALLOC_N
(
xml
,
header
.
xml_len
)
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"out of memory"
));
"%s"
,
_
(
"out of memory"
));
close
(
fd
);
goto
cleanup
;
return
-
1
;
}
}
if
(
saferead
(
fd
,
xml
,
header
.
xml_len
)
!=
header
.
xml_len
)
{
if
(
saferead
(
fd
,
xml
,
header
.
xml_len
)
!=
header
.
xml_len
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to read XML"
));
"%s"
,
_
(
"failed to read XML"
));
close
(
fd
);
goto
cleanup
;
VIR_FREE
(
xml
);
return
-
1
;
}
}
/* Create a domain from this XML */
/* Create a domain from this XML */
if
(
!
(
def
=
virDomainDefParseString
(
conn
,
driver
->
caps
,
xml
)))
{
if
(
!
(
def
=
virDomainDefParseString
(
conn
,
driver
->
caps
,
xml
)))
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to parse XML"
));
"%s"
,
_
(
"failed to parse XML"
));
close
(
fd
);
goto
cleanup
;
VIR_FREE
(
xml
);
return
-
1
;
}
}
VIR_FREE
(
xml
);
/* Ensure the name and UUID don't already exist in an active VM */
/* Ensure the name and UUID don't already exist in an active VM */
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
def
->
uuid
);
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
def
->
uuid
);
...
@@ -2262,8 +2338,7 @@ static int qemudDomainRestore(virConnectPtr conn,
...
@@ -2262,8 +2338,7 @@ static int qemudDomainRestore(virConnectPtr conn,
if
(
vm
&&
virDomainIsActive
(
vm
))
{
if
(
vm
&&
virDomainIsActive
(
vm
))
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"domain is already active as '%s'"
),
vm
->
def
->
name
);
_
(
"domain is already active as '%s'"
),
vm
->
def
->
name
);
close
(
fd
);
goto
cleanup
;
return
-
1
;
}
}
if
(
!
(
vm
=
virDomainAssignDef
(
conn
,
if
(
!
(
vm
=
virDomainAssignDef
(
conn
,
...
@@ -2271,15 +2346,15 @@ static int qemudDomainRestore(virConnectPtr conn,
...
@@ -2271,15 +2346,15 @@ static int qemudDomainRestore(virConnectPtr conn,
def
)))
{
def
)))
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to assign new VM"
));
"%s"
,
_
(
"failed to assign new VM"
));
virDomainDefFree
(
def
);
goto
cleanup
;
close
(
fd
);
return
-
1
;
}
}
def
=
NULL
;
/* Set the migration source and start it up. */
/* Set the migration source and start it up. */
vm
->
stdin_fd
=
fd
;
vm
->
stdin_fd
=
fd
;
ret
=
qemudStartVMDaemon
(
conn
,
driver
,
vm
,
"stdio"
);
ret
=
qemudStartVMDaemon
(
conn
,
driver
,
vm
,
"stdio"
);
close
(
fd
);
close
(
fd
);
fd
=
-
1
;
vm
->
stdin_fd
=
-
1
;
vm
->
stdin_fd
=
-
1
;
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
...
@@ -2287,7 +2362,7 @@ static int qemudDomainRestore(virConnectPtr conn,
...
@@ -2287,7 +2362,7 @@ static int qemudDomainRestore(virConnectPtr conn,
if
(
!
vm
->
persistent
)
if
(
!
vm
->
persistent
)
virDomainRemoveInactive
(
&
driver
->
domains
,
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
vm
);
return
-
1
;
goto
cleanup
;
}
}
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
...
@@ -2300,36 +2375,49 @@ static int qemudDomainRestore(virConnectPtr conn,
...
@@ -2300,36 +2375,49 @@ static int qemudDomainRestore(virConnectPtr conn,
if
(
qemudMonitorCommand
(
driver
,
vm
,
"cont"
,
&
info
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
"cont"
,
&
info
)
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to resume domain"
));
"%s"
,
_
(
"failed to resume domain"
));
return
-
1
;
goto
cleanup
;
}
}
VIR_FREE
(
info
);
VIR_FREE
(
info
);
vm
->
state
=
VIR_DOMAIN_RUNNING
;
vm
->
state
=
VIR_DOMAIN_RUNNING
;
}
}
ret
=
0
;
return
0
;
cleanup:
virDomainDefFree
(
def
);
VIR_FREE
(
xml
);
if
(
fd
!=
-
1
)
close
(
fd
);
return
ret
;
}
}
static
char
*
qemudDomainDumpXML
(
virDomainPtr
dom
,
static
char
*
qemudDomainDumpXML
(
virDomainPtr
dom
,
int
flags
ATTRIBUTE_UNUSED
)
{
int
flags
ATTRIBUTE_UNUSED
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
virDomainObjPtr
vm
;
char
*
ret
=
NULL
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
NULL
;
goto
cleanup
;
}
}
ret
urn
virDomainDefFormat
(
dom
->
conn
,
ret
=
virDomainDefFormat
(
dom
->
conn
,
(
flags
&
VIR_DOMAIN_XML_INACTIVE
)
&&
vm
->
newDef
?
(
flags
&
VIR_DOMAIN_XML_INACTIVE
)
&&
vm
->
newDef
?
vm
->
newDef
:
vm
->
def
,
vm
->
newDef
:
vm
->
def
,
flags
);
flags
);
cleanup:
return
ret
;
}
}
static
int
qemudListDefinedDomains
(
virConnectPtr
conn
,
static
int
qemudListDefinedDomains
(
virConnectPtr
conn
,
char
**
const
names
,
int
nnames
)
{
char
**
const
names
,
int
nnames
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
int
got
=
0
,
i
;
int
got
=
0
,
i
;
for
(
i
=
0
;
i
<
driver
->
domains
.
count
&&
got
<
nnames
;
i
++
)
{
for
(
i
=
0
;
i
<
driver
->
domains
.
count
&&
got
<
nnames
;
i
++
)
{
...
@@ -2351,7 +2439,7 @@ static int qemudListDefinedDomains(virConnectPtr conn,
...
@@ -2351,7 +2439,7 @@ static int qemudListDefinedDomains(virConnectPtr conn,
}
}
static
int
qemudNumDefinedDomains
(
virConnectPtr
conn
)
{
static
int
qemudNumDefinedDomains
(
virConnectPtr
conn
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
int
n
=
0
,
i
;
int
n
=
0
,
i
;
for
(
i
=
0
;
i
<
driver
->
domains
.
count
;
i
++
)
for
(
i
=
0
;
i
<
driver
->
domains
.
count
;
i
++
)
...
@@ -2363,35 +2451,37 @@ static int qemudNumDefinedDomains(virConnectPtr conn) {
...
@@ -2363,35 +2451,37 @@ static int qemudNumDefinedDomains(virConnectPtr conn) {
static
int
qemudDomainStart
(
virDomainPtr
dom
)
{
static
int
qemudDomainStart
(
virDomainPtr
dom
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
int
ret
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
goto
cleanup
;
}
}
ret
=
qemudStartVMDaemon
(
dom
->
conn
,
driver
,
vm
,
NULL
);
ret
=
qemudStartVMDaemon
(
dom
->
conn
,
driver
,
vm
,
NULL
);
if
(
ret
<
0
)
if
(
ret
!=
-
1
)
return
ret
;
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
VIR_DOMAIN_EVENT_STARTED
,
VIR_DOMAIN_EVENT_STARTED
,
VIR_DOMAIN_EVENT_STARTED_BOOTED
);
VIR_DOMAIN_EVENT_STARTED_BOOTED
);
return
0
;
cleanup:
return
ret
;
}
}
static
virDomainPtr
qemudDomainDefine
(
virConnectPtr
conn
,
const
char
*
xml
)
{
static
virDomainPtr
qemudDomainDefine
(
virConnectPtr
conn
,
const
char
*
xml
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
virDomainDefPtr
def
;
virDomainDefPtr
def
;
virDomainObjPtr
vm
;
virDomainObjPtr
vm
;
virDomainPtr
dom
;
virDomainPtr
dom
=
NULL
;
int
newVM
=
1
;
int
newVM
=
1
;
if
(
!
(
def
=
virDomainDefParseString
(
conn
,
driver
->
caps
,
xml
)))
if
(
!
(
def
=
virDomainDefParseString
(
conn
,
driver
->
caps
,
xml
)))
return
NULL
;
goto
cleanup
;
vm
=
virDomainFindByName
(
&
driver
->
domains
,
def
->
name
);
vm
=
virDomainFindByName
(
&
driver
->
domains
,
def
->
name
);
if
(
vm
)
if
(
vm
)
...
@@ -2401,7 +2491,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
...
@@ -2401,7 +2491,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
&
driver
->
domains
,
&
driver
->
domains
,
def
)))
{
def
)))
{
virDomainDefFree
(
def
);
virDomainDefFree
(
def
);
return
NULL
;
goto
cleanup
;
}
}
vm
->
persistent
=
1
;
vm
->
persistent
=
1
;
...
@@ -2410,7 +2500,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
...
@@ -2410,7 +2500,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
vm
->
newDef
?
vm
->
newDef
:
vm
->
def
)
<
0
)
{
vm
->
newDef
?
vm
->
newDef
:
vm
->
def
)
<
0
)
{
virDomainRemoveInactive
(
&
driver
->
domains
,
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
vm
);
return
NULL
;
goto
cleanup
;
}
}
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
...
@@ -2421,33 +2511,37 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
...
@@ -2421,33 +2511,37 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
dom
=
virGetDomain
(
conn
,
vm
->
def
->
name
,
vm
->
def
->
uuid
);
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
if
(
dom
)
dom
->
id
=
vm
->
def
->
id
;
cleanup:
return
dom
;
return
dom
;
}
}
static
int
qemudDomainUndefine
(
virDomainPtr
dom
)
{
static
int
qemudDomainUndefine
(
virDomainPtr
dom
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
virDomainObjPtr
vm
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
virDomainIsActive
(
vm
))
{
if
(
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot delete active domain"
));
"%s"
,
_
(
"cannot delete active domain"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
!
vm
->
persistent
)
{
if
(
!
vm
->
persistent
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot undefine transient domain"
));
"%s"
,
_
(
"cannot undefine transient domain"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
virDomainDeleteConfig
(
dom
->
conn
,
driver
->
configDir
,
driver
->
autostartDir
,
vm
)
<
0
)
if
(
virDomainDeleteConfig
(
dom
->
conn
,
driver
->
configDir
,
driver
->
autostartDir
,
vm
)
<
0
)
return
-
1
;
goto
cleanup
;
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
VIR_DOMAIN_EVENT_UNDEFINED
,
VIR_DOMAIN_EVENT_UNDEFINED
,
...
@@ -2455,12 +2549,14 @@ static int qemudDomainUndefine(virDomainPtr dom) {
...
@@ -2455,12 +2549,14 @@ static int qemudDomainUndefine(virDomainPtr dom) {
virDomainRemoveInactive
(
&
driver
->
domains
,
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
vm
);
ret
=
0
;
return
0
;
cleanup:
return
ret
;
}
}
/* Return the disks name for use in monitor commands */
/* Return the disks name for use in monitor commands */
static
char
*
qemudDiskDeviceName
(
const
vir
DomainPtr
dom
,
static
char
*
qemudDiskDeviceName
(
const
vir
ConnectPtr
conn
,
const
virDomainDiskDefPtr
disk
)
{
const
virDomainDiskDefPtr
disk
)
{
int
busid
,
devid
;
int
busid
,
devid
;
...
@@ -2468,7 +2564,7 @@ static char *qemudDiskDeviceName(const virDomainPtr dom,
...
@@ -2468,7 +2564,7 @@ static char *qemudDiskDeviceName(const virDomainPtr dom,
char
*
devname
;
char
*
devname
;
if
(
virDiskNameToBusDeviceIndex
(
disk
,
&
busid
,
&
devid
)
<
0
)
{
if
(
virDiskNameToBusDeviceIndex
(
disk
,
&
busid
,
&
devid
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot convert disk '%s' to bus/device index"
),
_
(
"cannot convert disk '%s' to bus/device index"
),
disk
->
dst
);
disk
->
dst
);
return
NULL
;
return
NULL
;
...
@@ -2494,37 +2590,31 @@ static char *qemudDiskDeviceName(const virDomainPtr dom,
...
@@ -2494,37 +2590,31 @@ static char *qemudDiskDeviceName(const virDomainPtr dom,
ret
=
asprintf
(
&
devname
,
"virtio%d"
,
devid
);
ret
=
asprintf
(
&
devname
,
"virtio%d"
,
devid
);
break
;
break
;
default:
default:
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_SUPPORT
,
_
(
"Unsupported disk name mapping for bus '%s'"
),
_
(
"Unsupported disk name mapping for bus '%s'"
),
virDomainDiskBusTypeToString
(
disk
->
bus
));
virDomainDiskBusTypeToString
(
disk
->
bus
));
return
NULL
;
return
NULL
;
}
}
if
(
ret
==
-
1
)
{
if
(
ret
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
NULL
;
return
NULL
;
}
}
return
devname
;
return
devname
;
}
}
static
int
qemudDomainChangeEjectableMedia
(
virDomainPtr
dom
,
static
int
qemudDomainChangeEjectableMedia
(
virConnectPtr
conn
,
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainDeviceDefPtr
dev
)
virDomainDeviceDefPtr
dev
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
virDomainDiskDefPtr
origdisk
=
NULL
,
newdisk
;
virDomainDiskDefPtr
origdisk
=
NULL
,
newdisk
;
char
*
cmd
,
*
reply
,
*
safe_path
;
char
*
cmd
,
*
reply
,
*
safe_path
;
char
*
devname
=
NULL
;
char
*
devname
=
NULL
;
unsigned
int
qemuCmdFlags
;
unsigned
int
qemuCmdFlags
;
int
i
;
int
i
;
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
}
origdisk
=
NULL
;
origdisk
=
NULL
;
newdisk
=
dev
->
data
.
disk
;
newdisk
=
dev
->
data
.
disk
;
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
...
@@ -2536,7 +2626,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
...
@@ -2536,7 +2626,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
}
}
if
(
!
origdisk
)
{
if
(
!
origdisk
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"No device with bus '%s' and target '%s'"
),
_
(
"No device with bus '%s' and target '%s'"
),
virDomainDiskBusTypeToString
(
newdisk
->
bus
),
virDomainDiskBusTypeToString
(
newdisk
->
bus
),
newdisk
->
dst
);
newdisk
->
dst
);
...
@@ -2546,14 +2636,14 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
...
@@ -2546,14 +2636,14 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
if
(
qemudExtractVersionInfo
(
vm
->
def
->
emulator
,
if
(
qemudExtractVersionInfo
(
vm
->
def
->
emulator
,
NULL
,
NULL
,
&
qemuCmdFlags
)
<
0
)
{
&
qemuCmdFlags
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"Cannot determine QEMU argv syntax %s"
),
_
(
"Cannot determine QEMU argv syntax %s"
),
vm
->
def
->
emulator
);
vm
->
def
->
emulator
);
return
-
1
;
return
-
1
;
}
}
if
(
qemuCmdFlags
&
QEMUD_CMD_FLAG_DRIVE
)
{
if
(
qemuCmdFlags
&
QEMUD_CMD_FLAG_DRIVE
)
{
if
(
!
(
devname
=
qemudDiskDeviceName
(
dom
,
newdisk
)))
if
(
!
(
devname
=
qemudDiskDeviceName
(
conn
,
newdisk
)))
return
-
1
;
return
-
1
;
}
else
{
}
else
{
/* Back compat for no -drive option */
/* Back compat for no -drive option */
...
@@ -2563,7 +2653,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
...
@@ -2563,7 +2653,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
STREQ
(
newdisk
->
dst
,
"hdc"
))
STREQ
(
newdisk
->
dst
,
"hdc"
))
devname
=
strdup
(
"cdrom"
);
devname
=
strdup
(
"cdrom"
);
else
{
else
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"Emulator version does not support removable "
_
(
"Emulator version does not support removable "
"media for device '%s' and target '%s'"
),
"media for device '%s' and target '%s'"
),
virDomainDiskDeviceTypeToString
(
newdisk
->
device
),
virDomainDiskDeviceTypeToString
(
newdisk
->
device
),
...
@@ -2572,7 +2662,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
...
@@ -2572,7 +2662,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
}
}
if
(
!
devname
)
{
if
(
!
devname
)
{
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
-
1
;
return
-
1
;
}
}
}
}
...
@@ -2580,12 +2670,12 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
...
@@ -2580,12 +2670,12 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
if
(
newdisk
->
src
)
{
if
(
newdisk
->
src
)
{
safe_path
=
qemudEscapeMonitorArg
(
newdisk
->
src
);
safe_path
=
qemudEscapeMonitorArg
(
newdisk
->
src
);
if
(
!
safe_path
)
{
if
(
!
safe_path
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
VIR_FREE
(
devname
);
VIR_FREE
(
devname
);
return
-
1
;
return
-
1
;
}
}
if
(
asprintf
(
&
cmd
,
"change %s
\"
%s
\"
"
,
devname
,
safe_path
)
==
-
1
)
{
if
(
asprintf
(
&
cmd
,
"change %s
\"
%s
\"
"
,
devname
,
safe_path
)
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
VIR_FREE
(
safe_path
);
VIR_FREE
(
safe_path
);
VIR_FREE
(
devname
);
VIR_FREE
(
devname
);
return
-
1
;
return
-
1
;
...
@@ -2593,14 +2683,14 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
...
@@ -2593,14 +2683,14 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
VIR_FREE
(
safe_path
);
VIR_FREE
(
safe_path
);
}
else
if
(
asprintf
(
&
cmd
,
"eject %s"
,
devname
)
==
-
1
)
{
}
else
if
(
asprintf
(
&
cmd
,
"eject %s"
,
devname
)
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
VIR_FREE
(
devname
);
VIR_FREE
(
devname
);
return
-
1
;
return
-
1
;
}
}
VIR_FREE
(
devname
);
VIR_FREE
(
devname
);
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"cannot change cdrom media"
));
"%s"
,
_
(
"cannot change cdrom media"
));
VIR_FREE
(
cmd
);
VIR_FREE
(
cmd
);
return
-
1
;
return
-
1
;
...
@@ -2611,7 +2701,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
...
@@ -2611,7 +2701,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
* No message is printed on success it seems */
* No message is printed on success it seems */
DEBUG
(
"ejectable media change reply: %s"
,
reply
);
DEBUG
(
"ejectable media change reply: %s"
,
reply
);
if
(
strstr
(
reply
,
"
\n
device "
))
{
if
(
strstr
(
reply
,
"
\n
device "
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"changing cdrom media failed"
));
"%s"
,
_
(
"changing cdrom media failed"
));
VIR_FREE
(
reply
);
VIR_FREE
(
reply
);
VIR_FREE
(
cmd
);
VIR_FREE
(
cmd
);
...
@@ -2627,37 +2717,32 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
...
@@ -2627,37 +2717,32 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
return
0
;
return
0
;
}
}
static
int
qemudDomainAttachPciDiskDevice
(
virDomainPtr
dom
,
virDomainDeviceDefPtr
dev
)
static
int
qemudDomainAttachPciDiskDevice
(
virConnectPtr
conn
,
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainDeviceDefPtr
dev
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
int
ret
,
i
;
int
ret
,
i
;
char
*
cmd
,
*
reply
,
*
s
;
char
*
cmd
,
*
reply
,
*
s
;
char
*
safe_path
;
char
*
safe_path
;
const
char
*
type
=
virDomainDiskBusTypeToString
(
dev
->
data
.
disk
->
bus
);
const
char
*
type
=
virDomainDiskBusTypeToString
(
dev
->
data
.
disk
->
bus
);
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
}
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
if
(
STREQ
(
vm
->
def
->
disks
[
i
]
->
dst
,
dev
->
data
.
disk
->
dst
))
{
if
(
STREQ
(
vm
->
def
->
disks
[
i
]
->
dst
,
dev
->
data
.
disk
->
dst
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"target %s already exists"
),
dev
->
data
.
disk
->
dst
);
_
(
"target %s already exists"
),
dev
->
data
.
disk
->
dst
);
return
-
1
;
return
-
1
;
}
}
}
}
if
(
VIR_REALLOC_N
(
vm
->
def
->
disks
,
vm
->
def
->
ndisks
+
1
)
<
0
)
{
if
(
VIR_REALLOC_N
(
vm
->
def
->
disks
,
vm
->
def
->
ndisks
+
1
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
-
1
;
return
-
1
;
}
}
safe_path
=
qemudEscapeMonitorArg
(
dev
->
data
.
disk
->
src
);
safe_path
=
qemudEscapeMonitorArg
(
dev
->
data
.
disk
->
src
);
if
(
!
safe_path
)
{
if
(
!
safe_path
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"out of memory"
));
"%s"
,
_
(
"out of memory"
));
return
-
1
;
return
-
1
;
}
}
...
@@ -2666,12 +2751,12 @@ static int qemudDomainAttachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
...
@@ -2666,12 +2751,12 @@ static int qemudDomainAttachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
safe_path
,
type
);
safe_path
,
type
);
VIR_FREE
(
safe_path
);
VIR_FREE
(
safe_path
);
if
(
ret
==
-
1
)
{
if
(
ret
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
ret
;
return
ret
;
}
}
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"cannot attach %s disk"
),
type
);
_
(
"cannot attach %s disk"
),
type
);
VIR_FREE
(
cmd
);
VIR_FREE
(
cmd
);
return
-
1
;
return
-
1
;
...
@@ -2688,7 +2773,7 @@ static int qemudDomainAttachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
...
@@ -2688,7 +2773,7 @@ static int qemudDomainAttachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
if
(
virStrToLong_i
((
const
char
*
)
s
,
&
dummy
,
10
,
&
dev
->
data
.
disk
->
slotnum
)
==
-
1
)
if
(
virStrToLong_i
((
const
char
*
)
s
,
&
dummy
,
10
,
&
dev
->
data
.
disk
->
slotnum
)
==
-
1
)
qemudLog
(
QEMUD_WARN
,
"%s"
,
_
(
"Unable to parse slot number
\n
"
));
qemudLog
(
QEMUD_WARN
,
"%s"
,
_
(
"Unable to parse slot number
\n
"
));
}
else
{
}
else
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"adding %s disk failed"
),
type
);
_
(
"adding %s disk failed"
),
type
);
VIR_FREE
(
reply
);
VIR_FREE
(
reply
);
VIR_FREE
(
cmd
);
VIR_FREE
(
cmd
);
...
@@ -2704,36 +2789,31 @@ static int qemudDomainAttachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
...
@@ -2704,36 +2789,31 @@ static int qemudDomainAttachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
return
0
;
return
0
;
}
}
static
int
qemudDomainAttachUsbMassstorageDevice
(
virDomainPtr
dom
,
virDomainDeviceDefPtr
dev
)
static
int
qemudDomainAttachUsbMassstorageDevice
(
virConnectPtr
conn
,
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainDeviceDefPtr
dev
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
int
ret
,
i
;
int
ret
,
i
;
char
*
safe_path
;
char
*
safe_path
;
char
*
cmd
,
*
reply
;
char
*
cmd
,
*
reply
;
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
}
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
if
(
STREQ
(
vm
->
def
->
disks
[
i
]
->
dst
,
dev
->
data
.
disk
->
dst
))
{
if
(
STREQ
(
vm
->
def
->
disks
[
i
]
->
dst
,
dev
->
data
.
disk
->
dst
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"target %s already exists"
),
dev
->
data
.
disk
->
dst
);
_
(
"target %s already exists"
),
dev
->
data
.
disk
->
dst
);
return
-
1
;
return
-
1
;
}
}
}
}
if
(
VIR_REALLOC_N
(
vm
->
def
->
disks
,
vm
->
def
->
ndisks
+
1
)
<
0
)
{
if
(
VIR_REALLOC_N
(
vm
->
def
->
disks
,
vm
->
def
->
ndisks
+
1
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
-
1
;
return
-
1
;
}
}
safe_path
=
qemudEscapeMonitorArg
(
dev
->
data
.
disk
->
src
);
safe_path
=
qemudEscapeMonitorArg
(
dev
->
data
.
disk
->
src
);
if
(
!
safe_path
)
{
if
(
!
safe_path
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"out of memory"
));
"%s"
,
_
(
"out of memory"
));
return
-
1
;
return
-
1
;
}
}
...
@@ -2741,12 +2821,12 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
...
@@ -2741,12 +2821,12 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
ret
=
asprintf
(
&
cmd
,
"usb_add disk:%s"
,
safe_path
);
ret
=
asprintf
(
&
cmd
,
"usb_add disk:%s"
,
safe_path
);
VIR_FREE
(
safe_path
);
VIR_FREE
(
safe_path
);
if
(
ret
==
-
1
)
{
if
(
ret
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
ret
;
return
ret
;
}
}
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"cannot attach usb disk"
));
"%s"
,
_
(
"cannot attach usb disk"
));
VIR_FREE
(
cmd
);
VIR_FREE
(
cmd
);
return
-
1
;
return
-
1
;
...
@@ -2756,7 +2836,7 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
...
@@ -2756,7 +2836,7 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
/* If the command failed qemu prints:
/* If the command failed qemu prints:
* Could not add ... */
* Could not add ... */
if
(
strstr
(
reply
,
"Could not add "
))
{
if
(
strstr
(
reply
,
"Could not add "
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
"%s"
,
_
(
"adding usb disk failed"
));
_
(
"adding usb disk failed"
));
VIR_FREE
(
reply
);
VIR_FREE
(
reply
);
...
@@ -2773,20 +2853,16 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
...
@@ -2773,20 +2853,16 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
return
0
;
return
0
;
}
}
static
int
qemudDomainAttachHostDevice
(
virDomainPtr
dom
,
virDomainDeviceDefPtr
dev
)
static
int
qemudDomainAttachHostDevice
(
virConnectPtr
conn
,
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainDeviceDefPtr
dev
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
int
ret
;
int
ret
;
char
*
cmd
,
*
reply
;
char
*
cmd
,
*
reply
;
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
}
if
(
VIR_REALLOC_N
(
vm
->
def
->
hostdevs
,
vm
->
def
->
nhostdevs
+
1
)
<
0
)
{
if
(
VIR_REALLOC_N
(
vm
->
def
->
hostdevs
,
vm
->
def
->
nhostdevs
+
1
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
-
1
;
return
-
1
;
}
}
...
@@ -2800,12 +2876,12 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
...
@@ -2800,12 +2876,12 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
dev
->
data
.
hostdev
->
source
.
subsys
.
usb
.
device
);
dev
->
data
.
hostdev
->
source
.
subsys
.
usb
.
device
);
}
}
if
(
ret
==
-
1
)
{
if
(
ret
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
-
1
;
return
-
1
;
}
}
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"cannot attach usb device"
));
"%s"
,
_
(
"cannot attach usb device"
));
VIR_FREE
(
cmd
);
VIR_FREE
(
cmd
);
return
-
1
;
return
-
1
;
...
@@ -2815,7 +2891,7 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
...
@@ -2815,7 +2891,7 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
/* If the command failed qemu prints:
/* If the command failed qemu prints:
* Could not add ... */
* Could not add ... */
if
(
strstr
(
reply
,
"Could not add "
))
{
if
(
strstr
(
reply
,
"Could not add "
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
"%s"
,
_
(
"adding usb device failed"
));
_
(
"adding usb device failed"
));
VIR_FREE
(
reply
);
VIR_FREE
(
reply
);
...
@@ -2832,79 +2908,74 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
...
@@ -2832,79 +2908,74 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
static
int
qemudDomainAttachDevice
(
virDomainPtr
dom
,
static
int
qemudDomainAttachDevice
(
virDomainPtr
dom
,
const
char
*
xml
)
{
const
char
*
xml
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
virDomainDeviceDefPtr
dev
;
virDomainDeviceDefPtr
dev
=
NULL
;
int
ret
=
0
,
supported
=
0
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot attach device on inactive domain"
));
"%s"
,
_
(
"cannot attach device on inactive domain"
));
return
-
1
;
goto
cleanup
;
}
}
dev
=
virDomainDeviceDefParse
(
dom
->
conn
,
dev
=
virDomainDeviceDefParse
(
dom
->
conn
,
driver
->
caps
,
driver
->
caps
,
vm
->
def
,
xml
);
vm
->
def
,
xml
);
if
(
dev
==
NULL
)
{
if
(
dev
==
NULL
)
return
-
1
;
goto
cleanup
;
}
if
(
dev
->
type
==
VIR_DOMAIN_DEVICE_DISK
)
{
if
(
dev
->
type
==
VIR_DOMAIN_DEVICE_DISK
)
{
switch
(
dev
->
data
.
disk
->
device
)
{
switch
(
dev
->
data
.
disk
->
device
)
{
case
VIR_DOMAIN_DISK_DEVICE_CDROM
:
case
VIR_DOMAIN_DISK_DEVICE_CDROM
:
case
VIR_DOMAIN_DISK_DEVICE_FLOPPY
:
case
VIR_DOMAIN_DISK_DEVICE_FLOPPY
:
supported
=
1
;
ret
=
qemudDomainChangeEjectableMedia
(
dom
->
conn
,
driver
,
vm
,
dev
);
ret
=
qemudDomainChangeEjectableMedia
(
dom
,
dev
);
break
;
break
;
case
VIR_DOMAIN_DISK_DEVICE_DISK
:
case
VIR_DOMAIN_DISK_DEVICE_DISK
:
if
(
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_USB
)
{
if
(
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_USB
)
{
supported
=
1
;
ret
=
qemudDomainAttachUsbMassstorageDevice
(
dom
->
conn
,
driver
,
vm
,
dev
);
ret
=
qemudDomainAttachUsbMassstorageDevice
(
dom
,
dev
);
}
else
if
(
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_SCSI
||
}
else
if
(
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_SCSI
||
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_VIRTIO
)
{
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_VIRTIO
)
{
supported
=
1
;
ret
=
qemudDomainAttachPciDiskDevice
(
dom
->
conn
,
driver
,
vm
,
dev
);
ret
=
qemudDomainAttachPciDiskDevice
(
dom
,
dev
);
}
}
break
;
break
;
default:
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"this disk device type cannot be attached"
));
goto
cleanup
;
}
}
}
else
if
(
dev
->
type
==
VIR_DOMAIN_DEVICE_HOSTDEV
&&
}
else
if
(
dev
->
type
==
VIR_DOMAIN_DEVICE_HOSTDEV
&&
dev
->
data
.
hostdev
->
mode
==
VIR_DOMAIN_HOSTDEV_MODE_SUBSYS
&&
dev
->
data
.
hostdev
->
mode
==
VIR_DOMAIN_HOSTDEV_MODE_SUBSYS
&&
dev
->
data
.
hostdev
->
source
.
subsys
.
type
==
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB
)
{
dev
->
data
.
hostdev
->
source
.
subsys
.
type
==
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB
)
{
supported
=
1
;
ret
=
qemudDomainAttachHostDevice
(
dom
->
conn
,
driver
,
vm
,
dev
);
ret
=
qemudDomainAttachHostDevice
(
dom
,
dev
);
}
else
{
}
if
(
!
supported
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"this device type cannot be attached"
));
"%s"
,
_
(
"this device type cannot be attached"
));
ret
=
-
1
;
goto
cleanup
;
}
}
VIR_FREE
(
dev
);
cleanup:
virDomainDeviceDefFree
(
dev
);
return
ret
;
return
ret
;
}
}
static
int
qemudDomainDetachPciDiskDevice
(
virDomainPtr
dom
,
virDomainDeviceDefPtr
dev
)
static
int
qemudDomainDetachPciDiskDevice
(
virConnectPtr
conn
,
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainDeviceDefPtr
dev
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
int
i
,
ret
=
-
1
;
int
i
,
ret
=
-
1
;
char
*
cmd
,
*
reply
;
char
*
cmd
=
NULL
;
char
*
reply
=
NULL
;
virDomainDiskDefPtr
detach
=
NULL
;
virDomainDiskDefPtr
detach
=
NULL
;
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
}
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
if
(
STREQ
(
vm
->
def
->
disks
[
i
]
->
dst
,
dev
->
data
.
disk
->
dst
))
{
if
(
STREQ
(
vm
->
def
->
disks
[
i
]
->
dst
,
dev
->
data
.
disk
->
dst
))
{
detach
=
vm
->
def
->
disks
[
i
];
detach
=
vm
->
def
->
disks
[
i
];
...
@@ -2913,48 +2984,45 @@ static int qemudDomainDetachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
...
@@ -2913,48 +2984,45 @@ static int qemudDomainDetachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
}
}
if
(
!
detach
)
{
if
(
!
detach
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"disk %s not found"
),
dev
->
data
.
disk
->
dst
);
_
(
"disk %s not found"
),
dev
->
data
.
disk
->
dst
);
return
-
1
;
goto
cleanup
;
}
}
if
(
detach
->
slotnum
<
1
)
{
if
(
detach
->
slotnum
<
1
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"disk %s cannot be detached - invalid slot number %d"
),
_
(
"disk %s cannot be detached - invalid slot number %d"
),
detach
->
dst
,
detach
->
slotnum
);
detach
->
dst
,
detach
->
slotnum
);
return
-
1
;
goto
cleanup
;
}
}
ret
=
asprintf
(
&
cmd
,
"pci_del 0 %d"
,
detach
->
slotnum
);
if
(
asprintf
(
&
cmd
,
"pci_del 0 %d"
,
detach
->
slotnum
)
<
0
)
{
if
(
ret
==
-
1
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
)
;
cmd
=
NULL
;
return
ret
;
goto
cleanup
;
}
}
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
reply
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"failed to execute detach disk %s command"
),
detach
->
dst
);
_
(
"failed to execute detach disk %s command"
),
detach
->
dst
);
VIR_FREE
(
cmd
);
goto
cleanup
;
return
-
1
;
}
}
DEBUG
(
"pci_del reply: %s"
,
reply
);
DEBUG
(
"pci_del reply: %s"
,
reply
);
/* If the command fails due to a wrong slot qemu prints: invalid slot,
/* If the command fails due to a wrong slot qemu prints: invalid slot,
* nothing is printed on success */
* nothing is printed on success */
if
(
strstr
(
reply
,
"invalid slot"
))
{
if
(
strstr
(
reply
,
"invalid slot"
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"failed to detach disk %s: invalid slot %d"
),
_
(
"failed to detach disk %s: invalid slot %d"
),
detach
->
dst
,
detach
->
slotnum
);
detach
->
dst
,
detach
->
slotnum
);
ret
=
-
1
;
goto
cleanup
;
goto
out
;
}
}
if
(
vm
->
def
->
ndisks
>
1
)
{
if
(
vm
->
def
->
ndisks
>
1
)
{
vm
->
def
->
disks
[
i
]
=
vm
->
def
->
disks
[
--
vm
->
def
->
ndisks
];
vm
->
def
->
disks
[
i
]
=
vm
->
def
->
disks
[
--
vm
->
def
->
ndisks
];
if
(
VIR_REALLOC_N
(
vm
->
def
->
disks
,
vm
->
def
->
ndisks
)
<
0
)
{
if
(
VIR_REALLOC_N
(
vm
->
def
->
disks
,
vm
->
def
->
ndisks
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
ret
=
-
1
;
goto
cleanup
;
goto
out
;
}
}
qsort
(
vm
->
def
->
disks
,
vm
->
def
->
ndisks
,
sizeof
(
*
vm
->
def
->
disks
),
qsort
(
vm
->
def
->
disks
,
vm
->
def
->
ndisks
,
sizeof
(
*
vm
->
def
->
disks
),
virDomainDiskQSort
);
virDomainDiskQSort
);
...
@@ -2963,7 +3031,8 @@ static int qemudDomainDetachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
...
@@ -2963,7 +3031,8 @@ static int qemudDomainDetachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPt
vm
->
def
->
ndisks
=
0
;
vm
->
def
->
ndisks
=
0
;
}
}
ret
=
0
;
ret
=
0
;
out:
cleanup:
VIR_FREE
(
reply
);
VIR_FREE
(
reply
);
VIR_FREE
(
cmd
);
VIR_FREE
(
cmd
);
return
ret
;
return
ret
;
...
@@ -2971,83 +3040,86 @@ out:
...
@@ -2971,83 +3040,86 @@ out:
static
int
qemudDomainDetachDevice
(
virDomainPtr
dom
,
static
int
qemudDomainDetachDevice
(
virDomainPtr
dom
,
const
char
*
xml
)
{
const
char
*
xml
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
virDomainDeviceDefPtr
dev
;
virDomainDeviceDefPtr
dev
=
NULL
;
int
ret
=
0
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot attach device on inactive domain"
));
"%s"
,
_
(
"cannot attach device on inactive domain"
));
return
-
1
;
goto
cleanup
;
}
}
dev
=
virDomainDeviceDefParse
(
dom
->
conn
,
driver
->
caps
,
vm
->
def
,
xml
);
dev
=
virDomainDeviceDefParse
(
dom
->
conn
,
driver
->
caps
,
vm
->
def
,
xml
);
if
(
dev
==
NULL
)
{
if
(
dev
==
NULL
)
return
-
1
;
goto
cleanup
;
}
if
(
dev
->
type
==
VIR_DOMAIN_DEVICE_DISK
&&
if
(
dev
->
type
==
VIR_DOMAIN_DEVICE_DISK
&&
dev
->
data
.
disk
->
device
==
VIR_DOMAIN_DISK_DEVICE_DISK
&&
dev
->
data
.
disk
->
device
==
VIR_DOMAIN_DISK_DEVICE_DISK
&&
(
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_SCSI
||
(
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_SCSI
||
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_VIRTIO
))
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_VIRTIO
))
ret
=
qemudDomainDetachPciDiskDevice
(
do
m
,
dev
);
ret
=
qemudDomainDetachPciDiskDevice
(
dom
->
conn
,
driver
,
v
m
,
dev
);
else
{
else
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"only SCSI or virtio disk device can be detached dynamically"
));
"%s"
,
_
(
"only SCSI or virtio disk device can be detached dynamically"
));
ret
=
-
1
;
}
VIR_FREE
(
dev
);
cleanup:
virDomainDeviceDefFree
(
dev
);
return
ret
;
return
ret
;
}
}
static
int
qemudDomainGetAutostart
(
virDomainPtr
dom
,
static
int
qemudDomainGetAutostart
(
virDomainPtr
dom
,
int
*
autostart
)
{
int
*
autostart
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
virDomainObjPtr
vm
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
goto
cleanup
;
}
}
*
autostart
=
vm
->
autostart
;
*
autostart
=
vm
->
autostart
;
ret
=
0
;
return
0
;
cleanup:
return
ret
;
}
}
static
int
qemudDomainSetAutostart
(
virDomainPtr
dom
,
static
int
qemudDomainSetAutostart
(
virDomainPtr
dom
,
int
autostart
)
{
int
autostart
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
char
*
configFile
=
NULL
,
*
autostartLink
=
NULL
;
char
*
configFile
=
NULL
,
*
autostartLink
=
NULL
;
int
ret
=
-
1
;
int
ret
=
-
1
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
!
vm
->
persistent
)
{
if
(
!
vm
->
persistent
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot set autostart for transient domain"
));
"%s"
,
_
(
"cannot set autostart for transient domain"
));
return
-
1
;
goto
cleanup
;
}
}
autostart
=
(
autostart
!=
0
);
autostart
=
(
autostart
!=
0
);
if
(
vm
->
autostart
==
autostart
)
if
(
vm
->
autostart
!=
autostart
)
{
return
0
;
if
((
configFile
=
virDomainConfigFile
(
dom
->
conn
,
driver
->
configDir
,
vm
->
def
->
name
))
==
NULL
)
if
((
configFile
=
virDomainConfigFile
(
dom
->
conn
,
driver
->
configDir
,
vm
->
def
->
name
))
==
NULL
)
goto
cleanup
;
goto
cleanup
;
if
((
autostartLink
=
virDomainConfigFile
(
dom
->
conn
,
driver
->
autostartDir
,
vm
->
def
->
name
))
==
NULL
)
if
((
autostartLink
=
virDomainConfigFile
(
dom
->
conn
,
driver
->
autostartDir
,
vm
->
def
->
name
))
==
NULL
)
...
@@ -3079,6 +3151,7 @@ static int qemudDomainSetAutostart(virDomainPtr dom,
...
@@ -3079,6 +3151,7 @@ static int qemudDomainSetAutostart(virDomainPtr dom,
}
}
vm
->
autostart
=
autostart
;
vm
->
autostart
=
autostart
;
}
ret
=
0
;
ret
=
0
;
cleanup:
cleanup:
...
@@ -3097,25 +3170,25 @@ qemudDomainBlockStats (virDomainPtr dom,
...
@@ -3097,25 +3170,25 @@ qemudDomainBlockStats (virDomainPtr dom,
const
char
*
path
,
const
char
*
path
,
struct
_virDomainBlockStats
*
stats
)
struct
_virDomainBlockStats
*
stats
)
{
{
struct
qemud_driver
*
driver
=
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
char
*
dummy
,
*
info
=
NULL
;
char
*
dummy
,
*
info
=
NULL
;
const
char
*
p
,
*
eol
;
const
char
*
p
,
*
eol
;
const
char
*
qemu_dev_name
=
NULL
;
const
char
*
qemu_dev_name
=
NULL
;
size_t
len
;
size_t
len
;
int
i
,
ret
=
-
1
;
int
i
,
ret
=
-
1
;
const
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
)
;
virDomainObjPtr
vm
;
virDomainDiskDefPtr
disk
=
NULL
;
virDomainDiskDefPtr
disk
=
NULL
;
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
_
(
"no domain with matching id %d"
),
dom
->
id
);
return
-
1
;
goto
cleanup
;
}
}
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"domain is not running"
));
"%s"
,
_
(
"domain is not running"
));
return
-
1
;
goto
cleanup
;
}
}
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
...
@@ -3128,18 +3201,18 @@ qemudDomainBlockStats (virDomainPtr dom,
...
@@ -3128,18 +3201,18 @@ qemudDomainBlockStats (virDomainPtr dom,
if
(
!
disk
)
{
if
(
!
disk
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
_
(
"invalid path: %s"
),
path
);
_
(
"invalid path: %s"
),
path
);
return
-
1
;
goto
cleanup
;
}
}
qemu_dev_name
=
qemudDiskDeviceName
(
dom
,
disk
);
qemu_dev_name
=
qemudDiskDeviceName
(
dom
->
conn
,
disk
);
if
(
!
qemu_dev_name
)
if
(
!
qemu_dev_name
)
return
-
1
;
goto
cleanup
;
len
=
strlen
(
qemu_dev_name
);
len
=
strlen
(
qemu_dev_name
);
if
(
qemudMonitorCommand
(
driver
,
vm
,
"info blockstats"
,
&
info
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
"info blockstats"
,
&
info
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"'info blockstats' command failed"
));
"%s"
,
_
(
"'info blockstats' command failed"
));
goto
out
;
goto
cleanup
;
}
}
DEBUG
(
"info blockstats reply: %s"
,
info
);
DEBUG
(
"info blockstats reply: %s"
,
info
);
...
@@ -3152,7 +3225,7 @@ qemudDomainBlockStats (virDomainPtr dom,
...
@@ -3152,7 +3225,7 @@ qemudDomainBlockStats (virDomainPtr dom,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
"%s"
,
_
(
"'info blockstats' not supported by this qemu"
));
_
(
"'info blockstats' not supported by this qemu"
));
goto
out
;
goto
cleanup
;
}
}
stats
->
rd_req
=
-
1
;
stats
->
rd_req
=
-
1
;
...
@@ -3204,7 +3277,7 @@ qemudDomainBlockStats (virDomainPtr dom,
...
@@ -3204,7 +3277,7 @@ qemudDomainBlockStats (virDomainPtr dom,
p
++
;
p
++
;
}
}
ret
=
0
;
ret
=
0
;
goto
out
;
goto
cleanup
;
}
}
/* Skip to next line. */
/* Skip to next line. */
...
@@ -3216,59 +3289,70 @@ qemudDomainBlockStats (virDomainPtr dom,
...
@@ -3216,59 +3289,70 @@ qemudDomainBlockStats (virDomainPtr dom,
/* If we reach here then the device was not found. */
/* If we reach here then the device was not found. */
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
_
(
"device not found: %s (%s)"
),
path
,
qemu_dev_name
);
_
(
"device not found: %s (%s)"
),
path
,
qemu_dev_name
);
out
:
cleanup
:
VIR_FREE
(
qemu_dev_name
);
VIR_FREE
(
qemu_dev_name
);
VIR_FREE
(
info
);
VIR_FREE
(
info
);
return
ret
;
return
ret
;
}
}
#ifdef __linux__
static
int
static
int
qemudDomainInterfaceStats
(
virDomainPtr
dom
,
qemudDomainInterfaceStats
(
virDomainPtr
dom
,
const
char
*
path
,
const
char
*
path
,
struct
_virDomainInterfaceStats
*
stats
)
struct
_virDomainInterfaceStats
*
stats
)
{
{
#ifdef __linux__
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
;
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
int
i
;
int
i
;
int
ret
=
-
1
;
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
_
(
"no domain with matching id %d"
),
dom
->
id
);
return
-
1
;
goto
cleanup
;
}
}
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"domain is not running"
));
"%s"
,
_
(
"domain is not running"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
!
path
||
path
[
0
]
==
'\0'
)
{
if
(
!
path
||
path
[
0
]
==
'\0'
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"NULL or empty path"
));
"%s"
,
_
(
"NULL or empty path"
));
return
-
1
;
goto
cleanup
;
}
}
/* Check the path is one of the domain's network interfaces. */
/* Check the path is one of the domain's network interfaces. */
for
(
i
=
0
;
i
<
vm
->
def
->
nnets
;
i
++
)
{
for
(
i
=
0
;
i
<
vm
->
def
->
nnets
;
i
++
)
{
if
(
vm
->
def
->
nets
[
i
]
->
ifname
&&
if
(
vm
->
def
->
nets
[
i
]
->
ifname
&&
STREQ
(
vm
->
def
->
nets
[
i
]
->
ifname
,
path
))
STREQ
(
vm
->
def
->
nets
[
i
]
->
ifname
,
path
))
{
goto
ok
;
ret
=
0
;
break
;
}
}
}
if
(
ret
==
0
)
ret
=
linuxDomainInterfaceStats
(
dom
->
conn
,
path
,
stats
);
else
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
_
(
"invalid path, '%s' is not a known interface"
),
path
);
_
(
"invalid path, '%s' is not a known interface"
),
path
);
return
-
1
;
ok:
return
linuxDomainInterfaceStats
(
dom
->
conn
,
path
,
stats
);
cleanup:
return
ret
;
}
#else
#else
static
int
qemudDomainInterfaceStats
(
virDomainPtr
dom
,
const
char
*
path
ATTRIBUTE_UNUSED
,
struct
_virDomainInterfaceStats
*
stats
ATTRIBUTE_UNUSED
)
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
__FUNCTION__
);
"%s"
,
__FUNCTION__
);
return
-
1
;
return
-
1
;
#endif
}
}
#endif
static
int
static
int
qemudDomainBlockPeek
(
virDomainPtr
dom
,
qemudDomainBlockPeek
(
virDomainPtr
dom
,
...
@@ -3277,39 +3361,40 @@ qemudDomainBlockPeek (virDomainPtr dom,
...
@@ -3277,39 +3361,40 @@ qemudDomainBlockPeek (virDomainPtr dom,
void
*
buffer
,
void
*
buffer
,
unsigned
int
flags
ATTRIBUTE_UNUSED
)
unsigned
int
flags
ATTRIBUTE_UNUSED
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
)
;
virDomainObjPtr
vm
;
int
fd
,
ret
=
-
1
,
i
;
int
fd
=
-
1
,
ret
=
-
1
,
i
;
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
"%s"
,
_
(
"no domain with matching uuid"
));
"%s"
,
_
(
"no domain with matching uuid"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
!
path
||
path
[
0
]
==
'\0'
)
{
if
(
!
path
||
path
[
0
]
==
'\0'
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"NULL or empty path"
));
"%s"
,
_
(
"NULL or empty path"
));
return
-
1
;
goto
cleanup
;
}
}
/* Check the path belongs to this domain. */
/* Check the path belongs to this domain. */
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
if
(
vm
->
def
->
disks
[
i
]
->
src
!=
NULL
&&
if
(
vm
->
def
->
disks
[
i
]
->
src
!=
NULL
&&
STREQ
(
vm
->
def
->
disks
[
i
]
->
src
,
path
))
STREQ
(
vm
->
def
->
disks
[
i
]
->
src
,
path
))
{
goto
found
;
ret
=
0
;
break
;
}
}
}
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"invalid path"
));
return
-
1
;
found:
if
(
ret
==
0
)
{
ret
=
-
1
;
/* The path is correct, now try to open it and get its size. */
/* The path is correct, now try to open it and get its size. */
fd
=
open
(
path
,
O_RDONLY
);
fd
=
open
(
path
,
O_RDONLY
);
if
(
fd
==
-
1
)
{
if
(
fd
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
"%s"
,
strerror
(
errno
));
"%s"
,
strerror
(
errno
));
goto
done
;
goto
cleanup
;
}
}
/* Seek and read. */
/* Seek and read. */
...
@@ -3320,12 +3405,18 @@ found:
...
@@ -3320,12 +3405,18 @@ found:
saferead
(
fd
,
buffer
,
size
)
==
(
ssize_t
)
-
1
)
{
saferead
(
fd
,
buffer
,
size
)
==
(
ssize_t
)
-
1
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
"%s"
,
strerror
(
errno
));
"%s"
,
strerror
(
errno
));
goto
done
;
goto
cleanup
;
}
}
ret
=
0
;
ret
=
0
;
done:
}
else
{
if
(
fd
>=
0
)
close
(
fd
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"invalid path"
));
}
cleanup:
if
(
fd
>=
0
)
close
(
fd
);
return
ret
;
return
ret
;
}
}
...
@@ -3335,35 +3426,37 @@ qemudDomainMemoryPeek (virDomainPtr dom,
...
@@ -3335,35 +3426,37 @@ qemudDomainMemoryPeek (virDomainPtr dom,
void
*
buffer
,
void
*
buffer
,
unsigned
int
flags
)
unsigned
int
flags
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
)
;
virDomainObjPtr
vm
;
char
cmd
[
256
],
*
info
;
char
cmd
[
256
],
*
info
=
NULL
;
char
tmp
[]
=
TEMPDIR
"/qemu.mem.XXXXXX"
;
char
tmp
[]
=
TEMPDIR
"/qemu.mem.XXXXXX"
;
int
fd
=
-
1
,
ret
=
-
1
;
int
fd
=
-
1
,
ret
=
-
1
;
if
(
flags
!=
VIR_MEMORY_VIRTUAL
)
{
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"QEMU driver only supports virtual memory addrs"
));
return
-
1
;
}
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
_
(
"no domain with matching id %d"
),
dom
->
id
);
return
-
1
;
goto
cleanup
;
}
if
(
flags
!=
VIR_MEMORY_VIRTUAL
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"QEMU driver only supports virtual memory addrs"
));
goto
cleanup
;
}
}
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"domain is not running"
));
"%s"
,
_
(
"domain is not running"
));
return
-
1
;
goto
cleanup
;
}
}
/* Create a temporary filename. */
/* Create a temporary filename. */
if
((
fd
=
mkstemp
(
tmp
))
==
-
1
)
{
if
((
fd
=
mkstemp
(
tmp
))
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
"%s"
,
strerror
(
errno
));
"%s"
,
strerror
(
errno
));
return
-
1
;
goto
cleanup
;
}
}
/* Issue the memsave command. */
/* Issue the memsave command. */
...
@@ -3371,21 +3464,22 @@ qemudDomainMemoryPeek (virDomainPtr dom,
...
@@ -3371,21 +3464,22 @@ qemudDomainMemoryPeek (virDomainPtr dom,
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
info
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
info
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"'memsave' command failed"
));
"%s"
,
_
(
"'memsave' command failed"
));
goto
done
;
goto
cleanup
;
}
}
DEBUG
(
"memsave reply: %s"
,
info
);
DEBUG
(
"memsave reply: %s"
,
info
);
free
(
info
);
/* Read the memory file into buffer. */
/* Read the memory file into buffer. */
if
(
saferead
(
fd
,
buffer
,
size
)
==
(
ssize_t
)
-
1
)
{
if
(
saferead
(
fd
,
buffer
,
size
)
==
(
ssize_t
)
-
1
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
"%s"
,
strerror
(
errno
));
"%s"
,
strerror
(
errno
));
goto
done
;
goto
cleanup
;
}
}
ret
=
0
;
ret
=
0
;
done:
cleanup:
VIR_FREE
(
info
);
if
(
fd
>=
0
)
close
(
fd
);
if
(
fd
>=
0
)
close
(
fd
);
unlink
(
tmp
);
unlink
(
tmp
);
return
ret
;
return
ret
;
...
@@ -3398,20 +3492,26 @@ qemudDomainEventRegister (virConnectPtr conn,
...
@@ -3398,20 +3492,26 @@ qemudDomainEventRegister (virConnectPtr conn,
void
*
opaque
,
void
*
opaque
,
virFreeCallback
freecb
)
virFreeCallback
freecb
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
int
ret
;
ret
urn
virDomainEventCallbackListAdd
(
conn
,
driver
->
domainEventCallbacks
,
ret
=
virDomainEventCallbackListAdd
(
conn
,
driver
->
domainEventCallbacks
,
callback
,
opaque
,
freecb
);
callback
,
opaque
,
freecb
);
return
ret
;
}
}
static
int
static
int
qemudDomainEventDeregister
(
virConnectPtr
conn
,
qemudDomainEventDeregister
(
virConnectPtr
conn
,
void
*
callback
)
void
*
callback
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
int
ret
;
ret
urn
virDomainEventCallbackListRemove
(
conn
,
driver
->
domainEventCallbacks
,
ret
=
virDomainEventCallbackListRemove
(
conn
,
driver
->
domainEventCallbacks
,
callback
);
callback
);
return
ret
;
}
}
static
void
qemudDomainEventDispatch
(
struct
qemud_driver
*
driver
,
static
void
qemudDomainEventDispatch
(
struct
qemud_driver
*
driver
,
...
@@ -3462,18 +3562,21 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
...
@@ -3462,18 +3562,21 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
const
char
*
dom_xml
)
const
char
*
dom_xml
)
{
{
static
int
port
=
0
;
static
int
port
=
0
;
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dconn
->
privateData
;
struct
qemud_driver
*
driver
=
dconn
->
privateData
;
virDomainDefPtr
def
;
virDomainDefPtr
def
=
NULL
;
virDomainObjPtr
vm
=
NULL
;
virDomainObjPtr
vm
=
NULL
;
int
this_port
;
int
this_port
;
char
hostname
[
HOST_NAME_MAX
+
1
];
char
hostname
[
HOST_NAME_MAX
+
1
];
char
migrateFrom
[
64
];
char
migrateFrom
[
64
];
const
char
*
p
;
const
char
*
p
;
int
ret
=
-
1
;;
*
uri_out
=
NULL
;
if
(
!
dom_xml
)
{
if
(
!
dom_xml
)
{
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"no domain XML passed"
));
"%s"
,
_
(
"no domain XML passed"
));
return
-
1
;
goto
cleanup
;
}
}
/* The URI passed in may be NULL or a string "tcp://somehostname:port".
/* The URI passed in may be NULL or a string "tcp://somehostname:port".
...
@@ -3494,14 +3597,15 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
...
@@ -3494,14 +3597,15 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
if
(
gethostname
(
hostname
,
HOST_NAME_MAX
+
1
)
==
-
1
)
{
if
(
gethostname
(
hostname
,
HOST_NAME_MAX
+
1
)
==
-
1
)
{
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
"%s"
,
strerror
(
errno
));
"%s"
,
strerror
(
errno
));
return
-
1
;
goto
cleanup
;
}
}
/* Caller frees */
/* Caller frees */
if
(
asprintf
(
uri_out
,
"tcp:%s:%d"
,
hostname
,
this_port
)
<
0
)
{
if
(
asprintf
(
uri_out
,
"tcp:%s:%d"
,
hostname
,
this_port
)
<
0
)
{
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
"%s"
,
strerror
(
errno
));
"%s"
,
strerror
(
errno
));
return
-
1
;
*
uri_out
=
NULL
;
goto
cleanup
;
}
}
}
else
{
}
else
{
/* Check the URI starts with "tcp:". We will escape the
/* Check the URI starts with "tcp:". We will escape the
...
@@ -3511,7 +3615,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
...
@@ -3511,7 +3615,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
if
(
!
STREQLEN
(
uri_in
,
"tcp:"
,
6
))
{
if
(
!
STREQLEN
(
uri_in
,
"tcp:"
,
6
))
{
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"only tcp URIs are supported for KVM migrations"
));
"%s"
,
_
(
"only tcp URIs are supported for KVM migrations"
));
return
-
1
;
goto
cleanup
;
}
}
/* Get the port number. */
/* Get the port number. */
...
@@ -3521,7 +3625,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
...
@@ -3521,7 +3625,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
if
(
this_port
==
-
1
||
p
-
uri_in
!=
strlen
(
uri_in
))
{
if
(
this_port
==
-
1
||
p
-
uri_in
!=
strlen
(
uri_in
))
{
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_INVALID_ARG
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_INVALID_ARG
,
"%s"
,
_
(
"URI did not have ':port' at the end"
));
"%s"
,
_
(
"URI did not have ':port' at the end"
));
return
-
1
;
goto
cleanup
;
}
}
}
}
...
@@ -3529,7 +3633,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
...
@@ -3529,7 +3633,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
if
(
!
(
def
=
virDomainDefParseString
(
dconn
,
driver
->
caps
,
dom_xml
)))
{
if
(
!
(
def
=
virDomainDefParseString
(
dconn
,
driver
->
caps
,
dom_xml
)))
{
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to parse XML"
));
"%s"
,
_
(
"failed to parse XML"
));
return
-
1
;
goto
cleanup
;
}
}
/* Target domain name, maybe renamed. */
/* Target domain name, maybe renamed. */
...
@@ -3546,6 +3650,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
...
@@ -3546,6 +3650,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
if
(
virUUIDGenerate
(
def
->
uuid
)
==
-
1
)
{
if
(
virUUIDGenerate
(
def
->
uuid
)
==
-
1
)
{
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"could not generate random UUID"
));
_
(
"could not generate random UUID"
));
goto
cleanup
;
}
}
#endif
#endif
...
@@ -3555,8 +3660,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
...
@@ -3555,8 +3660,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"domain with the same name or UUID already exists as '%s'"
),
_
(
"domain with the same name or UUID already exists as '%s'"
),
vm
->
def
->
name
);
vm
->
def
->
name
);
virDomainDefFree
(
def
);
goto
cleanup
;
return
-
1
;
}
}
}
}
...
@@ -3565,9 +3669,9 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
...
@@ -3565,9 +3669,9 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
def
)))
{
def
)))
{
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"failed to assign new VM"
));
"%s"
,
_
(
"failed to assign new VM"
));
virDomainDefFree
(
def
);
goto
cleanup
;
return
-
1
;
}
}
def
=
NULL
;
/* Domain starts inactive, even if the domain XML had an id field. */
/* Domain starts inactive, even if the domain XML had an id field. */
vm
->
def
->
id
=
-
1
;
vm
->
def
->
id
=
-
1
;
...
@@ -3582,13 +3686,20 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
...
@@ -3582,13 +3686,20 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
if
(
!
vm
->
persistent
)
if
(
!
vm
->
persistent
)
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
return
-
1
;
goto
cleanup
;
}
}
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
VIR_DOMAIN_EVENT_STARTED
,
VIR_DOMAIN_EVENT_STARTED
,
VIR_DOMAIN_EVENT_STARTED_MIGRATED
);
VIR_DOMAIN_EVENT_STARTED_MIGRATED
);
ret
=
0
;
return
0
;
cleanup:
virDomainDefFree
(
def
);
if
(
ret
!=
0
)
{
VIR_FREE
(
*
uri_out
);
}
return
ret
;
}
}
/* Perform is the second step, and it runs on the source host. */
/* Perform is the second step, and it runs on the source host. */
...
@@ -3601,22 +3712,24 @@ qemudDomainMigratePerform (virDomainPtr dom,
...
@@ -3601,22 +3712,24 @@ qemudDomainMigratePerform (virDomainPtr dom,
const
char
*
dname
ATTRIBUTE_UNUSED
,
const
char
*
dname
ATTRIBUTE_UNUSED
,
unsigned
long
resource
)
unsigned
long
resource
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
struct
qemud_driver
*
driver
=
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
)
;
virDomainObjPtr
vm
;
char
*
safe_uri
;
char
*
safe_uri
;
char
cmd
[
HOST_NAME_MAX
+
50
];
char
cmd
[
HOST_NAME_MAX
+
50
];
char
*
info
;
char
*
info
=
NULL
;
int
ret
=
-
1
;
vm
=
virDomainFindByID
(
&
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching id %d"
),
dom
->
id
);
_
(
"no domain with matching id %d"
),
dom
->
id
);
return
-
1
;
goto
cleanup
;
}
}
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"domain is not running"
));
"%s"
,
_
(
"domain is not running"
));
return
-
1
;
goto
cleanup
;
}
}
if
(
!
(
flags
&
VIR_MIGRATE_LIVE
))
{
if
(
!
(
flags
&
VIR_MIGRATE_LIVE
))
{
...
@@ -3645,7 +3758,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
...
@@ -3645,7 +3758,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
if
(
!
safe_uri
)
{
if
(
!
safe_uri
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_SYSTEM_ERROR
,
"%s"
,
strerror
(
errno
));
"%s"
,
strerror
(
errno
));
return
-
1
;
goto
cleanup
;
}
}
snprintf
(
cmd
,
sizeof
cmd
,
"migrate
\"
%s
\"
"
,
safe_uri
);
snprintf
(
cmd
,
sizeof
cmd
,
"migrate
\"
%s
\"
"
,
safe_uri
);
VIR_FREE
(
safe_uri
);
VIR_FREE
(
safe_uri
);
...
@@ -3653,7 +3766,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
...
@@ -3653,7 +3766,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
info
)
<
0
)
{
if
(
qemudMonitorCommand
(
driver
,
vm
,
cmd
,
&
info
)
<
0
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
"%s"
,
_
(
"migrate operation failed"
));
"%s"
,
_
(
"migrate operation failed"
));
return
-
1
;
goto
cleanup
;
}
}
DEBUG
(
"migrate reply: %s"
,
info
);
DEBUG
(
"migrate reply: %s"
,
info
);
...
@@ -3662,12 +3775,9 @@ qemudDomainMigratePerform (virDomainPtr dom,
...
@@ -3662,12 +3775,9 @@ qemudDomainMigratePerform (virDomainPtr dom,
if
(
strstr
(
info
,
"fail"
)
!=
NULL
)
{
if
(
strstr
(
info
,
"fail"
)
!=
NULL
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_OPERATION_FAILED
,
_
(
"migrate failed: %s"
),
info
);
_
(
"migrate failed: %s"
),
info
);
VIR_FREE
(
info
);
goto
cleanup
;
return
-
1
;
}
}
VIR_FREE
(
info
);
/* Clean up the source domain. */
/* Clean up the source domain. */
qemudShutdownVMDaemon
(
dom
->
conn
,
driver
,
vm
);
qemudShutdownVMDaemon
(
dom
->
conn
,
driver
,
vm
);
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
...
@@ -3675,8 +3785,11 @@ qemudDomainMigratePerform (virDomainPtr dom,
...
@@ -3675,8 +3785,11 @@ qemudDomainMigratePerform (virDomainPtr dom,
VIR_DOMAIN_EVENT_STOPPED_MIGRATED
);
VIR_DOMAIN_EVENT_STOPPED_MIGRATED
);
if
(
!
vm
->
persistent
)
if
(
!
vm
->
persistent
)
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
ret
=
0
;
return
0
;
cleanup:
VIR_FREE
(
info
);
return
ret
;
}
}
/* Finish is the third and final step, and it runs on the destination host. */
/* Finish is the third and final step, and it runs on the destination host. */
...
@@ -3689,15 +3802,16 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
...
@@ -3689,15 +3802,16 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
unsigned
long
flags
ATTRIBUTE_UNUSED
,
unsigned
long
flags
ATTRIBUTE_UNUSED
,
int
retcode
)
int
retcode
)
{
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dconn
->
privateData
;
struct
qemud_driver
*
driver
=
dconn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByName
(
&
driver
->
domains
,
dname
)
;
virDomainObjPtr
vm
;
virDomainPtr
dom
;
virDomainPtr
dom
=
NULL
;
char
*
info
=
NULL
;
char
*
info
=
NULL
;
vm
=
virDomainFindByName
(
&
driver
->
domains
,
dname
);
if
(
!
vm
)
{
if
(
!
vm
)
{
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
qemudReportError
(
dconn
,
NULL
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching name %s"
),
dname
);
_
(
"no domain with matching name %s"
),
dname
);
return
NULL
;
goto
cleanup
;
}
}
/* Did the migration go as planned? If yes, return the domain
/* Did the migration go as planned? If yes, return the domain
...
@@ -3710,7 +3824,6 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
...
@@ -3710,7 +3824,6 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
VIR_DOMAIN_EVENT_RESUMED
,
VIR_DOMAIN_EVENT_RESUMED
,
VIR_DOMAIN_EVENT_RESUMED_MIGRATED
);
VIR_DOMAIN_EVENT_RESUMED_MIGRATED
);
return
dom
;
}
else
{
}
else
{
qemudShutdownVMDaemon
(
dconn
,
driver
,
vm
);
qemudShutdownVMDaemon
(
dconn
,
driver
,
vm
);
qemudDomainEventDispatch
(
driver
,
vm
,
qemudDomainEventDispatch
(
driver
,
vm
,
...
@@ -3718,8 +3831,10 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
...
@@ -3718,8 +3831,10 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
VIR_DOMAIN_EVENT_STOPPED_FAILED
);
VIR_DOMAIN_EVENT_STOPPED_FAILED
);
if
(
!
vm
->
persistent
)
if
(
!
vm
->
persistent
)
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
return
NULL
;
}
}
cleanup:
return
dom
;
}
}
static
virDriver
qemuDriver
=
{
static
virDriver
qemuDriver
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录