]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs-tool: Add filesystem statistics reporting before and after benchmark runs
authorEdwin Rodriguez <edwin.rodriguez1@ibm.com>
Thu, 18 Jun 2026 14:14:43 +0000 (10:14 -0400)
committerEdwin Rodriguez <edwin.rodriguez1@ibm.com>
Wed, 1 Jul 2026 13:11:15 +0000 (09:11 -0400)
Added filesystem stats reporting to cephfs-tool.cc.

Helper functions
• fetch_statvfs() — uses ceph_ll_statfs on the root inode when --async-io
  is set, otherwise ceph_statfs on mount_root
• report_fs_stats() — prints and optionally JSON-encodes:
  • Total / free blocks
  • File count

When it runs
• Before the iteration loop (after the bench directory is created)
• After all iterations finish (before the final report and optional cleanup)

Console output example

Filesystem statistics (before iterations):
  Total blocks:      ...
  Free blocks:       ...
  Files:             ...

JSON output (when --json is used) adds a filesystem_stats section with before
and after objects containing the same fields.

Fixes: https://tracker.ceph.com/issues/76183
Signed-off-by: Edwin Rodriguez <edwin.rodriguez1@ibm.com>
src/tools/cephfs/cephfs-tool.cc

index 8c6af13bb8a413f3534b2fde437735e7a0344325..aa393cb55b346723cc8425671754096f01861273 100644 (file)
@@ -40,6 +40,7 @@
 // Standard Public Ceph API
 #include <cephfs/libcephfs.h>
 #include <fcntl.h>
+#include <sys/statvfs.h>
 #include <unistd.h>
 
 // Boost Program Options
@@ -1221,6 +1222,54 @@ print_statistics(
   }
 }
 
+static void dump_statvfs_json(ceph::Formatter* f, const struct statvfs& st)
+{
+  f->dump_unsigned("block_size", st.f_bsize);
+  f->dump_unsigned("total_blocks", st.f_blocks);
+  f->dump_unsigned("free_blocks", st.f_bfree);
+  f->dump_unsigned("files", st.f_files);
+}
+
+static int fetch_statvfs(struct ceph_mount_info* cmount,
+                         const BenchConfig& config,
+                         struct statvfs* stbuf)
+{
+  if (config.async_io) {
+    Inode* root = nullptr;
+    int rc = ceph_ll_lookup_root(cmount, &root);
+    if (rc < 0) {
+      return rc;
+    }
+    return ceph_ll_statfs(cmount, root, stbuf);
+  }
+  return ceph_statfs(cmount, config.mount_root.c_str(), stbuf);
+}
+
+static void report_fs_stats(const char* phase,
+                            struct ceph_mount_info* cmount,
+                            const BenchConfig& config,
+                            ceph::Formatter* json_formatter)
+{
+  struct statvfs stbuf = {};
+  int rc = fetch_statvfs(cmount, config, &stbuf);
+  if (rc < 0) {
+    cerr << "Failed to get filesystem stats (" << phase << "): "
+         << strerror(-rc) << std::endl;
+    return;
+  }
+
+  cout << "\nFilesystem statistics (" << phase << " iterations):" << std::endl;
+  cout << "  Total blocks:      " << stbuf.f_blocks << std::endl;
+  cout << "  Free blocks:       " << stbuf.f_bfree << std::endl;
+  cout << "  Files:             " << stbuf.f_files << std::endl;
+
+  if (json_formatter) {
+    json_formatter->open_object_section(phase);
+    dump_statvfs_json(json_formatter, stbuf);
+    json_formatter->close_section();
+  }
+}
+
 // Helper to check for errors and print them
 bool check_and_report_errors(const std::atomic<bool>& stop_signal,
                              const std::vector<std::stringstream>& outputs) {
@@ -1366,6 +1415,11 @@ int do_bench(BenchConfig& config) {
   int files_per_thread = config.num_files / config.num_threads;
   int remainder = config.num_files % config.num_threads;
 
+  if (json_formatter) {
+    json_formatter->open_object_section("filesystem_stats");
+  }
+  report_fs_stats("before", shared_cmount, config, json_formatter.get());
+
   std::vector<double> write_mbps;
   std::vector<double> write_fps;
   std::vector<double> read_mbps;
@@ -1641,6 +1695,11 @@ int do_bench(BenchConfig& config) {
     }
   }
 
+  report_fs_stats("after", shared_cmount, config, json_formatter.get());
+  if (json_formatter) {
+    json_formatter->close_section(); // filesystem_stats
+  }
+
   cout << std::endl << std::endl << "*** Final Report ***" << std::endl;
 
   if (json_formatter) {