]>
Commit | Line | Data |
---|---|---|
e306af50 TL |
1 | #!/usr/bin/env bash |
2 | ||
f67539c2 | 3 | # version 2021-02-04 |
e306af50 TL |
4 | |
5 | # IMPORTANT: affects order produced by 'sort' and 'ceph-diff-sorted' | |
6 | # relies on this ordering | |
f67539c2 | 7 | export LC_ALL=C |
e306af50 TL |
8 | |
9 | out_dir="." | |
10 | temp_file=/tmp/temp.$$ | |
f91f0fd5 | 11 | timestamp=$(date -u +%Y%m%d%H%M%S) |
e306af50 TL |
12 | lspools_err="${out_dir}/lspools-${timestamp}.error" |
13 | rados_out="${out_dir}/rados-${timestamp}.intermediate" | |
f91f0fd5 | 14 | rados_odd="${out_dir}/rados-${timestamp}.issues" |
e306af50 TL |
15 | rados_err="${out_dir}/rados-${timestamp}.error" |
16 | rgwadmin_out="${out_dir}/radosgw-admin-${timestamp}.intermediate" | |
17 | rgwadmin_err="${out_dir}/radosgw-admin-${timestamp}.error" | |
18 | delta_out="${out_dir}/orphan-list-${timestamp}.out" | |
19 | ||
20 | error_out() { | |
21 | echo "An error was encountered while running '$1'. Aborting." | |
f91f0fd5 TL |
22 | if [ $# -gt 2 ] ;then |
23 | echo "Error: $3" | |
24 | fi | |
e306af50 TL |
25 | if [ $# -gt 1 ] ;then |
26 | echo "Review file '$2' for details." | |
27 | fi | |
28 | echo "***" | |
29 | echo "*** WARNING: The results are incomplete. Do not use! ***" | |
30 | echo "***" | |
31 | exit 1 | |
32 | } | |
33 | ||
34 | prompt_pool() { | |
f6b5b4d7 TL |
35 | # note: all prompts go to stderr so stdout contains just the result |
36 | >&2 echo "Available pools:" | |
e306af50 TL |
37 | rados lspools >"$temp_file" 2>"$lspools_err" |
38 | if [ "$?" -ne 0 ] ;then | |
39 | error_out "rados lspools" "$lspools_err" | |
40 | fi | |
f6b5b4d7 | 41 | >&2 sed 's/^/ /' "$temp_file" # list pools and indent |
522d829b | 42 | >&2 printf "Which pool do you want to search for orphans (for multiple, use space-separated list)? " |
e306af50 TL |
43 | local mypool |
44 | read mypool | |
45 | echo $mypool | |
46 | } | |
47 | ||
48 | if [ $# -eq 0 ] ;then | |
49 | pool="$(prompt_pool)" | |
e306af50 | 50 | else |
522d829b | 51 | pool="$*" |
e306af50 TL |
52 | fi |
53 | ||
54 | echo "Pool is \"$pool\"." | |
55 | ||
56 | echo "Note: output files produced will be tagged with the current timestamp -- ${timestamp}." | |
57 | ||
58 | echo "running 'rados ls' at $(date)" | |
f91f0fd5 | 59 | # since --format is not specified, plain should be used |
522d829b TL |
60 | |
61 | rm -f "$rados_out" &> /dev/null | |
62 | for mypool in $pool ; do | |
63 | echo "running 'rados ls' on pool ${mypool}." | |
64 | rados ls --pool="$mypool" --all >>"$rados_out" 2>"$rados_err" | |
65 | if [ "$?" -ne 0 ] ;then | |
66 | error_out "rados ls" "$rados_err" | |
67 | fi | |
68 | done | |
f91f0fd5 TL |
69 | |
70 | # NOTE: Each entry (line of output) of `rados ls --all` should be in | |
71 | # one of four formats depending on whether or not an entry has a | |
72 | # namespace and/or locator: | |
73 | # | |
74 | # <TAB>oid | |
75 | # <TAB>oid<TAB>locator | |
76 | # namespace<TAB>oid | |
77 | # namespace<TAB>oid<TAB>locator | |
78 | # | |
79 | # Any occurrences of the 2nd, 3rd, or 4th (i.e., existence of | |
80 | # namespace and/or locator) should cause the create of the "odd" file | |
81 | # and an explanation in the output, and those entries will not be | |
82 | # retained, and therefore they will not be called out as orphans. They | |
83 | # will need special handling by the end-user as we do not expect | |
84 | # namespaces or locators. | |
85 | ||
86 | # check for namespaces -- any line that does not begin with a tab | |
87 | # indicates a namespace; add those to "odd" file and set flag; note: | |
88 | # this also picks up entries with namespace and locator | |
f67539c2 | 89 | grep --text $'^[^\t]' "$rados_out" >"$rados_odd" |
f91f0fd5 TL |
90 | if [ "${PIPESTATUS[0]}" -eq 0 ] ;then |
91 | namespace_found=1 | |
92 | fi | |
93 | ||
94 | # check for locators (w/o namespace); we idenitfy them by skipping | |
95 | # past the empty namespace (i.e., one TAB), skipping past the oid, | |
96 | # then looking for a TAB; note we use egrep to get the '+' character | |
97 | # and the $ in front of the ' allows the \t to be interpreted as a TAB | |
f67539c2 | 98 | egrep --text $'^\t[[:graph:]]+\t' "$rados_out" >>"$rados_odd" |
f91f0fd5 TL |
99 | if [ "${PIPESTATUS[0]}" -eq 0 ] ;then |
100 | locator_found=1 | |
101 | fi | |
102 | ||
103 | # extract the entries that are just oids (i.e., no namespace or | |
104 | # locator) for further processing; only look at lines that begin with | |
105 | # a TAB and do not contain a second TAB, and then grab everything | |
106 | # after the initial TAB | |
f67539c2 | 107 | grep --text $'^\t' "$rados_out" | grep --text -v $'^\t.*\t' | sed -E 's/^\t//' >"$temp_file" |
f91f0fd5 TL |
108 | mv -f "$temp_file" "$rados_out" |
109 | ||
e306af50 TL |
110 | sort -u "$rados_out" >"$temp_file" |
111 | mv -f "$temp_file" "$rados_out" | |
112 | ||
113 | echo "running 'radosgw-admin bucket radoslist' at $(date)" | |
114 | radosgw-admin bucket radoslist >"$rgwadmin_out" 2>"$rgwadmin_err" | |
115 | if [ "$?" -ne 0 ] ;then | |
116 | error_out "radosgw-admin radoslist" "$rgwadmin_err" | |
117 | fi | |
118 | sort -u "$rgwadmin_out" >"$temp_file" | |
119 | mv -f "$temp_file" "$rgwadmin_out" | |
120 | ||
121 | echo "computing delta at $(date)" | |
f67539c2 | 122 | ceph-diff-sorted "$rados_out" "$rgwadmin_out" | grep --text "^<" | sed 's/^< *//' >"$delta_out" |
e306af50 TL |
123 | # use PIPESTATUS to get at exit status of first process in above pipe; |
124 | # 0 means same, 1 means different, >1 means error | |
125 | if [ "${PIPESTATUS[0]}" -gt 1 ] ;then | |
126 | error_out "ceph-diff-sorted" | |
127 | fi | |
128 | ||
f6b5b4d7 TL |
129 | found=$(wc -l < "$delta_out") |
130 | possible=$(wc -l < "$rados_out") | |
131 | percentage=0 | |
132 | if [ $possible -ne 0 ] ;then | |
133 | percentage=$(expr 100 \* $found / $possible) | |
134 | fi | |
e306af50 TL |
135 | |
136 | echo "$found potential orphans found out of a possible $possible (${percentage}%)." | |
f91f0fd5 TL |
137 | echo "The results can be found in '${delta_out}'." |
138 | echo " Intermediate files are '${rados_out}' and '${rgwadmin_out}'." | |
139 | if [ -n "$namespace_found" -o -n "$locator_found" ] ;then | |
140 | echo " Note: 'rados ls' found entries that might be in a namespace or might" | |
141 | echo " have a locator; see '${rados_odd}' for those entries." | |
142 | fi | |
e306af50 TL |
143 | echo "***" |
144 | echo "*** WARNING: This is EXPERIMENTAL code and the results should be used" | |
145 | echo "*** only with CAUTION!" | |
146 | echo "***" | |
147 | echo "Done at $(date)." |