Revision 8716b1db

b/lib/locking.py
1467 1467
    return removed
1468 1468

  
1469 1469

  
1470
# Locking levels, must be acquired in increasing order.
1471
# Current rules are:
1472
#   - at level LEVEL_CLUSTER resides the Big Ganeti Lock (BGL) which must be
1473
#   acquired before performing any operation, either in shared or in exclusive
1474
#   mode. acquiring the BGL in exclusive mode is discouraged and should be
1475
#   avoided.
1476
#   - at levels LEVEL_NODE and LEVEL_INSTANCE reside node and instance locks.
1477
#   If you need more than one node, or more than one instance, acquire them at
1478
#   the same time.
1479
LEVEL_CLUSTER = 0
1480
LEVEL_INSTANCE = 1
1481
LEVEL_NODEGROUP = 2
1482
LEVEL_NODE = 3
1483
#: Level for node resources, used for operations with possibly high impact on
1484
#: the node's disks.
1485
LEVEL_NODE_RES = 4
1486
LEVEL_NETWORK = 5
1470
# Locking levels, must be acquired in increasing order. Current rules are:
1471
# - At level LEVEL_CLUSTER resides the Big Ganeti Lock (BGL) which must be
1472
#   acquired before performing any operation, either in shared or exclusive
1473
#   mode. Acquiring the BGL in exclusive mode is discouraged and should be
1474
#   avoided..
1475
# - At levels LEVEL_NODE and LEVEL_INSTANCE reside node and instance locks. If
1476
#   you need more than one node, or more than one instance, acquire them at the
1477
#   same time.
1478
# - LEVEL_NODE_RES is for node resources and should be used by operations with
1479
#   possibly high impact on the node's disks.
1480
# - LEVEL_NODE_ALLOC blocks instance allocations for the whole cluster
1481
#   ("NAL" is the only lock at this level). It should be acquired in shared
1482
#   mode when an opcode blocks all or a significant amount of a cluster's
1483
#   locks. Opcodes doing instance allocations should acquire in exclusive mode.
1484
#   Once the set of acquired locks for an opcode has been reduced to the working
1485
#   set, the NAL should be released as well to allow allocations to proceed.
1486
(LEVEL_CLUSTER,
1487
 LEVEL_NODE_ALLOC,
1488
 LEVEL_INSTANCE,
1489
 LEVEL_NODEGROUP,
1490
 LEVEL_NODE,
1491
 LEVEL_NODE_RES,
1492
 LEVEL_NETWORK) = range(0, 7)
1487 1493

  
1488 1494
LEVELS = [
1489 1495
  LEVEL_CLUSTER,
1496
  LEVEL_NODE_ALLOC,
1490 1497
  LEVEL_INSTANCE,
1491 1498
  LEVEL_NODEGROUP,
1492 1499
  LEVEL_NODE,
......
1511 1518
  LEVEL_NODE: "node",
1512 1519
  LEVEL_NODE_RES: "node-res",
1513 1520
  LEVEL_NETWORK: "network",
1521
  LEVEL_NODE_ALLOC: "node-alloc",
1514 1522
  }
1515 1523

  
1516 1524
# Constant for the big ganeti lock
1517 1525
BGL = "BGL"
1518 1526

  
1527
#: Node allocation lock
1528
NAL = "NAL"
1529

  
1519 1530

  
1520 1531
class GanetiLockManager:
1521 1532
  """The Ganeti Locking Library
......
1555 1566
      LEVEL_NODEGROUP: LockSet(nodegroups, "nodegroup", monitor=self._monitor),
1556 1567
      LEVEL_INSTANCE: LockSet(instances, "instance", monitor=self._monitor),
1557 1568
      LEVEL_NETWORK: LockSet(networks, "network", monitor=self._monitor),
1569
      LEVEL_NODE_ALLOC: LockSet([NAL], "node-alloc", monitor=self._monitor),
1558 1570
      }
1559 1571

  
1560 1572
    assert compat.all(ls.name == LEVEL_NAMES[level]
1561
                      for (level, ls) in self.__keyring.items())
1573
                      for (level, ls) in self.__keyring.items()), \
1574
      "Keyring name mismatch"
1562 1575

  
1563 1576
  def AddToLockMonitor(self, provider):
1564 1577
    """Registers a new lock with the monitor.
b/test/ganeti.locking_unittest.py
1804 1804

  
1805 1805
  def testLockNames(self):
1806 1806
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1807
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1807 1808
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1808 1809
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
1809 1810
                     set(self.nodegroups))
......
1816 1817
    locking.GanetiLockManager._instance = None
1817 1818
    self.GL = locking.GanetiLockManager([], [], [], [])
1818 1819
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1820
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1819 1821
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1820 1822
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1821 1823
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
......
1824 1826
    locking.GanetiLockManager._instance = None
1825 1827
    self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups, [], [])
1826 1828
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1829
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1827 1830
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1828 1831
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
1829 1832
                                    set(self.nodegroups))
......
1833 1836
    locking.GanetiLockManager._instance = None
1834 1837
    self.GL = locking.GanetiLockManager([], [], self.instances, [])
1835 1838
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1839
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1836 1840
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1837 1841
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1838 1842
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
......
1841 1845
    locking.GanetiLockManager._instance = None
1842 1846
    self.GL = locking.GanetiLockManager([], [], [], self.networks)
1843 1847
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1848
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1844 1849
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1845 1850
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1846 1851
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
......
1946 1951
  def testModifiableLevels(self):
1947 1952
    self.assertRaises(AssertionError, self.GL.add, locking.LEVEL_CLUSTER,
1948 1953
                      ["BGL2"])
1954
    self.assertRaises(AssertionError, self.GL.add, locking.LEVEL_NODE_ALLOC,
1955
                      ["NAL2"])
1949 1956
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"])
1950 1957
    self.GL.add(locking.LEVEL_INSTANCE, ["i4"])
1951 1958
    self.GL.remove(locking.LEVEL_INSTANCE, ["i3"])

Also available in: Unified diff