Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
72c23d65
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看板
提交
72c23d65
编写于
8月 11, 2014
作者:
T
Taowei
提交者:
Michal Privoznik
8月 15, 2014
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
vbox: Rewrite vboxDomainSnapshotGetXMLDesc
上级
677ecdc0
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
843 addition
and
647 deletion
+843
-647
src/vbox/vbox_common.c
src/vbox/vbox_common.c
+712
-0
src/vbox/vbox_tmpl.c
src/vbox/vbox_tmpl.c
+110
-646
src/vbox/vbox_uniformed_api.h
src/vbox/vbox_uniformed_api.h
+21
-1
未找到文件。
src/vbox/vbox_common.c
浏览文件 @
72c23d65
...
...
@@ -77,6 +77,8 @@ VIR_LOG_INIT("vbox.vbox_common");
#define VBOX_UTF16_TO_UTF8(arg1, arg2) gVBoxAPI.UPFN.Utf16ToUtf8(data->pFuncs, arg1, arg2)
#define VBOX_UTF8_TO_UTF16(arg1, arg2) gVBoxAPI.UPFN.Utf8ToUtf16(data->pFuncs, arg1, arg2)
#define VBOX_ADDREF(arg) gVBoxAPI.nsUISupports.AddRef((void *)(arg))
#define VBOX_RELEASE(arg) \
do { \
if (arg) { \
...
...
@@ -5357,3 +5359,713 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
virDomainSnapshotDefFree
(
def
);
return
ret
;
}
static
int
vboxDomainSnapshotGetAll
(
virDomainPtr
dom
,
IMachine
*
machine
,
ISnapshot
***
snapshots
)
{
vboxIIDUnion
empty
;
ISnapshot
**
list
=
NULL
;
PRUint32
count
;
nsresult
rc
;
unsigned
int
next
;
unsigned
int
top
;
VBOX_IID_INITIALIZE
(
&
empty
);
rc
=
gVBoxAPI
.
UIMachine
.
GetSnapshotCount
(
machine
,
&
count
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get snapshot count for domain %s"
),
dom
->
name
);
goto
error
;
}
if
(
count
==
0
)
goto
out
;
if
(
VIR_ALLOC_N
(
list
,
count
)
<
0
)
goto
error
;
rc
=
gVBoxAPI
.
UIMachine
.
FindSnapshot
(
machine
,
&
empty
,
list
);
if
(
NS_FAILED
(
rc
)
||
!
list
[
0
])
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get root snapshot for domain %s"
),
dom
->
name
);
goto
error
;
}
/* BFS walk through snapshot tree */
top
=
1
;
for
(
next
=
0
;
next
<
count
;
next
++
)
{
vboxArray
children
=
VBOX_ARRAY_INITIALIZER
;
size_t
i
;
if
(
!
list
[
next
])
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"unexpected number of snapshots < %u"
),
count
);
goto
error
;
}
rc
=
gVBoxAPI
.
UArray
.
vboxArrayGet
(
&
children
,
list
[
next
],
gVBoxAPI
.
UArray
.
handleSnapshotGetChildren
(
list
[
next
]));
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"could not get children snapshots"
));
goto
error
;
}
for
(
i
=
0
;
i
<
children
.
count
;
i
++
)
{
ISnapshot
*
child
=
children
.
items
[
i
];
if
(
!
child
)
continue
;
if
(
top
==
count
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"unexpected number of snapshots > %u"
),
count
);
gVBoxAPI
.
UArray
.
vboxArrayRelease
(
&
children
);
goto
error
;
}
VBOX_ADDREF
(
child
);
list
[
top
++
]
=
child
;
}
gVBoxAPI
.
UArray
.
vboxArrayRelease
(
&
children
);
}
out:
*
snapshots
=
list
;
return
count
;
error:
if
(
list
)
{
for
(
next
=
0
;
next
<
count
;
next
++
)
VBOX_RELEASE
(
list
[
next
]);
}
VIR_FREE
(
list
);
return
-
1
;
}
static
ISnapshot
*
vboxDomainSnapshotGet
(
vboxGlobalData
*
data
,
virDomainPtr
dom
,
IMachine
*
machine
,
const
char
*
name
)
{
ISnapshot
**
snapshots
=
NULL
;
ISnapshot
*
snapshot
=
NULL
;
nsresult
rc
;
int
count
=
0
;
size_t
i
;
if
((
count
=
vboxDomainSnapshotGetAll
(
dom
,
machine
,
&
snapshots
))
<
0
)
goto
cleanup
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
PRUnichar
*
nameUtf16
;
char
*
nameUtf8
;
rc
=
gVBoxAPI
.
UISnapshot
.
GetName
(
snapshots
[
i
],
&
nameUtf16
);
if
(
NS_FAILED
(
rc
)
||
!
nameUtf16
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"could not get snapshot name"
));
goto
cleanup
;
}
VBOX_UTF16_TO_UTF8
(
nameUtf16
,
&
nameUtf8
);
VBOX_UTF16_FREE
(
nameUtf16
);
if
(
STREQ
(
name
,
nameUtf8
))
snapshot
=
snapshots
[
i
];
VBOX_UTF8_FREE
(
nameUtf8
);
if
(
snapshot
)
break
;
}
if
(
!
snapshot
)
{
virReportError
(
VIR_ERR_OPERATION_INVALID
,
_
(
"domain %s has no snapshots with name %s"
),
dom
->
name
,
name
);
goto
cleanup
;
}
cleanup:
if
(
count
>
0
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
{
if
(
snapshots
[
i
]
!=
snapshot
)
VBOX_RELEASE
(
snapshots
[
i
]);
}
}
VIR_FREE
(
snapshots
);
return
snapshot
;
}
static
int
vboxSnapshotGetReadWriteDisks
(
virDomainSnapshotDefPtr
def
,
virDomainSnapshotPtr
snapshot
)
{
virDomainPtr
dom
=
snapshot
->
domain
;
VBOX_OBJECT_CHECK
(
dom
->
conn
,
int
,
-
1
);
vboxIIDUnion
domiid
;
IMachine
*
machine
=
NULL
;
ISnapshot
*
snap
=
NULL
;
IMachine
*
snapMachine
=
NULL
;
vboxArray
mediumAttachments
=
VBOX_ARRAY_INITIALIZER
;
PRUint32
maxPortPerInst
[
StorageBus_Floppy
+
1
]
=
{};
PRUint32
maxSlotPerPort
[
StorageBus_Floppy
+
1
]
=
{};
int
diskCount
=
0
;
nsresult
rc
;
vboxIIDUnion
snapIid
;
char
*
snapshotUuidStr
=
NULL
;
size_t
i
=
0
;
if
(
!
gVBoxAPI
.
vboxSnapshotRedefine
)
VIR_WARN
(
"This function may not work in current version"
);
VBOX_IID_INITIALIZE
(
&
snapIid
);
if
(
openSessionForMachine
(
data
,
dom
->
uuid
,
&
domiid
,
&
machine
,
false
)
<
0
)
goto
cleanup
;
if
(
!
(
snap
=
vboxDomainSnapshotGet
(
data
,
dom
,
machine
,
snapshot
->
name
)))
goto
cleanup
;
rc
=
gVBoxAPI
.
UISnapshot
.
GetId
(
snap
,
&
snapIid
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"Could not get snapshot id"
));
goto
cleanup
;
}
gVBoxAPI
.
UIID
.
vboxIIDToUtf8
(
data
,
&
snapIid
,
&
snapshotUuidStr
);
vboxIIDUnalloc
(
&
snapIid
);
rc
=
gVBoxAPI
.
UISnapshot
.
GetMachine
(
snap
,
&
snapMachine
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"could not get machine"
));
goto
cleanup
;
}
def
->
ndisks
=
0
;
rc
=
gVBoxAPI
.
UArray
.
vboxArrayGet
(
&
mediumAttachments
,
snapMachine
,
gVBoxAPI
.
UArray
.
handleMachineGetMediumAttachments
(
snapMachine
));
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"no medium attachments"
));
goto
cleanup
;
}
/* get the number of attachments */
for
(
i
=
0
;
i
<
mediumAttachments
.
count
;
i
++
)
{
IMediumAttachment
*
imediumattach
=
mediumAttachments
.
items
[
i
];
if
(
imediumattach
)
{
IMedium
*
medium
=
NULL
;
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetMedium
(
imediumattach
,
&
medium
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium"
));
goto
cleanup
;
}
if
(
medium
)
{
def
->
ndisks
++
;
VBOX_RELEASE
(
medium
);
}
}
}
/* Allocate mem, if fails return error */
if
(
VIR_ALLOC_N
(
def
->
disks
,
def
->
ndisks
)
<
0
)
goto
cleanup
;
for
(
i
=
0
;
i
<
def
->
ndisks
;
i
++
)
{
if
(
VIR_ALLOC
(
def
->
disks
[
i
].
src
)
<
0
)
goto
cleanup
;
}
if
(
!
vboxGetMaxPortSlotValues
(
data
->
vboxObj
,
maxPortPerInst
,
maxSlotPerPort
))
goto
cleanup
;
/* get the attachment details here */
for
(
i
=
0
;
i
<
mediumAttachments
.
count
&&
diskCount
<
def
->
ndisks
;
i
++
)
{
IStorageController
*
storageController
=
NULL
;
PRUnichar
*
storageControllerName
=
NULL
;
PRUint32
deviceType
=
DeviceType_Null
;
PRUint32
storageBus
=
StorageBus_Null
;
IMedium
*
disk
=
NULL
;
PRUnichar
*
childLocUtf16
=
NULL
;
char
*
childLocUtf8
=
NULL
;
PRUint32
deviceInst
=
0
;
PRInt32
devicePort
=
0
;
PRInt32
deviceSlot
=
0
;
vboxArray
children
=
VBOX_ARRAY_INITIALIZER
;
vboxArray
snapshotIids
=
VBOX_ARRAY_INITIALIZER
;
IMediumAttachment
*
imediumattach
=
mediumAttachments
.
items
[
i
];
void
*
handle
;
size_t
j
=
0
;
size_t
k
=
0
;
if
(
!
imediumattach
)
continue
;
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetMedium
(
imediumattach
,
&
disk
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium"
));
goto
cleanup
;
}
if
(
!
disk
)
continue
;
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetController
(
imediumattach
,
&
storageControllerName
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get controller"
));
goto
cleanup
;
}
if
(
!
storageControllerName
)
{
VBOX_RELEASE
(
disk
);
continue
;
}
handle
=
gVBoxAPI
.
UArray
.
handleMediumGetChildren
(
disk
);
rc
=
gVBoxAPI
.
UArray
.
vboxArrayGet
(
&
children
,
disk
,
handle
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get children disk"
));
goto
cleanup
;
}
handle
=
gVBoxAPI
.
UArray
.
handleMediumGetSnapshotIds
(
disk
);
rc
=
gVBoxAPI
.
UArray
.
vboxArrayGetWithIIDArg
(
&
snapshotIids
,
disk
,
handle
,
&
domiid
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get snapshot ids"
));
goto
cleanup
;
}
for
(
j
=
0
;
j
<
children
.
count
;
++
j
)
{
IMedium
*
child
=
children
.
items
[
j
];
for
(
k
=
0
;
k
<
snapshotIids
.
count
;
++
k
)
{
PRUnichar
*
diskSnapId
=
snapshotIids
.
items
[
k
];
char
*
diskSnapIdStr
=
NULL
;
VBOX_UTF16_TO_UTF8
(
diskSnapId
,
&
diskSnapIdStr
);
if
(
STREQ
(
diskSnapIdStr
,
snapshotUuidStr
))
{
rc
=
gVBoxAPI
.
UIMachine
.
GetStorageControllerByName
(
machine
,
storageControllerName
,
&
storageController
);
VBOX_UTF16_FREE
(
storageControllerName
);
if
(
!
storageController
)
{
VBOX_RELEASE
(
child
);
break
;
}
rc
=
gVBoxAPI
.
UIMedium
.
GetLocation
(
child
,
&
childLocUtf16
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get disk location"
));
goto
cleanup
;
}
VBOX_UTF16_TO_UTF8
(
childLocUtf16
,
&
childLocUtf8
);
VBOX_UTF16_FREE
(
childLocUtf16
);
if
(
VIR_STRDUP
(
def
->
disks
[
diskCount
].
src
->
path
,
childLocUtf8
)
<
0
)
{
VBOX_RELEASE
(
child
);
VBOX_RELEASE
(
storageController
);
goto
cleanup
;
}
VBOX_UTF8_FREE
(
childLocUtf8
);
rc
=
gVBoxAPI
.
UIStorageController
.
GetBus
(
storageController
,
&
storageBus
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get storage controller bus"
));
goto
cleanup
;
}
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetType
(
imediumattach
,
&
deviceType
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment type"
));
goto
cleanup
;
}
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetPort
(
imediumattach
,
&
devicePort
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment type"
));
goto
cleanup
;
}
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetDevice
(
imediumattach
,
&
deviceSlot
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment device"
));
goto
cleanup
;
}
def
->
disks
[
diskCount
].
src
->
type
=
VIR_STORAGE_TYPE_FILE
;
def
->
disks
[
diskCount
].
name
=
vboxGenerateMediumName
(
storageBus
,
deviceInst
,
devicePort
,
deviceSlot
,
maxPortPerInst
,
maxSlotPerPort
);
}
VBOX_UTF8_FREE
(
diskSnapIdStr
);
}
}
VBOX_RELEASE
(
storageController
);
VBOX_RELEASE
(
disk
);
diskCount
++
;
}
gVBoxAPI
.
UArray
.
vboxArrayRelease
(
&
mediumAttachments
);
ret
=
0
;
cleanup:
if
(
ret
<
0
)
{
for
(
i
=
0
;
i
<
def
->
ndisks
;
i
++
)
{
VIR_FREE
(
def
->
disks
[
i
].
src
);
}
VIR_FREE
(
def
->
disks
);
def
->
ndisks
=
0
;
}
VBOX_RELEASE
(
snap
);
return
ret
;
}
static
int
vboxSnapshotGetReadOnlyDisks
(
virDomainSnapshotPtr
snapshot
,
virDomainSnapshotDefPtr
def
)
{
virDomainPtr
dom
=
snapshot
->
domain
;
VBOX_OBJECT_CHECK
(
dom
->
conn
,
int
,
-
1
);
vboxIIDUnion
domiid
;
ISnapshot
*
snap
=
NULL
;
IMachine
*
machine
=
NULL
;
IMachine
*
snapMachine
=
NULL
;
IStorageController
*
storageController
=
NULL
;
IMedium
*
disk
=
NULL
;
nsresult
rc
;
vboxArray
mediumAttachments
=
VBOX_ARRAY_INITIALIZER
;
size_t
i
=
0
;
PRUint32
maxPortPerInst
[
StorageBus_Floppy
+
1
]
=
{};
PRUint32
maxSlotPerPort
[
StorageBus_Floppy
+
1
]
=
{};
int
diskCount
=
0
;
if
(
!
gVBoxAPI
.
vboxSnapshotRedefine
)
VIR_WARN
(
"This function may not work in current version"
);
if
(
openSessionForMachine
(
data
,
dom
->
uuid
,
&
domiid
,
&
machine
,
false
)
<
0
)
goto
cleanup
;
if
(
!
(
snap
=
vboxDomainSnapshotGet
(
data
,
dom
,
machine
,
snapshot
->
name
)))
goto
cleanup
;
rc
=
gVBoxAPI
.
UISnapshot
.
GetMachine
(
snap
,
&
snapMachine
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get machine"
));
goto
cleanup
;
}
/*
* Get READ ONLY disks
* In the snapshot metadata, these are the disks written inside the <domain> node
*/
rc
=
gVBoxAPI
.
UArray
.
vboxArrayGet
(
&
mediumAttachments
,
snapMachine
,
gVBoxAPI
.
UArray
.
handleMachineGetMediumAttachments
(
snapMachine
));
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachments"
));
goto
cleanup
;
}
/* get the number of attachments */
for
(
i
=
0
;
i
<
mediumAttachments
.
count
;
i
++
)
{
IMediumAttachment
*
imediumattach
=
mediumAttachments
.
items
[
i
];
if
(
imediumattach
)
{
IMedium
*
medium
=
NULL
;
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetMedium
(
imediumattach
,
&
medium
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium"
));
goto
cleanup
;
}
if
(
medium
)
{
def
->
dom
->
ndisks
++
;
VBOX_RELEASE
(
medium
);
}
}
}
/* Allocate mem, if fails return error */
if
(
VIR_ALLOC_N
(
def
->
dom
->
disks
,
def
->
dom
->
ndisks
)
>=
0
)
{
for
(
i
=
0
;
i
<
def
->
dom
->
ndisks
;
i
++
)
{
virDomainDiskDefPtr
diskDef
=
virDomainDiskDefNew
();
if
(
!
diskDef
)
goto
cleanup
;
def
->
dom
->
disks
[
i
]
=
diskDef
;
}
}
else
{
goto
cleanup
;
}
if
(
!
vboxGetMaxPortSlotValues
(
data
->
vboxObj
,
maxPortPerInst
,
maxSlotPerPort
))
goto
cleanup
;
/* get the attachment details here */
for
(
i
=
0
;
i
<
mediumAttachments
.
count
&&
diskCount
<
def
->
dom
->
ndisks
;
i
++
)
{
PRUnichar
*
storageControllerName
=
NULL
;
PRUint32
deviceType
=
DeviceType_Null
;
PRUint32
storageBus
=
StorageBus_Null
;
PRBool
readOnly
=
PR_FALSE
;
PRUnichar
*
mediumLocUtf16
=
NULL
;
char
*
mediumLocUtf8
=
NULL
;
PRUint32
deviceInst
=
0
;
PRInt32
devicePort
=
0
;
PRInt32
deviceSlot
=
0
;
IMediumAttachment
*
imediumattach
=
mediumAttachments
.
items
[
i
];
if
(
!
imediumattach
)
continue
;
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetMedium
(
imediumattach
,
&
disk
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium"
));
goto
cleanup
;
}
if
(
!
disk
)
continue
;
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetController
(
imediumattach
,
&
storageControllerName
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get storage controller name"
));
goto
cleanup
;
}
if
(
!
storageControllerName
)
continue
;
rc
=
gVBoxAPI
.
UIMachine
.
GetStorageControllerByName
(
machine
,
storageControllerName
,
&
storageController
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get storage controller"
));
goto
cleanup
;
}
VBOX_UTF16_FREE
(
storageControllerName
);
if
(
!
storageController
)
continue
;
rc
=
gVBoxAPI
.
UIMedium
.
GetLocation
(
disk
,
&
mediumLocUtf16
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get disk location"
));
goto
cleanup
;
}
VBOX_UTF16_TO_UTF8
(
mediumLocUtf16
,
&
mediumLocUtf8
);
VBOX_UTF16_FREE
(
mediumLocUtf16
);
if
(
VIR_STRDUP
(
def
->
dom
->
disks
[
diskCount
]
->
src
->
path
,
mediumLocUtf8
)
<
0
)
goto
cleanup
;
VBOX_UTF8_FREE
(
mediumLocUtf8
);
rc
=
gVBoxAPI
.
UIStorageController
.
GetBus
(
storageController
,
&
storageBus
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get storage controller bus"
));
goto
cleanup
;
}
if
(
storageBus
==
StorageBus_IDE
)
{
def
->
dom
->
disks
[
diskCount
]
->
bus
=
VIR_DOMAIN_DISK_BUS_IDE
;
}
else
if
(
storageBus
==
StorageBus_SATA
)
{
def
->
dom
->
disks
[
diskCount
]
->
bus
=
VIR_DOMAIN_DISK_BUS_SATA
;
}
else
if
(
storageBus
==
StorageBus_SCSI
)
{
def
->
dom
->
disks
[
diskCount
]
->
bus
=
VIR_DOMAIN_DISK_BUS_SCSI
;
}
else
if
(
storageBus
==
StorageBus_Floppy
)
{
def
->
dom
->
disks
[
diskCount
]
->
bus
=
VIR_DOMAIN_DISK_BUS_FDC
;
}
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetType
(
imediumattach
,
&
deviceType
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment type"
));
goto
cleanup
;
}
if
(
deviceType
==
DeviceType_HardDisk
)
def
->
dom
->
disks
[
diskCount
]
->
device
=
VIR_DOMAIN_DISK_DEVICE_DISK
;
else
if
(
deviceType
==
DeviceType_Floppy
)
def
->
dom
->
disks
[
diskCount
]
->
device
=
VIR_DOMAIN_DISK_DEVICE_FLOPPY
;
else
if
(
deviceType
==
DeviceType_DVD
)
def
->
dom
->
disks
[
diskCount
]
->
device
=
VIR_DOMAIN_DISK_DEVICE_CDROM
;
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetPort
(
imediumattach
,
&
devicePort
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment port"
));
goto
cleanup
;
}
rc
=
gVBoxAPI
.
UIMediumAttachment
.
GetDevice
(
imediumattach
,
&
deviceSlot
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get device"
));
goto
cleanup
;
}
rc
=
gVBoxAPI
.
UIMedium
.
GetReadOnly
(
disk
,
&
readOnly
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get read only attribute"
));
goto
cleanup
;
}
if
(
readOnly
==
PR_TRUE
)
def
->
dom
->
disks
[
diskCount
]
->
src
->
readonly
=
true
;
def
->
dom
->
disks
[
diskCount
]
->
src
->
type
=
VIR_STORAGE_TYPE_FILE
;
def
->
dom
->
disks
[
diskCount
]
->
dst
=
vboxGenerateMediumName
(
storageBus
,
deviceInst
,
devicePort
,
deviceSlot
,
maxPortPerInst
,
maxSlotPerPort
);
if
(
!
def
->
dom
->
disks
[
diskCount
]
->
dst
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not generate medium name for the disk "
"at: controller instance:%u, port:%d, slot:%d"
),
deviceInst
,
devicePort
,
deviceSlot
);
ret
=
-
1
;
goto
cleanup
;
}
diskCount
++
;
}
/* cleanup on error */
ret
=
0
;
cleanup:
if
(
ret
<
0
)
{
for
(
i
=
0
;
i
<
def
->
dom
->
ndisks
;
i
++
)
virDomainDiskDefFree
(
def
->
dom
->
disks
[
i
]);
VIR_FREE
(
def
->
dom
->
disks
);
def
->
dom
->
ndisks
=
0
;
}
VBOX_RELEASE
(
disk
);
VBOX_RELEASE
(
storageController
);
gVBoxAPI
.
UArray
.
vboxArrayRelease
(
&
mediumAttachments
);
VBOX_RELEASE
(
snap
);
return
ret
;
}
char
*
vboxDomainSnapshotGetXMLDesc
(
virDomainSnapshotPtr
snapshot
,
unsigned
int
flags
)
{
virDomainPtr
dom
=
snapshot
->
domain
;
VBOX_OBJECT_CHECK
(
dom
->
conn
,
char
*
,
NULL
);
vboxIIDUnion
domiid
;
IMachine
*
machine
=
NULL
;
ISnapshot
*
snap
=
NULL
;
ISnapshot
*
parent
=
NULL
;
nsresult
rc
;
virDomainSnapshotDefPtr
def
=
NULL
;
PRUnichar
*
str16
;
char
*
str8
;
PRInt64
timestamp
;
PRBool
online
=
PR_FALSE
;
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
virCheckFlags
(
0
,
NULL
);
if
(
openSessionForMachine
(
data
,
dom
->
uuid
,
&
domiid
,
&
machine
,
false
)
<
0
)
goto
cleanup
;
if
(
!
(
snap
=
vboxDomainSnapshotGet
(
data
,
dom
,
machine
,
snapshot
->
name
)))
goto
cleanup
;
if
(
VIR_ALLOC
(
def
)
<
0
||
VIR_ALLOC
(
def
->
dom
)
<
0
)
goto
cleanup
;
if
(
VIR_STRDUP
(
def
->
name
,
snapshot
->
name
)
<
0
)
goto
cleanup
;
if
(
gVBoxAPI
.
vboxSnapshotRedefine
)
{
/* Register def->dom properties for them to be saved inside the snapshot XMl
* Otherwise, there is a problem while parsing the xml
*/
PRUint32
memorySize
=
0
;
PRUint32
CPUCount
=
0
;
def
->
dom
->
virtType
=
VIR_DOMAIN_VIRT_VBOX
;
def
->
dom
->
id
=
dom
->
id
;
memcpy
(
def
->
dom
->
uuid
,
dom
->
uuid
,
VIR_UUID_BUFLEN
);
if
(
VIR_STRDUP
(
def
->
dom
->
name
,
dom
->
name
)
<
0
)
goto
cleanup
;
gVBoxAPI
.
UIMachine
.
GetMemorySize
(
machine
,
&
memorySize
);
def
->
dom
->
mem
.
cur_balloon
=
memorySize
*
1024
;
/* Currently setting memory and maxMemory as same, cause
* the notation here seems to be inconsistent while
* reading and while dumping xml
*/
def
->
dom
->
mem
.
max_balloon
=
memorySize
*
1024
;
if
(
VIR_STRDUP
(
def
->
dom
->
os
.
type
,
"hvm"
)
<
0
)
goto
cleanup
;
def
->
dom
->
os
.
arch
=
virArchFromHost
();
gVBoxAPI
.
UIMachine
.
GetCPUCount
(
machine
,
&
CPUCount
);
def
->
dom
->
maxvcpus
=
def
->
dom
->
vcpus
=
CPUCount
;
if
(
vboxSnapshotGetReadWriteDisks
(
def
,
snapshot
)
<
0
)
{
VIR_DEBUG
(
"Could not get read write disks for snapshot"
);
}
if
(
vboxSnapshotGetReadOnlyDisks
(
snapshot
,
def
)
<
0
)
{
VIR_DEBUG
(
"Could not get Readonly disks for snapshot"
);
}
}
rc
=
gVBoxAPI
.
UISnapshot
.
GetDescription
(
snap
,
&
str16
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get description of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
if
(
str16
)
{
VBOX_UTF16_TO_UTF8
(
str16
,
&
str8
);
VBOX_UTF16_FREE
(
str16
);
if
(
VIR_STRDUP
(
def
->
description
,
str8
)
<
0
)
{
VBOX_UTF8_FREE
(
str8
);
goto
cleanup
;
}
VBOX_UTF8_FREE
(
str8
);
}
rc
=
gVBoxAPI
.
UISnapshot
.
GetTimeStamp
(
snap
,
&
timestamp
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get creation time of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
/* timestamp is in milliseconds while creationTime in seconds */
def
->
creationTime
=
timestamp
/
1000
;
rc
=
gVBoxAPI
.
UISnapshot
.
GetParent
(
snap
,
&
parent
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get parent of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
if
(
parent
)
{
rc
=
gVBoxAPI
.
UISnapshot
.
GetName
(
parent
,
&
str16
);
if
(
NS_FAILED
(
rc
)
||
!
str16
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get name of parent of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
VBOX_UTF16_TO_UTF8
(
str16
,
&
str8
);
VBOX_UTF16_FREE
(
str16
);
if
(
VIR_STRDUP
(
def
->
parent
,
str8
)
<
0
)
{
VBOX_UTF8_FREE
(
str8
);
goto
cleanup
;
}
VBOX_UTF8_FREE
(
str8
);
}
rc
=
gVBoxAPI
.
UISnapshot
.
GetOnline
(
snap
,
&
online
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get online state of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
if
(
online
)
def
->
state
=
VIR_DOMAIN_RUNNING
;
else
def
->
state
=
VIR_DOMAIN_SHUTOFF
;
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
memcpy
(
def
->
dom
->
uuid
,
dom
->
uuid
,
VIR_UUID_BUFLEN
);
ret
=
virDomainSnapshotDefFormat
(
uuidstr
,
def
,
flags
,
0
);
cleanup:
virDomainSnapshotDefFree
(
def
);
VBOX_RELEASE
(
parent
);
VBOX_RELEASE
(
snap
);
VBOX_RELEASE
(
machine
);
vboxIIDUnalloc
(
&
domiid
);
return
ret
;
}
src/vbox/vbox_tmpl.c
浏览文件 @
72c23d65
...
...
@@ -676,70 +676,6 @@ _vboxIIDFromArrayItem(vboxGlobalData *data, vboxIIDUnion *iidu,
#endif
/* !(VBOX_API_VERSION == 2002000) */
/**
* function to generate the name for medium,
* for e.g: hda, sda, etc
*
* @returns null terminated string with device name or NULL
* for failures
* @param conn Input Connection Pointer
* @param storageBus Input storage bus type
* @param deviceInst Input device instance number
* @param devicePort Input port number
* @param deviceSlot Input slot number
* @param aMaxPortPerInst Input array of max port per device instance
* @param aMaxSlotPerPort Input array of max slot per device port
*
*/
/* This functions is used for 4.2 and later only since vboxDomainGetXMLDesc
* is rewritten. */
#if VBOX_API_VERSION >= 4002000
static
char
*
vboxGenerateMediumName
(
PRUint32
storageBus
,
PRInt32
deviceInst
,
PRInt32
devicePort
,
PRInt32
deviceSlot
,
PRUint32
*
aMaxPortPerInst
,
PRUint32
*
aMaxSlotPerPort
)
{
const
char
*
prefix
=
NULL
;
char
*
name
=
NULL
;
int
total
=
0
;
PRUint32
maxPortPerInst
=
0
;
PRUint32
maxSlotPerPort
=
0
;
if
(
!
aMaxPortPerInst
||
!
aMaxSlotPerPort
)
return
NULL
;
if
((
storageBus
<
StorageBus_IDE
)
||
(
storageBus
>
StorageBus_Floppy
))
return
NULL
;
maxPortPerInst
=
aMaxPortPerInst
[
storageBus
];
maxSlotPerPort
=
aMaxSlotPerPort
[
storageBus
];
total
=
(
deviceInst
*
maxPortPerInst
*
maxSlotPerPort
)
+
(
devicePort
*
maxSlotPerPort
)
+
deviceSlot
;
if
(
storageBus
==
StorageBus_IDE
)
{
prefix
=
"hd"
;
}
else
if
((
storageBus
==
StorageBus_SATA
)
||
(
storageBus
==
StorageBus_SCSI
))
{
prefix
=
"sd"
;
}
else
if
(
storageBus
==
StorageBus_Floppy
)
{
prefix
=
"fd"
;
}
name
=
virIndexToDiskName
(
total
,
prefix
);
VIR_DEBUG
(
"name=%s, total=%d, storageBus=%u, deviceInst=%d, "
"devicePort=%d deviceSlot=%d, maxPortPerInst=%u maxSlotPerPort=%u"
,
NULLSTR
(
name
),
total
,
storageBus
,
deviceInst
,
devicePort
,
deviceSlot
,
maxPortPerInst
,
maxSlotPerPort
);
return
name
;
}
#endif
/* VBOX_API_VERSION >= 4002000 */
/**
* function to get the StorageBus, Port number
* and Device number for the given devicename
...
...
@@ -803,7 +739,6 @@ static bool vboxGetDeviceDetails(const char *deviceName,
return
true
;
}
# endif
/* VBOX_API_VERSION < 4000000 */
/**
* function to get the values for max port per
...
...
@@ -816,9 +751,8 @@ static bool vboxGetDeviceDetails(const char *deviceName,
*
*/
/* This function would not be used in 4.0 and 4.1 since
* vboxDomainGetXMLDesc is written*/
# if VBOX_API_VERSION >= 4002000 || VBOX_API_VERSION < 4000000
/* This function would not be used in 4.1 and later since
* vboxDomainSnapshotGetXMLDesc is written*/
static
bool
vboxGetMaxPortSlotValues
(
IVirtualBox
*
vbox
,
PRUint32
*
maxPortPerInst
,
PRUint32
*
maxSlotPerPort
)
...
...
@@ -863,7 +797,7 @@ static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox,
return
true
;
}
# endif
/* VBOX_API_VERSION
>= 4002000 || VBOX_API_VERSION
< 4000000 */
# endif
/* VBOX_API_VERSION < 4000000 */
/**
* Converts Utf-16 string to int
...
...
@@ -1589,583 +1523,6 @@ vboxDomainSnapshotGet(vboxGlobalData *data,
return
snapshot
;
}
#if VBOX_API_VERSION >=4002000
static
int
vboxSnapshotGetReadWriteDisks
(
virDomainSnapshotDefPtr
def
,
virDomainSnapshotPtr
snapshot
)
{
virDomainPtr
dom
=
snapshot
->
domain
;
VBOX_OBJECT_CHECK
(
dom
->
conn
,
int
,
-
1
);
vboxIID
domiid
=
VBOX_IID_INITIALIZER
;
IMachine
*
machine
=
NULL
;
ISnapshot
*
snap
=
NULL
;
IMachine
*
snapMachine
=
NULL
;
vboxArray
mediumAttachments
=
VBOX_ARRAY_INITIALIZER
;
PRUint32
maxPortPerInst
[
StorageBus_Floppy
+
1
]
=
{};
PRUint32
maxSlotPerPort
[
StorageBus_Floppy
+
1
]
=
{};
int
diskCount
=
0
;
nsresult
rc
;
vboxIID
snapIid
=
VBOX_IID_INITIALIZER
;
char
*
snapshotUuidStr
=
NULL
;
size_t
i
=
0
;
vboxIIDFromUUID
(
&
domiid
,
dom
->
uuid
);
rc
=
VBOX_OBJECT_GET_MACHINE
(
domiid
.
value
,
&
machine
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"no domain with matching UUID"
));
goto
cleanup
;
}
if
(
!
(
snap
=
vboxDomainSnapshotGet
(
data
,
dom
,
machine
,
snapshot
->
name
)))
goto
cleanup
;
rc
=
snap
->
vtbl
->
GetId
(
snap
,
&
snapIid
.
value
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"Could not get snapshot id"
));
goto
cleanup
;
}
VBOX_UTF16_TO_UTF8
(
snapIid
.
value
,
&
snapshotUuidStr
);
rc
=
snap
->
vtbl
->
GetMachine
(
snap
,
&
snapMachine
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"could not get machine"
));
goto
cleanup
;
}
def
->
ndisks
=
0
;
rc
=
vboxArrayGet
(
&
mediumAttachments
,
snapMachine
,
snapMachine
->
vtbl
->
GetMediumAttachments
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"no medium attachments"
));
goto
cleanup
;
}
/* get the number of attachments */
for
(
i
=
0
;
i
<
mediumAttachments
.
count
;
i
++
)
{
IMediumAttachment
*
imediumattach
=
mediumAttachments
.
items
[
i
];
if
(
imediumattach
)
{
IMedium
*
medium
=
NULL
;
rc
=
imediumattach
->
vtbl
->
GetMedium
(
imediumattach
,
&
medium
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium"
));
goto
cleanup
;
}
if
(
medium
)
{
def
->
ndisks
++
;
VBOX_RELEASE
(
medium
);
}
}
}
/* Allocate mem, if fails return error */
if
(
VIR_ALLOC_N
(
def
->
disks
,
def
->
ndisks
)
<
0
)
goto
cleanup
;
for
(
i
=
0
;
i
<
def
->
ndisks
;
i
++
)
{
if
(
VIR_ALLOC
(
def
->
disks
[
i
].
src
)
<
0
)
goto
cleanup
;
}
if
(
!
vboxGetMaxPortSlotValues
(
data
->
vboxObj
,
maxPortPerInst
,
maxSlotPerPort
))
goto
cleanup
;
/* get the attachment details here */
for
(
i
=
0
;
i
<
mediumAttachments
.
count
&&
diskCount
<
def
->
ndisks
;
i
++
)
{
IStorageController
*
storageController
=
NULL
;
PRUnichar
*
storageControllerName
=
NULL
;
PRUint32
deviceType
=
DeviceType_Null
;
PRUint32
storageBus
=
StorageBus_Null
;
IMedium
*
disk
=
NULL
;
PRUnichar
*
childLocUtf16
=
NULL
;
char
*
childLocUtf8
=
NULL
;
PRUint32
deviceInst
=
0
;
PRInt32
devicePort
=
0
;
PRInt32
deviceSlot
=
0
;
vboxArray
children
=
VBOX_ARRAY_INITIALIZER
;
vboxArray
snapshotIids
=
VBOX_ARRAY_INITIALIZER
;
IMediumAttachment
*
imediumattach
=
mediumAttachments
.
items
[
i
];
size_t
j
=
0
;
size_t
k
=
0
;
if
(
!
imediumattach
)
continue
;
rc
=
imediumattach
->
vtbl
->
GetMedium
(
imediumattach
,
&
disk
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium"
));
goto
cleanup
;
}
if
(
!
disk
)
continue
;
rc
=
imediumattach
->
vtbl
->
GetController
(
imediumattach
,
&
storageControllerName
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get controller"
));
goto
cleanup
;
}
if
(
!
storageControllerName
)
{
VBOX_RELEASE
(
disk
);
continue
;
}
rc
=
vboxArrayGet
(
&
children
,
disk
,
disk
->
vtbl
->
GetChildren
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get children disk"
));
goto
cleanup
;
}
rc
=
vboxArrayGetWithPtrArg
(
&
snapshotIids
,
disk
,
disk
->
vtbl
->
GetSnapshotIds
,
domiid
.
value
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get snapshot ids"
));
goto
cleanup
;
}
for
(
j
=
0
;
j
<
children
.
count
;
++
j
)
{
IMedium
*
child
=
children
.
items
[
j
];
for
(
k
=
0
;
k
<
snapshotIids
.
count
;
++
k
)
{
PRUnichar
*
diskSnapId
=
snapshotIids
.
items
[
k
];
char
*
diskSnapIdStr
=
NULL
;
VBOX_UTF16_TO_UTF8
(
diskSnapId
,
&
diskSnapIdStr
);
if
(
STREQ
(
diskSnapIdStr
,
snapshotUuidStr
))
{
rc
=
machine
->
vtbl
->
GetStorageControllerByName
(
machine
,
storageControllerName
,
&
storageController
);
VBOX_UTF16_FREE
(
storageControllerName
);
if
(
!
storageController
)
{
VBOX_RELEASE
(
child
);
break
;
}
rc
=
child
->
vtbl
->
GetLocation
(
child
,
&
childLocUtf16
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get disk location"
));
goto
cleanup
;
}
VBOX_UTF16_TO_UTF8
(
childLocUtf16
,
&
childLocUtf8
);
VBOX_UTF16_FREE
(
childLocUtf16
);
if
(
VIR_STRDUP
(
def
->
disks
[
diskCount
].
src
->
path
,
childLocUtf8
)
<
0
)
{
VBOX_RELEASE
(
child
);
VBOX_RELEASE
(
storageController
);
goto
cleanup
;
}
VBOX_UTF8_FREE
(
childLocUtf8
);
rc
=
storageController
->
vtbl
->
GetBus
(
storageController
,
&
storageBus
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get storage controller bus"
));
goto
cleanup
;
}
rc
=
imediumattach
->
vtbl
->
GetType
(
imediumattach
,
&
deviceType
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment type"
));
goto
cleanup
;
}
rc
=
imediumattach
->
vtbl
->
GetPort
(
imediumattach
,
&
devicePort
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment type"
));
goto
cleanup
;
}
rc
=
imediumattach
->
vtbl
->
GetDevice
(
imediumattach
,
&
deviceSlot
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment device"
));
goto
cleanup
;
}
def
->
disks
[
diskCount
].
src
->
type
=
VIR_STORAGE_TYPE_FILE
;
def
->
disks
[
diskCount
].
name
=
vboxGenerateMediumName
(
storageBus
,
deviceInst
,
devicePort
,
deviceSlot
,
maxPortPerInst
,
maxSlotPerPort
);
}
VBOX_UTF8_FREE
(
diskSnapIdStr
);
}
}
VBOX_RELEASE
(
storageController
);
VBOX_RELEASE
(
disk
);
diskCount
++
;
}
vboxArrayRelease
(
&
mediumAttachments
);
ret
=
0
;
cleanup:
if
(
ret
<
0
)
{
for
(
i
=
0
;
i
<
def
->
ndisks
;
i
++
)
{
VIR_FREE
(
def
->
disks
[
i
].
src
);
}
VIR_FREE
(
def
->
disks
);
def
->
ndisks
=
0
;
}
VBOX_RELEASE
(
snap
);
return
ret
;
}
static
int
vboxSnapshotGetReadOnlyDisks
(
virDomainSnapshotPtr
snapshot
,
virDomainSnapshotDefPtr
def
)
{
virDomainPtr
dom
=
snapshot
->
domain
;
VBOX_OBJECT_CHECK
(
dom
->
conn
,
int
,
-
1
);
vboxIID
domiid
=
VBOX_IID_INITIALIZER
;
ISnapshot
*
snap
=
NULL
;
IMachine
*
machine
=
NULL
;
IMachine
*
snapMachine
=
NULL
;
IStorageController
*
storageController
=
NULL
;
IMedium
*
disk
=
NULL
;
nsresult
rc
;
vboxIIDFromUUID
(
&
domiid
,
dom
->
uuid
);
vboxArray
mediumAttachments
=
VBOX_ARRAY_INITIALIZER
;
size_t
i
=
0
;
PRUint32
maxPortPerInst
[
StorageBus_Floppy
+
1
]
=
{};
PRUint32
maxSlotPerPort
[
StorageBus_Floppy
+
1
]
=
{};
int
diskCount
=
0
;
rc
=
VBOX_OBJECT_GET_MACHINE
(
domiid
.
value
,
&
machine
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_NO_DOMAIN
,
"%s"
,
_
(
"no domain with matching UUID"
));
goto
cleanup
;
}
if
(
!
(
snap
=
vboxDomainSnapshotGet
(
data
,
dom
,
machine
,
snapshot
->
name
)))
goto
cleanup
;
rc
=
snap
->
vtbl
->
GetMachine
(
snap
,
&
snapMachine
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get machine"
));
goto
cleanup
;
}
/*
* Get READ ONLY disks
* In the snapshot metadata, these are the disks written inside the <domain> node
*/
rc
=
vboxArrayGet
(
&
mediumAttachments
,
snapMachine
,
snapMachine
->
vtbl
->
GetMediumAttachments
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachments"
));
goto
cleanup
;
}
/* get the number of attachments */
for
(
i
=
0
;
i
<
mediumAttachments
.
count
;
i
++
)
{
IMediumAttachment
*
imediumattach
=
mediumAttachments
.
items
[
i
];
if
(
imediumattach
)
{
IMedium
*
medium
=
NULL
;
rc
=
imediumattach
->
vtbl
->
GetMedium
(
imediumattach
,
&
medium
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium"
));
goto
cleanup
;
}
if
(
medium
)
{
def
->
dom
->
ndisks
++
;
VBOX_RELEASE
(
medium
);
}
}
}
/* Allocate mem, if fails return error */
if
(
VIR_ALLOC_N
(
def
->
dom
->
disks
,
def
->
dom
->
ndisks
)
>=
0
)
{
for
(
i
=
0
;
i
<
def
->
dom
->
ndisks
;
i
++
)
{
virDomainDiskDefPtr
diskDef
=
virDomainDiskDefNew
();
if
(
!
diskDef
)
goto
cleanup
;
def
->
dom
->
disks
[
i
]
=
diskDef
;
}
}
else
{
goto
cleanup
;
}
if
(
!
vboxGetMaxPortSlotValues
(
data
->
vboxObj
,
maxPortPerInst
,
maxSlotPerPort
))
goto
cleanup
;
/* get the attachment details here */
for
(
i
=
0
;
i
<
mediumAttachments
.
count
&&
diskCount
<
def
->
dom
->
ndisks
;
i
++
)
{
PRUnichar
*
storageControllerName
=
NULL
;
PRUint32
deviceType
=
DeviceType_Null
;
PRUint32
storageBus
=
StorageBus_Null
;
PRBool
readOnly
=
PR_FALSE
;
PRUnichar
*
mediumLocUtf16
=
NULL
;
char
*
mediumLocUtf8
=
NULL
;
PRUint32
deviceInst
=
0
;
PRInt32
devicePort
=
0
;
PRInt32
deviceSlot
=
0
;
IMediumAttachment
*
imediumattach
=
mediumAttachments
.
items
[
i
];
if
(
!
imediumattach
)
continue
;
rc
=
imediumattach
->
vtbl
->
GetMedium
(
imediumattach
,
&
disk
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium"
));
goto
cleanup
;
}
if
(
!
disk
)
continue
;
rc
=
imediumattach
->
vtbl
->
GetController
(
imediumattach
,
&
storageControllerName
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get storage controller name"
));
goto
cleanup
;
}
if
(
!
storageControllerName
)
continue
;
rc
=
machine
->
vtbl
->
GetStorageControllerByName
(
machine
,
storageControllerName
,
&
storageController
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get storage controller"
));
goto
cleanup
;
}
VBOX_UTF16_FREE
(
storageControllerName
);
if
(
!
storageController
)
continue
;
rc
=
disk
->
vtbl
->
GetLocation
(
disk
,
&
mediumLocUtf16
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get disk location"
));
goto
cleanup
;
}
VBOX_UTF16_TO_UTF8
(
mediumLocUtf16
,
&
mediumLocUtf8
);
VBOX_UTF16_FREE
(
mediumLocUtf16
);
if
(
VIR_STRDUP
(
def
->
dom
->
disks
[
diskCount
]
->
src
->
path
,
mediumLocUtf8
)
<
0
)
goto
cleanup
;
VBOX_UTF8_FREE
(
mediumLocUtf8
);
rc
=
storageController
->
vtbl
->
GetBus
(
storageController
,
&
storageBus
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get storage controller bus"
));
goto
cleanup
;
}
if
(
storageBus
==
StorageBus_IDE
)
{
def
->
dom
->
disks
[
diskCount
]
->
bus
=
VIR_DOMAIN_DISK_BUS_IDE
;
}
else
if
(
storageBus
==
StorageBus_SATA
)
{
def
->
dom
->
disks
[
diskCount
]
->
bus
=
VIR_DOMAIN_DISK_BUS_SATA
;
}
else
if
(
storageBus
==
StorageBus_SCSI
)
{
def
->
dom
->
disks
[
diskCount
]
->
bus
=
VIR_DOMAIN_DISK_BUS_SCSI
;
}
else
if
(
storageBus
==
StorageBus_Floppy
)
{
def
->
dom
->
disks
[
diskCount
]
->
bus
=
VIR_DOMAIN_DISK_BUS_FDC
;
}
rc
=
imediumattach
->
vtbl
->
GetType
(
imediumattach
,
&
deviceType
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment type"
));
goto
cleanup
;
}
if
(
deviceType
==
DeviceType_HardDisk
)
def
->
dom
->
disks
[
diskCount
]
->
device
=
VIR_DOMAIN_DISK_DEVICE_DISK
;
else
if
(
deviceType
==
DeviceType_Floppy
)
def
->
dom
->
disks
[
diskCount
]
->
device
=
VIR_DOMAIN_DISK_DEVICE_FLOPPY
;
else
if
(
deviceType
==
DeviceType_DVD
)
def
->
dom
->
disks
[
diskCount
]
->
device
=
VIR_DOMAIN_DISK_DEVICE_CDROM
;
rc
=
imediumattach
->
vtbl
->
GetPort
(
imediumattach
,
&
devicePort
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get medium attachment port"
));
goto
cleanup
;
}
rc
=
imediumattach
->
vtbl
->
GetDevice
(
imediumattach
,
&
deviceSlot
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get device"
));
goto
cleanup
;
}
rc
=
disk
->
vtbl
->
GetReadOnly
(
disk
,
&
readOnly
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot get read only attribute"
));
goto
cleanup
;
}
if
(
readOnly
==
PR_TRUE
)
def
->
dom
->
disks
[
diskCount
]
->
src
->
readonly
=
true
;
def
->
dom
->
disks
[
diskCount
]
->
src
->
type
=
VIR_STORAGE_TYPE_FILE
;
def
->
dom
->
disks
[
diskCount
]
->
dst
=
vboxGenerateMediumName
(
storageBus
,
deviceInst
,
devicePort
,
deviceSlot
,
maxPortPerInst
,
maxSlotPerPort
);
if
(
!
def
->
dom
->
disks
[
diskCount
]
->
dst
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not generate medium name for the disk "
"at: controller instance:%u, port:%d, slot:%d"
),
deviceInst
,
devicePort
,
deviceSlot
);
ret
=
-
1
;
goto
cleanup
;
}
diskCount
++
;
}
/* cleanup on error */
ret
=
0
;
cleanup:
if
(
ret
<
0
)
{
for
(
i
=
0
;
i
<
def
->
dom
->
ndisks
;
i
++
)
virDomainDiskDefFree
(
def
->
dom
->
disks
[
i
]);
VIR_FREE
(
def
->
dom
->
disks
);
def
->
dom
->
ndisks
=
0
;
}
VBOX_RELEASE
(
disk
);
VBOX_RELEASE
(
storageController
);
vboxArrayRelease
(
&
mediumAttachments
);
VBOX_RELEASE
(
snap
);
return
ret
;
}
#endif
static
char
*
vboxDomainSnapshotGetXMLDesc
(
virDomainSnapshotPtr
snapshot
,
unsigned
int
flags
)
{
virDomainPtr
dom
=
snapshot
->
domain
;
VBOX_OBJECT_CHECK
(
dom
->
conn
,
char
*
,
NULL
);
vboxIID
domiid
=
VBOX_IID_INITIALIZER
;
IMachine
*
machine
=
NULL
;
ISnapshot
*
snap
=
NULL
;
ISnapshot
*
parent
=
NULL
;
nsresult
rc
;
virDomainSnapshotDefPtr
def
=
NULL
;
PRUnichar
*
str16
;
char
*
str8
;
PRInt64
timestamp
;
PRBool
online
=
PR_FALSE
;
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
#if VBOX_API_VERSION >=4002000
PRUint32
memorySize
=
0
;
PRUint32
CPUCount
=
0
;
#endif
virCheckFlags
(
0
,
NULL
);
vboxIIDFromUUID
(
&
domiid
,
dom
->
uuid
);
rc
=
VBOX_OBJECT_GET_MACHINE
(
domiid
.
value
,
&
machine
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_NO_DOMAIN
,
"%s"
,
_
(
"no domain with matching UUID"
));
goto
cleanup
;
}
if
(
!
(
snap
=
vboxDomainSnapshotGet
(
data
,
dom
,
machine
,
snapshot
->
name
)))
goto
cleanup
;
if
(
VIR_ALLOC
(
def
)
<
0
||
VIR_ALLOC
(
def
->
dom
)
<
0
)
goto
cleanup
;
if
(
VIR_STRDUP
(
def
->
name
,
snapshot
->
name
)
<
0
)
goto
cleanup
;
#if VBOX_API_VERSION >=4002000
/* Register def->dom properties for them to be saved inside the snapshot XMl
* Otherwise, there is a problem while parsing the xml
*/
def
->
dom
->
virtType
=
VIR_DOMAIN_VIRT_VBOX
;
def
->
dom
->
id
=
dom
->
id
;
memcpy
(
def
->
dom
->
uuid
,
dom
->
uuid
,
VIR_UUID_BUFLEN
);
if
(
VIR_STRDUP
(
def
->
dom
->
name
,
dom
->
name
)
<
0
)
goto
cleanup
;
machine
->
vtbl
->
GetMemorySize
(
machine
,
&
memorySize
);
def
->
dom
->
mem
.
cur_balloon
=
memorySize
*
1024
;
/* Currently setting memory and maxMemory as same, cause
* the notation here seems to be inconsistent while
* reading and while dumping xml
*/
def
->
dom
->
mem
.
max_balloon
=
memorySize
*
1024
;
if
(
VIR_STRDUP
(
def
->
dom
->
os
.
type
,
"hvm"
)
<
0
)
goto
cleanup
;
def
->
dom
->
os
.
arch
=
virArchFromHost
();
machine
->
vtbl
->
GetCPUCount
(
machine
,
&
CPUCount
);
def
->
dom
->
maxvcpus
=
def
->
dom
->
vcpus
=
CPUCount
;
if
(
vboxSnapshotGetReadWriteDisks
(
def
,
snapshot
)
<
0
)
{
VIR_DEBUG
(
"Could not get read write disks for snapshot"
);
}
if
(
vboxSnapshotGetReadOnlyDisks
(
snapshot
,
def
)
<
0
)
{
VIR_DEBUG
(
"Could not get Readonly disks for snapshot"
);
}
#endif
/* VBOX_API_VERSION >= 4002000 */
rc
=
snap
->
vtbl
->
GetDescription
(
snap
,
&
str16
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get description of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
if
(
str16
)
{
VBOX_UTF16_TO_UTF8
(
str16
,
&
str8
);
VBOX_UTF16_FREE
(
str16
);
if
(
VIR_STRDUP
(
def
->
description
,
str8
)
<
0
)
{
VBOX_UTF8_FREE
(
str8
);
goto
cleanup
;
}
VBOX_UTF8_FREE
(
str8
);
}
rc
=
snap
->
vtbl
->
GetTimeStamp
(
snap
,
&
timestamp
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get creation time of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
/* timestamp is in milliseconds while creationTime in seconds */
def
->
creationTime
=
timestamp
/
1000
;
rc
=
snap
->
vtbl
->
GetParent
(
snap
,
&
parent
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get parent of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
if
(
parent
)
{
rc
=
parent
->
vtbl
->
GetName
(
parent
,
&
str16
);
if
(
NS_FAILED
(
rc
)
||
!
str16
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get name of parent of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
VBOX_UTF16_TO_UTF8
(
str16
,
&
str8
);
VBOX_UTF16_FREE
(
str16
);
if
(
VIR_STRDUP
(
def
->
parent
,
str8
)
<
0
)
{
VBOX_UTF8_FREE
(
str8
);
goto
cleanup
;
}
VBOX_UTF8_FREE
(
str8
);
}
rc
=
snap
->
vtbl
->
GetOnline
(
snap
,
&
online
);
if
(
NS_FAILED
(
rc
))
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"could not get online state of snapshot %s"
),
snapshot
->
name
);
goto
cleanup
;
}
if
(
online
)
def
->
state
=
VIR_DOMAIN_RUNNING
;
else
def
->
state
=
VIR_DOMAIN_SHUTOFF
;
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
memcpy
(
def
->
dom
->
uuid
,
dom
->
uuid
,
VIR_UUID_BUFLEN
);
ret
=
virDomainSnapshotDefFormat
(
uuidstr
,
def
,
flags
,
0
);
cleanup:
virDomainSnapshotDefFree
(
def
);
VBOX_RELEASE
(
parent
);
VBOX_RELEASE
(
snap
);
VBOX_RELEASE
(
machine
);
vboxIIDUnalloc
(
&
domiid
);
return
ret
;
}
static
int
vboxDomainSnapshotNum
(
virDomainPtr
dom
,
unsigned
int
flags
)
...
...
@@ -6709,6 +6066,12 @@ _vboxIIDToUtf8(vboxGlobalData *data ATTRIBUTE_UNUSED,
#endif
/* !(VBOX_API_VERSION == 2002000) */
}
static
nsresult
_vboxArrayGetWithIIDArg
(
vboxArray
*
array
,
void
*
self
,
void
*
getter
,
vboxIIDUnion
*
iidu
)
{
return
vboxArrayGetWithPtrArg
(
array
,
self
,
getter
,
IID_MEMBER
(
value
));
}
static
void
*
_handleGetMachines
(
IVirtualBox
*
vboxObj
)
{
return
vboxObj
->
vtbl
->
GetMachines
;
...
...
@@ -6733,11 +6096,36 @@ static void* _handleMachineGetSharedFolders(IMachine *machine)
return
machine
->
vtbl
->
GetSharedFolders
;
}
static
void
*
_handleSnapshotGetChildren
(
ISnapshot
*
snapshot
)
{
return
snapshot
->
vtbl
->
GetChildren
;
}
static
void
*
_handleMediumGetChildren
(
IMedium
*
medium
ATTRIBUTE_UNUSED
)
{
#if VBOX_API_VERSION < 3001000
vboxUnsupported
();
return
0
;
#else
/* VBOX_API_VERSION >= 3001000 */
return
medium
->
vtbl
->
GetChildren
;
#endif
/* VBOX_API_VERSION >= 3001000 */
}
static
void
*
_handleMediumGetSnapshotIds
(
IMedium
*
medium
)
{
return
medium
->
vtbl
->
GetSnapshotIds
;
}
static
nsresult
_nsisupportsRelease
(
nsISupports
*
nsi
)
{
return
nsi
->
vtbl
->
Release
(
nsi
);
}
static
nsresult
_nsisupportsAddRef
(
nsISupports
*
nsi
)
{
return
nsi
->
vtbl
->
AddRef
(
nsi
);
}
static
nsresult
_virtualboxGetVersion
(
IVirtualBox
*
vboxObj
,
PRUnichar
**
versionUtf16
)
{
...
...
@@ -6989,6 +6377,16 @@ _machineUnregister(IMachine *machine ATTRIBUTE_UNUSED,
#endif
/* VBOX_API_VERSION >= 4000000 */
}
static
nsresult
_machineFindSnapshot
(
IMachine
*
machine
,
vboxIIDUnion
*
iidu
,
ISnapshot
**
snapshot
)
{
#if VBOX_API_VERSION < 4000000
return
machine
->
vtbl
->
GetSnapshot
(
machine
,
IID_MEMBER
(
value
),
snapshot
);
#else
/* VBOX_API_VERSION >= 4000000 */
return
machine
->
vtbl
->
FindSnapshot
(
machine
,
IID_MEMBER
(
value
),
snapshot
);
#endif
/* VBOX_API_VERSION >= 4000000 */
}
static
nsresult
_machineGetAccessible
(
IMachine
*
machine
,
PRBool
*
isAccessible
)
{
...
...
@@ -7218,6 +6616,12 @@ _machineSetExtraData(IMachine *machine, PRUnichar *key, PRUnichar *value)
return
machine
->
vtbl
->
SetExtraData
(
machine
,
key
,
value
);
}
static
nsresult
_machineGetSnapshotCount
(
IMachine
*
machine
,
PRUint32
*
snapshotCount
)
{
return
machine
->
vtbl
->
GetSnapshotCount
(
machine
,
snapshotCount
);
}
static
nsresult
_machineSaveSettings
(
IMachine
*
machine
)
{
...
...
@@ -8156,6 +7560,48 @@ _sharedFolderGetWritable(ISharedFolder *sharedFolder, PRBool *writable)
return
sharedFolder
->
vtbl
->
GetWritable
(
sharedFolder
,
writable
);
}
static
nsresult
_snapshotGetName
(
ISnapshot
*
snapshot
,
PRUnichar
**
name
)
{
return
snapshot
->
vtbl
->
GetName
(
snapshot
,
name
);
}
static
nsresult
_snapshotGetId
(
ISnapshot
*
snapshot
,
vboxIIDUnion
*
iidu
)
{
return
snapshot
->
vtbl
->
GetId
(
snapshot
,
&
IID_MEMBER
(
value
));
}
static
nsresult
_snapshotGetMachine
(
ISnapshot
*
snapshot
,
IMachine
**
machine
)
{
return
snapshot
->
vtbl
->
GetMachine
(
snapshot
,
machine
);
}
static
nsresult
_snapshotGetDescription
(
ISnapshot
*
snapshot
,
PRUnichar
**
description
)
{
return
snapshot
->
vtbl
->
GetDescription
(
snapshot
,
description
);
}
static
nsresult
_snapshotGetTimeStamp
(
ISnapshot
*
snapshot
,
PRInt64
*
timeStamp
)
{
return
snapshot
->
vtbl
->
GetTimeStamp
(
snapshot
,
timeStamp
);
}
static
nsresult
_snapshotGetParent
(
ISnapshot
*
snapshot
,
ISnapshot
**
parent
)
{
return
snapshot
->
vtbl
->
GetParent
(
snapshot
,
parent
);
}
static
nsresult
_snapshotGetOnline
(
ISnapshot
*
snapshot
,
PRBool
*
online
)
{
return
snapshot
->
vtbl
->
GetOnline
(
snapshot
,
online
);
}
static
bool
_machineStateOnline
(
PRUint32
state
)
{
return
((
state
>=
MachineState_FirstOnline
)
&&
...
...
@@ -8213,15 +7659,20 @@ static vboxUniformedIID _UIID = {
static
vboxUniformedArray
_UArray
=
{
.
vboxArrayGet
=
vboxArrayGet
,
.
vboxArrayGetWithIIDArg
=
_vboxArrayGetWithIIDArg
,
.
vboxArrayRelease
=
vboxArrayRelease
,
.
handleGetMachines
=
_handleGetMachines
,
.
handleUSBGetDeviceFilters
=
_handleUSBGetDeviceFilters
,
.
handleMachineGetMediumAttachments
=
_handleMachineGetMediumAttachments
,
.
handleMachineGetSharedFolders
=
_handleMachineGetSharedFolders
,
.
handleSnapshotGetChildren
=
_handleSnapshotGetChildren
,
.
handleMediumGetChildren
=
_handleMediumGetChildren
,
.
handleMediumGetSnapshotIds
=
_handleMediumGetSnapshotIds
,
};
static
vboxUniformednsISupports
_nsUISupports
=
{
.
Release
=
_nsisupportsRelease
,
.
AddRef
=
_nsisupportsAddRef
,
};
static
vboxUniformedIVirtualBox
_UIVirtualBox
=
{
...
...
@@ -8244,6 +7695,7 @@ static vboxUniformedIMachine _UIMachine = {
.
RemoveSharedFolder
=
_machineRemoveSharedFolder
,
.
LaunchVMProcess
=
_machineLaunchVMProcess
,
.
Unregister
=
_machineUnregister
,
.
FindSnapshot
=
_machineFindSnapshot
,
.
GetAccessible
=
_machineGetAccessible
,
.
GetState
=
_machineGetState
,
.
GetName
=
_machineGetName
,
...
...
@@ -8276,6 +7728,7 @@ static vboxUniformedIMachine _UIMachine = {
.
SetAccelerate2DVideoEnabled
=
_machineSetAccelerate2DVideoEnabled
,
.
GetExtraData
=
_machineGetExtraData
,
.
SetExtraData
=
_machineSetExtraData
,
.
GetSnapshotCount
=
_machineGetSnapshotCount
,
.
SaveSettings
=
_machineSaveSettings
,
};
...
...
@@ -8433,6 +7886,16 @@ static vboxUniformedISharedFolder _UISharedFolder = {
.
GetWritable
=
_sharedFolderGetWritable
,
};
static
vboxUniformedISnapshot
_UISnapshot
=
{
.
GetName
=
_snapshotGetName
,
.
GetId
=
_snapshotGetId
,
.
GetMachine
=
_snapshotGetMachine
,
.
GetDescription
=
_snapshotGetDescription
,
.
GetTimeStamp
=
_snapshotGetTimeStamp
,
.
GetParent
=
_snapshotGetParent
,
.
GetOnline
=
_snapshotGetOnline
,
};
static
uniformedMachineStateChecker
_machineStateChecker
=
{
.
Online
=
_machineStateOnline
,
.
Inactive
=
_machineStateInactive
,
...
...
@@ -8482,6 +7945,7 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
pVBoxAPI
->
UIMediumAttachment
=
_UIMediumAttachment
;
pVBoxAPI
->
UIStorageController
=
_UIStorageController
;
pVBoxAPI
->
UISharedFolder
=
_UISharedFolder
;
pVBoxAPI
->
UISnapshot
=
_UISnapshot
;
pVBoxAPI
->
machineStateChecker
=
_machineStateChecker
;
#if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000
...
...
src/vbox/vbox_uniformed_api.h
浏览文件 @
72c23d65
...
...
@@ -166,17 +166,22 @@ typedef struct {
/* Functions for vboxArray */
typedef
struct
{
nsresult
(
*
vboxArrayGet
)(
vboxArray
*
array
,
void
*
self
,
void
*
getter
);
nsresult
(
*
vboxArrayGetWithIIDArg
)(
vboxArray
*
array
,
void
*
self
,
void
*
getter
,
vboxIIDUnion
*
iidu
);
void
(
*
vboxArrayRelease
)(
vboxArray
*
array
);
/* Generate function pointers for vboxArrayGet */
void
*
(
*
handleGetMachines
)(
IVirtualBox
*
vboxObj
);
void
*
(
*
handleUSBGetDeviceFilters
)(
IUSBCommon
*
USBCommon
);
void
*
(
*
handleMachineGetMediumAttachments
)(
IMachine
*
machine
);
void
*
(
*
handleMachineGetSharedFolders
)(
IMachine
*
machine
);
void
*
(
*
handleSnapshotGetChildren
)(
ISnapshot
*
snapshot
);
void
*
(
*
handleMediumGetChildren
)(
IMedium
*
medium
);
void
*
(
*
handleMediumGetSnapshotIds
)(
IMedium
*
medium
);
}
vboxUniformedArray
;
/* Functions for nsISupports */
typedef
struct
{
nsresult
(
*
Release
)(
nsISupports
*
nsi
);
nsresult
(
*
AddRef
)(
nsISupports
*
nsi
);
}
vboxUniformednsISupports
;
/* Functions for IVirtualBox */
...
...
@@ -211,6 +216,7 @@ typedef struct {
IProgress
**
progress
);
nsresult
(
*
Unregister
)(
IMachine
*
machine
,
PRUint32
cleanupMode
,
PRUint32
*
aMediaSize
,
IMedium
***
aMedia
);
nsresult
(
*
FindSnapshot
)(
IMachine
*
machine
,
vboxIIDUnion
*
iidu
,
ISnapshot
**
snapshot
);
nsresult
(
*
GetAccessible
)(
IMachine
*
machine
,
PRBool
*
isAccessible
);
nsresult
(
*
GetState
)(
IMachine
*
machine
,
PRUint32
*
state
);
nsresult
(
*
GetName
)(
IMachine
*
machine
,
PRUnichar
**
name
);
...
...
@@ -243,6 +249,7 @@ typedef struct {
nsresult
(
*
SetAccelerate2DVideoEnabled
)(
IMachine
*
machine
,
PRBool
accelerate2DVideoEnabled
);
nsresult
(
*
GetExtraData
)(
IMachine
*
machine
,
PRUnichar
*
key
,
PRUnichar
**
value
);
nsresult
(
*
SetExtraData
)(
IMachine
*
machine
,
PRUnichar
*
key
,
PRUnichar
*
value
);
nsresult
(
*
GetSnapshotCount
)(
IMachine
*
machine
,
PRUint32
*
snapshotCount
);
nsresult
(
*
SaveSettings
)(
IMachine
*
machine
);
}
vboxUniformedIMachine
;
...
...
@@ -427,6 +434,17 @@ typedef struct {
nsresult
(
*
GetWritable
)(
ISharedFolder
*
sharedFolder
,
PRBool
*
writable
);
}
vboxUniformedISharedFolder
;
/* Functions for ISnapshot */
typedef
struct
{
nsresult
(
*
GetName
)(
ISnapshot
*
snapshot
,
PRUnichar
**
name
);
nsresult
(
*
GetId
)(
ISnapshot
*
snapshot
,
vboxIIDUnion
*
iidu
);
nsresult
(
*
GetMachine
)(
ISnapshot
*
snapshot
,
IMachine
**
machine
);
nsresult
(
*
GetDescription
)(
ISnapshot
*
snapshot
,
PRUnichar
**
description
);
nsresult
(
*
GetTimeStamp
)(
ISnapshot
*
snapshot
,
PRInt64
*
timeStamp
);
nsresult
(
*
GetParent
)(
ISnapshot
*
snapshot
,
ISnapshot
**
parent
);
nsresult
(
*
GetOnline
)(
ISnapshot
*
snapshot
,
PRBool
*
online
);
}
vboxUniformedISnapshot
;
typedef
struct
{
bool
(
*
Online
)(
PRUint32
state
);
bool
(
*
Inactive
)(
PRUint32
state
);
...
...
@@ -477,6 +495,7 @@ typedef struct {
vboxUniformedIMediumAttachment
UIMediumAttachment
;
vboxUniformedIStorageController
UIStorageController
;
vboxUniformedISharedFolder
UISharedFolder
;
vboxUniformedISnapshot
UISnapshot
;
uniformedMachineStateChecker
machineStateChecker
;
/* vbox API features */
bool
domainEventCallbacks
;
...
...
@@ -556,7 +575,8 @@ virDomainSnapshotPtr
vboxDomainSnapshotCreateXML
(
virDomainPtr
dom
,
const
char
*
xmlDesc
,
unsigned
int
flags
);
char
*
vboxDomainSnapshotGetXMLDesc
(
virDomainSnapshotPtr
snapshot
,
unsigned
int
flags
);
/* Version specified functions for installing uniformed API */
void
vbox22InstallUniformedAPI
(
vboxUniformedAPI
*
pVBoxAPI
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录