virDomainDefPtr newDef; /* New definition to activate at shutdown */
virDomainSnapshotObjListPtr snapshots;
- virDomainSnapshotObjPtr current_snapshot;
bool hasManagedSave;
return -1;
}
if (other) {
- if (other == vm->current_snapshot) {
+ if (other == virDomainSnapshotGetCurrent(vm->snapshots)) {
*update_current = true;
- vm->current_snapshot = NULL;
+ virDomainSnapshotSetCurrent(vm->snapshots, NULL);
}
/* Drop and rebuild the parent relationship, but keep all
virHashTable *objs;
virDomainSnapshotObj metaroot; /* Special parent of all root snapshots */
+ virDomainSnapshotObjPtr current; /* The current snapshot, if any */
};
virDomainSnapshotObjListParse(const char *xmlStr,
const unsigned char *domain_uuid,
virDomainSnapshotObjListPtr snapshots,
- virDomainSnapshotObjPtr *current_snap,
virCapsPtr caps,
virDomainXMLOptionPtr xmlopt,
unsigned int flags)
int n;
size_t i;
int keepBlanksDefault = xmlKeepBlanksDefault(0);
+ virDomainSnapshotObjPtr snap;
VIR_AUTOFREE(xmlNodePtr *) nodes = NULL;
VIR_AUTOFREE(char *) current = NULL;
_("incorrect flags for bulk parse"));
return -1;
}
- if (snapshots->metaroot.nchildren || *current_snap) {
+ if (snapshots->metaroot.nchildren || snapshots->current) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("bulk define of snapshots only possible with "
"no existing snapshot"));
for (i = 0; i < n; i++) {
virDomainSnapshotDefPtr def;
- virDomainSnapshotObjPtr snap;
def = virDomainSnapshotDefParseNode(xml, nodes[i], caps, xmlopt, NULL,
flags);
}
if (current) {
- if (!(*current_snap = virDomainSnapshotFindByName(snapshots,
- current))) {
+ snap = virDomainSnapshotFindByName(snapshots, current);
+ if (!snap) {
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
_("no snapshot matching current='%s'"), current);
goto cleanup;
}
+ virDomainSnapshotSetCurrent(snapshots, snap);
}
ret = n;
virDomainSnapshotObjListFormat(virBufferPtr buf,
const char *uuidstr,
virDomainSnapshotObjListPtr snapshots,
- virDomainSnapshotObjPtr current_snapshot,
virCapsPtr caps,
virDomainXMLOptionPtr xmlopt,
unsigned int flags)
virCheckFlags(VIR_DOMAIN_SNAPSHOT_FORMAT_SECURE, -1);
virBufferAddLit(buf, "<snapshots");
- if (current_snapshot)
- virBufferEscapeString(buf, " current='%s'",
- current_snapshot->def->name);
+ virBufferEscapeString(buf, " current='%s'",
+ virDomainSnapshotGetCurrentName(snapshots));
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
if (virDomainSnapshotForEach(snapshots, virDomainSnapshotFormatOne,
return name ? virHashLookup(snapshots->objs, name) : &snapshots->metaroot;
}
-void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
- virDomainSnapshotObjPtr snapshot)
+
+/* Return the current snapshot, or NULL */
+virDomainSnapshotObjPtr
+virDomainSnapshotGetCurrent(virDomainSnapshotObjListPtr snapshots)
+{
+ return snapshots->current;
+}
+
+
+/* Return the current snapshot's name, or NULL */
+const char *
+virDomainSnapshotGetCurrentName(virDomainSnapshotObjListPtr snapshots)
+{
+ if (snapshots->current)
+ return snapshots->current->def->name;
+ return NULL;
+}
+
+
+/* Return true if name matches the current snapshot */
+bool
+virDomainSnapshotIsCurrentName(virDomainSnapshotObjListPtr snapshots,
+ const char *name)
{
+ return snapshots->current && STREQ(snapshots->current->def->name, name);
+}
+
+
+/* Update the current snapshot, using NULL if no current remains */
+void
+virDomainSnapshotSetCurrent(virDomainSnapshotObjListPtr snapshots,
+ virDomainSnapshotObjPtr snapshot)
+{
+ snapshots->current = snapshot;
+}
+
+
+/* Remove snapshot from the list; return true if it was current */
+bool
+virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
+ virDomainSnapshotObjPtr snapshot)
+{
+ bool ret = snapshots->current == snapshot;
virHashRemoveEntry(snapshots->objs, snapshot->def->name);
+ if (ret)
+ snapshots->current = NULL;
+ return ret;
}
int
snapshots->metaroot.nchildren = 0;
snapshots->metaroot.first_child = NULL;
virHashForEach(snapshots->objs, virDomainSnapshotSetRelations, &act);
+ if (act.err)
+ snapshots->current = NULL;
return act.err;
}
int virDomainSnapshotObjListParse(const char *xmlStr,
const unsigned char *domain_uuid,
virDomainSnapshotObjListPtr snapshots,
- virDomainSnapshotObjPtr *current_snap,
virCapsPtr caps,
virDomainXMLOptionPtr xmlopt,
unsigned int flags);
int virDomainSnapshotObjListFormat(virBufferPtr buf,
const char *uuidstr,
virDomainSnapshotObjListPtr snapshots,
- virDomainSnapshotObjPtr current_snapshot,
virCapsPtr caps,
virDomainXMLOptionPtr xmlopt,
unsigned int flags);
unsigned int flags);
virDomainSnapshotObjPtr virDomainSnapshotFindByName(virDomainSnapshotObjListPtr snapshots,
const char *name);
-void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
+virDomainSnapshotObjPtr virDomainSnapshotGetCurrent(virDomainSnapshotObjListPtr snapshots);
+const char *virDomainSnapshotGetCurrentName(virDomainSnapshotObjListPtr snapshots);
+bool virDomainSnapshotIsCurrentName(virDomainSnapshotObjListPtr snapshots,
+ const char *name);
+void virDomainSnapshotSetCurrent(virDomainSnapshotObjListPtr snapshots,
+ virDomainSnapshotObjPtr snapshot);
+bool virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
virDomainSnapshotObjPtr snapshot);
int virDomainSnapshotForEach(virDomainSnapshotObjListPtr snapshots,
virHashIterator iter,
virDomainSnapshotAssignDef;
virDomainSnapshotFindByName;
virDomainSnapshotForEach;
+virDomainSnapshotGetCurrent;
+virDomainSnapshotGetCurrentName;
+virDomainSnapshotIsCurrentName;
virDomainSnapshotObjListFormat;
virDomainSnapshotObjListFree;
virDomainSnapshotObjListGetNames;
virDomainSnapshotObjListNum;
virDomainSnapshotObjListParse;
virDomainSnapshotObjListRemove;
+virDomainSnapshotSetCurrent;
virDomainSnapshotUpdateRelations;
unsigned int flags = VIR_DOMAIN_SNAPSHOT_FORMAT_SECURE |
VIR_DOMAIN_SNAPSHOT_FORMAT_INTERNAL;
- if (vm->current_snapshot == snapshot)
+ if (virDomainSnapshotGetCurrent(vm->snapshots) == snapshot)
flags |= VIR_DOMAIN_SNAPSHOT_FORMAT_CURRENT;
virUUIDFormat(vm->def->uuid, uuidstr);
newxml = virDomainSnapshotDefFormat(uuidstr, snapshot->def, caps, xmlopt,
vm->def->name, snap->def->name) < 0)
goto cleanup;
- if (snap == vm->current_snapshot) {
- vm->current_snapshot = NULL;
+ if (snap == virDomainSnapshotGetCurrent(vm->snapshots)) {
+ virDomainSnapshotSetCurrent(vm->snapshots, NULL);
if (update_parent && snap->def->parent) {
parentsnap = virDomainSnapshotFindByName(vm->snapshots,
snap->def->parent);
VIR_WARN("missing parent snapshot matching name '%s'",
snap->def->parent);
} else {
- vm->current_snapshot = parentsnap;
+ virDomainSnapshotSetCurrent(vm->snapshots, parentsnap);
if (qemuDomainSnapshotWriteMetadata(vm, parentsnap, driver->caps,
driver->xmlopt,
cfg->snapshotDir) < 0) {
VIR_WARN("failed to set parent snapshot '%s' as current",
snap->def->parent);
- vm->current_snapshot = NULL;
+ virDomainSnapshotSetCurrent(vm->snapshots, NULL);
}
}
}
virQEMUSnapRemovePtr curr = data;
int err;
- if (curr->vm->current_snapshot == snap)
+ if (virDomainSnapshotGetCurrent(curr->vm->snapshots) == snap)
curr->current = true;
err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap, false,
curr->metadata_only);
rem.err = 0;
virDomainSnapshotForEach(vm->snapshots, qemuDomainSnapshotDiscardAll,
&rem);
- if (rem.current)
- vm->current_snapshot = NULL;
if (virDomainSnapshotUpdateRelations(vm->snapshots) < 0 && !rem.err)
rem.err = -1;
_("Failed to fully read directory %s"),
snapDir);
- vm->current_snapshot = current;
+ virDomainSnapshotSetCurrent(vm->snapshots, current);
if (virDomainSnapshotUpdateRelations(vm->snapshots) < 0)
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Snapshots have inconsistent relations for domain %s"),
def = NULL;
}
- current = vm->current_snapshot;
+ current = virDomainSnapshotGetCurrent(vm->snapshots);
if (current) {
if (!redefine &&
VIR_STRDUP(snap->def->parent, current->def->name) < 0)
goto endjob;
if (update_current) {
- vm->current_snapshot = NULL;
+ virDomainSnapshotSetCurrent(vm->snapshots, NULL);
if (qemuDomainSnapshotWriteMetadata(vm, current,
driver->caps, driver->xmlopt,
cfg->snapshotDir) < 0)
endjob:
if (snapshot && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
if (update_current)
- vm->current_snapshot = snap;
+ virDomainSnapshotSetCurrent(vm->snapshots, snap);
if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps,
driver->xmlopt,
cfg->snapshotDir) < 0) {
_("unable to save metadata for snapshot %s"),
snap->def->name);
virDomainSnapshotObjListRemove(vm->snapshots, snap);
- vm->current_snapshot = NULL;
} else {
other = virDomainSnapshotFindByName(vm->snapshots,
snap->def->parent);
if (virDomainHasCurrentSnapshotEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
- ret = (vm->current_snapshot != NULL);
+ ret = (virDomainSnapshotGetCurrent(vm->snapshots) != NULL);
cleanup:
virDomainObjEndAPI(&vm);
if (virDomainSnapshotCurrentEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
- if (!vm->current_snapshot) {
+ if (!virDomainSnapshotGetCurrent(vm->snapshots)) {
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s",
_("the domain does not have a current snapshot"));
goto cleanup;
}
- snapshot = virGetDomainSnapshot(domain, vm->current_snapshot->def->name);
+ snapshot = virGetDomainSnapshot(domain, virDomainSnapshotGetCurrentName(vm->snapshots));
cleanup:
virDomainObjEndAPI(&vm);
if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
goto cleanup;
- ret = (vm->current_snapshot &&
- STREQ(snapshot->name, vm->current_snapshot->def->name));
+ ret = virDomainSnapshotIsCurrentName(vm->snapshots, snapshot->name);
cleanup:
virDomainObjEndAPI(&vm);
}
}
- current = vm->current_snapshot;
+ current = virDomainSnapshotGetCurrent(vm->snapshots);
if (current) {
- vm->current_snapshot = NULL;
+ virDomainSnapshotSetCurrent(vm->snapshots, NULL);
if (qemuDomainSnapshotWriteMetadata(vm, current,
driver->caps, driver->xmlopt,
cfg->snapshotDir) < 0)
goto endjob;
- /* XXX Should we restore vm->current_snapshot after this point
+ /* XXX Should we restore the current snapshot after this point
* in the failure cases where we know there was no change? */
}
*
* XXX Should domain snapshots track live xml rather
* than inactive xml? */
- vm->current_snapshot = snap;
if (snap->def->dom) {
config = virDomainDefCopy(snap->def->dom, caps,
driver->xmlopt, NULL, true);
cleanup:
if (ret == 0) {
- vm->current_snapshot = snap;
+ virDomainSnapshotSetCurrent(vm->snapshots, snap);
if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps,
driver->xmlopt,
cfg->snapshotDir) < 0) {
- vm->current_snapshot = NULL;
+ virDomainSnapshotSetCurrent(vm->snapshots, NULL);
ret = -1;
}
} else if (snap) {
- vm->current_snapshot = NULL;
+ virDomainSnapshotSetCurrent(vm->snapshots, NULL);
}
if (ret == 0 && config && vm->persistent &&
!(ret = virDomainSaveConfig(cfg->configDir, driver->caps,
if (rem.err < 0)
goto endjob;
if (rem.current) {
- vm->current_snapshot = snap;
+ virDomainSnapshotSetCurrent(vm->snapshots, snap);
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps,
driver->xmlopt,
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to set snapshot '%s' as current"),
snap->def->name);
- vm->current_snapshot = NULL;
+ virDomainSnapshotSetCurrent(vm->snapshots, NULL);
goto endjob;
}
}
}
if (cur) {
- if (domobj->current_snapshot) {
+ if (virDomainSnapshotGetCurrent(domobj->snapshots)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("more than one snapshot claims to be active"));
goto error;
}
- domobj->current_snapshot = snap;
+ virDomainSnapshotSetCurrent(domobj->snapshots, snap);
}
}
if (!(vm = testDomObjFromDomain(domain)))
return -1;
- ret = (vm->current_snapshot != NULL);
+ ret = (virDomainSnapshotGetCurrent(vm->snapshots) != NULL);
virDomainObjEndAPI(&vm);
return ret;
{
virDomainObjPtr vm;
virDomainSnapshotPtr snapshot = NULL;
+ virDomainSnapshotObjPtr current;
virCheckFlags(0, NULL);
if (!(vm = testDomObjFromDomain(domain)))
return NULL;
- if (!vm->current_snapshot) {
+ current = virDomainSnapshotGetCurrent(vm->snapshots);
+ if (!current) {
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s",
_("the domain does not have a current snapshot"));
goto cleanup;
}
- snapshot = virGetDomainSnapshot(domain, vm->current_snapshot->def->name);
+ snapshot = virGetDomainSnapshot(domain, current->def->name);
cleanup:
virDomainObjEndAPI(&vm);
if (!(vm = testDomObjFromSnapshot(snapshot)))
return -1;
- ret = (vm->current_snapshot &&
- STREQ(snapshot->name, vm->current_snapshot->def->name));
+ ret = virDomainSnapshotIsCurrentName(vm->snapshots, snapshot->name);
virDomainObjEndAPI(&vm);
return ret;
}
if (!redefine) {
- if (vm->current_snapshot &&
- (VIR_STRDUP(snap->def->parent,
- vm->current_snapshot->def->name) < 0))
+ if (VIR_STRDUP(snap->def->parent,
+ virDomainSnapshotGetCurrentName(vm->snapshots)) < 0)
goto cleanup;
if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT) &&
if (snapshot) {
virDomainSnapshotObjPtr other;
if (update_current)
- vm->current_snapshot = snap;
+ virDomainSnapshotSetCurrent(vm->snapshots, snap);
other = virDomainSnapshotFindByName(vm->snapshots,
snap->def->parent);
snap->parent = other;
virDomainSnapshotObjPtr snap = payload;
testSnapRemoveDataPtr curr = data;
- if (curr->vm->current_snapshot == snap)
- curr->current = true;
- virDomainSnapshotObjListRemove(curr->vm->snapshots, snap);
+ curr->current |= virDomainSnapshotObjListRemove(curr->vm->snapshots, snap);
return 0;
}
testDomainSnapshotDiscardAll,
&rem);
if (rem.current)
- vm->current_snapshot = snap;
+ virDomainSnapshotSetCurrent(vm->snapshots, snap);
} else if (snap->nchildren) {
testSnapReparentData rep;
rep.parent = snap->parent;
snap->first_child = NULL;
} else {
virDomainSnapshotDropParent(snap);
- if (snap == vm->current_snapshot) {
+ if (snap == virDomainSnapshotGetCurrent(vm->snapshots)) {
if (snap->def->parent) {
parentsnap = virDomainSnapshotFindByName(vm->snapshots,
snap->def->parent);
VIR_WARN("missing parent snapshot matching name '%s'",
snap->def->parent);
}
- vm->current_snapshot = parentsnap;
+ virDomainSnapshotSetCurrent(vm->snapshots, parentsnap);
}
virDomainSnapshotObjListRemove(vm->snapshots, snap);
}
}
}
-
- if (vm->current_snapshot)
- vm->current_snapshot = NULL;
+ virDomainSnapshotSetCurrent(vm->snapshots, NULL);
config = virDomainDefCopy(snap->def->dom, privconn->caps,
privconn->xmlopt, NULL, true);
}
}
- vm->current_snapshot = snap;
+ virDomainSnapshotSetCurrent(vm->snapshots, snap);
ret = 0;
cleanup:
if (event) {