Revision b8d26c6e lib/cmdlib.py
b/lib/cmdlib.py | ||
---|---|---|
1168 | 1168 |
EINSTANCEDOWN = (TINSTANCE, "EINSTANCEDOWN") |
1169 | 1169 |
EINSTANCELAYOUT = (TINSTANCE, "EINSTANCELAYOUT") |
1170 | 1170 |
EINSTANCEMISSINGDISK = (TINSTANCE, "EINSTANCEMISSINGDISK") |
1171 |
EINSTANCEMISSINGDISK = (TINSTANCE, "EINSTANCEMISSINGDISK")
|
|
1171 |
EINSTANCEFAULTYDISK = (TINSTANCE, "EINSTANCEFAULTYDISK")
|
|
1172 | 1172 |
EINSTANCEWRONGNODE = (TINSTANCE, "EINSTANCEWRONGNODE") |
1173 | 1173 |
ENODEDRBD = (TNODE, "ENODEDRBD") |
1174 | 1174 |
ENODEDRBDHELPER = (TNODE, "ENODEDRBDHELPER") |
... | ... | |
1341 | 1341 |
_ErrorIf(test, self.ENODEHV, node, |
1342 | 1342 |
"hypervisor %s verify failure: '%s'", hv_name, hv_result) |
1343 | 1343 |
|
1344 |
|
|
1345 | 1344 |
test = nresult.get(constants.NV_NODESETUP, |
1346 | 1345 |
["Missing NODESETUP results"]) |
1347 | 1346 |
_ErrorIf(test, self.ENODESETUP, node, "node setup error: %s", |
... | ... | |
1460 | 1459 |
msg = "cannot reach the master IP" |
1461 | 1460 |
_ErrorIf(True, self.ENODENET, node, msg) |
1462 | 1461 |
|
1463 |
|
|
1464 |
def _VerifyInstance(self, instance, instanceconfig, node_image):
|
|
1462 |
def _VerifyInstance(self, instance, instanceconfig, node_image, |
|
1463 |
diskstatus):
|
|
1465 | 1464 |
"""Verify an instance. |
1466 | 1465 |
|
1467 | 1466 |
This function checks to see if the required block devices are |
... | ... | |
1497 | 1496 |
_ErrorIf(test, self.EINSTANCEWRONGNODE, instance, |
1498 | 1497 |
"instance should not run on node %s", node) |
1499 | 1498 |
|
1499 |
diskdata = [(nname, disk, idx) |
|
1500 |
for (nname, disks) in diskstatus.items() |
|
1501 |
for idx, disk in enumerate(disks)] |
|
1502 |
|
|
1503 |
for nname, bdev_status, idx in diskdata: |
|
1504 |
_ErrorIf(not bdev_status, |
|
1505 |
self.EINSTANCEFAULTYDISK, instance, |
|
1506 |
"couldn't retrieve status for disk/%s on %s", idx, nname) |
|
1507 |
_ErrorIf(bdev_status and bdev_status.ldisk_status == constants.LDS_FAULTY, |
|
1508 |
self.EINSTANCEFAULTYDISK, instance, |
|
1509 |
"disk/%s on %s is faulty", idx, nname) |
|
1510 |
|
|
1500 | 1511 |
def _VerifyOrphanVolumes(self, node_vol_should, node_image, reserved): |
1501 | 1512 |
"""Verify if there are any unknown volumes in the cluster. |
1502 | 1513 |
|
... | ... | |
1847 | 1858 |
_ErrorIf(True, self.ENODERPC, node, |
1848 | 1859 |
"node returned invalid LVM info, check LVM status") |
1849 | 1860 |
|
1861 |
def _CollectDiskInfo(self, nodelist, node_image, instanceinfo): |
|
1862 |
"""Gets per-disk status information for all instances. |
|
1863 |
|
|
1864 |
@type nodelist: list of strings |
|
1865 |
@param nodelist: Node names |
|
1866 |
@type node_image: dict of (name, L{objects.Node}) |
|
1867 |
@param node_image: Node objects |
|
1868 |
@type instanceinfo: dict of (name, L{objects.Instance}) |
|
1869 |
@param instanceinfo: Instance objects |
|
1870 |
|
|
1871 |
""" |
|
1872 |
_ErrorIf = self._ErrorIf # pylint: disable-msg=C0103 |
|
1873 |
|
|
1874 |
node_disks = {} |
|
1875 |
node_disks_devonly = {} |
|
1876 |
|
|
1877 |
for nname in nodelist: |
|
1878 |
disks = [(inst, disk) |
|
1879 |
for instlist in [node_image[nname].pinst, |
|
1880 |
node_image[nname].sinst] |
|
1881 |
for inst in instlist |
|
1882 |
for disk in instanceinfo[inst].disks] |
|
1883 |
|
|
1884 |
if not disks: |
|
1885 |
# No need to collect data |
|
1886 |
continue |
|
1887 |
|
|
1888 |
node_disks[nname] = disks |
|
1889 |
|
|
1890 |
# Creating copies as SetDiskID below will modify the objects and that can |
|
1891 |
# lead to incorrect data returned from nodes |
|
1892 |
devonly = [dev.Copy() for (_, dev) in disks] |
|
1893 |
|
|
1894 |
for dev in devonly: |
|
1895 |
self.cfg.SetDiskID(dev, nname) |
|
1896 |
|
|
1897 |
node_disks_devonly[nname] = devonly |
|
1898 |
|
|
1899 |
assert len(node_disks) == len(node_disks_devonly) |
|
1900 |
|
|
1901 |
# Collect data from all nodes with disks |
|
1902 |
result = self.rpc.call_blockdev_getmirrorstatus_multi(node_disks.keys(), |
|
1903 |
node_disks_devonly) |
|
1904 |
|
|
1905 |
assert len(result) == len(node_disks) |
|
1906 |
|
|
1907 |
instdisk = {} |
|
1908 |
|
|
1909 |
for (nname, nres) in result.items(): |
|
1910 |
if nres.offline: |
|
1911 |
# Ignore offline node |
|
1912 |
continue |
|
1913 |
|
|
1914 |
disks = node_disks[nname] |
|
1915 |
|
|
1916 |
msg = nres.fail_msg |
|
1917 |
_ErrorIf(msg, self.ENODERPC, nname, |
|
1918 |
"while getting disk information: %s", nres.fail_msg) |
|
1919 |
if msg: |
|
1920 |
# No data from this node |
|
1921 |
data = len(disks) * [None] |
|
1922 |
else: |
|
1923 |
data = nres.payload |
|
1924 |
|
|
1925 |
for ((inst, _), status) in zip(disks, data): |
|
1926 |
instdisk.setdefault(inst, {}).setdefault(nname, []).append(status) |
|
1927 |
|
|
1928 |
assert compat.all(len(statuses) == len(instanceinfo[inst].disks) and |
|
1929 |
len(nnames) <= len(instanceinfo[inst].all_nodes) |
|
1930 |
for inst, nnames in instdisk.items() |
|
1931 |
for nname, statuses in nnames.items()) |
|
1932 |
|
|
1933 |
return instdisk |
|
1934 |
|
|
1850 | 1935 |
def BuildHooksEnv(self): |
1851 | 1936 |
"""Build hooks env. |
1852 | 1937 |
|
... | ... | |
1977 | 2062 |
|
1978 | 2063 |
all_drbd_map = self.cfg.ComputeDRBDMap() |
1979 | 2064 |
|
2065 |
feedback_fn("* Gathering disk information (%s nodes)" % len(nodelist)) |
|
2066 |
instdisk = self._CollectDiskInfo(nodelist, node_image, instanceinfo) |
|
2067 |
|
|
1980 | 2068 |
feedback_fn("* Verifying node status") |
1981 | 2069 |
|
1982 | 2070 |
refos_img = None |
... | ... | |
2034 | 2122 |
if verbose: |
2035 | 2123 |
feedback_fn("* Verifying instance %s" % instance) |
2036 | 2124 |
inst_config = instanceinfo[instance] |
2037 |
self._VerifyInstance(instance, inst_config, node_image) |
|
2125 |
self._VerifyInstance(instance, inst_config, node_image, |
|
2126 |
instdisk[instance]) |
|
2038 | 2127 |
inst_nodes_offline = [] |
2039 | 2128 |
|
2040 | 2129 |
pnode = inst_config.primary_node |
Also available in: Unified diff