}
-virDomainSnapshotPtr
-qemuSnapshotCreateXML(virDomainPtr domain,
- virDomainObj *vm,
- const char *xmlDesc,
- unsigned int flags)
+static int
+qemuSnapshotCreateXMLValidateDef(virDomainObj *vm,
+ virDomainSnapshotDef *def,
+ unsigned int flags)
{
- virQEMUDriver *driver = domain->conn->privateData;
- g_autofree char *xml = NULL;
- virDomainMomentObj *snap = NULL;
- virDomainSnapshotPtr snapshot = NULL;
- virDomainMomentObj *current = NULL;
- bool update_current = true;
bool redefine = flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE;
- int align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL;
- bool align_match = true;
- g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
- qemuDomainObjPrivate *priv = vm->privateData;
virDomainSnapshotState state;
- g_autoptr(virDomainSnapshotDef) def = NULL;
-
- virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
- VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
- VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA |
- VIR_DOMAIN_SNAPSHOT_CREATE_HALT |
- VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY |
- VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT |
- VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE |
- VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC |
- VIR_DOMAIN_SNAPSHOT_CREATE_LIVE |
- VIR_DOMAIN_SNAPSHOT_CREATE_VALIDATE, NULL);
-
- VIR_REQUIRE_FLAG_RET(VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE,
- VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY,
- NULL);
- VIR_EXCLUSIVE_FLAGS_RET(VIR_DOMAIN_SNAPSHOT_CREATE_LIVE,
- VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE,
- NULL);
-
- if ((redefine && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT)) ||
- (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA))
- update_current = false;
-
- if (qemuDomainSupportsCheckpointsBlockjobs(vm) < 0)
- return NULL;
-
- if (!vm->persistent && (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT)) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("cannot halt after transient domain snapshot"));
- return NULL;
- }
-
- if (!(def = qemuSnapshotCreateXMLParse(vm, driver, xmlDesc, flags)))
- return NULL;
/* reject snapshot names containing slashes or starting with dot as
* snapshot definitions are saved in files named by the snapshot name */
_("invalid snapshot name '%s': "
"name can't contain '/'"),
def->parent.name);
- return NULL;
+ return -1;
}
if (def->parent.name[0] == '.') {
_("invalid snapshot name '%s': "
"name can't start with '.'"),
def->parent.name);
- return NULL;
+ return -1;
}
}
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("live snapshot creation is supported only "
"during full system snapshots"));
- return NULL;
+ return -1;
}
/* allow snapshots only in certain states */
if (!redefine) {
virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state %s"),
virDomainSnapshotStateTypeToString(state));
- return NULL;
+ return -1;
}
break;
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("qemu doesn't support taking snapshots of "
"PMSUSPENDED guests"));
- return NULL;
+ return -1;
/* invalid states */
case VIR_DOMAIN_SNAPSHOT_NOSTATE:
case VIR_DOMAIN_SNAPSHOT_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state %s"),
virDomainSnapshotStateTypeToString(state));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+virDomainSnapshotPtr
+qemuSnapshotCreateXML(virDomainPtr domain,
+ virDomainObj *vm,
+ const char *xmlDesc,
+ unsigned int flags)
+{
+ virQEMUDriver *driver = domain->conn->privateData;
+ g_autofree char *xml = NULL;
+ virDomainMomentObj *snap = NULL;
+ virDomainSnapshotPtr snapshot = NULL;
+ virDomainMomentObj *current = NULL;
+ bool update_current = true;
+ bool redefine = flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE;
+ int align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL;
+ bool align_match = true;
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+ qemuDomainObjPrivate *priv = vm->privateData;
+ g_autoptr(virDomainSnapshotDef) def = NULL;
+
+ virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
+ VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
+ VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA |
+ VIR_DOMAIN_SNAPSHOT_CREATE_HALT |
+ VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY |
+ VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT |
+ VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE |
+ VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC |
+ VIR_DOMAIN_SNAPSHOT_CREATE_LIVE |
+ VIR_DOMAIN_SNAPSHOT_CREATE_VALIDATE, NULL);
+
+ VIR_REQUIRE_FLAG_RET(VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE,
+ VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY,
+ NULL);
+ VIR_EXCLUSIVE_FLAGS_RET(VIR_DOMAIN_SNAPSHOT_CREATE_LIVE,
+ VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE,
+ NULL);
+
+ if ((redefine && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT)) ||
+ (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA))
+ update_current = false;
+
+ if (qemuDomainSupportsCheckpointsBlockjobs(vm) < 0)
+ return NULL;
+
+ if (!vm->persistent && (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("cannot halt after transient domain snapshot"));
return NULL;
}
+ if (!(def = qemuSnapshotCreateXMLParse(vm, driver, xmlDesc, flags)))
+ return NULL;
+
+ if (qemuSnapshotCreateXMLValidateDef(vm, def, flags) < 0)
+ return NULL;
+
/* We are going to modify the domain below. Internal snapshots would use
* a regular job, so we need to set the job mask to disallow query as
* 'savevm' blocks the monitor. External snapshot will then modify the