提交 462c74c3 编写于 作者: C Chris Lalancette

Snapshot QEMU driver.

Signed-off-by: NChris Lalancette <clalance@redhat.com>
上级 32c3c1f0
...@@ -3373,7 +3373,9 @@ int qemudBuildCommandLine(virConnectPtr conn, ...@@ -3373,7 +3373,9 @@ int qemudBuildCommandLine(virConnectPtr conn,
const char ***retenv, const char ***retenv,
int **tapfds, int **tapfds,
int *ntapfds, int *ntapfds,
const char *migrateFrom) { const char *migrateFrom,
virDomainSnapshotObjPtr current_snapshot)
{
int i; int i;
char memory[50]; char memory[50];
char boot[VIR_DOMAIN_BOOT_LAST]; char boot[VIR_DOMAIN_BOOT_LAST];
...@@ -4578,6 +4580,11 @@ int qemudBuildCommandLine(virConnectPtr conn, ...@@ -4578,6 +4580,11 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ARG_LIT("virtio"); ADD_ARG_LIT("virtio");
} }
if (current_snapshot && current_snapshot->def->active) {
ADD_ARG_LIT("-loadvm");
ADD_ARG_LIT(current_snapshot->def->name);
}
ADD_ARG(NULL); ADD_ARG(NULL);
ADD_ENV(NULL); ADD_ENV(NULL);
......
...@@ -121,6 +121,7 @@ struct qemud_driver { ...@@ -121,6 +121,7 @@ struct qemud_driver {
char *libDir; char *libDir;
char *cacheDir; char *cacheDir;
char *saveDir; char *saveDir;
char *snapshotDir;
unsigned int vncTLS : 1; unsigned int vncTLS : 1;
unsigned int vncTLSx509verify : 1; unsigned int vncTLSx509verify : 1;
unsigned int vncSASL : 1; unsigned int vncSASL : 1;
...@@ -199,7 +200,8 @@ int qemudBuildCommandLine (virConnectPtr conn, ...@@ -199,7 +200,8 @@ int qemudBuildCommandLine (virConnectPtr conn,
const char ***retenv, const char ***retenv,
int **tapfds, int **tapfds,
int *ntapfds, int *ntapfds,
const char *migrateFrom) const char *migrateFrom,
virDomainSnapshotObjPtr current_snapshot)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);
/* With vlan == -1, use netdev syntax, else old hostnet */ /* With vlan == -1, use netdev syntax, else old hostnet */
......
此差异已折叠。
...@@ -1491,3 +1491,42 @@ int qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon, ...@@ -1491,3 +1491,42 @@ int qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon,
ret = qemuMonitorTextSetDrivePassphrase(mon, alias, passphrase); ret = qemuMonitorTextSetDrivePassphrase(mon, alias, passphrase);
return ret; return ret;
} }
int qemuMonitorCreateSnapshot(qemuMonitorPtr mon, const char *name)
{
int ret;
DEBUG("mon=%p, name=%s",mon,name);
if (mon->json)
ret = qemuMonitorJSONCreateSnapshot(mon, name);
else
ret = qemuMonitorTextCreateSnapshot(mon, name);
return ret;
}
int qemuMonitorLoadSnapshot(qemuMonitorPtr mon, const char *name)
{
int ret;
DEBUG("mon=%p, name=%s",mon,name);
if (mon->json)
ret = qemuMonitorJSONLoadSnapshot(mon, name);
else
ret = qemuMonitorTextLoadSnapshot(mon, name);
return ret;
}
int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name)
{
int ret;
DEBUG("mon=%p, name=%s",mon,name);
if (mon->json)
ret = qemuMonitorJSONDeleteSnapshot(mon, name);
else
ret = qemuMonitorTextDeleteSnapshot(mon, name);
return ret;
}
...@@ -344,4 +344,8 @@ int qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon, ...@@ -344,4 +344,8 @@ int qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias, const char *alias,
const char *passphrase); const char *passphrase);
int qemuMonitorCreateSnapshot(qemuMonitorPtr mon, const char *name);
int qemuMonitorLoadSnapshot(qemuMonitorPtr mon, const char *name);
int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name);
#endif /* QEMU_MONITOR_H */ #endif /* QEMU_MONITOR_H */
...@@ -2156,3 +2156,69 @@ int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon, ...@@ -2156,3 +2156,69 @@ int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
virJSONValueFree(reply); virJSONValueFree(reply);
return ret; return ret;
} }
int qemuMonitorJSONCreateSnapshot(qemuMonitorPtr mon, const char *name)
{
int ret;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
cmd = qemuMonitorJSONMakeCommand("savevm",
"s:name", name,
NULL);
if (!cmd)
return -1;
ret = qemuMonitorJSONCommand(mon, cmd, &reply);
if (ret == 0)
ret = qemuMonitorJSONCheckError(cmd, reply);
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
}
int qemuMonitorJSONLoadSnapshot(qemuMonitorPtr mon, const char *name)
{
int ret;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
cmd = qemuMonitorJSONMakeCommand("loadvm",
"s:name", name,
NULL);
if (!cmd)
return -1;
ret = qemuMonitorJSONCommand(mon, cmd, &reply);
if (ret == 0)
ret = qemuMonitorJSONCheckError(cmd, reply);
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
}
int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name)
{
int ret;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
cmd = qemuMonitorJSONMakeCommand("delvm",
"s:name", name,
NULL);
if (!cmd)
return -1;
ret = qemuMonitorJSONCommand(mon, cmd, &reply);
if (ret == 0)
ret = qemuMonitorJSONCheckError(cmd, reply);
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
}
...@@ -175,4 +175,8 @@ int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon, ...@@ -175,4 +175,8 @@ int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias, const char *alias,
const char *passphrase); const char *passphrase);
int qemuMonitorJSONCreateSnapshot(qemuMonitorPtr mon, const char *name);
int qemuMonitorJSONLoadSnapshot(qemuMonitorPtr mon, const char *name);
int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name);
#endif /* QEMU_MONITOR_JSON_H */ #endif /* QEMU_MONITOR_JSON_H */
...@@ -2290,3 +2290,144 @@ cleanup: ...@@ -2290,3 +2290,144 @@ cleanup:
VIR_FREE(safe_str); VIR_FREE(safe_str);
return ret; return ret;
} }
int qemuMonitorTextCreateSnapshot(qemuMonitorPtr mon, const char *name)
{
char *cmd;
char *reply = NULL;
int ret = -1;
if (virAsprintf(&cmd, "savevm \"%s\"", name) < 0) {
virReportOOMError();
return -1;
}
if (qemuMonitorCommand(mon, cmd, &reply)) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
_("failed to take snapshot using command '%s'"), cmd);
goto cleanup;
}
if (strstr(reply, "Error while creating snapshot") != NULL) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
_("Failed to take snapshot: %s"), reply);
goto cleanup;
}
else if (strstr(reply, "No block device can accept snapshots") != NULL) {
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("this domain does not have a device to take snapshots"));
goto cleanup;
}
else if (strstr(reply, "Could not open VM state file") != NULL) {
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", reply);
goto cleanup;
}
else if (strstr(reply, "Error") != NULL
&& strstr(reply, "while writing VM") != NULL) {
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", reply);
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(cmd);
VIR_FREE(reply);
return ret;
}
int qemuMonitorTextLoadSnapshot(qemuMonitorPtr mon, const char *name)
{
char *cmd;
char *reply = NULL;
int ret = -1;
if (virAsprintf(&cmd, "loadvm \"%s\"", name) < 0) {
virReportOOMError();
return -1;
}
if (qemuMonitorCommand(mon, cmd, &reply)) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
_("failed to restore snapshot using command '%s'"),
cmd);
goto cleanup;
}
if (strstr(reply, "No block device supports snapshots") != NULL) {
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("this domain does not have a device to load snapshots"));
goto cleanup;
}
else if (strstr(reply, "Could not find snapshot") != NULL) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
_("the snapshot '%s' does not exist, and was not loaded"),
name);
goto cleanup;
}
else if (strstr(reply, "Snapshots not supported on device") != NULL) {
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", reply);
goto cleanup;
}
else if (strstr(reply, "Could not open VM state file") != NULL) {
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", reply);
goto cleanup;
}
else if (strstr(reply, "Error") != NULL
&& strstr(reply, "while loading VM state") != NULL) {
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", reply);
goto cleanup;
}
else if (strstr(reply, "Error") != NULL
&& strstr(reply, "while activating snapshot on") != NULL) {
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", reply);
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(cmd);
VIR_FREE(reply);
return ret;
}
int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name)
{
char *cmd;
char *reply = NULL;
int ret = -1;
if (virAsprintf(&cmd, "delvm \"%s\"", name) < 0) {
virReportOOMError();
return -1;
}
if (qemuMonitorCommand(mon, cmd, &reply)) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
_("failed to delete snapshot using command '%s'"),
cmd);
goto cleanup;
}
if (strstr(reply, "No block device supports snapshots") != NULL) {
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("this domain does not have a device to delete snapshots"));
goto cleanup;
}
else if (strstr(reply, "Snapshots not supported on device") != NULL) {
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", reply);
goto cleanup;
}
else if (strstr(reply, "Error") != NULL
&& strstr(reply, "while deleting snapshot") != NULL) {
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", reply);
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(cmd);
VIR_FREE(reply);
return ret;
}
...@@ -177,4 +177,8 @@ int qemuMonitorTextSetDrivePassphrase(qemuMonitorPtr mon, ...@@ -177,4 +177,8 @@ int qemuMonitorTextSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias, const char *alias,
const char *passphrase); const char *passphrase);
int qemuMonitorTextCreateSnapshot(qemuMonitorPtr mon, const char *name);
int qemuMonitorTextLoadSnapshot(qemuMonitorPtr mon, const char *name);
int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name);
#endif /* QEMU_MONITOR_TEXT_H */ #endif /* QEMU_MONITOR_TEXT_H */
...@@ -83,7 +83,7 @@ static int testCompareXMLToArgvFiles(const char *xml, ...@@ -83,7 +83,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
if (qemudBuildCommandLine(conn, &driver, if (qemudBuildCommandLine(conn, &driver,
vmdef, &monitor_chr, 0, flags, vmdef, &monitor_chr, 0, flags,
&argv, &qenv, &argv, &qenv,
NULL, NULL, migrateFrom) < 0) NULL, NULL, migrateFrom, NULL) < 0)
goto fail; goto fail;
len = 1; /* for trailing newline */ len = 1; /* for trailing newline */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册