]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
1 | # List of valid osd flags |
2 | OSD_FLAGS = [ | |
3 | 'pause', 'noup', 'nodown', 'noout', 'noin', 'nobackfill', | |
4 | 'norecover', 'noscrub', 'nodeep-scrub', | |
5 | ] | |
6 | ||
7 | # Implemented osd commands | |
8 | OSD_IMPLEMENTED_COMMANDS = [ | |
9 | 'scrub', 'deep_scrub', 'repair' | |
10 | ] | |
11 | ||
12 | # Valid values for the 'var' argument to 'ceph osd pool set' | |
13 | POOL_PROPERTIES_1 = [ | |
14 | 'size', 'min_size', 'crash_replay_interval', 'pg_num', | |
28e407b8 | 15 | 'crush_rule', 'hashpspool', 'auid', |
31f18b77 FG |
16 | ] |
17 | ||
18 | POOL_PROPERTIES_2 = [ | |
19 | 'pgp_num' | |
20 | ] | |
21 | ||
22 | POOL_PROPERTIES = POOL_PROPERTIES_1 + POOL_PROPERTIES_2 | |
23 | ||
24 | # Valid values for the 'ceph osd pool set-quota' command | |
25 | POOL_QUOTA_PROPERTIES = [ | |
26 | ('quota_max_bytes', 'max_bytes'), | |
27 | ('quota_max_objects', 'max_objects'), | |
28 | ] | |
29 | ||
30 | POOL_ARGS = POOL_PROPERTIES + map( | |
31 | lambda x: x[0], | |
32 | POOL_QUOTA_PROPERTIES | |
33 | ) | |
34 | ||
35 | ||
36 | # Transform command to a human readable form | |
37 | def humanify_command(command): | |
38 | out = [command['prefix']] | |
39 | ||
40 | for arg, val in command.iteritems(): | |
41 | if arg != 'prefix': | |
42 | out.append("%s=%s" % (str(arg), str(val))) | |
43 | ||
44 | return " ".join(out) | |
45 | ||
46 | ||
47 | def invalid_pool_args(args): | |
48 | invalid = [] | |
49 | for arg in args: | |
50 | if arg not in POOL_ARGS: | |
51 | invalid.append(arg) | |
52 | ||
53 | return invalid | |
54 | ||
55 | ||
56 | def pool_update_commands(pool_name, args): | |
57 | commands = [[], []] | |
58 | ||
59 | # We should increase pgp_num when we are re-setting pg_num | |
60 | if 'pg_num' in args and 'pgp_num' not in args: | |
61 | args['pgp_num'] = args['pg_num'] | |
62 | ||
63 | # Run the first pool set and quota properties in parallel | |
64 | for var in POOL_PROPERTIES_1: | |
65 | if var in args: | |
66 | commands[0].append({ | |
67 | 'prefix': 'osd pool set', | |
68 | 'pool': pool_name, | |
69 | 'var': var, | |
70 | 'val': args[var], | |
71 | }) | |
72 | ||
73 | for (var, field) in POOL_QUOTA_PROPERTIES: | |
74 | if var in args: | |
75 | commands[0].append({ | |
76 | 'prefix': 'osd pool set-quota', | |
77 | 'pool': pool_name, | |
78 | 'field': field, | |
79 | 'val': str(args[var]), | |
80 | }) | |
81 | ||
82 | # The second pool set properties need to be run after the first wave | |
83 | for var in POOL_PROPERTIES_2: | |
84 | if var in args: | |
85 | commands[1].append({ | |
86 | 'prefix': 'osd pool set', | |
87 | 'pool': pool_name, | |
88 | 'var': var, | |
28e407b8 | 89 | 'val': args[var], |
31f18b77 FG |
90 | }) |
91 | ||
92 | return commands | |
93 | ||
94 | ||
95 | def crush_rule_osds(nodes, rule): | |
96 | nodes_by_id = dict((n['id'], n) for n in nodes) | |
97 | ||
98 | def _gather_leaf_ids(node): | |
99 | if node['id'] >= 0: | |
100 | return set([node['id']]) | |
101 | ||
102 | result = set() | |
103 | for child_id in node['children']: | |
104 | if child_id >= 0: | |
105 | result.add(child_id) | |
106 | else: | |
107 | result |= _gather_leaf_ids(nodes_by_id[child_id]) | |
108 | ||
109 | return result | |
110 | ||
111 | def _gather_descendent_ids(node, typ): | |
112 | result = set() | |
113 | for child_id in node['children']: | |
114 | child_node = nodes_by_id[child_id] | |
115 | if child_node['type'] == typ: | |
116 | result.add(child_node['id']) | |
117 | elif 'children' in child_node: | |
118 | result |= _gather_descendent_ids(child_node, typ) | |
119 | ||
120 | return result | |
121 | ||
122 | def _gather_osds(root, steps): | |
123 | if root['id'] >= 0: | |
124 | return set([root['id']]) | |
125 | ||
126 | osds = set() | |
127 | step = steps[0] | |
128 | if step['op'] == 'choose_firstn': | |
129 | # Choose all descendents of the current node of type 'type' | |
130 | d = _gather_descendent_ids(root, step['type']) | |
131 | for desc_node in [nodes_by_id[i] for i in d]: | |
132 | osds |= _gather_osds(desc_node, steps[1:]) | |
133 | elif step['op'] == 'chooseleaf_firstn': | |
134 | # Choose all descendents of the current node of type 'type', | |
135 | # and select all leaves beneath those | |
136 | for desc_node in [nodes_by_id[i] for i in _gather_descendent_ids(root, step['type'])]: | |
137 | # Short circuit another iteration to find the emit | |
138 | # and assume anything we've done a chooseleaf on | |
139 | # is going to be part of the selected set of osds | |
140 | osds |= _gather_leaf_ids(desc_node) | |
141 | elif step['op'] == 'emit': | |
142 | if root['id'] >= 0: | |
143 | osds |= root['id'] | |
144 | ||
145 | return osds | |
146 | ||
147 | osds = set() | |
148 | for i, step in enumerate(rule['steps']): | |
149 | if step['op'] == 'take': | |
150 | osds |= _gather_osds(nodes_by_id[step['item']], rule['steps'][i + 1:]) | |
151 | return osds |