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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list