]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw-orphan-list
import ceph 16.2.6
[ceph.git] / ceph / src / rgw / rgw-orphan-list
CommitLineData
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 7export LC_ALL=C
e306af50
TL
8
9out_dir="."
10temp_file=/tmp/temp.$$
f91f0fd5 11timestamp=$(date -u +%Y%m%d%H%M%S)
e306af50
TL
12lspools_err="${out_dir}/lspools-${timestamp}.error"
13rados_out="${out_dir}/rados-${timestamp}.intermediate"
f91f0fd5 14rados_odd="${out_dir}/rados-${timestamp}.issues"
e306af50
TL
15rados_err="${out_dir}/rados-${timestamp}.error"
16rgwadmin_out="${out_dir}/radosgw-admin-${timestamp}.intermediate"
17rgwadmin_err="${out_dir}/radosgw-admin-${timestamp}.error"
18delta_out="${out_dir}/orphan-list-${timestamp}.out"
19
20error_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
34prompt_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
48if [ $# -eq 0 ] ;then
49 pool="$(prompt_pool)"
e306af50 50else
522d829b 51 pool="$*"
e306af50
TL
52fi
53
54echo "Pool is \"$pool\"."
55
56echo "Note: output files produced will be tagged with the current timestamp -- ${timestamp}."
57
58echo "running 'rados ls' at $(date)"
f91f0fd5 59# since --format is not specified, plain should be used
522d829b
TL
60
61rm -f "$rados_out" &> /dev/null
62for 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
68done
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 89grep --text $'^[^\t]' "$rados_out" >"$rados_odd"
f91f0fd5
TL
90if [ "${PIPESTATUS[0]}" -eq 0 ] ;then
91 namespace_found=1
92fi
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 98egrep --text $'^\t[[:graph:]]+\t' "$rados_out" >>"$rados_odd"
f91f0fd5
TL
99if [ "${PIPESTATUS[0]}" -eq 0 ] ;then
100 locator_found=1
101fi
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 107grep --text $'^\t' "$rados_out" | grep --text -v $'^\t.*\t' | sed -E 's/^\t//' >"$temp_file"
f91f0fd5
TL
108mv -f "$temp_file" "$rados_out"
109
e306af50
TL
110sort -u "$rados_out" >"$temp_file"
111mv -f "$temp_file" "$rados_out"
112
113echo "running 'radosgw-admin bucket radoslist' at $(date)"
114radosgw-admin bucket radoslist >"$rgwadmin_out" 2>"$rgwadmin_err"
115if [ "$?" -ne 0 ] ;then
116 error_out "radosgw-admin radoslist" "$rgwadmin_err"
117fi
118sort -u "$rgwadmin_out" >"$temp_file"
119mv -f "$temp_file" "$rgwadmin_out"
120
121echo "computing delta at $(date)"
f67539c2 122ceph-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
125if [ "${PIPESTATUS[0]}" -gt 1 ] ;then
126 error_out "ceph-diff-sorted"
127fi
128
f6b5b4d7
TL
129found=$(wc -l < "$delta_out")
130possible=$(wc -l < "$rados_out")
131percentage=0
132if [ $possible -ne 0 ] ;then
133 percentage=$(expr 100 \* $found / $possible)
134fi
e306af50
TL
135
136echo "$found potential orphans found out of a possible $possible (${percentage}%)."
f91f0fd5
TL
137echo "The results can be found in '${delta_out}'."
138echo " Intermediate files are '${rados_out}' and '${rgwadmin_out}'."
139if [ -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."
142fi
e306af50
TL
143echo "***"
144echo "*** WARNING: This is EXPERIMENTAL code and the results should be used"
145echo "*** only with CAUTION!"
146echo "***"
147echo "Done at $(date)."