]> git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/osd_max_pg_per_osd.py
update sources to 12.2.7
[ceph.git] / ceph / qa / tasks / osd_max_pg_per_osd.py
1 import logging
2 import random
3
4
5 log = logging.getLogger(__name__)
6
7
8 def pg_num_in_all_states(pgs, *states):
9 return sum(1 for state in pgs.itervalues()
10 if all(s in state for s in states))
11
12
13 def pg_num_in_any_state(pgs, *states):
14 return sum(1 for state in pgs.itervalues()
15 if any(s in state for s in states))
16
17
18 def test_create_from_mon(ctx, config):
19 """
20 osd should stop creating new pools if the number of pg it servers
21 exceeds the max-pg-per-osd setting, and it should resume the previously
22 suspended pg creations once the its pg number drops down below the setting
23 How it works::
24 1. set the hard limit of pg-per-osd to "2"
25 2. create pool.a with pg_num=2
26 # all pgs should be active+clean
27 2. create pool.b with pg_num=2
28 # new pgs belonging to this pool should be unknown (the primary osd
29 reaches the limit) or creating (replica osd reaches the limit)
30 3. remove pool.a
31 4. all pg belonging to pool.b should be active+clean
32 """
33 pg_num = config.get('pg_num', 2)
34 manager = ctx.managers['ceph']
35 log.info('1. creating pool.a')
36 pool_a = manager.create_pool_with_unique_name(pg_num)
37 pg_states = manager.wait_till_pg_convergence(300)
38 pg_created = pg_num_in_all_states(pg_states, 'active', 'clean')
39 assert pg_created == pg_num
40
41 log.info('2. creating pool.b')
42 pool_b = manager.create_pool_with_unique_name(pg_num)
43 pg_states = manager.wait_till_pg_convergence(300)
44 pg_created = pg_num_in_all_states(pg_states, 'active', 'clean')
45 assert pg_created == pg_num
46 pg_pending = pg_num_in_any_state(pg_states, 'unknown', 'creating')
47 assert pg_pending == pg_num
48
49 log.info('3. removing pool.a')
50 manager.remove_pool(pool_a)
51 pg_states = manager.wait_till_pg_convergence(300)
52 assert len(pg_states) == pg_num
53 pg_created = pg_num_in_all_states(pg_states, 'active', 'clean')
54 assert pg_created == pg_num
55
56 # cleanup
57 manager.remove_pool(pool_b)
58
59
60 def test_create_from_peer(ctx, config):
61 """
62 osd should stop creating new pools if the number of pg it servers
63 exceeds the max-pg-per-osd setting, and it should resume the previously
64 suspended pg creations once the its pg number drops down below the setting
65
66 How it works::
67 0. create 4 OSDs.
68 1. create pool.a with pg_num=1, size=2
69 pg will be mapped to osd.0, and osd.1, and it should be active+clean
70 2. create pool.b with pg_num=1, size=2.
71 if the pgs stuck in creating, delete the pool since the pool and try
72 again, eventually we'll get the pool to land on the other 2 osds that
73 aren't occupied by pool.a. (this will also verify that pgs for deleted
74 pools get cleaned out of the creating wait list.)
75 3. mark an osd out. verify that some pgs get stuck stale or peering.
76 4. delete a pool, verify pgs go active.
77 """
78 pg_num = config.get('pg_num', 1)
79 pool_size = config.get('pool_size', 2)
80 from_primary = config.get('from_primary', True)
81
82 manager = ctx.managers['ceph']
83 log.info('1. creating pool.a')
84 pool_a = manager.create_pool_with_unique_name(pg_num)
85 pg_states = manager.wait_till_pg_convergence(300)
86 pg_created = pg_num_in_all_states(pg_states, 'active', 'clean')
87 assert pg_created == pg_num
88
89 log.info('2. creating pool.b')
90 while True:
91 pool_b = manager.create_pool_with_unique_name(pg_num)
92 pg_states = manager.wait_till_pg_convergence(300)
93 pg_created = pg_num_in_all_states(pg_states, 'active', 'clean')
94 assert pg_created >= pg_num
95 pg_pending = pg_num_in_any_state(pg_states, 'unknown', 'creating')
96 assert pg_pending == pg_num * 2 - pg_created
97 if pg_created == pg_num * 2:
98 break
99 manager.remove_pool(pool_b)
100
101 log.info('3. mark an osd out')
102 pg_stats = manager.get_pg_stats()
103 pg = random.choice(pg_stats)
104 if from_primary:
105 victim = pg['acting'][-1]
106 else:
107 victim = pg['acting'][0]
108 manager.mark_out_osd(victim)
109 pg_states = manager.wait_till_pg_convergence(300)
110 pg_stuck = pg_num_in_any_state(pg_states, 'activating', 'stale', 'peering')
111 assert pg_stuck > 0
112
113 log.info('4. removing pool.b')
114 manager.remove_pool(pool_b)
115 manager.wait_for_clean(30)
116
117 # cleanup
118 manager.remove_pool(pool_a)
119
120
121 def task(ctx, config):
122 assert isinstance(config, dict), \
123 'osd_max_pg_per_osd task only accepts a dict for config'
124 manager = ctx.managers['ceph']
125 if config.get('test_create_from_mon', True):
126 test_create_from_mon(ctx, config)
127 else:
128 test_create_from_peer(ctx, config)