Revision a81c53c9 lib/config.py
b/lib/config.py | ||
---|---|---|
77 | 77 |
else: |
78 | 78 |
self._cfg_file = cfg_file |
79 | 79 |
self._temporary_ids = set() |
80 |
self._temporary_drbds = {} |
|
80 | 81 |
# Note: in order to prevent errors when resolving our name in |
81 | 82 |
# _DistributeConfig, we compute it here once and reuse it; it's |
82 | 83 |
# better to raise an error before starting to modify the config |
... | ... | |
307 | 308 |
self._WriteConfig() |
308 | 309 |
return port |
309 | 310 |
|
311 |
def _ComputeDRBDMap(self, instance): |
|
312 |
"""Compute the used DRBD minor/nodes. |
|
313 |
|
|
314 |
Return: dictionary of node_name: dict of minor: instance_name. The |
|
315 |
returned dict will have all the nodes in it (even if with an empty |
|
316 |
list). |
|
317 |
|
|
318 |
""" |
|
319 |
def _AppendUsedPorts(instance_name, disk, used): |
|
320 |
if disk.dev_type == constants.LD_DRBD8 and len(disk.logical_id) == 5: |
|
321 |
nodeA, nodeB, dummy, minorA, minorB = disk.logical_id |
|
322 |
for node, port in ((nodeA, minorA), (nodeB, minorB)): |
|
323 |
assert node in used, "Instance node not found in node list" |
|
324 |
if port in used[node]: |
|
325 |
raise errors.ProgrammerError("DRBD minor already used:" |
|
326 |
" %s/%s, %s/%s" % |
|
327 |
(node, port, instance_name, |
|
328 |
used[node][port])) |
|
329 |
|
|
330 |
used[node][port] = instance_name |
|
331 |
if disk.children: |
|
332 |
for child in disk.children: |
|
333 |
_AppendUsedPorts(instance_name, child, used) |
|
334 |
|
|
335 |
my_dict = dict((node, {}) for node in self._config_data.nodes) |
|
336 |
for (node, minor), instance in self._temporary_drbds.iteritems(): |
|
337 |
my_dict[node][minor] = instance |
|
338 |
for instance in self._config_data.instances.itervalues(): |
|
339 |
for disk in instance.disks: |
|
340 |
_AppendUsedPorts(instance.name, disk, my_dict) |
|
341 |
return my_dict |
|
342 |
|
|
343 |
@locking.ssynchronized(_config_lock) |
|
344 |
def AllocateDRBDMinor(self, nodes, instance): |
|
345 |
"""Allocate a drbd minor. |
|
346 |
|
|
347 |
The free minor will be automatically computed from the existing |
|
348 |
devices. A node can be given multiple times in order to allocate |
|
349 |
multiple minors. The result is the list of minors, in the same |
|
350 |
order as the passed nodes. |
|
351 |
|
|
352 |
""" |
|
353 |
self._OpenConfig() |
|
354 |
|
|
355 |
d_map = self._ComputeDRBDMap(instance) |
|
356 |
result = [] |
|
357 |
for nname in nodes: |
|
358 |
ndata = d_map[nname] |
|
359 |
if not ndata: |
|
360 |
# no minors used, we can start at 0 |
|
361 |
result.append(0) |
|
362 |
ndata[0] = instance |
|
363 |
continue |
|
364 |
keys = ndata.keys() |
|
365 |
keys.sort() |
|
366 |
ffree = utils.FirstFree(keys) |
|
367 |
if ffree is None: |
|
368 |
# return the next minor |
|
369 |
# TODO: implement high-limit check |
|
370 |
minor = keys[-1] + 1 |
|
371 |
else: |
|
372 |
minor = ffree |
|
373 |
result.append(minor) |
|
374 |
ndata[minor] = instance |
|
375 |
assert (nname, minor) not in self._temporary_drbds, \ |
|
376 |
"Attempt to reuse reserved DRBD minor" |
|
377 |
self._temporary_drbds[(nname, minor)] = instance |
|
378 |
logging.debug("Request to allocate drbd minors, input: %s, returning %s", |
|
379 |
nodes, result) |
|
380 |
return result |
|
381 |
|
|
382 |
@locking.ssynchronized(_config_lock) |
|
383 |
def ReleaseDRBDMinors(self, instance): |
|
384 |
"""Release temporary drbd minors allocated for a given instance. |
|
385 |
|
|
386 |
This should be called on both the error paths and on the success |
|
387 |
paths (after the instance has been added or updated). |
|
388 |
|
|
389 |
@type instance: string |
|
390 |
@param instance: the instance for which temporary minors should be |
|
391 |
released |
|
392 |
|
|
393 |
""" |
|
394 |
for key, name in self._temporary_drbds.items(): |
|
395 |
if name == instance: |
|
396 |
del self._temporary_drbds[key] |
|
397 |
|
|
310 | 398 |
@locking.ssynchronized(_config_lock, shared=1) |
311 | 399 |
def GetHostKey(self): |
312 | 400 |
"""Return the rsa hostkey from the config. |
Also available in: Unified diff