summaryrefslogtreecommitdiffstats
path: root/src/tools/cephfs/DataScan.cc
diff options
context:
space:
mode:
authorJohn Spray <john.spray@redhat.com>2015-07-27 12:07:49 +0200
committerYan, Zheng <zyan@redhat.com>2015-12-02 08:24:04 +0100
commite04beab82acf3a2212036a6191c2b8f80ef93013 (patch)
tree211b1fc77b5f98d41aec52e525e3058983dc9340 /src/tools/cephfs/DataScan.cc
parenttools/cephfs: fix datascan kwarg parsing (diff)
downloadceph-e04beab82acf3a2212036a6191c2b8f80ef93013.tar.xz
ceph-e04beab82acf3a2212036a6191c2b8f80ef93013.zip
tools/cephfs: enable tag filter in DataScan
Fixes: #12133 Signed-off-by: John Spray <john.spray@redhat.com>
Diffstat (limited to 'src/tools/cephfs/DataScan.cc')
-rw-r--r--src/tools/cephfs/DataScan.cc71
1 files changed, 65 insertions, 6 deletions
diff --git a/src/tools/cephfs/DataScan.cc b/src/tools/cephfs/DataScan.cc
index f9c491dbb70..96f09ce9cb9 100644
--- a/src/tools/cephfs/DataScan.cc
+++ b/src/tools/cephfs/DataScan.cc
@@ -60,6 +60,7 @@ bool DataScan::parse_kwarg(
*r = -EINVAL;
return false;
}
+ dout(4) << "Using local file output to '" << val << "'" << dendl;
driver = new LocalFileDriver(val, data_io);
return true;
} else if (arg == std::string("-n")) {
@@ -80,6 +81,10 @@ bool DataScan::parse_kwarg(
return false;
}
return true;
+ } else if (arg == std::string("--filter-tag")) {
+ filter_tag = val;
+ dout(10) << "Applying tag filter: '" << filter_tag << "'" << dendl;
+ return true;
} else {
return false;
}
@@ -156,6 +161,7 @@ int DataScan::main(const std::vector<const char*> &args)
driver = new MetadataDriver();
driver->set_force_corrupt(force_corrupt);
driver->set_force_init(force_init);
+ dout(4) << "Using metadata pool output" << dendl;
}
dout(4) << "connecting to RADOS..." << dendl;
@@ -447,7 +453,28 @@ int DataScan::scan_inodes()
float progress = 0.0;
librados::NObjectIterator i = data_io.nobjects_begin(n, m);
#else
- librados::NObjectIterator i = data_io.nobjects_begin();
+ librados::NObjectIterator i;
+ bool legacy_filtering = false;
+
+ bufferlist filter_bl;
+ ClsCephFSClient::build_tag_filter(filter_tag, &filter_bl);
+
+ // try/catch to deal with older OSDs that don't support
+ // the cephfs pgls filtering mode
+ try {
+ i = data_io.nobjects_begin(filter_bl);
+ dout(4) << "OSDs accepted cephfs object filtering" << dendl;
+ } catch (const std::runtime_error &e) {
+ // A little unfriendly, librados raises std::runtime_error
+ // on pretty much any unhandled I/O return value, such as
+ // the OSD saying -EINVAL because of our use of a filter
+ // mode that it doesn't know about.
+ std::cerr << "OSDs do not support cephfs object filtering: using "
+ "(slower) fallback mode" << std::endl;
+ legacy_filtering = true;
+ i = data_io.nobjects_begin();
+ }
+
#endif
librados::NObjectIterator i_end = data_io.nobjects_end();
@@ -484,10 +511,38 @@ int DataScan::scan_inodes()
continue;
}
- // We are only interested in 0th objects during this phase: we touched
- // the other objects during scan_extents
- if (obj_name_offset != 0) {
- continue;
+ if (legacy_filtering) {
+ dout(20) << "Applying filter to " << oid << dendl;
+
+ // We are only interested in 0th objects during this phase: we touched
+ // the other objects during scan_extents
+ if (obj_name_offset != 0) {
+ dout(20) << "Non-zeroth object" << dendl;
+ continue;
+ }
+
+ bufferlist scrub_tag_bl;
+ int r = data_io.getxattr(oid, "scrub_tag", scrub_tag_bl);
+ if (r >= 0) {
+ std::string read_tag;
+ bufferlist::iterator q = scrub_tag_bl.begin();
+ try {
+ ::decode(read_tag, q);
+ if (read_tag == filter_tag) {
+ dout(20) << "skipping " << oid << " because it has the filter_tag"
+ << dendl;
+ continue;
+ }
+ } catch (const buffer::error &err) {
+ }
+ dout(20) << "read non-matching tag '" << read_tag << "'" << dendl;
+ } else {
+ dout(20) << "no tag read (" << r << ")" << dendl;
+ }
+
+ } else {
+ assert(obj_name_offset == 0);
+ dout(20) << "OSD matched oid " << oid << dendl;
}
AccumulateResult accum_res;
@@ -496,7 +551,11 @@ int DataScan::scan_inodes()
int r = ClsCephFSClient::fetch_inode_accumulate_result(
data_io, oid, &backtrace, &loaded_layout, &accum_res);
- if (r < 0) {
+ if (r == -EINVAL) {
+ dout(4) << "Accumulated metadata missing from '"
+ << oid << ", did you run scan_extents?" << dendl;
+ continue;
+ } else if (r < 0) {
dout(4) << "Unexpected error loading accumulated metadata from '"
<< oid << "': " << cpp_strerror(r) << dendl;
// FIXME: this creates situation where if a client has a corrupt