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