Revision d7cdb55d lib/bootstrap.py

b/lib/bootstrap.py
384 384
    rcode = 1
385 385

  
386 386
  return rcode
387

  
388

  
389
def GatherMasterVotes(node_list):
390
  """Check the agreement on who is the master.
391

  
392
  This function will return a list of (node, number of votes), ordered
393
  by the number of votes. Errors will be denoted by the key 'None'.
394

  
395
  Note that the sum of votes is the number of nodes this machine
396
  knows, whereas the number of entries in the list could be different
397
  (if some nodes vote for another master).
398

  
399
  We remove ourselves from the list since we know that (bugs aside)
400
  since we use the same source for configuration information for both
401
  backend and boostrap, we'll always vote for ourselves.
402

  
403
  @type node_list: list
404
  @param node_list: the list of nodes to query for master info; the current
405
      node wil be removed if it is in the list
406
  @rtype: list
407
  @return: list of (node, votes)
408

  
409
  """
410
  myself = utils.HostInfo().name
411
  try:
412
    node_list.remove(myself)
413
  except ValueError:
414
    pass
415
  if not node_list:
416
    # no nodes left (eventually after removing myself)
417
    return []
418
  results = rpc.RpcRunner.call_master_info(node_list)
419
  if not isinstance(results, dict):
420
    # this should not happen (unless internal error in rpc)
421
    logging.critical("Can't complete rpc call, aborting master startup")
422
    return [(None, len(node_list))]
423
  positive = negative = 0
424
  other_masters = {}
425
  votes = {}
426
  for node in results:
427
    if not isinstance(results[node], (tuple, list)) or len(results[node]) < 3:
428
      # here the rpc layer should have already logged errors
429
      if None not in votes:
430
        votes[None] = 0
431
      votes[None] += 1
432
      continue
433
    master_node = results[node][2]
434
    if master_node not in votes:
435
      votes[master_node] = 0
436
    votes[master_node] += 1
437

  
438
  vote_list = [v for v in votes.items()]
439
  # sort first on number of votes then on name, since we want None
440
  # sorted later if we have the half of the nodes not responding, and
441
  # half voting all for the same master
442
  vote_list.sort(key=lambda x: (x[1], x[0]), reverse=True)
443

  
444
  return vote_list

Also available in: Unified diff