Change in vdsm[master]: profile: runtime support to enable/disable profile

fromani at redhat.com fromani at redhat.com
Fri Mar 6 19:45:54 UTC 2015


Francesco Romani has uploaded a new change for review.

Change subject: profile: runtime support to enable/disable profile
......................................................................

profile: runtime support to enable/disable profile

Currently, the only way to enable profiling support
in VDSM is to edit the configuration file and
restart the process.

This makes hard to profile specific flows without
doing a full restart of VDSM and adding extra noise.

This patch adds support to enable or disable
profiling support at runtime, using vdsClient.
This feature is expected to be used only in development,
or maybe as debug aid in controlled environments.

To prevent any form of misbehaving in production
environment, an additional tunable is added, disabled
by default, to enable this runtime support.

Change-Id: I32441b2c211acbf3bb91202b2e4c3e01eb3f40d9
Signed-off-by: Francesco Romani <fromani at redhat.com>
---
M client/vdsClient.py
M lib/vdsm/config.py.in
M lib/vdsm/profile.py
M vdsm/API.py
M vdsm/rpc/BindingXMLRPC.py
M vdsm/vdsm
6 files changed, 67 insertions(+), 8 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/16/35016/5

diff --git a/client/vdsClient.py b/client/vdsClient.py
index 9091644..aabf7a1 100644
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -1617,6 +1617,12 @@
             print message
             return 0, ''
 
+    def startProfile(self, args):
+        return self.ExecAndExit(self.s.startProfile())
+
+    def stopProfile(self, args):
+        return self.ExecAndExit(self.s.stopProfile())
+
     def _eqSplit(self, args):
         d = {}
         for arg in args:
@@ -2715,6 +2721,18 @@
                 '<vmId> <vcpuLimit>',
                 'set SLA parameter for a VM'
             )),
+        'startProfile': (
+            serv.startProfile, (
+                '',
+                'Start dynamic profiling of VDSM. '
+                'Requires configuration on the host.'
+            )),
+        'stopProfile': (
+            serv.stopProfile, (
+                '',
+                'Stop dynamic profiling of VDSM. '
+                'Requires configuration on the host.'
+            )),
     }
     if _glusterEnabled:
         commands.update(ge.getGlusterCmdDict(serv))
diff --git a/lib/vdsm/config.py.in b/lib/vdsm/config.py.in
index 92d3af5..9618b7f 100644
--- a/lib/vdsm/config.py.in
+++ b/lib/vdsm/config.py.in
@@ -348,6 +348,9 @@
         ('profile_clock', 'cpu',
             'Sets the underlying clock type (cpu, wall)'),
 
+        ('profile_dynamic', 'false',
+            'Control profiling support using vdsClient'),
+
         ('python_warnings_enable', 'false',
             'Display python warnings in the log'),
 
diff --git a/lib/vdsm/profile.py b/lib/vdsm/profile.py
index 9710225..04c6414 100644
--- a/lib/vdsm/profile.py
+++ b/lib/vdsm/profile.py
@@ -48,19 +48,22 @@
     """ Raised when profiler is used incorrectly """
 
 
-def start():
+def start(dynamic=False):
     """ Starts application wide profiling """
-    if is_enabled():
+    if is_enabled(dynamic):
         _start_profiling(_CLOCK, _BUILTINS, _THREADS)
 
 
-def stop():
+def stop(dynamic=False):
     """ Stops application wide profiling """
-    if is_enabled():
+    if is_enabled(dynamic):
         _stop_profiling(_FILENAME, _FORMAT)
 
 
-def is_enabled():
+def is_enabled(dynamic=False):
+    if dynamic:
+        return (config.getboolean('devel', 'profile_enable')
+                and config.getboolean('devel', 'profile_dynamic'))
     return config.getboolean('devel', 'profile_enable')
 
 
diff --git a/vdsm/API.py b/vdsm/API.py
index 6c35cfb..4090b9c 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -37,6 +37,7 @@
 from clientIF import clientIF
 from vdsm import netinfo
 from vdsm import constants
+from vdsm import profile
 import storage.misc
 import storage.clusterlock
 import storage.volume
@@ -1612,6 +1613,28 @@
             return errCode['haErr']
         return {'status': doneCode}
 
+    def startProfile(self):
+        if config.getboolean('devel', 'profile_dynamic'):
+            if not profile.is_running():
+                profile.start(dynamic=True)
+                return {'status': doneCode}
+            else:
+                self.log.error("dynamic profiling already enabled")
+        else:
+            self.log.error("dynamic profiling not supported")
+        return errCode['unavail']
+
+    def stopProfile(self):
+        if config.getboolean('devel', 'profile_dynamic'):
+            if profile.is_running():
+                profile.stop(dynamic=True)
+                return {'status': doneCode}
+            else:
+                self.log.error("dynamic profiling already disabled")
+        else:
+            self.log.error("dynamic profiling not supported")
+        return errCode['unavail']
+
     # take a rough estimate on how much free mem is available for new vm
     # memTotal = memFree + memCached + mem_used_by_non_qemu + resident  .
     # simply returning (memFree + memCached) is not good enough, as the
diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py
index 0164691..2babd52 100644
--- a/vdsm/rpc/BindingXMLRPC.py
+++ b/vdsm/rpc/BindingXMLRPC.py
@@ -601,6 +601,14 @@
         api = API.Global()
         return api.setHaMaintenanceMode(mode, enabled)
 
+    def startProfile(self):
+        api = API.Global()
+        return api.startProfile()
+
+    def stopProfile(self):
+        api = API.Global()
+        return api.stopProfile()
+
     def domainActivate(self, sdUUID, spUUID, options=None):
         domain = API.StorageDomain(sdUUID)
         return domain.activate(spUUID)
@@ -1036,7 +1044,9 @@
                 (self.merge, 'merge'),
                 (self.vmUpdateVmPolicy, 'updateVmPolicy'),
                 (self.vmSetIoTune, 'setIoTune'),
-                (self.vmGetIoTunePolicy, 'getIoTunePolicy'))
+                (self.vmGetIoTunePolicy, 'getIoTunePolicy'),
+                (self.startProfile, 'startProfile'),
+                (self.stopProfile, 'stopProfile'))
 
     def getIrsMethods(self):
         return ((self.domainActivate, 'activateStorageDomain'),
diff --git a/vdsm/vdsm b/vdsm/vdsm
index 5c1ab71..661de52 100755
--- a/vdsm/vdsm
+++ b/vdsm/vdsm
@@ -75,7 +75,8 @@
     signal.signal(signal.SIGUSR1, sigusr1Handler)
     zombiereaper.registerSignalHandler()
 
-    profile.start()
+    if not config.getboolean('devel', 'profile_dynamic'):
+        profile.start()
 
     libvirtconnection.start_event_loop()
 
@@ -92,7 +93,8 @@
         while running[0]:
             signal.pause()
 
-        profile.stop()
+        if not config.getboolean('devel', 'profile_dynamic'):
+            profile.stop()
     finally:
         cif.prepareForShutdown()
 


-- 
To view, visit https://gerrit.ovirt.org/35016
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I32441b2c211acbf3bb91202b2e4c3e01eb3f40d9
Gerrit-PatchSet: 5
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani at redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani at redhat.com>
Gerrit-Reviewer: automation at ovirt.org
Gerrit-Reviewer: oVirt Jenkins CI Server


More information about the vdsm-patches mailing list