FdsRegistry.py
Go to the documentation of this file.
1 # @file GaudiMP.FdsRegistry.py
2 # @purpose file descriptor registration and handling
3 # @author Mous Tatarkhanov <tmmous@berkeley.edu>
4 
5 _O_ACCMODE = 3 #access-mode check for file flags.
6 
7 import logging
8 msg = logging.getLogger( 'FdsRegistry' )
9 
10 class FdsDict(dict):
11  name = "fds_dict"
12  curdir = None
13 
14  def __missing__(self, key):
15  self[key] = ""
16  return ""
17 
18  def fname(self,i):
19  if i in self:
20  return self[i][0]
21  else:
22  msg.warning ("fds_dict:fname: No Key %s" % i)
23  return ""
24 
25  def fds(self, fname):
26  return [i for i, v in self.iteritems() if v[0]==fname]
27 
28  def has_name(self, fname):
29  for v in self.values():
30  if (v[0] == fname):
31  return True
32  return False
33 
34  # i - is the fd index (int)
35  def add(self, i, fname, iomode, flags):
36  self[i] = (fname, iomode, flags)
37  return
38 
39  def iomode(self,i):
40  if i in self:
41  return self[i][1]
42  else:
43  msg.warning ("fds_dict:iomode: No Key %s" % i)
44  return ""
45 
46  def get_output_fds(self):
47  return [i for i in self.keys() if self[i][1]=='<OUTPUT>']
48 
49  def get_input_fds(self):
50  return [i for i in self.keys() if self[i][1]=='<INPUT>']
51 
52  def get_fds_in_dir(self, dir=""):
53  import os
54  if dir == "" and self.curdir is not None:
55  dir = self.curdir
56  msg.debug("get_fds_in_dir(%s)" % dir)
57  return [i for i in self.keys()
58  if os.path.samefile(os.path.dirname(self[i][0]), dir) ]
59 
60  def create_symlinks(self, wkdir=""):
61  """
62  create necessary symlinks in worker's dir if the fd is <INPUT>
63  otherwise copy <OUTPUT> file
64  """
65  import os,shutil
66  msg.info("create_symlinks: %s" % self.get_fds_in_dir())
67  #some files expected to be in curdir
68  for fd in self.get_fds_in_dir():
69  src = self[fd][0]
70  iomode = self[fd][1]
71  dst = os.path.join(wkdir, os.path.basename(src))
72  if iomode == "<INPUT>":
73  if os.path.exists(dst):
74  # update_io_registry took care of this
75  msg.debug("fds_dict.create_symlink:update_io_registry took care of src=%s" % src)
76  pass
77  else:
78  msg.debug("fds_dict.create_symlink:(symlink) src=%s, iomode=%s" % (src,iomode))
79  os.symlink(src, dst)
80  else:
81  msg.debug("fds_dict.create_symlink: (copy) src=%s, dst=%s" % (src, dst))
82  shutil.copy(src, dst)
83  pass
84  return
85 
86  def extract_fds(self, dir=""):
87  """parse the fds of the processs -> build fds_dict
88  """
89  import os, fcntl
90  msg.info("extract_fds: making snapshot of parent process file descriptors")
91  self.curdir = os.path.abspath(os.curdir)
92  iomode = '<INPUT>'
93 
94  procfd = '/proc/self/fd'
95  fds = os.listdir(procfd)
96  for i in fds:
97  fd = int(i) # spurious entries should raise at this point
98  if (fd==1 or fd==2):
99  #leave stdout and stderr to redirect_log
100  continue
101  elif (fd==0):
102  #with only a single controlling terminal, leave stdin alone
103  continue
104 
105  try:
106  realname = os.path.realpath(os.path.join(procfd,i))
107  except (OSError, IOError, TypeError):
108  # can fail because the symlink resolution (why is that needed
109  # anyway?) may follow while a temp file disappears
110  msg.debug( "failed to resolve: %s ... skipping", os.path.join(procfd,i) )
111  continue
112 
113  if os.path.exists(realname):
114  try:
115  flags = fcntl.fcntl(fd, fcntl.F_GETFL)
116  if (flags & _O_ACCMODE) == 0: #read-only --> <INPUT>
117  iomode = "<INPUT>"
118  else:
119  iomode = "<OUTPUT>"
120 
121  self.add(fd, realname, iomode, flags)
122  except (OSError, IOError):
123  # likely saw a temoorary file; for now log a debug
124  # message, but this is fine if silently ignored
125  msg.debug( "failed access to: %s ... skipping", realname )
126  continue
127 
128  # at this point the list of fds may still include temp files
129  # TODO: figure out if they can be identified (seeing /tmp is
130  # not enough as folks like to run with data from /tmp b/c of
131  # space constraints on /afs
132 
133  msg.debug( "extract_fds.fds_dict=%s" % self)
134  return
135 
136  pass #FdsDict
137 
def has_name(self, fname)
Definition: FdsRegistry.py:28
def get_fds_in_dir(self, dir="")
Definition: FdsRegistry.py:52
def extract_fds(self, dir="")
Definition: FdsRegistry.py:86
def fds(self, fname)
Definition: FdsRegistry.py:25
def __missing__(self, key)
Definition: FdsRegistry.py:14
def add(self, i, fname, iomode, flags)
Definition: FdsRegistry.py:35
def create_symlinks(self, wkdir="")
Definition: FdsRegistry.py:60