]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: expose qemu 1.3 add-fd monitor command
authorEric Blake <eblake@redhat.com>
Thu, 31 Jan 2013 00:18:44 +0000 (17:18 -0700)
committerEric Blake <eblake@redhat.com>
Thu, 31 Jan 2013 17:23:28 +0000 (10:23 -0700)
Add entry points for calling the qemu 'add-fd' and 'remove-fd'
monitor commands.  There is no entry point for 'query-fdsets';
the assumption is that a developer can use
 virsh qemu-monitor-command domain '{"execute":"query-fdsets"}'
when debugging issues, and that meanwhile, libvirt is responsible
enough to remember what fds it associated with what fdsets.
Likewise, on the 'add-fd' command, it is assumed that libvirt
will always pass a set id, rather than letting qemu autogenerate
the next available id number.

* src/qemu/qemu_monitor.c (qemuMonitorAddFd, qemuMonitorRemoveFd):
New functions.
* src/qemu/qemu_monitor.h (qemuMonitorAddFd, qemuMonitorRemoveFd):
New prototypes.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONAddFd)
(qemuMonitorJSONRemoveFd): New functions.
* src/qemu/qemu_monitor_json.h (qemuMonitorJSONAddFd)
(qemuMonitorJSONRemoveFd): New prototypes.

src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h

index a160c9a44bdb8d2faccd78bb3673efc6c3a3cf1c..3f1aed85957410f833a424e297a8f51c6777a60e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * qemu_monitor.c: interaction with QEMU monitor console
  *
- * Copyright (C) 2006-2012 Red Hat, Inc.
+ * Copyright (C) 2006-2013 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -2353,6 +2353,78 @@ cleanup:
 }
 
 
+/* Add the open file descriptor FD into the non-negative set FDSET.
+ * If NAME is present, it will be passed along for logging purposes.
+ * Returns the counterpart fd that qemu received, or -1 on error.  */
+int
+qemuMonitorAddFd(qemuMonitorPtr mon, int fdset, int fd, const char *name)
+{
+    int ret = -1;
+    VIR_DEBUG("mon=%p, fdset=%d, fd=%d, name=%s",
+              mon, fdset, fd, NULLSTR(name));
+
+    if (!mon) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("monitor must not be NULL"));
+        return -1;
+    }
+
+    if (fd < 0 || fdset < 0) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("fd and fdset must be valid"));
+        return -1;
+    }
+
+    if (!mon->hasSendFD) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("qemu is not using a unix socket monitor, "
+                         "cannot send fd %s"), NULLSTR(name));
+        return -1;
+    }
+
+    if (mon->json)
+        ret = qemuMonitorJSONAddFd(mon, fdset, fd, name);
+    else
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("add fd requires JSON monitor"));
+    return ret;
+}
+
+
+/* Remove one of qemu's fds from the given FDSET, or if FD is
+ * negative, remove the entire set.  Preserve any previous error on
+ * entry.  Returns 0 on success, -1 on error.  */
+int
+qemuMonitorRemoveFd(qemuMonitorPtr mon, int fdset, int fd)
+{
+    int ret = -1;
+    virErrorPtr error;
+
+    VIR_DEBUG("mon=%p, fdset=%d, fd=%d", mon, fdset, fd);
+
+    error = virSaveLastError();
+
+    if (!mon) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("monitor must not be NULL"));
+        goto cleanup;
+    }
+
+    if (mon->json)
+        ret = qemuMonitorJSONRemoveFd(mon, fdset, fd);
+    else
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("remove fd requires JSON monitor"));
+
+cleanup:
+    if (error) {
+        virSetError(error);
+        virFreeError(error);
+    }
+    return ret;
+}
+
+
 int qemuMonitorAddHostNetwork(qemuMonitorPtr mon,
                               const char *netstr,
                               int tapfd, const char *tapfd_name,
index 7953b8201f0c2f2d668ed8634e9b642faa3d784a..ac77158ecca737df859dc4bb2dcea99304c5bc96 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * qemu_monitor.h: interaction with QEMU monitor console
  *
- * Copyright (C) 2006-2012 Red Hat, Inc.
+ * Copyright (C) 2006-2013 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -439,13 +439,14 @@ int qemuMonitorRemovePCIDevice(qemuMonitorPtr mon,
 int qemuMonitorSendFileHandle(qemuMonitorPtr mon,
                               const char *fdname,
                               int fd);
+int qemuMonitorAddFd(qemuMonitorPtr mon, int fdset, int fd, const char *name);
 
-/* The function preserves previous error and only sets it's own error if no
- * error was set before.
+/* These two functions preserve previous error and only set their own
+ * error if no error was set before.
  */
 int qemuMonitorCloseFileHandle(qemuMonitorPtr mon,
                                const char *fdname);
-
+int qemuMonitorRemoveFd(qemuMonitorPtr mon, int fdset, int fd);
 
 /* XXX do we really want to hardcode 'netstr' as the
  * sendable item here
index 2d2a5d045054debe4ddf854f443498862476e5a2..686cee9adfa33bdeb30f92bf95d67bea698b4cc7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * qemu_monitor_json.c: interaction with QEMU monitor console
  *
- * Copyright (C) 2006-2012 Red Hat, Inc.
+ * Copyright (C) 2006-2013 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -2646,6 +2646,77 @@ int qemuMonitorJSONCloseFileHandle(qemuMonitorPtr mon,
 }
 
 
+int
+qemuMonitorJSONAddFd(qemuMonitorPtr mon, int fdset, int fd, const char *name)
+{
+    int ret;
+    virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("add-fd",
+                                                     "i:fdset-id", fdset,
+                                                     name ? "s:opaque" : NULL,
+                                                     name, NULL);
+    virJSONValuePtr reply = NULL;
+    if (!cmd)
+        return -1;
+
+    ret = qemuMonitorJSONCommandWithFd(mon, cmd, fd, &reply);
+
+    if (ret == 0)
+        ret = qemuMonitorJSONCheckError(cmd, reply);
+    if (ret == 0) {
+        virJSONValuePtr data = virJSONValueObjectGet(reply, "return");
+
+        if (!data || data->type != VIR_JSON_TYPE_OBJECT) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("missing return information"));
+            goto error;
+        }
+        data = virJSONValueObjectGet(data, "fd");
+        if (!data || data->type != VIR_JSON_TYPE_NUMBER ||
+            virJSONValueGetNumberInt(data, &ret) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("incomplete return information"));
+            goto error;
+        }
+    }
+
+cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+
+error:
+    /* Best effort cleanup - kill the entire fdset (even if it has
+     * earlier successful fd registrations), since we don't know which
+     * fd qemu got, and don't want to leave the fd leaked in qemu.  */
+    qemuMonitorJSONRemoveFd(mon, fdset, -1);
+    ret = -1;
+    goto cleanup;
+}
+
+
+int
+qemuMonitorJSONRemoveFd(qemuMonitorPtr mon, int fdset, int fd)
+{
+    int ret;
+    virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("remove-fd",
+                                                     "i:fdset-id", fdset,
+                                                     fd < 0 ? NULL : "i:fd",
+                                                     fd, NULL);
+    virJSONValuePtr reply = NULL;
+    if (!cmd)
+        return -1;
+
+    ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+    if (ret == 0)
+        ret = qemuMonitorJSONCheckError(cmd, reply);
+
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
+
 int qemuMonitorJSONAddNetdev(qemuMonitorPtr mon,
                              const char *netdevstr)
 {
index 2b09a8f3403b6d501ebe7a09012ad12884f21f6f..925d937cbc6eab2077eb62bf588de27b26ec708e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * qemu_monitor_json.h: interaction with QEMU monitor console
  *
- * Copyright (C) 2006-2009, 2011-2012 Red Hat, Inc.
+ * Copyright (C) 2006-2009, 2011-2013 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -175,9 +175,12 @@ int qemuMonitorJSONRemovePCIDevice(qemuMonitorPtr mon,
 int qemuMonitorJSONSendFileHandle(qemuMonitorPtr mon,
                                   const char *fdname,
                                   int fd);
+int qemuMonitorJSONAddFd(qemuMonitorPtr mon, int fdset, int fd,
+                         const char *name);
 
 int qemuMonitorJSONCloseFileHandle(qemuMonitorPtr mon,
                                    const char *fdname);
+int qemuMonitorJSONRemoveFd(qemuMonitorPtr mon, int fdset, int fd);
 
 int qemuMonitorJSONAddNetdev(qemuMonitorPtr mon,
                              const char *netdevstr);