Last active
August 29, 2015 14:25
-
-
Save azat/35e472ccf0b0293430fa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
function pid_files() | |
{ | |
ls -l /proc/$1/fd/* | awk -v p=$pattern '$0 ~ p {fd=$(NF-2); sub(/^.*\/fd\//, "", fd); printf("%s %s\n", fd, $NF);}' | |
} | |
function pid_files_offsets() | |
{ | |
ls -1 /proc/$1/fdinfo/* | awk '{ fd=f=$NF; sub(/^.*\/fdinfo\//, "", fd); getline < f; pos=$NF; printf("%s %s\n", fd, pos); }' | |
} | |
function j_sort() { sort -k 1b,1; } | |
function pid_files_extend() | |
{ | |
join -o 1.2,2.2 -j1 \ | |
<(pid_files $1 | j_sort) \ | |
<(pid_files_offsets $1 | j_sort) | |
} | |
function usage() | |
{ | |
cat -<<EOL | |
Usage: $0 [ OPTIONS ] pid1[ pid2 ...] | |
It will replace first X bytes that already readed by PID in file that opened by | |
this PID with holes, to free space back to fs. | |
Options: | |
-p - pattern for files that can be modified | |
-D - disable dry run mode | |
-l - minimal offset after which hole is appropriate | |
EOL | |
} | |
function options() | |
{ | |
pattern=".*" | |
dry_run=1 | |
limit=$((4096 * 10)) | |
if [ $# -eq 0 ]; then | |
usage | |
exit | |
fi | |
local OPTIND c OPTARG | |
while getopts "p:l:D" c; do | |
case "$c" in | |
p) pattern="$OPTARG";; | |
D) dry_run=0;; | |
l) limit="$OPTARG";; | |
esac | |
done | |
shift $((OPTIND - 1)) | |
pids=( "$@" ) | |
} | |
function dry_run_mode() | |
{ | |
function fallocate() { echo "[fallocate]" "$@"; } | |
export -f fallocate | |
function xargs() { command xargs -t "$@"; } | |
} | |
function main() | |
{ | |
options "$@" | |
[ $dry_run -eq 0 ] || dry_run_mode | |
# otherwise we can't save extents info, that could help us to revert this? | |
if ! which filefrag >& /dev/null; then | |
echo "No filefrag" | |
exit 1 | |
fi | |
for p in "${pids[@]}"; do | |
pid_files_extend $p | \ | |
sort -u | \ | |
awk -v limit=$limit '$2 > limit' | \ | |
tee /dev/stderr | \ | |
xargs -r -n1 -i bash -c \ | |
'l=({}); f=${l[0]}; s=${l[1]}; filefrag -v $f && fallocate -p -o 0 -l $((s-limit)) $f' | |
done | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment