]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #pragma once | |
5 | ||
6 | #include <map> | |
20effc67 | 7 | #include <optional> |
11fdf7f2 TL |
8 | #include <ostream> |
9 | #include <string> | |
10 | ||
11 | #include "include/utime.h" | |
12 | #include "common/options.h" | |
13 | #include "common/entity_name.h" | |
14 | ||
15 | class CrushWrapper; | |
16 | ||
17 | // the precedence is thus: | |
18 | // | |
19 | // global | |
20 | // crush location (coarse to fine, ordered by type id) | |
21 | // daemon type (e.g., osd) | |
22 | // device class (osd only) | |
23 | // crush location (coarse to fine, ordered by type id) | |
24 | // daemon name (e.g., mds.foo) | |
25 | // | |
26 | // Note that this means that if we have | |
27 | // | |
28 | // config/host:foo/a = 1 | |
29 | // config/osd/rack:foo/a = 2 | |
30 | // | |
31 | // then we get a = 2. The osd-level config wins, even though rack | |
32 | // is less precise than host, because the crush limiters are only | |
33 | // resolved within a section (global, per-daemon, per-instance). | |
34 | ||
35 | struct OptionMask { | |
36 | std::string location_type, location_value; ///< matches crush_location | |
37 | std::string device_class; ///< matches device class | |
38 | ||
39 | bool empty() const { | |
40 | return location_type.size() == 0 | |
41 | && location_value.size() == 0 | |
42 | && device_class.size() == 0; | |
43 | } | |
44 | ||
45 | std::string to_str() const { | |
46 | std::string r; | |
47 | if (location_type.size()) { | |
48 | r += location_type + ":" + location_value; | |
49 | } | |
50 | if (device_class.size()) { | |
51 | if (r.size()) { | |
52 | r += "/"; | |
53 | } | |
54 | r += "class:" + device_class; | |
55 | } | |
56 | return r; | |
57 | } | |
f67539c2 | 58 | void dump(ceph::Formatter *f) const; |
11fdf7f2 TL |
59 | }; |
60 | ||
61 | struct MaskedOption { | |
f67539c2 | 62 | std::string raw_value; ///< raw, unparsed, unvalidated value |
11fdf7f2 TL |
63 | const Option *opt; ///< the option |
64 | OptionMask mask; | |
f67539c2 | 65 | std::unique_ptr<const Option> unknown_opt; ///< if fabricated for an unknown option |
11fdf7f2 TL |
66 | |
67 | MaskedOption(const Option *o, bool fab=false) : opt(o) { | |
68 | if (fab) { | |
69 | unknown_opt.reset(o); | |
70 | } | |
71 | } | |
72 | MaskedOption(MaskedOption&& o) { | |
73 | raw_value = std::move(o.raw_value); | |
74 | opt = o.opt; | |
75 | mask = std::move(o.mask); | |
76 | unknown_opt = std::move(o.unknown_opt); | |
77 | } | |
78 | const MaskedOption& operator=(const MaskedOption& o) = delete; | |
79 | const MaskedOption& operator=(MaskedOption&& o) = delete; | |
80 | ||
81 | /// return a precision metric (smaller is more precise) | |
82 | int get_precision(const CrushWrapper *crush); | |
83 | ||
f67539c2 | 84 | friend std::ostream& operator<<(std::ostream& out, const MaskedOption& o); |
11fdf7f2 | 85 | |
f67539c2 | 86 | void dump(ceph::Formatter *f) const; |
11fdf7f2 TL |
87 | }; |
88 | ||
89 | struct Section { | |
90 | std::multimap<std::string,MaskedOption> options; | |
91 | ||
92 | void clear() { | |
93 | options.clear(); | |
94 | } | |
f67539c2 | 95 | void dump(ceph::Formatter *f) const; |
11fdf7f2 TL |
96 | std::string get_minimal_conf() const; |
97 | }; | |
98 | ||
99 | struct ConfigMap { | |
100 | Section global; | |
f67539c2 TL |
101 | std::map<std::string,Section, std::less<>> by_type; |
102 | std::map<std::string,Section, std::less<>> by_id; | |
103 | std::list<std::unique_ptr<Option>> stray_options; | |
11fdf7f2 TL |
104 | |
105 | Section *find_section(const std::string& name) { | |
106 | if (name == "global") { | |
107 | return &global; | |
108 | } | |
109 | auto i = by_type.find(name); | |
110 | if (i != by_type.end()) { | |
111 | return &i->second; | |
112 | } | |
113 | i = by_id.find(name); | |
114 | if (i != by_id.end()) { | |
115 | return &i->second; | |
116 | } | |
117 | return nullptr; | |
118 | } | |
119 | void clear() { | |
120 | global.clear(); | |
121 | by_type.clear(); | |
122 | by_id.clear(); | |
f67539c2 | 123 | stray_options.clear(); |
11fdf7f2 | 124 | } |
f67539c2 | 125 | void dump(ceph::Formatter *f) const; |
9f95a23c | 126 | std::map<std::string,std::string,std::less<>> generate_entity_map( |
11fdf7f2 | 127 | const EntityName& name, |
f67539c2 | 128 | const std::map<std::string,std::string>& crush_location, |
11fdf7f2 TL |
129 | const CrushWrapper *crush, |
130 | const std::string& device_class, | |
f67539c2 | 131 | std::map<std::string,std::pair<std::string,const MaskedOption*>> *src=0); |
11fdf7f2 | 132 | |
f67539c2 TL |
133 | void parse_key( |
134 | const std::string& key, | |
135 | std::string *name, | |
136 | std::string *who); | |
11fdf7f2 TL |
137 | static bool parse_mask( |
138 | const std::string& in, | |
139 | std::string *section, | |
140 | OptionMask *mask); | |
141 | }; | |
142 | ||
143 | ||
144 | struct ConfigChangeSet { | |
145 | version_t version; | |
146 | utime_t stamp; | |
f67539c2 | 147 | std::string name; |
11fdf7f2 TL |
148 | |
149 | // key -> (old value, new value) | |
20effc67 | 150 | std::map<std::string,std::pair<std::optional<std::string>,std::optional<std::string>>> diff; |
11fdf7f2 | 151 | |
f67539c2 TL |
152 | void dump(ceph::Formatter *f) const; |
153 | void print(std::ostream& out) const; | |
11fdf7f2 | 154 | }; |