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