Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / objectstore / workload_generator.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2012 New Dream Network
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software
11  * Foundation.  See file COPYING.
12  */
13 #ifndef WORKLOAD_GENERATOR_H_
14 #define WORKLOAD_GENERATOR_H_
15
16 #include "os/ObjectStore.h"
17 #include <boost/scoped_ptr.hpp>
18 #include <boost/random/mersenne_twister.hpp>
19 #include <boost/random/uniform_int.hpp>
20 #include <sys/time.h>
21
22 #include "TestObjectStoreState.h"
23
24 #include <map>
25 #include <atomic>
26
27 typedef boost::mt11213b rngen_t;
28
29 class WorkloadGenerator : public TestObjectStoreState {
30  public:
31   static const int def_max_in_flight = 50;
32
33   static const int def_destroy_coll_every_nr_runs = 100;
34   static const int def_num_obj_per_coll = 6000;
35   static const int def_num_colls = 30;
36
37   static const size_t min_write_bytes = 1;
38   static const size_t max_write_mb = 5;
39   static const size_t max_write_bytes = (max_write_mb * 1024 * 1024);
40
41   static const size_t min_xattr_obj_bytes = 2;
42   static const size_t max_xattr_obj_bytes = 300;
43   static const size_t min_xattr_coll_bytes = 4;
44   static const size_t max_xattr_coll_bytes = 600;
45
46   static const size_t log_append_bytes = 1024;
47
48   struct C_StatState {
49     utime_t start;
50     unsigned int written_data;
51     WorkloadGenerator *wrkldgen;
52
53     C_StatState(WorkloadGenerator *state, utime_t s)
54       : start(s), written_data(0), wrkldgen(state) { }
55   };
56
57
58  protected:
59   int m_max_in_flight;
60   int m_num_ops;
61   int m_destroy_coll_every_nr_runs;
62   std::atomic<int> m_nr_runs = { 0 };
63
64   int m_num_colls;
65
66   rngen_t m_rng;
67
68   map<coll_t, uint64_t> pg_log_size;
69
70   size_t m_write_data_bytes;
71   size_t m_write_xattr_obj_bytes;
72   size_t m_write_xattr_coll_bytes;
73   size_t m_write_pglog_bytes;
74
75   bool m_suppress_write_data;
76   bool m_suppress_write_xattr_obj;
77   bool m_suppress_write_xattr_coll;
78   bool m_suppress_write_log;
79
80   bool m_do_stats;
81
82   int m_stats_finished_txs;
83   Mutex m_stats_lock;
84   int m_stats_show_secs;
85
86   size_t m_stats_total_written;
87   utime_t m_stats_begin;
88
89  private:
90
91   void _suppress_ops_or_die(std::string& val);
92   size_t _parse_size_or_die(std::string& val);
93   void init_args(vector<const char*> args);
94
95   int get_uniform_random_value(int min, int max);
96   coll_entry_t *get_rnd_coll_entry(bool erase);
97   hobject_t *get_rnd_obj(coll_entry_t *entry);
98   int get_random_collection_nr();
99   int get_random_object_nr(int coll_nr);
100
101   size_t get_random_byte_amount(size_t min, size_t max);
102   void get_filled_byte_array(bufferlist& bl, size_t size);
103
104   void do_write_object(ObjectStore::Transaction *t,
105       coll_t coll, hobject_t obj, C_StatState *stat);
106   void do_setattr_object(ObjectStore::Transaction *t,
107       coll_t coll, hobject_t obj, C_StatState *stat);
108   void do_pgmeta_omap_set(ObjectStore::Transaction *t, spg_t pgid, coll_t coll,
109       C_StatState *stat);
110   void do_append_log(ObjectStore::Transaction *t, coll_entry_t *entry,
111       C_StatState *stat);
112
113   bool should_destroy_collection() {
114     return ((m_destroy_coll_every_nr_runs > 0) &&
115         (m_nr_runs >= m_destroy_coll_every_nr_runs));
116   }
117   void do_destroy_collection(ObjectStore::Transaction *t, coll_entry_t *entry,
118       C_StatState *stat);
119   coll_entry_t *do_create_collection(ObjectStore::Transaction *t,
120       C_StatState *stat);
121
122   void do_stats();
123
124 public:
125   explicit WorkloadGenerator(vector<const char*> args);
126   ~WorkloadGenerator() {
127     m_store->umount();
128   }
129
130   class C_OnReadable: public TestObjectStoreState::C_OnFinished {
131     WorkloadGenerator *wrkldgen_state;
132
133   public:
134     explicit C_OnReadable(WorkloadGenerator *state)
135      :TestObjectStoreState::C_OnFinished(state), wrkldgen_state(state) { }
136
137     void finish(int r) override
138     {
139       TestObjectStoreState::C_OnFinished::finish(r);
140       wrkldgen_state->m_nr_runs++;
141     }
142   };
143
144   class C_OnDestroyed: public C_OnReadable {
145     coll_entry_t *m_entry;
146
147   public:
148     C_OnDestroyed(WorkloadGenerator *state, coll_entry_t *entry) :
149           C_OnReadable(state), m_entry(entry) {}
150
151     void finish(int r) override {
152       C_OnReadable::finish(r);
153       delete m_entry;
154     }
155   };
156
157   class C_StatWrapper : public Context {
158     C_StatState *stat_state;
159     Context *ctx;
160
161    public:
162     C_StatWrapper(C_StatState *state, Context *context)
163       : stat_state(state), ctx(context) { }
164
165     void finish(int r) override {
166       ctx->complete(r);
167
168       stat_state->wrkldgen->m_stats_lock.Lock();
169
170       stat_state->wrkldgen->m_stats_total_written += stat_state->written_data;
171       stat_state->wrkldgen->m_stats_finished_txs ++;
172       stat_state->wrkldgen->m_stats_lock.Unlock();
173     }
174   };
175
176   void run(void);
177 };
178
179 bool operator<(const WorkloadGenerator::coll_entry_t& l,
180     const WorkloadGenerator::coll_entry_t& r) {
181       return (l.m_id < r.m_id);
182 }
183
184 #endif /* WORKLOAD_GENERATOR_H_ */