]> git.proxmox.com Git - ceph.git/blob - ceph/qa/workunits/fs/damage/test-first-damage.sh
update ceph source to reef 18.1.2
[ceph.git] / ceph / qa / workunits / fs / damage / test-first-damage.sh
1 #!/bin/bash
2
3 set -ex
4
5 FIRST_DAMAGE="first-damage.py"
6 FS=cephfs
7 METADATA_POOL=cephfs_meta
8 MOUNT=~/mnt/mnt.0
9
10 function usage {
11 printf '%s: [--fs=<fs_name>] [--metadata-pool=<pool>] [--first-damage=</path/to/first-damage.py>]\n'
12 exit 1
13 }
14
15
16 function create {
17 ceph config set mds mds_bal_fragment_dirs 0
18 mkdir dir
19 DIR_INODE=$(stat -c '%i' dir)
20 touch dir/a
21 touch dir/"a space"
22 mkdir dir/.snap/1
23 mkdir dir/.snap/2
24 # two snaps
25 rm dir/a
26 mkdir dir/.snap/3
27 # not present in HEAD
28 touch dir/a
29 mkdir dir/.snap/4
30 # one snap
31 rm dir/a
32 touch dir/a
33 mkdir dir/.snap/5
34 # unlink then create
35 rm dir/a
36 touch dir/a
37 # unlink then create, HEAD not snapped
38 ls dir/.snap/*/
39 mkdir big
40 BIG_DIR_INODE=$(stat -c '%i' big)
41 for i in `seq 1 15000`; do
42 touch $(printf 'big/%08d' $i)
43 done
44 }
45
46 function flush {
47 ceph tell mds."$FS":0 flush journal
48 }
49
50 function damage {
51 local IS=$(printf '%llx.%08llx' "$DIR_INODE" 0)
52 local LS=$(ceph tell mds."$FS":0 dump snaps | jq .last_created)
53
54 local T=$(mktemp -p /tmp)
55
56 # nuke snap 1 version of "a"
57 rados --pool="$METADATA_POOL" getomapval "$IS" a_$(printf %x $((LS-4))) "$T"
58 printf '\xff\xff\xff\xf0' | dd of="$T" count=4 bs=1 conv=notrunc,nocreat
59 rados --pool="$METADATA_POOL" setomapval "$IS" a_$(printf %x $((LS-4))) --input-file="$T"
60
61 # nuke snap 4 version of "a"
62 rados --pool="$METADATA_POOL" getomapval "$IS" a_$(printf %x $((LS-1))) "$T"
63 printf '\xff\xff\xff\xff' | dd of="$T" count=4 bs=1 conv=notrunc,nocreat
64 rados --pool="$METADATA_POOL" setomapval "$IS" a_$(printf %x $((LS-1))) --input-file="$T"
65
66 # screw up HEAD
67 rados --pool="$METADATA_POOL" getomapval "$IS" a_head "$T"
68 printf '\xfe\xff\xff\xff' | dd of="$T" count=4 bs=1 conv=notrunc,nocreat
69 rados --pool="$METADATA_POOL" setomapval "$IS" a_head --input-file="$T"
70
71 # screw up HEAD on what dentry in big
72 IS=$(printf '%llx.%08llx' "$BIG_DIR_INODE" 0)
73 rados --pool="$METADATA_POOL" getomapval "$IS" 00009999_head "$T"
74 printf '\xfe\xff\xff\xff' | dd of="$T" count=4 bs=1 conv=notrunc,nocreat
75 rados --pool="$METADATA_POOL" setomapval "$IS" 00009999_head --input-file="$T"
76
77 rm -f "$T"
78 }
79
80 function recover {
81 flush
82 ceph fs fail "$FS"
83 sleep 5
84 cephfs-journal-tool --rank="$FS":0 event recover_dentries summary
85 cephfs-journal-tool --rank="$FS":0 journal reset
86 python3 $FIRST_DAMAGE --debug /tmp/debug1 --memo /tmp/memo1 "$METADATA_POOL"
87 python3 $FIRST_DAMAGE --debug /tmp/debug2 --memo /tmp/memo2 --repair-nosnap "$METADATA_POOL"
88 python3 $FIRST_DAMAGE --debug /tmp/debug3 --memo /tmp/memo3 --remove "$METADATA_POOL"
89 ceph fs set "$FS" joinable true
90 }
91
92 function check {
93 stat dir || exit 1
94 stat dir/a || exit 1
95 for i in `seq 1 5`; do
96 stat dir/.snap/$i || exit 2
97 done
98 stat dir/.snap/2/a || exit 3
99 stat dir/.snap/5/a || exit 4
100 if stat dir/.snap/1/a; then
101 echo should be gone
102 exit 5
103 fi
104 if stat dir/.snap/3/a; then
105 echo should not ever exist
106 exit 6
107 fi
108 if stat dir/.snap/4/a; then
109 echo should be gone
110 exit 7
111 fi
112 }
113
114 function cleanup {
115 rmdir dir/.snap/*
116 find dir
117 rm -rf dir
118 }
119
120 function mount {
121 sudo --preserve-env=CEPH_CONF bin/mount.ceph :/ "$MOUNT" -o name=admin,noshare
122 df -h "$MOUNT"
123 }
124
125 function main {
126 eval set -- $(getopt --name "$0" --options '' --longoptions 'help,fs:,metadata-pool:,first-damage:,mount:' -- "$@")
127
128 while [ "$#" -gt 0 ]; do
129 echo "$*"
130 echo "$1"
131 case "$1" in
132 -h|--help)
133 usage
134 ;;
135 --fs)
136 FS="$2"
137 shift 2
138 ;;
139 --metadata-pool)
140 METADATA_POOL="$2"
141 shift 2
142 ;;
143 --mount)
144 MOUNT="$2"
145 shift 2
146 ;;
147 --first-damage)
148 FIRST_DAMAGE="$2"
149 shift 2
150 ;;
151 --)
152 shift
153 break
154 ;;
155 *)
156 usage
157 ;;
158 esac
159 done
160
161 mount
162
163 pushd "$MOUNT"
164 create
165 popd
166
167 sudo umount -f "$MOUNT"
168
169 # flush dentries/inodes to omap
170 flush
171
172 damage
173
174 recover
175
176 sleep 5 # for mds to join
177
178 mount
179
180 pushd "$MOUNT"
181 check
182 cleanup
183 popd
184
185 sudo umount -f "$MOUNT"
186 }
187
188 main "$@"