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
|