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