From 8e8f8dd260a51e23588f7ef8b7f080355fa3fde2 Mon Sep 17 00:00:00 2001 From: Vishal Kanaujia Date: Tue, 6 Dec 2016 18:38:24 +0530 Subject: [PATCH] tools: cleanup phase of cephfs-data-scan cephfs-data-scan has a new optional phase to delete xattrs generated during recovery. Signed-off-by: Vishal Kanaujia --- doc/cephfs/disaster-recovery.rst | 7 +++++++ src/cls/cephfs/cls_cephfs_client.cc | 15 +++++++++++++++ src/cls/cephfs/cls_cephfs_client.h | 4 ++++ src/tools/cephfs/DataScan.cc | 29 +++++++++++++++++++++++++++-- src/tools/cephfs/DataScan.h | 5 +++++ 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/doc/cephfs/disaster-recovery.rst b/doc/cephfs/disaster-recovery.rst index ee54c90a70a..8b6ffe90582 100644 --- a/doc/cephfs/disaster-recovery.rst +++ b/doc/cephfs/disaster-recovery.rst @@ -161,6 +161,13 @@ the range 0-(N_workers - 1), like so: It is important to ensure that all workers have completed the scan_extents phase before any workers enter the scan_inodes phase. +After completing the metadata recovery, you may want to run cleanup +operation to delete ancillary data geneated during recovery. + +:: + + cephfs-data-scan cleanup + Finding files affected by lost data PGs --------------------------------------- diff --git a/src/cls/cephfs/cls_cephfs_client.cc b/src/cls/cephfs/cls_cephfs_client.cc index 9bc97aeb055..17202bb3844 100644 --- a/src/cls/cephfs/cls_cephfs_client.cc +++ b/src/cls/cephfs/cls_cephfs_client.cc @@ -50,6 +50,21 @@ int ClsCephFSClient::accumulate_inode_metadata( return ctx.operate(zeroth_object.name, &op, &outbl); } +int ClsCephFSClient::delete_inode_accumulate_result( + librados::IoCtx &ctx, + const std::string &oid) +{ + librados::ObjectWriteOperation op; + + // Remove xattrs from object + // + op.rmxattr(XATTR_CEILING); + op.rmxattr(XATTR_MAX_SIZE); + op.rmxattr(XATTR_MAX_MTIME); + + return (ctx.operate(oid, &op)); +} + int ClsCephFSClient::fetch_inode_accumulate_result( librados::IoCtx &ctx, const std::string &oid, diff --git a/src/cls/cephfs/cls_cephfs_client.h b/src/cls/cephfs/cls_cephfs_client.h index 51d12231230..1305358f385 100644 --- a/src/cls/cephfs/cls_cephfs_client.h +++ b/src/cls/cephfs/cls_cephfs_client.h @@ -23,6 +23,10 @@ class ClsCephFSClient file_layout_t *layout, AccumulateResult *result); + static int delete_inode_accumulate_result( + librados::IoCtx &ctx, + const std::string &oid); + static void build_tag_filter( const std::string &scrub_tag, bufferlist *out_bl); diff --git a/src/tools/cephfs/DataScan.cc b/src/tools/cephfs/DataScan.cc index 6cd3a508c56..951a0171353 100644 --- a/src/tools/cephfs/DataScan.cc +++ b/src/tools/cephfs/DataScan.cc @@ -42,6 +42,7 @@ void DataScan::usage() << " --force-pool: use data pool even if it is not in FSMap\n" << "\n" << " cephfs-data-scan scan_frags [--force-corrupt]\n" + << " cephfs-data-scan cleanup \n" << std::endl; generic_client_usage(); @@ -165,7 +166,9 @@ int DataScan::main(const std::vector &args) // Trailing positional argument if (i + 1 == args.end() && - (command == "scan_inodes" || command == "scan_extents")) { + (command == "scan_inodes" + || command == "scan_extents" + || command == "cleanup")) { data_pool_name = *i; continue; } @@ -235,7 +238,8 @@ int DataScan::main(const std::vector &args) // Initialize data_io for those commands that need it if (command == "scan_inodes" || - command == "scan_extents") { + command == "scan_extents" || + command == "cleanup") { if (data_pool_name.empty()) { std::cerr << "Data pool not specified" << std::endl; usage(); @@ -300,6 +304,8 @@ int DataScan::main(const std::vector &args) return scan_frags(); } else if (command == "scan_links") { return scan_links(); + } else if (command == "cleanup") { + return cleanup(); } else if (command == "init") { return driver->init_roots(fs->mds_map.get_first_data_pool()); } else { @@ -844,6 +850,25 @@ int DataScan::scan_inodes() }); } +int DataScan::cleanup() +{ + // We are looking for only zeroth object + // + return forall_objects(data_io, true, [this]( + std::string const &oid, + uint64_t obj_name_ino, + uint64_t obj_name_offset) -> int + { + int r = 0; + r = ClsCephFSClient::delete_inode_accumulate_result(data_io, oid); + if (r < 0) { + dout(4) << "Error deleting accumulated metadata from '" + << oid << "': " << cpp_strerror(r) << dendl; + } + return r; + }); +} + bool DataScan::valid_ino(inodeno_t ino) const { return (ino >= inodeno_t((1ull << 40))) diff --git a/src/tools/cephfs/DataScan.h b/src/tools/cephfs/DataScan.h index 462699d2224..6c482e63382 100644 --- a/src/tools/cephfs/DataScan.h +++ b/src/tools/cephfs/DataScan.h @@ -261,6 +261,11 @@ class DataScan : public MDSUtility, public MetadataTool */ int scan_frags(); + /** + * Cleanup xattrs from data pool + */ + int cleanup(); + /** * Check if an inode number is in the permitted ranges */ -- 2.39.5