The little things give you away... A collection of various small helper stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

83 lines
3.5 KiB

  1. #!/bin/bash
  2. # kill-wpull-connections is a workaround for wpull's bug of HTTPS connections getting stuck, slowing down or entirely stopping progress (https://github.com/ArchiveTeam/wpull/issues/407).
  3. # It works by attaching to the process and shutting down the TCP connections directly using the `shutdown` syscall. Although written for use with wpull, it can actually be used for any process.
  4. #
  5. # Usage:
  6. # - To kill all TCP connections except those to 127.0.0.1 of a process: `kill-wpull-connections -p $PID`
  7. # - As a convenience option for ArchiveBot pipeline maintainers, to kill the connections of a running ArchiveBot job: `kill-wpull-connections -j $JOBID`
  8. # - If you get an error of `gdb.error: 'shutdown' has unknown return type; cast the call to its declared return type` then add the `-c` option *before* `-p` or `-j`, e.g. `kill-wpull-connections -c -p $PID`.
  9. # - If you're running wpull inside a Docker container without ptrace capabilities, you need to run kill-wpull-connections outside of the container (where you do have ptrace cap) but inside the container's network namespace.
  10. # One way to do this is: `nsenter --net=$(docker inspect $CONTAINERID | jq -r .[].NetworkSettings.SandboxKey) kill-wpull-connections -p $PID`
  11. function usage_exit {
  12. # usage E -- print usage; exit with status code E
  13. echo 'Usage: kill-wpull-connections (-h | [-c] (-p PID | -j JOBID))'
  14. echo
  15. echo ' -h: Display this message and exit'
  16. echo ' -c: Cast return value of shutdown(2) to int explicitly (only necessary on broken machines)'
  17. echo ' -p PID: Kill connections of wpull process PID'
  18. echo ' -j JOBID: Kill connections of the wpull process for ArchiveBot job JOBID'
  19. exit $1
  20. }
  21. if [[ $# -eq 0 || $# -gt 3 ]]; then usage_exit 1; fi
  22. if [[ $# -eq 1 && "$1" == '-h' ]]; then usage_exit 0; fi
  23. if [[ $# -ne 2 && $# -ne 3 ]]; then usage_exit 1; fi
  24. cast=
  25. if [[ "$1" == '-c' ]]; then cast='(int)'; shift; fi
  26. if [[ "$1" != -[pj] ]]; then usage_exit 1; fi
  27. if [[ $# -ne 2 ]]; then usage_exit 1; fi
  28. if [[ "$1" == '-p' ]]
  29. then
  30. wpullPid=$2
  31. if [[ "${wpullPid}" == *[^0-9]* ]]
  32. then
  33. echo "Error: '${wpullPid}' is not a valid PID"
  34. exit 1
  35. fi
  36. elif [[ "$1" == '-j' ]]
  37. then
  38. pids=($(pgrep --full "wpull.*/$2/"))
  39. if [[ ${#pids[@]} -ne 1 ]]
  40. then
  41. echo "Error: not exactly one process found for '$2'"
  42. exit 1
  43. fi
  44. wpullPid=${pids[0]}
  45. fi
  46. if ! command -v lsof >/dev/null 2>&1
  47. then
  48. echo "Error: could not find lsof"
  49. exit 1
  50. fi
  51. if ! command -v gdb >/dev/null 2>&1
  52. then
  53. echo "Error: could not find gdb"
  54. exit 1
  55. fi
  56. if ! ps -p ${wpullPid} >/dev/null 2>&1
  57. then
  58. echo "Error: no process with PID ${wpullPid}"
  59. exit 1
  60. fi
  61. if [[ -e /proc/sys/kernel/yama/ptrace_scope && "$(< /proc/sys/kernel/yama/ptrace_scope)" != "0" && $EUID -ne 0 ]]
  62. then
  63. echo "Warning: /proc/sys/kernel/yama/ptrace_scope is not zero. You likely need to run this script as root."
  64. fi
  65. gdb -batch -batch-silent \
  66. -ex "attach ${wpullPid}" \
  67. -ex 'python import subprocess' \
  68. -ex 'python def call(s): return subprocess.call(s, shell = True) == 0' \
  69. -ex 'python call("echo '\''FDs before forced shutdown:'\''") and call("lsof -an -p '${wpullPid}' -i TCP | grep -v 127\.0\.0\.1") and ([gdb.execute("p '${cast}'shutdown(" + fd + ", 2)") for fd in subprocess.check_output("lsof -an -p '${wpullPid}' -i TCP -F pfn | awk '\''NR%2==0{fd=substr($0,2)}NR%2==1&&NR>1&&!/127\.0\.0\.1/{print fd}'\''", shell = True).decode("ascii").strip().split("\n")] or True) and call("echo '\''FDs after forced shutdown:'\''") and call("lsof -an -p '${wpullPid}' -i TCP | grep -v 127\.0\.0\.1")' \
  70. -ex detach \
  71. -ex quit