From 4c32a8bd9c1289ef64847da552ed047c2290627b Mon Sep 17 00:00:00 2001
From: Luca Bigliardi <shammash@google.com>
Date: Tue, 6 Jul 2010 15:28:58 +0100
Subject: [PATCH] Mlockall: decrease warnings if ctypes module is not present

Node daemon prints a lot of warnings if --no-mlock option is not specified and
ctypes module is not present.

With the following patch the warning is printed only at noded startup.

Signed-off-by: Luca Bigliardi <shammash@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 daemons/ganeti-noded                   |  6 +++++-
 lib/errors.py                          |  6 ++++++
 lib/utils.py                           | 13 +++++++------
 test/ganeti.utils_mlockall_unittest.py | 19 +++++++++++++++++--
 4 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded
index e40771cb6..666d9ebd2 100755
--- a/daemons/ganeti-noded
+++ b/daemons/ganeti-noded
@@ -845,8 +845,12 @@ def ExecNoded(options, _):
 
   """
   if options.mlock:
-    utils.Mlockall()
     request_executor_class = MlockallRequestExecutor
+    try:
+      utils.Mlockall()
+    except errors.NoCtypesError:
+      logging.warning("Cannot set memory lock, ctypes module not found")
+      request_executor_class = http.server.HttpServerRequestExecutor
   else:
     request_executor_class = http.server.HttpServerRequestExecutor
 
diff --git a/lib/errors.py b/lib/errors.py
index 17a02371d..8a731e12d 100644
--- a/lib/errors.py
+++ b/lib/errors.py
@@ -336,6 +336,12 @@ class UdpDataSizeError(GenericError):
   """
 
 
+class NoCtypesError(GenericError):
+  """python ctypes module is not found in the system.
+
+  """
+
+
 # errors should be added above
 
 
diff --git a/lib/utils.py b/lib/utils.py
index 17baab751..887a74e4b 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -1772,18 +1772,19 @@ def CloseFDs(noclose_fds=None):
     _CloseFDNoErr(fd)
 
 
-def Mlockall():
+def Mlockall(_ctypes=ctypes):
   """Lock current process' virtual address space into RAM.
 
   This is equivalent to the C call mlockall(MCL_CURRENT|MCL_FUTURE),
   see mlock(2) for more details. This function requires ctypes module.
 
+  @raises errors.NoCtypesError: if ctypes module is not found
+
   """
-  if ctypes is None:
-    logging.warning("Cannot set memory lock, ctypes module not found")
-    return
+  if _ctypes is None:
+    raise errors.NoCtypesError()
 
-  libc = ctypes.cdll.LoadLibrary("libc.so.6")
+  libc = _ctypes.cdll.LoadLibrary("libc.so.6")
   if libc is None:
     logging.error("Cannot set memory lock, ctypes cannot load libc")
     return
@@ -1794,7 +1795,7 @@ def Mlockall():
   # its value correctly, should the mlockall call fail, in order to see what
   # the actual error code was.
   # pylint: disable-msg=W0212
-  libc.__errno_location.restype = ctypes.POINTER(ctypes.c_int)
+  libc.__errno_location.restype = _ctypes.POINTER(_ctypes.c_int)
 
   if libc.mlockall(_MCL_CURRENT | _MCL_FUTURE):
     # pylint: disable-msg=W0212
diff --git a/test/ganeti.utils_mlockall_unittest.py b/test/ganeti.utils_mlockall_unittest.py
index 654d518a5..17726b7cb 100755
--- a/test/ganeti.utils_mlockall_unittest.py
+++ b/test/ganeti.utils_mlockall_unittest.py
@@ -28,13 +28,28 @@ This test is run in a separate process because it changes memory behaviour.
 import unittest
 
 from ganeti import utils
+from ganeti import errors
 
 import testutils
 
 
-class TestResetTempfileModule(unittest.TestCase):
+class TestMlockallWithCtypes(unittest.TestCase):
+  """Whether Mlockall() works if ctypes is present.
+
+  """
+
+  def test(self):
+    if utils.ctypes:
+      utils.Mlockall()
+
+
+class TestMlockallWithNoCtypes(unittest.TestCase):
+  """Whether Mlockall() raises an error if ctypes is not present.
+
+  """
+
   def test(self):
-    utils.Mlockall()
+    self.assertRaises(errors.NoCtypesError, utils.Mlockall, _ctypes=None)
 
 
 if __name__ == "__main__":
-- 
GitLab