1 # List of valid osd flags
3 'pause', 'noup', 'nodown', 'noout', 'noin', 'nobackfill',
4 'norecover', 'noscrub', 'nodeep-scrub',
7 # Implemented osd commands
8 OSD_IMPLEMENTED_COMMANDS = [
9 'scrub', 'deep_scrub', 'repair'
12 # Valid values for the 'var' argument to 'ceph osd pool set'
14 'size', 'min_size', 'crash_replay_interval', 'pg_num',
15 'crush_rule', 'hashpspool',
22 POOL_PROPERTIES = POOL_PROPERTIES_1 + POOL_PROPERTIES_2
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'),
30 POOL_ARGS = POOL_PROPERTIES + map(
36 # Transform command to a human readable form
37 def humanify_command(command):
38 out = [command['prefix']]
40 for arg, val in command.iteritems():
42 out.append("%s=%s" % (str(arg), str(val)))
47 def invalid_pool_args(args):
50 if arg not in POOL_ARGS:
56 def pool_update_commands(pool_name, args):
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']
63 # Run the first pool set and quota properties in parallel
64 for var in POOL_PROPERTIES_1:
67 'prefix': 'osd pool set',
73 for (var, field) in POOL_QUOTA_PROPERTIES:
76 'prefix': 'osd pool set-quota',
79 'val': str(args[var]),
82 # The second pool set properties need to be run after the first wave
83 for var in POOL_PROPERTIES_2:
86 'prefix': 'osd pool set',
94 def crush_rule_osds(nodes, rule):
95 nodes_by_id = dict((n['id'], n) for n in nodes)
97 def _gather_leaf_ids(node):
99 return set([node['id']])
102 for child_id in node['children']:
106 result |= _gather_leaf_ids(nodes_by_id[child_id])
110 def _gather_descendent_ids(node, typ):
112 for child_id in node['children']:
113 child_node = nodes_by_id[child_id]
114 if child_node['type'] == typ:
115 result.add(child_node['id'])
116 elif 'children' in child_node:
117 result |= _gather_descendent_ids(child_node, typ)
121 def _gather_osds(root, steps):
123 return set([root['id']])
127 if step['op'] == 'choose_firstn':
128 # Choose all descendents of the current node of type 'type'
129 d = _gather_descendent_ids(root, step['type'])
130 for desc_node in [nodes_by_id[i] for i in d]:
131 osds |= _gather_osds(desc_node, steps[1:])
132 elif step['op'] == 'chooseleaf_firstn':
133 # Choose all descendents of the current node of type 'type',
134 # and select all leaves beneath those
135 for desc_node in [nodes_by_id[i] for i in _gather_descendent_ids(root, step['type'])]:
136 # Short circuit another iteration to find the emit
137 # and assume anything we've done a chooseleaf on
138 # is going to be part of the selected set of osds
139 osds |= _gather_leaf_ids(desc_node)
140 elif step['op'] == 'emit':
147 for i, step in enumerate(rule['steps']):
148 if step['op'] == 'take':
149 osds |= _gather_osds(nodes_by_id[step['item']], rule['steps'][i + 1:])