Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/qemu/qemu_snapshot.c | 140 +++++++++++++++++++++------------------
1 file changed, 77 insertions(+), 63 deletions(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 6ba3215ee3..5ebe959151 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -1555,6 +1555,82 @@ qemuSnapshotCreateXMLParse(virDomainObj *vm,
}
+static int
+qemuSnapshotCreateXMLValidateDef(virDomainObj *vm,
+ virDomainSnapshotDef *def,
+ unsigned int flags)
+{
+ bool redefine = flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE;
+ virDomainSnapshotState state;
+
+ /* reject snapshot names containing slashes or starting with dot as
+ * snapshot definitions are saved in files named by the snapshot name */
+ if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
+ if (strchr(def->parent.name, '/')) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("invalid snapshot name '%s': "
+ "name can't contain '/'"),
+ def->parent.name);
+ return -1;
+ }
+
+ if (def->parent.name[0] == '.') {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("invalid snapshot name '%s': "
+ "name can't start with '.'"),
+ def->parent.name);
+ return -1;
+ }
+ }
+
+ /* reject the VIR_DOMAIN_SNAPSHOT_CREATE_LIVE flag where not supported */
+ if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_LIVE &&
+ (!virDomainObjIsActive(vm) ||
+ def->memory != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL)) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("live snapshot creation is supported only "
+ "during full system snapshots"));
+ return -1;
+ }
+
+ /* allow snapshots only in certain states */
+ state = redefine ? def->state : vm->state.state;
+ switch (state) {
+ /* valid states */
+ case VIR_DOMAIN_SNAPSHOT_RUNNING:
+ case VIR_DOMAIN_SNAPSHOT_PAUSED:
+ case VIR_DOMAIN_SNAPSHOT_SHUTDOWN:
+ case VIR_DOMAIN_SNAPSHOT_SHUTOFF:
+ case VIR_DOMAIN_SNAPSHOT_CRASHED:
+ break;
+
+ case VIR_DOMAIN_SNAPSHOT_DISK_SNAPSHOT:
+ if (!redefine) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state
%s"),
+ virDomainSnapshotStateTypeToString(state));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_SNAPSHOT_PMSUSPENDED:
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("qemu doesn't support taking snapshots of "
+ "PMSUSPENDED guests"));
+ return -1;
+
+ /* invalid states */
+ case VIR_DOMAIN_SNAPSHOT_NOSTATE:
+ case VIR_DOMAIN_SNAPSHOT_BLOCKED: /* invalid state, unused in qemu */
+ 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,
@@ -1572,7 +1648,6 @@ qemuSnapshotCreateXML(virDomainPtr domain,
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 |
@@ -1609,69 +1684,8 @@ qemuSnapshotCreateXML(virDomainPtr domain,
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 */
- if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
- if (strchr(def->parent.name, '/')) {
- virReportError(VIR_ERR_XML_DETAIL,
- _("invalid snapshot name '%s': "
- "name can't contain '/'"),
- def->parent.name);
- return NULL;
- }
-
- if (def->parent.name[0] == '.') {
- virReportError(VIR_ERR_XML_DETAIL,
- _("invalid snapshot name '%s': "
- "name can't start with '.'"),
- def->parent.name);
- return NULL;
- }
- }
-
- /* reject the VIR_DOMAIN_SNAPSHOT_CREATE_LIVE flag where not supported */
- if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_LIVE &&
- (!virDomainObjIsActive(vm) ||
- def->memory != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL)) {
- virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
- _("live snapshot creation is supported only "
- "during full system snapshots"));
+ if (qemuSnapshotCreateXMLValidateDef(vm, def, flags) < 0)
return NULL;
- }
-
- /* allow snapshots only in certain states */
- state = redefine ? def->state : vm->state.state;
- switch (state) {
- /* valid states */
- case VIR_DOMAIN_SNAPSHOT_RUNNING:
- case VIR_DOMAIN_SNAPSHOT_PAUSED:
- case VIR_DOMAIN_SNAPSHOT_SHUTDOWN:
- case VIR_DOMAIN_SNAPSHOT_SHUTOFF:
- case VIR_DOMAIN_SNAPSHOT_CRASHED:
- break;
-
- case VIR_DOMAIN_SNAPSHOT_DISK_SNAPSHOT:
- if (!redefine) {
- virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state
%s"),
- virDomainSnapshotStateTypeToString(state));
- return NULL;
- }
- break;
-
- case VIR_DOMAIN_SNAPSHOT_PMSUSPENDED:
- virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
- _("qemu doesn't support taking snapshots of "
- "PMSUSPENDED guests"));
- return NULL;
-
- /* invalid states */
- case VIR_DOMAIN_SNAPSHOT_NOSTATE:
- case VIR_DOMAIN_SNAPSHOT_BLOCKED: /* invalid state, unused in qemu */
- case VIR_DOMAIN_SNAPSHOT_LAST:
- virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state %s"),
- virDomainSnapshotStateTypeToString(state));
- 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
--
2.31.1