diff options
author | Erich Eckner <git@eckner.net> | 2019-04-08 11:20:07 +0200 |
---|---|---|
committer | Erich Eckner <git@eckner.net> | 2019-04-08 11:20:07 +0200 |
commit | e495e47515bda44ee81a7323f5318e7f45aa042a (patch) | |
tree | 5d70559b1e41cf8e0bf71b3883ec02b894d0b811 | |
download | kamikaze-fsck-e495e47515bda44ee81a7323f5318e7f45aa042a.tar.xz |
Initial commit
-rwxr-xr-x | kamikaze-fsck | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/kamikaze-fsck b/kamikaze-fsck new file mode 100755 index 0000000..6858a8a --- /dev/null +++ b/kamikaze-fsck @@ -0,0 +1,62 @@ +#!/bin/bash + +if [ $# -ne 1 ] || [ ! -b "$1" ]; then + >&2 echo 'run:' + >&2 echo ' kamikaze-fsck /dev/$device' + exit 1 +fi + +if ! [ -w "$1" ]; then + >&2 printf 'Cannot write to "%s" - you are not root, are you?\n' "$1" + exit 1 +fi + +>&2 printf 'Warning: running e2fsck in kamikaze-mode - this WILL destroy data on "%s".\n' "$1" +>&2 printf 'Enter uppercase yes to continue.\n' +read -r s +if [ "$s" != 'YES' ]; then + >&2 echo 'aborted.' + exit 1 +fi + +>&2 echo 'ok, lets do it' + +tmp_dir=$(mktemp -d) +trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT + +touch "${tmp_dir}/faulty-inode" + +while [ -f "${tmp_dir}/faulty-inode" ]; do + if [ -s "${tmp_dir}/faulty-inode" ]; then + debugfs -w "$1" -R "$(cat "${tmp_dir}/faulty-inode")" + fi + rm "${tmp_dir}/faulty-inode" + + last_faulty_inode='INVALID' + + e2fsck -f -y "$1" -E no_optimize_extents,fixes_only -C 0 \ + | tee /dev/stderr \ + | sed ' + s/^Inode \([0-9]\+\) block [0-9]\+ conflicts with critical metadata, skipping block checks\.$/\1/ + t + d + ' \ + | while read -r faulty_inode; do + if [ "${last_faulty_inode}" != "${faulty_inode}" ]; then + last_faulty_inode="${faulty_inode}" + faulty_inode_count=0 + fi + faulty_inode_count=$((faulty_inode_count+1)) + if [ ${faulty_inode_count} -ge 5 ]; then + printf 'clri <%s>\n' "${faulty_inode}" \ + >> "${tmp_dir}/faulty-inode" + + pkill -xf "e2fsck -f -y $1 -E no_optimize_extents,fixes_only -C 0" + sleep 20 + pkill -9 -xf "e2fsck -f -y $1 -E no_optimize_extents,fixes_only -C 0" + while pgrep -xf "e2fsck -f -y $1 -E no_optimize_extents,fixes_only -C 0"; do + sleep 1 + done + fi + done +done |