]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
CrushTester: mark_down_ratio and mark_down_bucket_ratio
authorcaleb miles <caleb.miles@inktank.com>
Sat, 9 Jun 2012 03:17:52 +0000 (20:17 -0700)
committerSage Weil <sage@inktank.com>
Sat, 9 Jun 2012 04:28:24 +0000 (21:28 -0700)
Move functionality to allow user to control bucket vs device mark-down
probabilities independently.

Signed-off-by: caleb miles <caleb.miles@inktank.com>
src/crush/CrushTester.cc
src/crush/CrushTester.h
src/crushtool.cc

index c6c66f0e17cda0ceff15dd7b229a01919f7fecfc..da55ace3ff096907fa3a20ee7e6d688cdfa92872 100644 (file)
@@ -51,30 +51,96 @@ int CrushTester::test()
     max_x = 1023;
   }
 
+  // get the ID's of active buckets
+  vector<int> bucket_ids;
+  vector<int> buckets_above_devices;
+  int num_buckets_active = 0;
+
   // check that all the devices we think we have are actually in buckets
   int num_devices_active = 0;
-  for (int o = 0; o < crush.get_max_devices(); o++)
+  for (int o = 0; o < crush.get_max_devices(); o++){
     if (!crush.check_item_present(o))
       device_weight[o] = 0;
     else
       num_devices_active++;
+  }
   
-  // allow for the user to mark a range or a percentage of the total devices down
-//  if (batch_mark_down) {
-//    if (down_percentage_marked) {
-//      for (int o = 0; o < mark_down_percentage*crush.get_max_devices(); o++) {
-//        device_weight[(o*crush.get_max_devices()*mark_down_percentage)] = 0;
-//        num_devices_active--;
-//      }
-//    } else if (down_range_marked) {
-//      for (int o = mark_down_start; o <= (mark_down_start + down_range); o++) {
-//        device_weight[o] = 0;
-//        num_devices_active--;
-//      }
-//    }
-//  }
+  if (down_ratio_marked){
+    for (int i = 1; i <= crush.get_max_buckets(); i++ ){
+
+      int id = -1 - i;
+
+      if (crush.get_bucket_weight(id) > 0){
+        bucket_ids.push_back(id);
+        num_buckets_active++;
+      }
+    }
+
+    // possible debugging statement
+    //err << "number of buckets with devices" << num_buckets_active << std::endl;
+
+
+    // get the number of buckets that are one level above a device
+    int num_eligible_buckets = 0;
+
+    for (int i = 0; i < num_buckets_active; i++){
+      // grab the first child object of a bucket and check if it's ID is less than 0
+      int id = bucket_ids[i];
+      int first_child = crush.get_bucket_item(id, 0); // returns the ID of the bucket or device
+
+      // possible debugging statement
+      //err << "bucket ID " << id << " has first child " << first_child << std::endl;
+
+      if (first_child >= 0){
+        buckets_above_devices.push_back(id);
+        num_eligible_buckets++;
+      }
+    }
+
+    // possible debugging statement
+    //err << "number of eligible buckets " << num_eligible_buckets << std::endl;
 
+    // calculate how many buckets and devices we need to reap...
+    int num_buckets_to_visit = (int) (mark_down_bucket_ratio * num_eligible_buckets);
+    int num_devices_to_visit = (int) (mark_down_device_ratio * num_devices_active);
 
+    for (int i = 0; i < num_buckets_to_visit; i++){
+      int id = buckets_above_devices[i];
+      int local_devices_to_visit = (int) (mark_down_device_ratio*crush.get_bucket_size(id));
+
+      // possible debugging statement
+      //err << "device " << id << " is set to mark down " << local_devices_to_visit << " devices" << std::endl;
+
+      for (int o = 0; o < local_devices_to_visit; o++){
+        int item = crush.get_bucket_item(id, o);
+
+        // the following two statements are NOT equivalent because if we adjust the item weight we spread the change over the remaining
+        // buckets which is a change we can detect in the chi squared testing, we need to decide which behavior to use
+        //crush.adjust_item_weightf(g_ceph_context, item, 0.0); // parent bucket weight unchanged
+        //crush.set_bucket_item_weightf(id, item, 0.0);       // parent bucket weight reduced by the weight of the lost device
+
+       // possible debugging statement
+       //err << "device in position " << o << " in bucket " << id << " now has weight " << crush.get_bucket_item_weight(id, o) << std::endl;
+
+       device_weight[item] = 0; // we really shouldn't have to do this if things worked perfectly... FIXME
+       num_devices_to_visit--;
+       num_devices_active--;
+      }
+    }
+
+    if (num_devices_to_visit > 0)
+      err << "warning not all requested devices marked out" << std::endl;
+  }
+
+
+
+  // allow for the user to mark a range of devices down
+  if (down_range_marked) {
+    for (int o = mark_down_start; o <= (mark_down_start + down_range); o++) {
+      device_weight[o] = 0;
+      num_devices_active--;
+    }
+  }
 
 
   // all osds in
index fba36febab2e6cf43e8f51c84910d7831c70a127..56f5f5cd46c645ab5c4abfcb2cf414ad5865b2fc 100644 (file)
@@ -4,6 +4,8 @@
 #ifndef CEPH_CRUSH_TESTER_H
 #define CEPH_CRUSH_TESTER_H
 
+// remove me
+#include "global/global_context.h"
 #include "crush/CrushWrapper.h"
 
 class CrushTester {
@@ -19,12 +21,12 @@ class CrushTester {
   int num_batches;
   bool use_crush;
 
-  bool batch_mark_down;
-  bool down_percentage_marked;
   bool down_range_marked;
-  float mark_down_percentage;
   int mark_down_start;
   int down_range;
+  bool down_ratio_marked;
+  float mark_down_device_ratio;
+  float mark_down_bucket_ratio;
 
 public:
   bool output_utilization;
@@ -33,6 +35,7 @@ public:
   bool output_bad_mappings;
   bool output_choose_tries;
 
+
 public:
   CrushTester(CrushWrapper& c, ostream& eo, int verbosity=0)
     : crush(c), err(eo), verbose(verbosity),
@@ -41,12 +44,12 @@ public:
       min_rep(-1), max_rep(-1),
       num_batches(1),
       use_crush(true),
-      batch_mark_down(false),
-      down_percentage_marked(false),
       down_range_marked(false),
-      mark_down_percentage(0.0),
       mark_down_start(0),
       down_range(1),
+      down_ratio_marked(false),
+      mark_down_device_ratio(0.0),
+      mark_down_bucket_ratio(1.0),
       output_utilization(false),
       output_utilization_all(false),
       output_statistics(false),
@@ -77,15 +80,16 @@ public:
     use_crush = false;
   }
   void set_range_down(int start, int range){
-    batch_mark_down = true;
     down_range_marked = true;
     mark_down_start = start;
     down_range = range;
   }
-  void set_percentage_down(float percent) {
-    batch_mark_down = true;
-    down_percentage_marked = true;
-    mark_down_percentage = percent;
+  void set_bucket_down_ratio(float bucket_ratio) {
+    mark_down_bucket_ratio = bucket_ratio;
+  }
+  void set_device_down_ratio(float device_ratio) {
+    down_ratio_marked = true;
+    mark_down_device_ratio = device_ratio;
   }
   void set_device_weight(int dev, float f);
 
index 809144ccfe1c72459fc388f5a456b27f2e5d0842..63df6e5e7ba2b15959e72aed4466f967b5663f7f 100644 (file)
@@ -303,12 +303,18 @@ int main(int argc, const char **argv)
       int range = atof(*i);
       i = args.erase(i);
       tester.set_range_down(start, range);
-    } else if (ceph_argparse_withfloat(args, i, &y, &err, "--mark-percentage-down", (char*)NULL)) {
+    } else if (ceph_argparse_withfloat(args, i, &y, &err, "--mark-down-ratio", (char*)NULL)) {
       if (!err.str().empty()) {
-       cerr << err.str() << std::endl;
-       exit(EXIT_FAILURE);
+        cerr << err.str() << std::endl;
+        exit(EXIT_FAILURE);
+      }
+      tester.set_device_down_ratio(y);
+    } else if (ceph_argparse_withfloat(args, i, &y, &err, "--mark-down-bucket-ratio", (char*)NULL)) {
+      if (!err.str().empty()) {
+        cerr << err.str() << std::endl;
+        exit(EXIT_FAILURE);
       }
-      tester.set_percentage_down(y);
+      tester.set_bucket_down_ratio(y);
     } else if (ceph_argparse_withint(args, i, &tmp, &err, "--weight", (char*)NULL)) {
       if (!err.str().empty()) {
        cerr << err.str() << std::endl;