-
Notifications
You must be signed in to change notification settings - Fork 0
/
xfs_recover.sh
executable file
·53 lines (38 loc) · 1.23 KB
/
xfs_recover.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/bin/bash
dir_name=$1
xfsdevice=$2
tmp_file=$3
# Get the agblock size as we will need this for all files we recover.
agblocks=$(xfs_db -r $xfsdevice -c sb -c p | grep ^agblocks | sed 's/.* = //')
blksize=$(xfs_db -r $xfsdevice -c sb -c p | grep ^blocksize | sed 's/.* = //')
files=$(find $dir_name -size 0)
for f in $files
do
echo $f
# Getting the inode of the file we want to recover
inode=$(ls -i $f | cut -f1 -d ' ')
user=$(ls -l $f | cut -f3 -d ' ')
group=$(ls -l $f | cut -f4 -d ' ')
perm=$(stat -c "%a" $f)
# Getting info on this inode
dbinfo=$(xfs_db -r $xfsdevice -c "inode $inode" -c "bmap")
# Grabbing field 6
agoffset=$(echo $dbinfo | cut -f6 -d ' ')
if [[ ! -z $agoffset ]];
then
# Removing head and tail parentheses
agoffset=${agoffset//(}
agoffset=${agoffset//)}
agnumber=$(echo $agoffset | cut -f1 -d '/')
offset=$(echo $agoffset | cut -f2 -d '/')
#Grabbing field 8 which is the count.
count=$(echo $dbinfo | cut -f8 -d ' ')
# Copy file off of disk to a temp file.
dd if=$xfsdevice bs=$blksize skip=$(($agblocks * $agnumber + $offset)) count=$count of=$tmp_file
# Copy over permissions
chown $user:$group $tmp_file
chmod $perm $tmp_file
# Copy file back.
mv -f $tmp_file $f
fi
done