]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
ch: use monitor socket fd to send restore request
authorPurna Pavan Chandra <paekkaladevi@linux.microsoft.com>
Mon, 5 Aug 2024 14:40:57 +0000 (14:40 +0000)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 9 Aug 2024 13:03:07 +0000 (15:03 +0200)
Instead of curl, use low-level socket connections to make restore api
request to CH. This will enable passing new net FDs to CH while
restoring domains with network configuration.

Signed-off-by: Purna Pavan Chandra <paekkaladevi@linux.microsoft.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/ch/ch_monitor.c
src/ch/ch_monitor.h
src/ch/ch_process.c

index 619a417d61fce66650ec30c528e68032d20c457a..e76277855e9976719bcd4825aaea6d008a93091b 100644 (file)
@@ -993,9 +993,19 @@ virCHMonitorSaveVM(virCHMonitor *mon, const char *to)
 }
 
 int
-virCHMonitorRestoreVM(virCHMonitor *mon, const char *from)
+virCHMonitorBuildRestoreJson(const char *from,
+                             char **jsonstr)
 {
-    return virCHMonitorSaveRestoreVM(mon, from, false);
+    g_autoptr(virJSONValue) restore_json = virJSONValueNewObject();
+
+    g_autofree char *path_url = g_strdup_printf("file://%s", from);
+    if (virJSONValueObjectAppendString(restore_json, "source_url", path_url))
+        return -1;
+
+    if (!(*jsonstr = virJSONValueToString(restore_json, false)))
+        return -1;
+
+    return 0;
 }
 
 /**
index b20f28c3d7e5e6ab2b9b5f533352d683074dcb35..11bac0c2327e4ff7b5b67ceaf0718742dc1d2758 100644 (file)
@@ -115,7 +115,6 @@ 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);
@@ -130,3 +129,5 @@ int
 virCHMonitorBuildNetJson(virDomainNetDef *netdef,
                          int netindex,
                          char **jsonstr);
+int virCHMonitorBuildRestoreJson(const char *from,
+                                 char **jsonstr);
index a0a1770139b37e3cd41f2196b4b42f8a6e9a792f..c1acea66d17f1c1d4159785b81234385496b495e 100644 (file)
@@ -913,6 +913,12 @@ virCHProcessStartRestore(virCHDriver *driver, virDomainObj *vm, const char *from
 {
     virCHDomainObjPrivate *priv = vm->privateData;
     g_autoptr(virCHDriverConfig) cfg = virCHDriverGetConfig(priv->driver);
+    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+    g_auto(virBuffer) http_headers = VIR_BUFFER_INITIALIZER;
+    g_autofree char *payload = NULL;
+    g_autofree char *response = NULL;
+    VIR_AUTOCLOSE mon_sockfd = -1;
+    size_t payload_len;
 
     if (!priv->monitor) {
         /* Get the first monitor connection if not already */
@@ -927,12 +933,6 @@ virCHProcessStartRestore(virCHDriver *driver, virDomainObj *vm, const char *from
     vm->def->id = vm->pid;
     priv->machineName = virCHDomainGetMachineName(vm);
 
-    if (virCHMonitorRestoreVM(priv->monitor, from) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("failed to restore domain"));
-        return -1;
-    }
-
     /* Pass 0, NULL as restore only works without networking support */
     if (virDomainCgroupSetupCgroup("ch", vm,
                                    0, NULL, /* nnicindexes, nicindexes */
@@ -943,6 +943,34 @@ virCHProcessStartRestore(virCHDriver *driver, virDomainObj *vm, const char *from
                                    priv->machineName) < 0)
         return -1;
 
+    if (virCHMonitorBuildRestoreJson(from, &payload) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("failed to restore domain"));
+        return -1;
+    }
+
+    virBufferAddLit(&http_headers, "PUT /api/v1/vm.restore HTTP/1.1\r\n");
+    virBufferAddLit(&http_headers, "Host: localhost\r\n");
+    virBufferAddLit(&http_headers, "Content-Type: application/json\r\n");
+    virBufferAsprintf(&buf, "%s", virBufferCurrentContent(&http_headers));
+    virBufferAsprintf(&buf, "Content-Length: %ld\r\n\r\n", strlen(payload));
+    virBufferAsprintf(&buf, "%s", payload);
+    payload_len = virBufferUse(&buf);
+    payload = virBufferContentAndReset(&buf);
+
+    if ((mon_sockfd = chMonitorSocketConnect(priv->monitor)) < 0)
+        return -1;
+
+    if (virSocketSendMsgWithFDs(mon_sockfd, payload, payload_len, NULL, 0) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("Failed to send restore request to CH"));
+        return -1;
+    }
+
+    /* Restore is a synchronous operation in CH. so, pass false to wait until there's a response */
+    if (chSocketProcessHttpResponse(mon_sockfd, false) < 0)
+        return -1;
+
     if (virCHProcessSetup(vm) < 0)
         return -1;