| # Gaudi Framework, version v23r1 |

Home |  | Generated: Wed Feb 29 2012

# FdsRegistry.py

Go to the documentation of this file.

    00001 # @file GaudiMP.FdsRegistry.py
    00002 # @purpose file descriptor registration and handling
    00003 # @author Mous Tatarkhanov <tmmous@berkeley.edu>
    00004
    00005 _O_ACCMODE = 3  #access-mode check for file flags.
    00006
    00007 import logging
    00008 msg = logging.getLogger( 'FdsRegistry' )
    00009
    00010 class FdsDict(dict):
    00011     name = "fds_dict"
    00012     curdir = None
    00013
    00014     def __missing__(self, key):
    00015         self[key] = ""
    00016         return ""
    00017
    00018     def fname(self,i):
    00019         if i in self:
    00020             return self[i][0]
    00021         else:
    00022             msg.warning ("fds_dict:fname: No Key %s" % i)
    00023             return ""
    00024
    00025     def fds(self, fname):
    00026         return [i for i, v in self.iteritems() if v[0]==fname]
    00027
    00028     def has_name(self, fname):
    00029         for v in self.values():
    00030             if (v[0] == fname):
    00031                 return True
    00032         return False
    00033
    00034     # i - is the fd index (int)
    00035     def add(self, i, fname, iomode, flags):
    00036         self[i] = (fname, iomode, flags)
    00037         return
    00038
    00039     def iomode(self,i):
    00040         if i in self:
    00041             return self[i][1]
    00042         else:
    00043             msg.warning ("fds_dict:iomode: No Key %s" % i)
    00044             return ""
    00045
    00046     def get_output_fds(self):
    00047         return [i for i in self.keys() if self[i][1]=='<OUTPUT>']
    00048
    00049     def get_input_fds(self):
    00050         return [i for i in self.keys() if self[i][1]=='<INPUT>']
    00051
    00052     def get_fds_in_dir(self, dir=""):
    00053         import os
    00054         if dir == "" and self.curdir is not None:
    00055             dir = self.curdir
    00056         msg.debug("get_fds_in_dir(%s)" % dir)
    00057         return [i for i in self.keys()
    00058                 if os.path.samefile(os.path.dirname(self[i][0]), dir) ]
    00059
    00060     def create_symlinks(self, wkdir=""):
    00061         """
    00062         create necessary symlinks in worker's dir if the fd is <INPUT>
    00063         otherwise copy <OUTPUT> file
    00064         """
    00065         import os,shutil
    00066         msg.info("create_symlinks: %s" % self.get_fds_in_dir())
    00067         #some files expected to be in curdir
    00068         for fd in self.get_fds_in_dir():
    00069             src = self[fd][0]
    00070             iomode = self[fd][1]
    00071             dst = os.path.join(wkdir, os.path.basename(src))
    00072             if iomode == "<INPUT>":
    00073                 if os.path.exists(dst):
    00074                     # update_io_registry took care of this
    00075                     msg.debug("fds_dict.create_symlink:update_io_registry took care of src=%s" % src)
    00076                     pass
    00077                 else:
    00078                     msg.debug("fds_dict.create_symlink:(symlink) src=%s, iomode=%s" % (src,iomode))
    00079                     os.symlink(src, dst)
    00080             else:
    00081                 msg.debug("fds_dict.create_symlink: (copy) src=%s, dst=%s" % (src, dst))
    00082                 shutil.copy(src, dst)
    00083                 pass
    00084         return
    00085
    00086     def extract_fds(self, dir=""):
    00087         """parse the fds of the processs -> build fds_dict
    00088         """
    00089         import os, fcntl
    00090         msg.info("extract_fds: making snapshot of parent process file descriptors")
    00091         self.curdir = os.path.abspath(os.curdir)
    00092         iomode = '<INPUT>'
    00093
    00094         procfd = '/proc/self/fd'
    00095         fds = os.listdir(procfd)
    00096         for i in fds:
    00097             fd = int(i)       # spurious entries should raise at this point
    00098             if (fd==1 or fd==2):
    00099                 #leave stdout and stderr to redirect_log
    00100                 continue
    00101             elif (fd==0):
    00102                 #with only a single controlling terminal, leave stdin alone
    00103                 continue
    00104
    00105             try:
    00106                 realname = os.path.realpath(os.path.join(procfd,i))
    00107             except (OSError, IOError, TypeError):
    00108                 # can fail because the symlink resolution (why is that needed
    00109                 # anyway?) may follow while a temp file disappears
    00110                 msg.debug( "failed to resolve: %s ... skipping", os.path.join(procfd,i) )
    00111                 continue
    00112
    00113             if os.path.exists(realname):
    00114                 try:
    00115                     flags = fcntl.fcntl(fd, fcntl.F_GETFL)
    00116                     if (flags & _O_ACCMODE) == 0: #read-only --> <INPUT>
    00117                         iomode = "<INPUT>"
    00118                     else:
    00119                         iomode = "<OUTPUT>"
    00120
    00121                     self.add(fd, realname, iomode, flags)
    00122                 except (OSError, IOError):
    00123                     # likely saw a temoorary file; for now log a debug
    00124                     # message, but this is fine if silently ignored
    00125                     msg.debug( "failed access to: %s ... skipping", realname )
    00126                     continue
    00127
    00128                 # at this point the list of fds may still include temp files
    00129                 # TODO: figure out if they can be identified (seeing /tmp is
    00130                 # not enough as folks like to run with data from /tmp b/c of
    00131                 # space constraints on /afs
    00132
    00133         msg.debug( "extract_fds.fds_dict=%s" % self)
    00134         return
    00135
    00136     pass #FdsDict
    00137

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines