]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
obj_bencher: remove benchmark objects by prefix
authorMike Ryan <mike.ryan@inktank.com>
Thu, 21 Jun 2012 17:08:53 +0000 (10:08 -0700)
committerMike Ryan <mike.ryan@inktank.com>
Thu, 23 Aug 2012 22:52:16 +0000 (15:52 -0700)
This intelligently removes objects from a rados or rest benchmark run by
using parameters from the metadata file.

Signed-off-by: Mike Ryan <mike.ryan@inktank.com>
src/common/obj_bencher.cc
src/common/obj_bencher.h
src/rados.cc
src/tools/rest_bench.cc

index f8a598d0be86942260edb00ebce13b4461714416..12818fde1b341c40f2e27c1282f88585aadbf0dd 100644 (file)
@@ -27,7 +27,7 @@
 #include <sstream>
 
 
-const char *BENCH_METADATA = "benchmark_write_metadata";
+const std::string BENCH_LASTRUN_METADATA = "benchmark_last_metadata";
 const std::string BENCH_PREFIX = "benchmark_data";
 
 static std::string generate_object_prefix(int pid = 0) {
@@ -170,8 +170,8 @@ int ObjBencher::aio_bench(int operation, int secondsToRun, int concurrentios, in
 
   //get data from previous write run, if available
   if (operation != OP_WRITE) {
-    r = fetch_bench_metadata(&object_size, &num_objects, &prevPid);
-    if (r <= 0) {
+    r = fetch_bench_metadata(BENCH_LASTRUN_METADATA, &object_size, &num_objects, &prevPid);
+    if (r < 0) {
       delete[] contentsChars;
       if (r == -ENOENT)
        cerr << "Must write data before running a read benchmark!" << std::endl;
@@ -213,8 +213,8 @@ int ObjBencher::aio_bench(int operation, int secondsToRun, int concurrentios, in
   }
 
   if (OP_WRITE == operation && cleanup) {
-    r = fetch_bench_metadata(&object_size, &num_objects, &prevPid);
-    if (r <= 0) {
+    r = fetch_bench_metadata(BENCH_LASTRUN_METADATA, &object_size, &num_objects, &prevPid);
+    if (r < 0) {
       if (r == -ENOENT)
        cerr << "Should never happen: bench metadata missing for current run!" << std::endl;
       goto out;
@@ -223,9 +223,11 @@ int ObjBencher::aio_bench(int operation, int secondsToRun, int concurrentios, in
     r = clean_up(num_objects, prevPid);
     if (r != 0) goto out;
 
-    r = sync_remove(BENCH_METADATA);
+    // lastrun file
+    r = sync_remove(BENCH_LASTRUN_METADATA);
     if (r != 0) goto out;
 
+    // prefix-based file
     r = sync_remove(generate_metadata_name());
   }
 
@@ -271,12 +273,16 @@ static double vec_stddev(vector<double>& v)
   return sqrt(stddev);
 }
 
-int ObjBencher::fetch_bench_metadata(int* object_size, int* num_objects, int* prevPid) {
+int ObjBencher::fetch_bench_metadata(const std::string& metadata_file, int* object_size, int* num_objects, int* prevPid) {
   int r = 0;
   bufferlist object_data;
 
-  r = sync_read(BENCH_METADATA, object_data, sizeof(int)*3);
+  r = sync_read(metadata_file, object_data, sizeof(int)*3);
   if (r <= 0) {
+    // treat an empty file as a file that does not exist
+    if (r == 0) {
+      r = -ENOENT;
+    }
     return r;
   }
   bufferlist::iterator p = object_data.begin();
@@ -284,7 +290,7 @@ int ObjBencher::fetch_bench_metadata(int* object_size, int* num_objects, int* pr
   ::decode(*num_objects, p);
   ::decode(*prevPid, p);
 
-  return 1;
+  return 0;
 }
 
 int ObjBencher::write_bench(int secondsToRun, int concurrentios) {
@@ -461,8 +467,11 @@ int ObjBencher::write_bench(int secondsToRun, int concurrentios) {
   ::encode(data.object_size, b_write);
   ::encode(data.finished, b_write);
   ::encode(getpid(), b_write);
-  sync_write(BENCH_METADATA, b_write, sizeof(int)*3);
 
+  // lastrun file
+  sync_write(BENCH_LASTRUN_METADATA, b_write, sizeof(int)*3);
+
+  // PID-specific run
   sync_write(generate_metadata_name(), b_write, sizeof(int)*3);
 
   completions_done();
@@ -676,3 +685,28 @@ int ObjBencher::clean_up(int num_objects, int prevPid) {
 }
 
 
+int ObjBencher::clean_up(const std::string& prefix, int concurrent_ios) {
+  int r = 0;
+  int object_size;
+  int num_objects;
+  int prevPid;
+
+  std::string metadata_name = prefix;
+  metadata_name.append("_metadata");
+
+  r = fetch_bench_metadata(metadata_name, &object_size, &num_objects, &prevPid);
+  if (r < 0) {
+    return r;
+  }
+  // if this file is not found we should try to do a linear search on the prefix
+
+  r = clean_up(num_objects, prevPid);
+  if (r != 0) return r;
+
+  r = sync_remove(metadata_name);
+  if (r != 0) return r;
+
+  return 0;
+}
+
+
index 5802b53af09f254c6b31d0d2753823a4ebefb304..f766462e93cfd7ad22896608c90c39901dc20505 100644 (file)
@@ -58,7 +58,7 @@ protected:
 
   struct bench_data data;
 
-  int fetch_bench_metadata(int* object_size, int* num_objects, int* prevPid);
+  int fetch_bench_metadata(const std::string& metadata_file, int* object_size, int* num_objects, int* prevPid);
 
   int write_bench(int secondsToRun, int concurrentios);
   int seq_read_bench(int secondsToRun, int concurrentios, int num_objects, int writePid);
@@ -88,6 +88,7 @@ public:
   ObjBencher() : show_time(false), lock("ObjBencher::lock") {}
   virtual ~ObjBencher() {}
   int aio_bench(int operation, int secondsToRun, int concurrentios, int op_size, bool cleanup);
+  int clean_up(const std::string& prefix, int concurrent_ios);
 
   void set_show_time(bool dt) {
     show_time = dt;
index 323d403e53e8d6acbe3a36b9239fed95bd14e077..f02badd6809d58b995ddb0a4e91381dd0fe77deb 100644 (file)
@@ -87,6 +87,7 @@ void usage(ostream& out)
 "   bench <seconds> write|seq|rand [-t concurrent_operations] [--no-cleanup]\n"
 "                                    default is 16 concurrent IOs and 4 MB ops\n"
 "                                    default is to clean up after write benchmark\n"
+"   cleanup <prefix>                 clean up a previous benchmark operation\n"
 "   load-gen [options]               generate load on the cluster\n"
 "   listomapkeys <obj-name>          list the keys in the object map\n"
 "   getomapval <obj-name> <key>      show the value for the specified key\n"
@@ -1836,6 +1837,15 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
     if (ret != 0)
       cerr << "error during benchmark: " << ret << std::endl;
   }
+  else if (strcmp(nargs[0], "cleanup") == 0) {
+    if (!pool_name || nargs.size() < 2)
+      usage_exit();
+    const char *prefix = nargs[1];
+    RadosBencher bencher(rados, io_ctx);
+    ret = bencher.clean_up(prefix, concurrent_ios);
+    if (ret != 0)
+      cerr << "error during cleanup: " << ret << std::endl;
+  }
   else if (strcmp(nargs[0], "watch") == 0) {
     if (!pool_name || nargs.size() < 2)
       usage_exit();
index 1903907a3caf1b2601421d3a3dcb530b97ecf7ae..99d222fc8781048d8180b60055cfb4675b913460 100644 (file)
@@ -36,6 +36,7 @@ void usage(ostream& out)
 {
   out <<                                       \
 "usage: rest-bench [options] <write|seq>\n"
+"       rest-bench [options] cleanup <prefix>\n"
 "BENCHMARK OPTIONS\n"
 "   --seconds\n"
 "        benchmak length (default: 60)\n"
@@ -75,6 +76,7 @@ enum OpType {
   OP_GET_OBJ = 1,
   OP_PUT_OBJ = 2,
   OP_DELETE_OBJ = 3,
+  OP_CLEANUP = 4,
 };
 
 struct req_context : public RefCountedObject {
@@ -657,13 +659,19 @@ int main(int argc, const char **argv)
   if (args.size() < 1)
     usage_exit();
   int operation = 0;
+  const char *prefix = NULL;
   if (strcmp(args[0], "write") == 0)
     operation = OP_WRITE;
   else if (strcmp(args[0], "seq") == 0)
     operation = OP_SEQ_READ;
   else if (strcmp(args[0], "rand") == 0)
     operation = OP_RAND_READ;
-  else
+  else if (strcmp(args[0], "cleanup") == 0) {
+    if (args.size() < 2)
+      usage_exit();
+    operation = OP_CLEANUP;
+    prefix = argv[1];
+  } else
     usage_exit();
 
   if (host.empty()) {
@@ -694,9 +702,15 @@ int main(int argc, const char **argv)
     exit(1);
   }
 
-  ret = bencher.aio_bench(operation, seconds, concurrent_ios, op_size, cleanup);
-  if (ret != 0) {
-      cerr << "error during benchmark: " << ret << std::endl;
+  if (operation == OP_CLEANUP) {
+    ret = bencher.clean_up(prefix, concurrent_ios);
+    if (ret != 0)
+      cerr << "error during cleanup: " << ret << std::endl;
+  } else {
+    ret = bencher.aio_bench(operation, seconds, concurrent_ios, op_size, cleanup);
+    if (ret != 0) {
+        cerr << "error during benchmark: " << ret << std::endl;
+    }
   }
 
   return 0;