Loading [MathJax]/jax/input/TeX/config.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 [
59  i for i in self.keys()
60  if os.path.samefile(os.path.dirname(self[i][0]), dir)
61  ]
62 
63  def create_symlinks(self, wkdir=""):
64  """
65  create necessary symlinks in worker's dir if the fd is <INPUT>
66  otherwise copy <OUTPUT> file
67  """
68  import os
69  import shutil
70  msg.info("create_symlinks: %s" % self.get_fds_in_dir())
71  # some files expected to be in curdir
72  for fd in self.get_fds_in_dir():
73  src = self[fd][0]
74  iomode = self[fd][1]
75  dst = os.path.join(wkdir, os.path.basename(src))
76  if iomode == "<INPUT>":
77  if os.path.exists(dst):
78  # update_io_registry took care of this
79  msg.debug(
80  "fds_dict.create_symlink:update_io_registry took care of src=%s"
81  % src)
82  pass
83  else:
84  msg.debug(
85  "fds_dict.create_symlink:(symlink) src=%s, iomode=%s" %
86  (src, iomode))
87  os.symlink(src, dst)
88  else:
89  msg.debug("fds_dict.create_symlink: (copy) src=%s, dst=%s" %
90  (src, dst))
91  shutil.copy(src, dst)
92  pass
93  return
94 
95  def extract_fds(self, dir=""):
96  """parse the fds of the processs -> build fds_dict
97  """
98  import os
99  import fcntl
100  msg.info(
101  "extract_fds: making snapshot of parent process file descriptors")
102  self.curdir = os.path.abspath(os.curdir)
103  iomode = '<INPUT>'
104 
105  procfd = '/proc/self/fd'
106  fds = os.listdir(procfd)
107  for i in fds:
108  fd = int(i) # spurious entries should raise at this point
109  if (fd == 1 or fd == 2):
110  # leave stdout and stderr to redirect_log
111  continue
112  elif (fd == 0):
113  # with only a single controlling terminal, leave stdin alone
114  continue
115 
116  try:
117  realname = os.path.realpath(os.path.join(procfd, i))
118  except (OSError, IOError, TypeError):
119  # can fail because the symlink resolution (why is that needed
120  # anyway?) may follow while a temp file disappears
121  msg.debug("failed to resolve: %s ... skipping",
122  os.path.join(procfd, i))
123  continue
124 
125  if os.path.exists(realname):
126  try:
127  flags = fcntl.fcntl(fd, fcntl.F_GETFL)
128  if (flags & _O_ACCMODE) == 0: # read-only --> <INPUT>
129  iomode = "<INPUT>"
130  else:
131  iomode = "<OUTPUT>"
132 
133  self.add(fd, realname, iomode, flags)
134  except (OSError, IOError):
135  # likely saw a temoorary file; for now log a debug
136  # message, but this is fine if silently ignored
137  msg.debug("failed access to: %s ... skipping", realname)
138  continue
139 
140  # at this point the list of fds may still include temp files
141  # TODO: figure out if they can be identified (seeing /tmp is
142  # not enough as folks like to run with data from /tmp b/c of
143  # space constraints on /afs
144 
145  msg.debug("extract_fds.fds_dict=%s" % self)
146  return
147 
148  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:95
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:63