Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / tools / psim.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "osd/OSDMap.h"
5 #include "include/buffer.h"
6
7 int main(int argc, char **argv)
8 {
9   /*
10    * you need to create a suitable osdmap first.  e.g., for 40 osds, 
11    * $ ./osdmaptool --createsimple 40 --clobber .ceph_osdmap
12    */
13   bufferlist bl;
14   std::string error;
15   if (bl.read_file(".ceph_osdmap", &error)) {
16     cout << argv[0] << ": error reading .ceph_osdmap: " << error << std::endl;
17     return 1;
18   }
19   OSDMap osdmap;
20
21   try {
22     osdmap.decode(bl);
23   } catch (ceph::buffer::end_of_buffer &eob) {
24     cout << "Exception (end_of_buffer) in decode(), exit." << std::endl;
25     exit(1);
26   }
27
28   //osdmap.set_primary_affinity(0, 0x8000);
29   //osdmap.set_primary_affinity(3, 0);
30
31   int n = osdmap.get_max_osd();
32   int count[n];
33   int first_count[n];
34   int primary_count[n];
35   int size[4];
36
37   memset(count, 0, sizeof(count));
38   memset(first_count, 0, sizeof(first_count));
39   memset(primary_count, 0, sizeof(primary_count));
40   memset(size, 0, sizeof(size));
41
42   for (int i=0; i<n; i++) {
43     osdmap.set_state(i, osdmap.get_state(i) | CEPH_OSD_UP);
44     //if (i<12)
45       osdmap.set_weight(i, CEPH_OSD_IN);
46   }
47
48   //pg_pool_t *p = (pg_pool_t *)osdmap.get_pg_pool(0);
49   //p->type = pg_pool_t::TYPE_ERASURE;
50
51   for (int n = 0; n < 10; n++) {   // namespaces
52     char nspace[20];
53     snprintf(nspace, sizeof(nspace), "n%d", n);
54   for (int f = 0; f < 5000; f++) {  // files
55     for (int b = 0; b < 4; b++) {   // blocks
56       char foo[20];
57       snprintf(foo, sizeof(foo), "%d.%d", f, b);
58       object_t oid(foo);
59       ceph_object_layout l = osdmap.make_object_layout(oid, 0, nspace);
60       vector<int> osds;
61       pg_t pgid = pg_t(l.ol_pgid);
62       //pgid.u.ps = f * 4 + b;
63       int primary;
64       osdmap.pg_to_acting_osds(pgid, &osds, &primary);
65       size[osds.size()]++;
66 #if 0
67       if (0) {
68         hash<object_t> H;
69         int x = H(oid);
70         x = ceph_stable_mod(x, 1023, 1023);
71         int s = crush_hash32(x) % 15;
72         //cout << "ceph_psim: x = " << x << " s = " << s << std::endl;
73         //osds[0] = s;
74       }
75 #endif
76       //osds[0] = crush_hash32(f) % n;
77       //cout << "oid " << oid << " pgid " << pgid << " on " << osds << std::endl;
78       for (unsigned i=0; i<osds.size(); i++) {
79         //cout << " rep " << i << " on " << osds[i] << std::endl;
80         count[osds[i]]++;
81       }
82       if (osds.size())
83         first_count[osds[0]]++;
84       if (primary >= 0)
85         primary_count[primary]++;
86     }
87   }
88   }
89
90   uint64_t avg = 0;
91   for (int i=0; i<n; i++) {
92     cout << "osd." << i << "\t" << count[i]
93          << "\t" << first_count[i]
94          << "\t" << primary_count[i]
95          << std::endl;
96     avg += count[i];
97   }
98   avg /= n;
99   double dev = 0;
100   for (int i=0; i<n; i++)
101     dev += (avg - count[i]) * (avg - count[i]);
102   dev /= n;
103   dev = sqrt(dev);
104
105   double pgavg = (double)osdmap.get_pg_pool(0)->get_pg_num() / (double)n;
106   double edev = sqrt(pgavg) * (double)avg / pgavg;
107   cout << " avg " << avg
108        << " stddev " << dev
109        << " (expected " << edev << ")"
110        << " (indep object placement would be " << sqrt(avg) << ")" << std::endl;
111
112   for (int i=0; i<4; i++) {
113     cout << "size" << i << "\t" << size[i] << std::endl;
114   }
115   
116   return 0;
117 }