diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem index 6d3960162..7021f13da 100755 --- a/heartbeat/Filesystem +++ b/heartbeat/Filesystem @@ -680,16 +680,40 @@ get_pids() # -path "/proc/[!0-9]*" -prune -o ... # -path "/proc/[0-9]*" -a ... # the latter seemd to be significantly faster for this one in my naive test. - procs=$(exec 2>/dev/null; - find /proc -path "/proc/[0-9]*" -type l \( -lname "${dir}/*" -o -lname "${dir}" \) -print | - awk -F/ '{print $3}' | uniq) - - # This finds both /proc//maps and /proc//task//maps; - # if you don't want the latter, add -maxdepth. - mmap_procs=$(exec 2>/dev/null; - find /proc -path "/proc/[0-9]*/maps" -print | - xargs -r grep -l " ${dir}/" | awk -F/ '{print $3}' | uniq) - printf "${procs}\n${mmap_procs}" | sort -u + + # root, cwd, exe, maps, fd: all per process, not per task ("thread"). + # -maxdepth to avoid repeatedly scanning the same thing + # for all threads of a heavily threaded process. + # + # Adding -maxdepth reduced scanning from > 16 seconds to < 2 seconds + # on a mostly idle system that happened to run a few java processes. + # + # We can also add a dedicated helper in C do twhat is done below, + # which would reduce the scanning time by an + # additional factor of 10 again. + # + # Or trust that fuser (above) learned something in the last 15 years + # and avoids blocking operations meanwhile? + ( + # If you want to debug this, drop this redirection. + # But it producess too much "No such file" noise for kernel + # threads or due to races with exiting processes or closing fds. + exec 2>/dev/null; + find /proc -mindepth 1 -maxdepth 3 \ + -path "/proc/[0-9]*" \ + -type l \( -lname "${dir}/*" -o -lname "${dir}" \) -print | + awk -F/ '{print $3}' | uniq + + # If we have "map_files/", "find" above already found the + # relevant symlinks, and we don't need to grep "maps" below. + # Available since kernel 3.3, respectively 4.3. + test -d /proc/$$/map_files || + # memory mappings are also per process, not per task. + # This finds only /proc//maps, and not /proc//task//maps; + # if you also want the latter, drop -maxdepth. + find /proc -mindepth 2 -maxdepth 2 -path "/proc/[0-9]*/maps" -print | + xargs -r grep -l " ${dir}/" | awk -F/ '{print $3}' | uniq + ) | sort -u fi }