Package ganeti :: Package utils :: Module wrapper
[hide private]
[frames] | no frames]

Source Code for Module ganeti.utils.wrapper

  1  # 
  2  # 
  3   
  4  # Copyright (C) 2006, 2007, 2010, 2011 Google Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, but 
 12  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 14  # General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
 19  # 02110-1301, USA. 
 20   
 21  """Utility functions wrapping other functions. 
 22   
 23  """ 
 24   
 25  import time 
 26  import socket 
 27  import errno 
 28  import tempfile 
 29  import fcntl 
 30  import os 
 31  import select 
 32  import logging 
 33   
 34   
35 -def TestDelay(duration):
36 """Sleep for a fixed amount of time. 37 38 @type duration: float 39 @param duration: the sleep duration 40 @rtype: boolean 41 @return: False for negative value, True otherwise 42 43 """ 44 if duration < 0: 45 return False, "Invalid sleep duration" 46 time.sleep(duration) 47 return True, None
48 49
50 -def CloseFdNoError(fd, retries=5):
51 """Close a file descriptor ignoring errors. 52 53 @type fd: int 54 @param fd: the file descriptor 55 @type retries: int 56 @param retries: how many retries to make, in case we get any 57 other error than EBADF 58 59 """ 60 try: 61 os.close(fd) 62 except OSError, err: 63 if err.errno != errno.EBADF: 64 if retries > 0: 65 CloseFdNoError(fd, retries - 1)
66 # else either it's closed already or we're out of retries, so we 67 # ignore this and go on 68 69
70 -def SetCloseOnExecFlag(fd, enable):
71 """Sets or unsets the close-on-exec flag on a file descriptor. 72 73 @type fd: int 74 @param fd: File descriptor 75 @type enable: bool 76 @param enable: Whether to set or unset it. 77 78 """ 79 flags = fcntl.fcntl(fd, fcntl.F_GETFD) 80 81 if enable: 82 flags |= fcntl.FD_CLOEXEC 83 else: 84 flags &= ~fcntl.FD_CLOEXEC 85 86 fcntl.fcntl(fd, fcntl.F_SETFD, flags)
87 88
89 -def SetNonblockFlag(fd, enable):
90 """Sets or unsets the O_NONBLOCK flag on on a file descriptor. 91 92 @type fd: int 93 @param fd: File descriptor 94 @type enable: bool 95 @param enable: Whether to set or unset it 96 97 """ 98 flags = fcntl.fcntl(fd, fcntl.F_GETFL) 99 100 if enable: 101 flags |= os.O_NONBLOCK 102 else: 103 flags &= ~os.O_NONBLOCK 104 105 fcntl.fcntl(fd, fcntl.F_SETFL, flags)
106 107
108 -def RetryOnSignal(fn, *args, **kwargs):
109 """Calls a function again if it failed due to EINTR. 110 111 """ 112 while True: 113 try: 114 return fn(*args, **kwargs) 115 except EnvironmentError, err: 116 if err.errno != errno.EINTR: 117 raise 118 except (socket.error, select.error), err: 119 # In python 2.6 and above select.error is an IOError, so it's handled 120 # above, in 2.5 and below it's not, and it's handled here. 121 if not (err.args and err.args[0] == errno.EINTR): 122 raise
123 124
125 -def IgnoreProcessNotFound(fn, *args, **kwargs):
126 """Ignores ESRCH when calling a process-related function. 127 128 ESRCH is raised when a process is not found. 129 130 @rtype: bool 131 @return: Whether process was found 132 133 """ 134 try: 135 fn(*args, **kwargs) 136 except EnvironmentError, err: 137 # Ignore ESRCH 138 if err.errno == errno.ESRCH: 139 return False 140 raise 141 142 return True
143 144
145 -def IgnoreSignals(fn, *args, **kwargs):
146 """Tries to call a function ignoring failures due to EINTR. 147 148 """ 149 try: 150 return fn(*args, **kwargs) 151 except EnvironmentError, err: 152 if err.errno == errno.EINTR: 153 return None 154 else: 155 raise 156 except (select.error, socket.error), err: 157 # In python 2.6 and above select.error is an IOError, so it's handled 158 # above, in 2.5 and below it's not, and it's handled here. 159 if err.args and err.args[0] == errno.EINTR: 160 return None 161 else: 162 raise
163 164
165 -def GetClosedTempfile(*args, **kwargs):
166 """Creates a temporary file and returns its path. 167 168 """ 169 (fd, path) = tempfile.mkstemp(*args, **kwargs) 170 CloseFdNoError(fd) 171 return path
172 173
174 -def ResetTempfileModule():
175 """Resets the random name generator of the tempfile module. 176 177 This function should be called after C{os.fork} in the child process to 178 ensure it creates a newly seeded random generator. Otherwise it would 179 generate the same random parts as the parent process. If several processes 180 race for the creation of a temporary file, this could lead to one not getting 181 a temporary name. 182 183 """ 184 # pylint: disable-msg=W0212 185 if hasattr(tempfile, "_once_lock") and hasattr(tempfile, "_name_sequence"): 186 tempfile._once_lock.acquire() 187 try: 188 # Reset random name generator 189 tempfile._name_sequence = None 190 finally: 191 tempfile._once_lock.release() 192 else: 193 logging.critical("The tempfile module misses at least one of the" 194 " '_once_lock' and '_name_sequence' attributes")
195