mirror of https://github.com/fail2ban/fail2ban
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
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…
Reference in New Issue