virConnectSetKeepAlive public API can be used by a client connecting to remote server to start using keepalive protocol. The API is handled directly by remote driver and not transmitted over the wire to the server. --- Notes: Version 3 ACKed. Version 4: - explicitly document the semantics of interval <= 0 and count = 0 Version 3: - remove virConnectAllowKeepAlive - rename virConnectStartKeepAlive as virConnectSetKeepAlive - add a note to virEventRegisterImpl that running the event loop is mandatory once registered Version 2: - no change include/libvirt/libvirt.h.in | 4 +++ src/driver.h | 5 +++ src/libvirt.c | 57 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_internal.h | 10 ++++++- src/libvirt_public.syms | 1 + src/util/event.c | 6 ++-- 6 files changed, 78 insertions(+), 5 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7102bce..8ce4335 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -3275,6 +3275,10 @@ typedef struct _virTypedParameter virMemoryParameter; */ typedef virMemoryParameter *virMemoryParameterPtr; +int virConnectSetKeepAlive(virConnectPtr conn, + int interval, + unsigned int count); + #ifdef __cplusplus } #endif diff --git a/src/driver.h b/src/driver.h index b899d0e..c1223c1 100644 --- a/src/driver.h +++ b/src/driver.h @@ -735,6 +735,10 @@ typedef int (*virDrvDomainBlockPull)(virDomainPtr dom, const char *path, unsigned long bandwidth, unsigned int flags); +typedef int + (*virDrvSetKeepAlive)(virConnectPtr conn, + int interval, + unsigned int count); /** * _virDriver: @@ -893,6 +897,7 @@ struct _virDriver { virDrvDomainGetBlockJobInfo domainGetBlockJobInfo; virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed; virDrvDomainBlockPull domainBlockPull; + virDrvSetKeepAlive setKeepAlive; }; typedef int diff --git a/src/libvirt.c b/src/libvirt.c index a6bcee6..0c33da1 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -16964,3 +16964,60 @@ error: virDispatchError(dom->conn); return -1; } + +/** + * virConnectSetKeepAlive: + * @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. When interval is <= 0, + * no keepalive messages will be sent. When count is 0, the connection will be + * automatically closed after interval seconds of inactivity without sending + * any keepalive messages. + * + * Note: client has to implement and run event loop to be able to use keepalive + * messages. Failure to do so may result in connections being closed + * unexpectedly. + * + * Returns -1 on error, 0 on success, 1 when remote party doesn't support + * keepalive messages. + */ +int virConnectSetKeepAlive(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->setKeepAlive) { + ret = conn->driver->setKeepAlive(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 9762fc4..468e28a 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -491,6 +491,7 @@ LIBVIRT_0.9.5 { LIBVIRT_0.9.7 { global: + virConnectSetKeepAlive; virDomainReset; virDomainSnapshotGetParent; virDomainSnapshotListChildrenNames; diff --git a/src/util/event.c b/src/util/event.c index bd781ec..495a1f3 100644 --- a/src/util/event.c +++ b/src/util/event.c @@ -193,9 +193,9 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle, * not have a need to integrate with an external event * loop impl. * - * Once registered, the application can invoke - * virEventRunDefaultImpl in a loop to process - * events + * Once registered, the application has to invoke virEventRunDefaultImpl in + * a loop to process events. Failure to do so may result in connections being + * closed unexpectedly as a result of keepalive timeout. * * Returns 0 on success, -1 on failure. */ -- 1.7.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list