]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Implement qemuDomainQemuMonitorCommandWithFiles
authorPeter Krempa <pkrempa@redhat.com>
Fri, 28 Jan 2022 13:39:24 +0000 (14:39 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 1 Mar 2022 12:29:49 +0000 (13:29 +0100)
Add support for sending one FD from the client along with a monitor
command so that it's possible to use 'getfd' and 'add-fd' to use FDs
passed from the client with other QMP commands.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_driver.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h
src/qemu/qemu_monitor_text.c

index d4517ba22d861ca7cb7e6da4ffd2ca726b037ebb..bcd9bdb4368231806e01dc8374d146ecd81bd517 100644 (file)
@@ -13920,21 +13920,44 @@ qemuDomainBackupGetXMLDesc(virDomainPtr domain,
 }
 
 
-static int qemuDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
-                                        char **result, unsigned int flags)
+static int
+qemuDomainQemuMonitorCommandWithFiles(virDomainPtr domain,
+                                      const char *cmd,
+                                      unsigned int ninfds,
+                                      int *infds,
+                                      unsigned int *noutfds,
+                                      int **outfds,
+                                      char **result,
+                                      unsigned int flags)
 {
     virQEMUDriver *driver = domain->conn->privateData;
     virDomainObj *vm = NULL;
     int ret = -1;
     qemuDomainObjPrivate *priv;
     bool hmp;
+    int fd = -1;
 
     virCheckFlags(VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP, -1);
 
+    /* currently we don't pass back any fds */
+    if (outfds)
+        *outfds = NULL;
+    if (noutfds)
+        *noutfds = 0;
+
+    if (ninfds > 1) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("at most 1 fd can be passed to qemu along with a command"));
+        return -1;
+    }
+
+    if (ninfds == 1)
+        fd = infds[0];
+
     if (!(vm = qemuDomainObjFromDomain(domain)))
         goto cleanup;
 
-    if (virDomainQemuMonitorCommandEnsureACL(domain->conn, vm->def) < 0)
+    if (virDomainQemuMonitorCommandWithFilesEnsureACL(domain->conn, vm->def) < 0)
         goto cleanup;
 
     if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
@@ -13950,7 +13973,7 @@ static int qemuDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
     hmp = !!(flags & VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP);
 
     qemuDomainObjEnterMonitor(driver, vm);
-    ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result, hmp);
+    ret = qemuMonitorArbitraryCommand(priv->mon, cmd, fd, result, hmp);
     qemuDomainObjExitMonitor(driver, vm);
 
  endjob:
@@ -13962,6 +13985,16 @@ static int qemuDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
 }
 
 
+static int
+qemuDomainQemuMonitorCommand(virDomainPtr domain,
+                             const char *cmd,
+                             char **result,
+                             unsigned int flags)
+{
+    return qemuDomainQemuMonitorCommandWithFiles(domain, cmd, 0, NULL, NULL, NULL, result, flags);
+}
+
+
 static int
 qemuDomainOpenConsole(virDomainPtr dom,
                       const char *dev_name,
@@ -20923,6 +20956,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainRevertToSnapshot = qemuDomainRevertToSnapshot, /* 0.8.0 */
     .domainSnapshotDelete = qemuDomainSnapshotDelete, /* 0.8.0 */
     .domainQemuMonitorCommand = qemuDomainQemuMonitorCommand, /* 0.8.3 */
+    .domainQemuMonitorCommandWithFiles = qemuDomainQemuMonitorCommandWithFiles, /* 8.2.0 */
     .domainQemuAttach = NULL, /* 0.9.4 - 5.5.0 */
     .domainQemuAgentCommand = qemuDomainQemuAgentCommand, /* 0.10.0 */
     .connectDomainQemuMonitorEventRegister = qemuConnectDomainQemuMonitorEventRegister, /* 1.2.3 */
index 8fc2a49abf60f98941dfcc30f30690be71c10099..316cff5b9b6b8cfc4f13de9fdeb3be4ed55a6ee9 100644 (file)
@@ -3074,17 +3074,18 @@ qemuMonitorDrivePivot(qemuMonitor *mon,
 int
 qemuMonitorArbitraryCommand(qemuMonitor *mon,
                             const char *cmd,
+                            int fd,
                             char **reply,
                             bool hmp)
 {
-    VIR_DEBUG("cmd=%s, reply=%p, hmp=%d", cmd, reply, hmp);
+    VIR_DEBUG("cmd=%s, fd=%d, reply=%p, hmp=%d", cmd, fd, reply, hmp);
 
     QEMU_CHECK_MONITOR(mon);
 
     if (hmp)
-        return qemuMonitorJSONHumanCommand(mon, cmd, reply);
+        return qemuMonitorJSONHumanCommand(mon, cmd, fd, reply);
     else
-        return qemuMonitorJSONArbitraryCommand(mon, cmd, reply);
+        return qemuMonitorJSONArbitraryCommand(mon, cmd, fd, reply);
 }
 
 
index 18da2ff0e4c78573f8deffcd963c5854a78ca8b0..5c2a749282f5598cb5bcdd1e2fffe138740a48e0 100644 (file)
@@ -1088,6 +1088,7 @@ char *qemuMonitorDiskNameLookup(qemuMonitor *mon,
 
 int qemuMonitorArbitraryCommand(qemuMonitor *mon,
                                 const char *cmd,
+                                int fd,
                                 char **reply,
                                 bool hmp);
 
index 4d339f29b85d9bd89b717dd41ec6528f036940df..27c5e1c9922aa34cb0f1a26cb32811356bf0b7b4 100644 (file)
@@ -1438,6 +1438,7 @@ qemuMonitorJSONHandleGuestCrashloaded(qemuMonitor *mon,
 int
 qemuMonitorJSONHumanCommand(qemuMonitor *mon,
                             const char *cmd_str,
+                            int fd,
                             char **reply_str)
 {
     g_autoptr(virJSONValue) cmd = NULL;
@@ -1449,7 +1450,7 @@ qemuMonitorJSONHumanCommand(qemuMonitor *mon,
                                      "s:command-line", cmd_str,
                                      NULL);
 
-    if (!cmd || qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+    if (!cmd || qemuMonitorJSONCommandWithFd(mon, cmd, fd, &reply) < 0)
         return -1;
 
     if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
@@ -4471,6 +4472,7 @@ qemuMonitorJSONDiskNameLookup(qemuMonitor *mon,
 
 int qemuMonitorJSONArbitraryCommand(qemuMonitor *mon,
                                     const char *cmd_str,
+                                    int fd,
                                     char **reply_str)
 {
     g_autoptr(virJSONValue) cmd = NULL;
@@ -4479,7 +4481,7 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitor *mon,
     if (!(cmd = virJSONValueFromString(cmd_str)))
         return -1;
 
-    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+    if (qemuMonitorJSONCommandWithFd(mon, cmd, fd, &reply) < 0)
         return -1;
 
     if (!(*reply_str = virJSONValueToString(reply, false)))
index 8e34f3baa4bd1d66ecce99c4190b0461a3c351f3..982fbad44e1950d80f15e8e9e79d5abf6be44d1f 100644 (file)
@@ -43,6 +43,7 @@ qemuMonitorJSONIOProcess(qemuMonitor *mon,
 int
 qemuMonitorJSONHumanCommand(qemuMonitor *mon,
                             const char *cmd,
+                            int fd,
                             char **reply);
 
 int
@@ -369,6 +370,7 @@ qemuMonitorJSONDiskNameLookup(qemuMonitor *mon,
 int
 qemuMonitorJSONArbitraryCommand(qemuMonitor *mon,
                                 const char *cmd_str,
+                                int fd,
                                 char **reply_str);
 
 int
index 0ca7f5a470b26efbf82807339f9de6a854a574e4..86af1e49754a994fc4e446c58b112bd4e3a92a11 100644 (file)
@@ -43,7 +43,7 @@ int qemuMonitorTextAddDrive(qemuMonitor *mon,
      * address required when attaching drives to a controller */
     cmd = g_strdup_printf("drive_add dummy %s", drivestr);
 
-    if (qemuMonitorJSONHumanCommand(mon, cmd, &reply) < 0)
+    if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply) < 0)
         return -1;
 
     if (strstr(reply, "unknown command:")) {
@@ -93,7 +93,7 @@ int qemuMonitorTextDriveDel(qemuMonitor *mon,
 
     cmd = g_strdup_printf("drive_del %s", drivestr);
 
-    if (qemuMonitorJSONHumanCommand(mon, cmd, &reply) < 0)
+    if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply) < 0)
         return -1;
 
     if (strstr(reply, "unknown command:")) {
@@ -124,7 +124,7 @@ qemuMonitorTextCreateSnapshot(qemuMonitor *mon,
 
     cmd = g_strdup_printf("savevm \"%s\"", name);
 
-    if (qemuMonitorJSONHumanCommand(mon, cmd, &reply))
+    if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply))
         return -1;
 
     if (strstr(reply, "Error while creating snapshot") ||
@@ -150,7 +150,7 @@ int qemuMonitorTextDeleteSnapshot(qemuMonitor *mon, const char *name)
     g_autofree char *reply = NULL;
 
     cmd = g_strdup_printf("delvm \"%s\"", name);
-    if (qemuMonitorJSONHumanCommand(mon, cmd, &reply))
+    if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply))
         return -1;
 
     if (strstr(reply, "No block device supports snapshots")) {