mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 07:05:28 +00:00
snapshot: implement snapshot children listing in qemu
Not too hard to wire up. The trickiest part is realizing that listing children of a snapshot cannot use SNAPSHOT_LIST_ROOTS, and that we overloaded that bit to also mean SNAPSHOT_LIST_DESCENDANTS; we use that bit to decide which iteration to use, but don't want the existing counting/listing functions to see that bit. * src/conf/domain_conf.h (virDomainSnapshotObjListNumFrom) (virDomainSnapshotObjListGetNamesFrom): New prototypes. * src/conf/domain_conf.c (virDomainSnapshotObjListNumFrom) (virDomainSnapshotObjListGetNamesFrom): New functions. * src/libvirt_private.syms (domain_conf.h): Export them. * src/qemu/qemu_driver.c (qemuDomainSnapshotNumChildren) (qemuDomainSnapshotListChildrenNames): New functions.
This commit is contained in:
parent
db536236f4
commit
5907403716
@ -12180,6 +12180,37 @@ cleanup:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot,
|
||||||
|
virDomainSnapshotObjListPtr snapshots,
|
||||||
|
char **const names, int maxnames,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
struct virDomainSnapshotNameData data = { 0, 0, maxnames, names, 0 };
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data.flags = flags & ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
|
||||||
|
|
||||||
|
if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS)
|
||||||
|
virDomainSnapshotForEachDescendant(snapshots, snapshot,
|
||||||
|
virDomainSnapshotObjListCopyNames,
|
||||||
|
&data);
|
||||||
|
else
|
||||||
|
virDomainSnapshotForEachChild(snapshots, snapshot,
|
||||||
|
virDomainSnapshotObjListCopyNames, &data);
|
||||||
|
|
||||||
|
if (data.oom) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.numnames;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
for (i = 0; i < data.numnames; i++)
|
||||||
|
VIR_FREE(data.names[i]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
struct virDomainSnapshotNumData {
|
struct virDomainSnapshotNumData {
|
||||||
int count;
|
int count;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
@ -12207,6 +12238,26 @@ int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots,
|
|||||||
return data.count;
|
return data.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot,
|
||||||
|
virDomainSnapshotObjListPtr snapshots,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
struct virDomainSnapshotNumData data = { 0, 0 };
|
||||||
|
|
||||||
|
data.flags = flags & ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
|
||||||
|
|
||||||
|
if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS)
|
||||||
|
virDomainSnapshotForEachDescendant(snapshots, snapshot,
|
||||||
|
virDomainSnapshotObjListCount,
|
||||||
|
&data);
|
||||||
|
else
|
||||||
|
virDomainSnapshotForEachChild(snapshots, snapshot,
|
||||||
|
virDomainSnapshotObjListCount, &data);
|
||||||
|
|
||||||
|
return data.count;
|
||||||
|
}
|
||||||
|
|
||||||
virDomainSnapshotObjPtr
|
virDomainSnapshotObjPtr
|
||||||
virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots,
|
virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots,
|
||||||
const char *name)
|
const char *name)
|
||||||
|
@ -1499,6 +1499,13 @@ int virDomainSnapshotObjListGetNames(virDomainSnapshotObjListPtr snapshots,
|
|||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots,
|
int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot,
|
||||||
|
virDomainSnapshotObjListPtr snapshots,
|
||||||
|
char **const names, int maxnames,
|
||||||
|
unsigned int flags);
|
||||||
|
int virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot,
|
||||||
|
virDomainSnapshotObjListPtr snapshots,
|
||||||
|
unsigned int flags);
|
||||||
virDomainSnapshotObjPtr virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots,
|
virDomainSnapshotObjPtr virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots,
|
||||||
const char *name);
|
const char *name);
|
||||||
void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
|
void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
|
||||||
|
@ -415,7 +415,9 @@ virDomainSnapshotForEachChild;
|
|||||||
virDomainSnapshotForEachDescendant;
|
virDomainSnapshotForEachDescendant;
|
||||||
virDomainSnapshotHasChildren;
|
virDomainSnapshotHasChildren;
|
||||||
virDomainSnapshotObjListGetNames;
|
virDomainSnapshotObjListGetNames;
|
||||||
|
virDomainSnapshotObjListGetNamesFrom;
|
||||||
virDomainSnapshotObjListNum;
|
virDomainSnapshotObjListNum;
|
||||||
|
virDomainSnapshotObjListNumFrom;
|
||||||
virDomainSnapshotObjListRemove;
|
virDomainSnapshotObjListRemove;
|
||||||
virDomainSnapshotStateTypeFromString;
|
virDomainSnapshotStateTypeFromString;
|
||||||
virDomainSnapshotStateTypeToString;
|
virDomainSnapshotStateTypeToString;
|
||||||
|
@ -9446,6 +9446,91 @@ cleanup:
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
|
||||||
|
char **names,
|
||||||
|
int nameslen,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
struct qemud_driver *driver = snapshot->domain->conn->privateData;
|
||||||
|
virDomainObjPtr vm = NULL;
|
||||||
|
virDomainSnapshotObjPtr snap = NULL;
|
||||||
|
int n = -1;
|
||||||
|
|
||||||
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
|
||||||
|
VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
|
||||||
|
|
||||||
|
qemuDriverLock(driver);
|
||||||
|
vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
|
||||||
|
if (!vm) {
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(snapshot->domain->uuid, uuidstr);
|
||||||
|
qemuReportError(VIR_ERR_NO_DOMAIN,
|
||||||
|
_("no domain with matching uuid '%s'"), uuidstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
|
||||||
|
if (!snap) {
|
||||||
|
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
|
||||||
|
_("no domain snapshot with matching name '%s'"),
|
||||||
|
snapshot->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = virDomainSnapshotObjListGetNamesFrom(snap, &vm->snapshots,
|
||||||
|
names, nameslen, flags);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (vm)
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
|
qemuDriverUnlock(driver);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
struct qemud_driver *driver = snapshot->domain->conn->privateData;
|
||||||
|
virDomainObjPtr vm = NULL;
|
||||||
|
virDomainSnapshotObjPtr snap = NULL;
|
||||||
|
int n = -1;
|
||||||
|
|
||||||
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
|
||||||
|
VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
|
||||||
|
|
||||||
|
qemuDriverLock(driver);
|
||||||
|
vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
|
||||||
|
if (!vm) {
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(snapshot->domain->uuid, uuidstr);
|
||||||
|
qemuReportError(VIR_ERR_NO_DOMAIN,
|
||||||
|
_("no domain with matching uuid '%s'"), uuidstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
|
||||||
|
if (!snap) {
|
||||||
|
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
|
||||||
|
_("no domain snapshot with matching name '%s'"),
|
||||||
|
snapshot->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All qemu snapshots have libvirt metadata, so
|
||||||
|
* VIR_DOMAIN_SNAPSHOT_LIST_METADATA makes no difference to our
|
||||||
|
* answer. */
|
||||||
|
|
||||||
|
n = virDomainSnapshotObjListNumFrom(snap, &vm->snapshots, flags);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (vm)
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
|
qemuDriverUnlock(driver);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
static virDomainSnapshotPtr qemuDomainSnapshotLookupByName(virDomainPtr domain,
|
static virDomainSnapshotPtr qemuDomainSnapshotLookupByName(virDomainPtr domain,
|
||||||
const char *name,
|
const char *name,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
@ -10568,6 +10653,8 @@ static virDriver qemuDriver = {
|
|||||||
.domainSnapshotGetXMLDesc = qemuDomainSnapshotGetXMLDesc, /* 0.8.0 */
|
.domainSnapshotGetXMLDesc = qemuDomainSnapshotGetXMLDesc, /* 0.8.0 */
|
||||||
.domainSnapshotNum = qemuDomainSnapshotNum, /* 0.8.0 */
|
.domainSnapshotNum = qemuDomainSnapshotNum, /* 0.8.0 */
|
||||||
.domainSnapshotListNames = qemuDomainSnapshotListNames, /* 0.8.0 */
|
.domainSnapshotListNames = qemuDomainSnapshotListNames, /* 0.8.0 */
|
||||||
|
.domainSnapshotNumChildren = qemuDomainSnapshotNumChildren, /* 0.9.7 */
|
||||||
|
.domainSnapshotListChildrenNames = qemuDomainSnapshotListChildrenNames, /* 0.9.7 */
|
||||||
.domainSnapshotLookupByName = qemuDomainSnapshotLookupByName, /* 0.8.0 */
|
.domainSnapshotLookupByName = qemuDomainSnapshotLookupByName, /* 0.8.0 */
|
||||||
.domainHasCurrentSnapshot = qemuDomainHasCurrentSnapshot, /* 0.8.0 */
|
.domainHasCurrentSnapshot = qemuDomainHasCurrentSnapshot, /* 0.8.0 */
|
||||||
.domainSnapshotGetParent = qemuDomainSnapshotGetParent, /* 0.9.7 */
|
.domainSnapshotGetParent = qemuDomainSnapshotGetParent, /* 0.9.7 */
|
||||||
|
Loading…
Reference in New Issue
Block a user