code review

pull/1778/head
sebres 2017-05-15 15:20:43 +02:00
parent 5c1d01bf58
commit 16a84ca0b5
2 changed files with 57 additions and 56 deletions

View File

@ -895,7 +895,7 @@ class FileFilter(Filter):
# see http://python.org/dev/peps/pep-3151/ # see http://python.org/dev/peps/pep-3151/
except IOError as e: except IOError as e:
logSys.error("Unable to open %s", filename) logSys.error("Unable to open %s", filename)
if e.errno != 2: if e.errno != 2: # errno.ENOENT
logSys.exception(e) logSys.exception(e)
return False return False
except OSError as e: # pragma: no cover - requires race condition to tigger this except OSError as e: # pragma: no cover - requires race condition to tigger this

View File

@ -89,23 +89,12 @@ class FilterPyinotify(FileFilter):
logSys.log(7, "[%s] %sCallback for Event: %s", self.jailName, origin, event) logSys.log(7, "[%s] %sCallback for Event: %s", self.jailName, origin, event)
path = event.pathname path = event.pathname
# check watching of this path: # check watching of this path:
isWF = isWD = False isWF = False
if path in self.__watchDirs: isWD = path in self.__watchDirs
isWD = True if not isWD and path in self.__watchFiles:
elif path in self.__watchFiles:
isWF = True isWF = True
# fix pyinotify behavior with '-unknown-path' (if target not watched also):
if (event.mask & pyinotify.IN_MOVE_SELF and
path.endswith('-unknown-path') and not isWF and not isWD
):
path = path[:-len('-unknown-path')]
isWD = path in self.__watchDirs
assumeNoDir = False assumeNoDir = False
if event.mask & ( pyinotify.IN_CREATE | pyinotify.IN_MOVED_TO ): if event.mask & ( pyinotify.IN_CREATE | pyinotify.IN_MOVED_TO ):
# refresh watched dir (may be expected):
if isWD:
self._refreshWatcher(path, isDir=True)
return
# skip directories altogether # skip directories altogether
if event.mask & pyinotify.IN_ISDIR: if event.mask & pyinotify.IN_ISDIR:
logSys.debug("Ignoring creation of directory %s", path) logSys.debug("Ignoring creation of directory %s", path)
@ -116,8 +105,14 @@ class FilterPyinotify(FileFilter):
return return
self._refreshWatcher(path) self._refreshWatcher(path)
elif event.mask & (pyinotify.IN_IGNORED | pyinotify.IN_MOVE_SELF | pyinotify.IN_DELETE_SELF): elif event.mask & (pyinotify.IN_IGNORED | pyinotify.IN_MOVE_SELF | pyinotify.IN_DELETE_SELF):
# watch was removed for some reasons (log-rotate?):
assumeNoDir = event.mask & (pyinotify.IN_MOVE_SELF | pyinotify.IN_DELETE_SELF) assumeNoDir = event.mask & (pyinotify.IN_MOVE_SELF | pyinotify.IN_DELETE_SELF)
# fix pyinotify behavior with '-unknown-path' (if target not watched also):
if (assumeNoDir and
path.endswith('-unknown-path') and not isWF and not isWD
):
path = path[:-len('-unknown-path')]
isWD = path in self.__watchDirs
# watch was removed for some reasons (log-rotate?):
if isWD and (assumeNoDir or not os.path.isdir(path)): if isWD and (assumeNoDir or not os.path.isdir(path)):
self._addPending(path, event, isDir=True) self._addPending(path, event, isDir=True)
elif not isWF: elif not isWF:
@ -153,7 +148,7 @@ class FilterPyinotify(FileFilter):
def _addPending(self, path, reason, isDir=False): def _addPending(self, path, reason, isDir=False):
if path not in self.__pending: if path not in self.__pending:
self.__pending[path] = [self.sleeptime / 10, isDir]; self.__pending[path] = [Utils.DEFAULT_SLEEP_INTERVAL, isDir];
self.__pendingNextTime = 0 self.__pendingNextTime = 0
if isinstance(reason, pyinotify.Event): if isinstance(reason, pyinotify.Event):
reason = [reason.maskname, reason.pathname] reason = [reason.maskname, reason.pathname]
@ -166,43 +161,49 @@ class FilterPyinotify(FileFilter):
except KeyError: pass except KeyError: pass
def _checkPending(self): def _checkPending(self):
if self.__pending: if not self.__pending:
ntm = time.time() return
if ntm > self.__pendingNextTime: ntm = time.time()
found = {} if ntm < self.__pendingNextTime:
minTime = 60 return
for path, (retardTM, isDir) in self.__pending.iteritems(): found = {}
if ntm - self.__pendingChkTime < retardTM: minTime = 60
if minTime > retardTM: minTime = retardTM for path, (retardTM, isDir) in self.__pending.iteritems():
continue if ntm - self.__pendingChkTime < retardTM:
chkpath = os.path.isdir if isDir else os.path.isfile if minTime > retardTM: minTime = retardTM
if not chkpath(path): # not found - prolong for next time continue
if retardTM < 60: retardTM *= 2 chkpath = os.path.isdir if isDir else os.path.isfile
if minTime > retardTM: minTime = retardTM if not chkpath(path): # not found - prolong for next time
self.__pending[path][0] = retardTM if retardTM < 60: retardTM *= 2
continue if minTime > retardTM: minTime = retardTM
logSys.log(logging.MSG, "Log presence detected for %s %s", self.__pending[path][0] = retardTM
"directory" if isDir else "file", path) continue
found[path] = isDir logSys.log(logging.MSG, "Log presence detected for %s %s",
for path in found: "directory" if isDir else "file", path)
try: found[path] = isDir
del self.__pending[path] for path in found:
except KeyError: pass try:
self.__pendingChkTime = time.time() del self.__pending[path]
self.__pendingNextTime = self.__pendingChkTime + minTime except KeyError: pass
# process now because we'he missed it in monitoring: self.__pendingChkTime = time.time()
for path, isDir in found.iteritems(): self.__pendingNextTime = self.__pendingChkTime + minTime
self._refreshWatcher(path, isDir=isDir) # process now because we've missed it in monitoring:
if isDir: for path, isDir in found.iteritems():
for logpath in self.__watchFiles: # refresh monitoring of this:
if logpath.startswith(path + pathsep): self._refreshWatcher(path, isDir=isDir)
if not os.path.isfile(logpath): if isDir:
self._addPending(logpath, ['FROM_PARDIR', path]) # check all files belong to this dir:
else: for logpath in self.__watchFiles:
self._refreshWatcher(logpath) if logpath.startswith(path + pathsep):
self._process_file(logpath) # if still no file - add to pending, otherwise refresh and process:
else: if not os.path.isfile(logpath):
self._process_file(path) self._addPending(logpath, ('FROM_PARDIR', path))
else:
self._refreshWatcher(logpath)
self._process_file(logpath)
else:
# process (possibly no old events for it from watcher):
self._process_file(path)
def _refreshWatcher(self, oldPath, newPath=None, isDir=False): def _refreshWatcher(self, oldPath, newPath=None, isDir=False):
if not newPath: newPath = oldPath if not newPath: newPath = oldPath
@ -286,7 +287,7 @@ class FilterPyinotify(FileFilter):
def __process_default(self, event): def __process_default(self, event):
try: try:
self.callback(event, origin='Default ') self.callback(event, origin='Default ')
except Exception as e: except Exception as e: # pragma: no cover
logSys.error("Error in FilterPyinotify callback: %s", logSys.error("Error in FilterPyinotify callback: %s",
e, exc_info=logSys.getEffectiveLevel() <= logging.DEBUG) e, exc_info=logSys.getEffectiveLevel() <= logging.DEBUG)
self.ticks += 1 self.ticks += 1
@ -300,7 +301,7 @@ class FilterPyinotify(FileFilter):
pass pass
# check pending files/dirs (logrotate ready): # check pending files/dirs (logrotate ready):
if not self.idle: if not self.idle and self.active:
self._checkPending() self._checkPending()
self.ticks += 1 self.ticks += 1