Implement folowing API calls from CH monitor
* vmm.snapshot -> to save a domain
* vmm.restore -> to restore saved domain
Signed-off-by: Purna Pavan Chandra Aekkaladevi <paekkaladevi(a)linux.microsoft.com>
---
src/ch/ch_monitor.c | 87 +++++++++++++++++++++++++++++++++++++++++++++
src/ch/ch_monitor.h | 4 +++
2 files changed, 91 insertions(+)
diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c
index fefbf7e67a..facbff002e 100644
--- a/src/ch/ch_monitor.c
+++ b/src/ch/ch_monitor.c
@@ -457,6 +457,22 @@ virCHMonitorBuildVMJson(virCHDriver *driver, virDomainDef *vmdef,
return 0;
}
+static int
+virCHMonitorBuildKeyValueStringJson(char **jsonstr,
+ const char *key,
+ const char *value)
+{
+ g_autoptr(virJSONValue) content = virJSONValueNewObject();
+
+ if (virJSONValueObjectAppendString(content, key, value) < 0)
+ return -1;
+
+ if (!(*jsonstr = virJSONValueToString(content, false)))
+ return -1;
+
+ return 0;
+}
+
static int
chMonitorCreateSocket(const char *socket_path)
{
@@ -896,6 +912,77 @@ virCHMonitorResumeVM(virCHMonitor *mon)
return virCHMonitorPutNoContent(mon, URL_VM_RESUME);
}
+static int
+virCHMonitorSaveRestoreVM(virCHMonitor *mon, const char *path, bool save)
+{
+ g_autofree char *url = NULL;
+ int responseCode = 0;
+ int ret = -1;
+ g_autofree char *payload = NULL;
+ g_autofree char *path_url = NULL;
+ struct curl_slist *headers = NULL;
+ struct curl_data data = {0};
+
+ if (save)
+ url = g_strdup_printf("%s/%s", URL_ROOT, URL_VM_SAVE);
+ else
+ url = g_strdup_printf("%s/%s", URL_ROOT, URL_VM_RESTORE);
+
+ headers = curl_slist_append(headers, "Accept: application/json");
+ headers = curl_slist_append(headers, "Content-Type: application/json");
+
+ path_url = g_strdup_printf("file://%s", path);
+ if (save) {
+ if (virCHMonitorBuildKeyValueStringJson(&payload,
"destination_url", path_url) != 0)
+ return -1;
+ } else {
+ if (virCHMonitorBuildKeyValueStringJson(&payload, "source_url",
path_url) != 0)
+ return -1;
+ }
+
+ VIR_WITH_OBJECT_LOCK_GUARD(mon) {
+ /* reset all options of a libcurl session handle at first */
+ curl_easy_reset(mon->handle);
+
+ curl_easy_setopt(mon->handle, CURLOPT_UNIX_SOCKET_PATH, mon->socketpath);
+ curl_easy_setopt(mon->handle, CURLOPT_URL, url);
+ curl_easy_setopt(mon->handle, CURLOPT_CUSTOMREQUEST, "PUT");
+ curl_easy_setopt(mon->handle, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(mon->handle, CURLOPT_POSTFIELDS, payload);
+ curl_easy_setopt(mon->handle, CURLOPT_WRITEFUNCTION, curl_callback);
+ curl_easy_setopt(mon->handle, CURLOPT_WRITEDATA, (void *)&data);
+
+ responseCode = virCHMonitorCurlPerform(mon->handle);
+ }
+
+ if (responseCode == 200 || responseCode == 204) {
+ ret = 0;
+ } else {
+ data.content = g_realloc(data.content, data.size + 1);
+ data.content[data.size] = 0;
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ data.content);
+ g_free(data.content);
+ }
+
+ /* reset the libcurl handle to avoid leaking a stack pointer to data */
+ curl_easy_reset(mon->handle);
+ curl_slist_free_all(headers);
+ return ret;
+}
+
+int
+virCHMonitorSaveVM(virCHMonitor *mon, const char *to)
+{
+ return virCHMonitorSaveRestoreVM(mon, to, true);
+}
+
+int
+virCHMonitorRestoreVM(virCHMonitor *mon, const char *from)
+{
+ return virCHMonitorSaveRestoreVM(mon, from, false);
+}
+
/**
* virCHMonitorGetInfo:
* @mon: Pointer to the monitor
diff --git a/src/ch/ch_monitor.h b/src/ch/ch_monitor.h
index 47b4e7abbd..3e0befe5d0 100644
--- a/src/ch/ch_monitor.h
+++ b/src/ch/ch_monitor.h
@@ -37,6 +37,8 @@
#define URL_VM_Suspend "vm.pause"
#define URL_VM_RESUME "vm.resume"
#define URL_VM_INFO "vm.info"
+#define URL_VM_SAVE "vm.snapshot"
+#define URL_VM_RESTORE "vm.restore"
#define VIRCH_THREAD_NAME_LEN 16
@@ -110,6 +112,8 @@ int virCHMonitorShutdownVM(virCHMonitor *mon);
int virCHMonitorRebootVM(virCHMonitor *mon);
int virCHMonitorSuspendVM(virCHMonitor *mon);
int virCHMonitorResumeVM(virCHMonitor *mon);
+int virCHMonitorSaveVM(virCHMonitor *mon, const char *to);
+int virCHMonitorRestoreVM(virCHMonitor *mon, const char *from);
int virCHMonitorGetInfo(virCHMonitor *mon, virJSONValue **info);
void virCHMonitorCPUInfoFree(virCHMonitorCPUInfo *cpus);
--
2.34.1