ENH(+possibly BF): for FilterPoll rely not only on mtime but also ino and size to assess if file was modified

mtime alone is a poor measure here as many of our tests shown -- on older Pythons and some file systems
mtime might be reported only with precision up to a second.  If file gets rotated fast, or there are new
modifications within the same second, fail2ban might miss them with Polling backend if judging only by
mtime.  With this modification we will track also inode and size which are all indicative of a file
change.
pull/280/head
Yaroslav Halchenko 12 years ago
parent 8c125b6053
commit f340e5c0f5

@ -57,7 +57,7 @@ class FilterPoll(FileFilter):
FileFilter.__init__(self, jail)
self.__modified = False
## The time of the last modification of the file.
self.__lastModTime = dict()
self.__prevStats = dict()
self.__file404Cnt = dict()
logSys.debug("Created FilterPoll")
@ -67,7 +67,7 @@ class FilterPoll(FileFilter):
# @param path log file path
def _addLogPath(self, path):
self.__lastModTime[path] = 0
self.__prevStats[path] = (0, None, None) # mtime, ino, size
self.__file404Cnt[path] = 0
##
@ -76,7 +76,7 @@ class FilterPoll(FileFilter):
# @param path the log file to delete
def _delLogPath(self, path):
del self.__lastModTime[path]
del self.__prevStats[path]
del self.__file404Cnt[path]
##
@ -126,18 +126,20 @@ class FilterPoll(FileFilter):
def isModified(self, filename):
try:
logStats = os.stat(filename)
stats = logStats.st_mtime, logStats.st_ino, logStats.st_size
pstats = self.__prevStats[filename]
self.__file404Cnt[filename] = 0
if logSys.getEffectiveLevel() <= 7:
# we do not want to waste time on strftime etc if not necessary
dt = logStats.st_mtime - self.__lastModTime[filename]
logSys.log(7, "Checking %s for being modified. Previous/current mtimes: %s / %s. dt: %s",
filename, _ctime(self.__lastModTime[filename]), _ctime(logStats.st_mtime), dt)
dt = logStats.st_mtime - pstats[0]
logSys.log(7, "Checking %s for being modified. Previous/current stats: %s / %s. dt: %s",
filename, pstats, stats, dt)
# os.system("stat %s | grep Modify" % filename)
if self.__lastModTime[filename] == logStats.st_mtime:
if pstats == stats:
return False
else:
logSys.debug(filename + " has been modified")
self.__lastModTime[filename] = logStats.st_mtime
logSys.debug("%s has been modified", filename)
self.__prevStats[filename] = stats
return True
except OSError, e:
logSys.error("Unable to get stat on %s because of: %s"

Loading…
Cancel
Save