On 13.10.2015 15:38, Erik Skultety wrote:
Since close callback and URI support was introduced in the earlier
patches, it
is now the right time to implement the disconnect handler itself and switch the
dummy NULL reference in virAdmConnectRegisterCloseCallback for this new handler.
The handler itself is the same as the one used in virsh, it only remembers that
the event occurs, lets the user know, but no other useful logic is present.
---
tools/virt-admin.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 48 insertions(+), 3 deletions(-)
diff --git a/tools/virt-admin.c b/tools/virt-admin.c
index a202ce2..3069d48 100644
--- a/tools/virt-admin.c
+++ b/tools/virt-admin.c
@@ -77,6 +77,51 @@ static const vshClientHooks hooks;
*/
static int disconnected; /* we may have been disconnected */
+/*
+ * vshAdmCatchDisconnect:
+ *
+ * We get here when the connection was closed. Right now, we only save the fact
+ * the event was raised.
+ */
+static void
+vshAdmCatchDisconnect(virAdmConnectPtr conn ATTRIBUTE_UNUSED,
+ int reason,
+ void *opaque)
+{
+ if (reason != VIR_CONNECT_CLOSE_REASON_CLIENT) {
+ vshControl *ctl = opaque;
+ const char *str = "unknown reason";
+ virErrorPtr error;
+ char *uri = NULL;
+
+ error = virSaveLastError();
+ uri = virAdmConnectGetURI(conn);
+
+ switch ((virConnectCloseReason) reason) {
+ case VIR_CONNECT_CLOSE_REASON_ERROR:
+ str = N_("Disconnected from %s due to I/O error");
+ break;
+ case VIR_CONNECT_CLOSE_REASON_EOF:
+ str = N_("Disconnected from %s due to end of file");
+ break;
+ case VIR_CONNECT_CLOSE_REASON_KEEPALIVE:
+ str = N_("Disconnected from %s due to keepalive timeout");
+ break;
+ /* coverity[dead_error_condition] */
+ case VIR_CONNECT_CLOSE_REASON_CLIENT:
+ case VIR_CONNECT_CLOSE_REASON_LAST:
+ break;
+ }
+ vshError(ctl, _(str), NULLSTR(uri));
+
+ if (error) {
+ virSetError(error);
+ virFreeError(error);
+ }
+ disconnected++;
+ }
+}
+
static virAdmConnectPtr
vshAdmConnect(vshControl *ctl, unsigned int flags)
{
@@ -91,8 +136,8 @@ vshAdmConnect(vshControl *ctl, unsigned int flags)
vshError(ctl, "%s", _("Failed to connect to the admin
server"));
return NULL;
} else {
- if (virAdmConnectRegisterCloseCallback(priv->conn, NULL, NULL,
- NULL) < 0)
+ if (virAdmConnectRegisterCloseCallback(priv->conn, vshAdmCatchDisconnect,
+ NULL, NULL) < 0)
vshError(ctl, "%s", _("Unable to register disconnect
callback"));
if (priv->wantReconnect)
@@ -112,7 +157,7 @@ vshAdmDisconnectInternal(vshControl *ctl, virAdmConnectPtr *conn)
if (!*conn)
return ret;
- virAdmConnectUnregisterCloseCallback(*conn, NULL);
+ virAdmConnectUnregisterCloseCallback(*conn, vshAdmCatchDisconnect);
ret = virAdmConnectClose(*conn);
if (ret < 0)
vshError(ctl, "%s", _("Failed to disconnect from the admin
server"));
For some reason, this is not working yet... Maybe you need to enable it
somewhere?
Michal