Change in vdsm[master]: libvirtconnection: retry to establish connection

dougsland at redhat.com dougsland at redhat.com
Fri May 16 06:24:46 UTC 2014


Douglas Schilling Landgraf has uploaded a new change for review.

Change subject: libvirtconnection: retry to establish connection
......................................................................

libvirtconnection: retry to establish connection

Currently if ovirt-node-plugin-vdsm or other app uses vdsm
to consult informations and for some reason
the connection between vdsm and libvirt is not available
vdsm kills the caller. This patch will add a retry to
establish connection with libvirt before kill the caller.

Change-Id: I2dbc389beccbd09b53b85756baf1d941f771c3f7
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1097645
Signed-off-by: Douglas Schilling Landgraf <dougsland at redhat.com>
---
M lib/vdsm/libvirtconnection.py
1 file changed, 47 insertions(+), 41 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/54/27754/1

diff --git a/lib/vdsm/libvirtconnection.py b/lib/vdsm/libvirtconnection.py
index 31b6a3a..56d274d 100644
--- a/lib/vdsm/libvirtconnection.py
+++ b/lib/vdsm/libvirtconnection.py
@@ -86,6 +86,49 @@
     Wrap methods of connection object so that they catch disconnection, and
     take the current process down.
     """
+    def req(credentials, user_data):
+        passwd = file(constants.P_VDSM_LIBVIRT_PASSWD).readline().rstrip("\n")
+        for cred in credentials:
+            if cred[0] == libvirt.VIR_CRED_AUTHNAME:
+                cred[4] = constants.SASL_USERNAME
+            elif cred[0] == libvirt.VIR_CRED_PASSPHRASE:
+                cred[4] = passwd
+        return 0
+
+    auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE],
+            req, None]
+
+    def make_libvirt_conn():
+        libvirtOpenAuth = functools.partial(libvirt.openAuth,
+                                            'qemu:///system', auth, 0)
+        conn = utils.retry(libvirtOpenAuth, timeout=10, sleep=0.2)
+        __connections[id(target)] = conn
+        setattr(conn, 'pingLibvirt', getattr(conn, 'getLibVersion'))
+        for name in dir(libvirt.virConnect):
+            method = getattr(conn, name)
+            if callable(method) and name[0] != '_':
+                setattr(conn, name, wrapMethod(method))
+        if target is not None:
+            for ev in (libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
+                       libvirt.VIR_DOMAIN_EVENT_ID_REBOOT,
+                       libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
+                       libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
+                       libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS,
+                       libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
+                       libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG):
+                conn.domainEventRegisterAny(
+                    None,
+                    ev,
+                    target.dispatchLibvirtEvents,
+                    ev
+                )
+            # In case we're running into troubles with keeping the connections
+            # alive we should place here:
+            # conn.setKeepAlive(interval=5, count=3)
+            # However the values need to be considered wisely to not affect
+            # hosts which are hosting a lot of virtual machines
+        return conn
+
     def wrapMethod(f):
         @functools.wraps(f)
         def wrapper(*args, **kwargs):
@@ -116,6 +159,9 @@
                             log.warning('connection to libvirt broken.'
                                         ' ecode: %d edom: %d', ecode, edom)
                             if killOnFailure:
+                                # Before kill, let's try to reconnect
+                                if make_libvirt_conn():
+                                    return wrapper
                                 log.critical('taking calling process down.')
                                 os.kill(os.getpid(), signal.SIGTERM)
                             else:
@@ -126,50 +172,10 @@
                 raise
         return wrapper
 
-    def req(credentials, user_data):
-        passwd = file(constants.P_VDSM_LIBVIRT_PASSWD).readline().rstrip("\n")
-        for cred in credentials:
-            if cred[0] == libvirt.VIR_CRED_AUTHNAME:
-                cred[4] = constants.SASL_USERNAME
-            elif cred[0] == libvirt.VIR_CRED_PASSPHRASE:
-                cred[4] = passwd
-        return 0
-
-    auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE],
-            req, None]
-
     with __connectionLock:
         conn = __connections.get(id(target))
         if not conn:
-            libvirtOpenAuth = functools.partial(libvirt.openAuth,
-                                                'qemu:///system', auth, 0)
-            log.debug('trying to connect libvirt')
-            conn = utils.retry(libvirtOpenAuth, timeout=10, sleep=0.2)
-            __connections[id(target)] = conn
-
-            setattr(conn, 'pingLibvirt', getattr(conn, 'getLibVersion'))
-            for name in dir(libvirt.virConnect):
-                method = getattr(conn, name)
-                if callable(method) and name[0] != '_':
-                    setattr(conn, name, wrapMethod(method))
-            if target is not None:
-                for ev in (libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
-                           libvirt.VIR_DOMAIN_EVENT_ID_REBOOT,
-                           libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
-                           libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
-                           libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS,
-                           libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
-                           libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG):
-                    conn.domainEventRegisterAny(None,
-                                                ev,
-                                                target.dispatchLibvirtEvents,
-                                                ev)
-            # In case we're running into troubles with keeping the connections
-            # alive we should place here:
-            # conn.setKeepAlive(interval=5, count=3)
-            # However the values need to be considered wisely to not affect
-            # hosts which are hosting a lot of virtual machines
-
+            conn = make_libvirt_conn()
         return conn
 
 


-- 
To view, visit http://gerrit.ovirt.org/27754
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2dbc389beccbd09b53b85756baf1d941f771c3f7
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Douglas Schilling Landgraf <dougsland at redhat.com>


More information about the vdsm-patches mailing list