From 4b6fa0bfc2e1f9c44b45e270bf26be5c28758889 Mon Sep 17 00:00:00 2001 From: Luca Bigliardi <shammash@google.com> Date: Tue, 4 May 2010 14:55:21 +0100 Subject: [PATCH] Introduce Mlockall() Add Mlockall() utility to lock current process' virtual adress space into RAM. Signed-off-by: Luca Bigliardi <shammash@google.com> Reviewed-by: Michael Hanselmann <hansmi@google.com> --- Makefile.am | 1 + lib/utils.py | 40 +++++++++++++++++++++++++ test/ganeti.utils_mlockall_unittest.py | 41 ++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100755 test/ganeti.utils_mlockall_unittest.py diff --git a/Makefile.am b/Makefile.am index ddc0bdfbc..0aaab2a70 100644 --- a/Makefile.am +++ b/Makefile.am @@ -340,6 +340,7 @@ python_tests = \ test/ganeti.ssh_unittest.py \ test/ganeti.uidpool_unittest.py \ test/ganeti.utils_unittest.py \ + test/ganeti.utils_mlockall_unittest.py \ test/ganeti.workerpool_unittest.py \ test/docs_unittest.py \ test/tempfile_fork_unittest.py diff --git a/lib/utils.py b/lib/utils.py index bcf811a7b..a9075e6e5 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -57,6 +57,11 @@ except ImportError: import sha sha1 = sha.new +try: + import ctypes +except ImportError: + ctypes = None + from ganeti import errors from ganeti import constants @@ -83,6 +88,10 @@ _RANDOM_UUID_FILE = "/proc/sys/kernel/random/uuid" _STRUCT_UCRED = "iII" _STRUCT_UCRED_SIZE = struct.calcsize(_STRUCT_UCRED) +# Flags for mlockall() (from bits/mman.h) +_MCL_CURRENT = 1 +_MCL_FUTURE = 2 + class RunResult(object): """Holds the result of running external programs. @@ -1739,6 +1748,37 @@ def CloseFDs(noclose_fds=None): _CloseFDNoErr(fd) +def Mlockall(): + """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. + + """ + if ctypes is None: + logging.warning("Cannot set memory lock, ctypes module not found") + return + + libc = ctypes.cdll.LoadLibrary("libc.so.6") + if libc is None: + logging.error("Cannot set memory lock, ctypes cannot load libc") + return + + # Some older version of the ctypes module don't have built-in functionality + # to access the errno global variable, where function error codes are stored. + # By declaring this variable as a pointer to an integer we can then access + # its value correctly, should the mlockall call fail, in order to see what + # the actual error code was. + libc.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + + if libc.mlockall(_MCL_CURRENT | _MCL_FUTURE): + logging.error("Cannot set memory lock: %s" % + os.strerror(libc.__errno_location().contents.value)) + return + + logging.debug("Memory lock set") + + def Daemonize(logfile): """Daemonize the current process. diff --git a/test/ganeti.utils_mlockall_unittest.py b/test/ganeti.utils_mlockall_unittest.py new file mode 100755 index 000000000..654d518a5 --- /dev/null +++ b/test/ganeti.utils_mlockall_unittest.py @@ -0,0 +1,41 @@ +#!/usr/bin/python +# + +# Copyright (C) 2010 Google Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + + +"""Script for testing utils.Mlockall + +This test is run in a separate process because it changes memory behaviour. + +""" + +import unittest + +from ganeti import utils + +import testutils + + +class TestResetTempfileModule(unittest.TestCase): + def test(self): + utils.Mlockall() + + +if __name__ == "__main__": + testutils.GanetiTestProgram() -- GitLab