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