mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
ch_driver: Support Save, Restore VM actions from monitor
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@linux.microsoft.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
aead1e49da
commit
6ea6208f35
@ -457,6 +457,22 @@ virCHMonitorBuildVMJson(virCHDriver *driver, virDomainDef *vmdef,
|
|||||||
return 0;
|
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
|
static int
|
||||||
chMonitorCreateSocket(const char *socket_path)
|
chMonitorCreateSocket(const char *socket_path)
|
||||||
{
|
{
|
||||||
@ -896,6 +912,77 @@ virCHMonitorResumeVM(virCHMonitor *mon)
|
|||||||
return virCHMonitorPutNoContent(mon, URL_VM_RESUME);
|
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:
|
* virCHMonitorGetInfo:
|
||||||
* @mon: Pointer to the monitor
|
* @mon: Pointer to the monitor
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
#define URL_VM_Suspend "vm.pause"
|
#define URL_VM_Suspend "vm.pause"
|
||||||
#define URL_VM_RESUME "vm.resume"
|
#define URL_VM_RESUME "vm.resume"
|
||||||
#define URL_VM_INFO "vm.info"
|
#define URL_VM_INFO "vm.info"
|
||||||
|
#define URL_VM_SAVE "vm.snapshot"
|
||||||
|
#define URL_VM_RESTORE "vm.restore"
|
||||||
|
|
||||||
#define VIRCH_THREAD_NAME_LEN 16
|
#define VIRCH_THREAD_NAME_LEN 16
|
||||||
|
|
||||||
@ -110,6 +112,8 @@ int virCHMonitorShutdownVM(virCHMonitor *mon);
|
|||||||
int virCHMonitorRebootVM(virCHMonitor *mon);
|
int virCHMonitorRebootVM(virCHMonitor *mon);
|
||||||
int virCHMonitorSuspendVM(virCHMonitor *mon);
|
int virCHMonitorSuspendVM(virCHMonitor *mon);
|
||||||
int virCHMonitorResumeVM(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);
|
int virCHMonitorGetInfo(virCHMonitor *mon, virJSONValue **info);
|
||||||
|
|
||||||
void virCHMonitorCPUInfoFree(virCHMonitorCPUInfo *cpus);
|
void virCHMonitorCPUInfoFree(virCHMonitorCPUInfo *cpus);
|
||||||
|
Loading…
Reference in New Issue
Block a user