This introduces virConnectAllowKeepAlive and virConnectStartKeepAlive
public APIs which can be used by a client connecting to remote server to
indicate support for keepalive protocol. Both APIs are handled directly
by remote driver and not transmitted over the wire to the server.
---
include/libvirt/libvirt.h.in | 5 ++
src/driver.h | 9 ++++
src/libvirt.c | 107 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt_internal.h | 10 +++-
src/libvirt_public.syms | 6 ++
5 files changed, 135 insertions(+), 2 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 39155a6..6f61cc0 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -3210,6 +3210,11 @@ typedef struct _virTypedParameter virMemoryParameter;
*/
typedef virMemoryParameter *virMemoryParameterPtr;
+int virConnectAllowKeepAlive(virConnectPtr conn);
+int virConnectStartKeepAlive(virConnectPtr conn,
+ int interval,
+ unsigned int count);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/driver.h b/src/driver.h
index 3792003..cd17d83 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -718,6 +718,13 @@ typedef int
(*virDrvDomainBlockPull)(virDomainPtr dom, const char *path,
unsigned long bandwidth, unsigned int flags);
+typedef int
+ (*virDrvAllowKeepAlive)(virConnectPtr conn);
+
+typedef int
+ (*virDrvStartKeepAlive)(virConnectPtr conn,
+ int interval,
+ unsigned int count);
/**
* _virDriver:
@@ -872,6 +879,8 @@ struct _virDriver {
virDrvDomainGetBlockJobInfo domainGetBlockJobInfo;
virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed;
virDrvDomainBlockPull domainBlockPull;
+ virDrvAllowKeepAlive allowKeepAlive;
+ virDrvStartKeepAlive startKeepAlive;
};
typedef int
diff --git a/src/libvirt.c b/src/libvirt.c
index 8f94b11..138f367 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -16590,3 +16590,110 @@ error:
virDispatchError(dom->conn);
return -1;
}
+
+/**
+ * virConnectAllowKeepAlive:
+ * @conn: pointer to a hypervisor connection
+ *
+ * Tell remote party we support keepalive messages so the it can use them and
+ * we will respond to them. To actually start sending keepalive messages to a
+ * client needs to call virConnectStartKeepAlive().
+ *
+ * Note: client has to implement and run event loop to be able to respond to
+ * asynchronous keepalive messages. If a client doesn't run event loop but
+ * still calls this API, every connection made may be automatically closed by
+ * remote party after a certain period of inactivity.
+ *
+ * Returns -1 on error, 0 on success, 1 when remote party doesn't support
+ * keepalive messages.
+ */
+int virConnectAllowKeepAlive(virConnectPtr conn)
+{
+ int ret = -1;
+
+ VIR_DEBUG("conn=%p", conn);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (!VIR_DRV_SUPPORTS_FEATURE(conn->driver, conn,
+ VIR_DRV_FEATURE_PROGRAM_KEEPALIVE)) {
+ VIR_DEBUG("Remote party doesn't support keepalive messages");
+ return 1;
+ }
+
+ if (conn->driver->allowKeepAlive) {
+ ret = conn->driver->allowKeepAlive(conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(conn);
+ return -1;
+}
+
+/**
+ * virConnectStartKeepAlive:
+ * @conn: pointer to a hypervisor connection
+ * @interval: number of seconds of inactivity before a keepalive message is sent
+ * @count: number of messages that can be sent in a row
+ *
+ * Start sending keepalive messages after interval second of inactivity and
+ * consider the connection to be broken when no response is received after
+ * count keepalive messages sent in a row. In other words, sending count + 1
+ * keepalive message results in closing the connection.
+ *
+ * This API may be called only after calling virConnectAllowKeepAlive and
+ * checking it returned 0, which ensures remote party supports keepalive
+ * protocol. Failure to do so will be detected and reported as an error.
+ *
+ * Note: client has to implement and run event loop to be able to use keepalive
+ * messages. Failture to do so may result in connections being closed
+ * unexpectedly.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int virConnectStartKeepAlive(virConnectPtr conn,
+ int interval,
+ unsigned int count)
+{
+ int ret = -1;
+
+ VIR_DEBUG("conn=%p, interval=%d, count=%u", conn, interval, count);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (interval <= 0) {
+ virLibConnError(VIR_ERR_INVALID_ARG,
+ _("negative or zero interval make no sense"));
+ goto error;
+ }
+
+ if (conn->driver->startKeepAlive) {
+ ret = conn->driver->startKeepAlive(conn, interval, count);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(conn);
+ return -1;
+}
diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h
index 6e44341..dbbf7e0 100644
--- a/src/libvirt_internal.h
+++ b/src/libvirt_internal.h
@@ -39,8 +39,8 @@ int virStateActive(void);
*
* The remote driver passes features through to the real driver at the
* remote end unmodified, except if you query a VIR_DRV_FEATURE_REMOTE*
- * feature.
- *
+ * feature. Queries for VIR_DRV_FEATURE_PROGRAM* features are answered
+ * directly by the RPC layer and not by the real driver.
*/
enum {
/* Driver supports V1-style virDomainMigrate, ie. domainMigratePrepare/
@@ -79,6 +79,12 @@ enum {
* to domain configuration, i.e., starting from Begin3 and not Perform3.
*/
VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION = 7,
+
+ /*
+ * Remote party supports keepalive program (i.e., sending keepalive
+ * messages).
+ */
+ VIR_DRV_FEATURE_PROGRAM_KEEPALIVE = 8,
};
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 8a6d55a..f7441d7 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -489,4 +489,10 @@ LIBVIRT_0.9.5 {
virDomainSnapshotGetName;
} LIBVIRT_0.9.4;
+LIBVIRT_0.9.7 {
+ global:
+ virConnectAllowKeepAlive;
+ virConnectStartKeepAlive;
+} LIBVIRT_0.9.5;
+
# .... define new API here using predicted next version number ....
--
1.7.6.1