def _VerifyNPlusOneMemory(self, node_image, all_insts):
    cluster_info = self.cfg.GetClusterInfo()
    ipolicy = ganeti.masterd.instance.CalculateGroupIPolicy(cluster_info,
                                                            self.group_info)
    memory_ratio = ipolicy[constants.IPOLICY_MEMORY_RATIO]

    for node_uuid, n_img in node_image.items():
      # This code checks that every node which is now listed as
      # secondary has enough memory to host all instances it is
      # supposed to should a single other node in the cluster fail.
      # FIXME: not ready for failover to an arbitrary node
      # FIXME: does not support file-backed instances
      # WARNING: we currently take into account down instances as well
      # as up ones, considering that even if they're down someone
      # might want to start them even in the event of a node failure.
      node_cfg = self.all_node_info[node_uuid]
      if n_img.offline or \
         node_cfg.group != self.group_uuid:
        # we're skipping nodes marked offline and nodes in other groups from
        # the N+1 warning, since most likely we don't have good memory
        # information from them; we already list instances living on such
        # nodes, and that's enough warning
        continue
      #TODO(dynmem): also consider ballooning out other instances
      for prinode, inst_uuids in n_img.sbp.items():
        needed_mem = 0
        for inst_uuid in inst_uuids:
          bep = cluster_info.FillBE(all_insts[inst_uuid])
          if bep[constants.BE_AUTO_BALANCE]:
            needed_mem += bep[constants.BE_MINMEM]
        mnode = n_img.mdom0
        (hv, hv_state) = self.cfg.GetFilledHvStateParams(node_cfg).items()[0]
        if hv != constants.HT_XEN_PVM and hv != constants.HT_XEN_HVM:
          mnode = hv_state["mem_node"]
        # minimum allowed free memory (it's negative due to over-commitment)
        mem_treshold = (n_img.mtotal - mnode) * (memory_ratio - 1)
        test = n_img.mfree - needed_mem < mem_treshold
        self._ErrorIf(test, constants.CV_ENODEN1,
                      self.cfg.GetNodeName(node_uuid),
                      "not enough memory to accomodate instance failovers"
                      " should node %s fail (%dMiB needed, %dMiB available)",
                      self.cfg.GetNodeName(prinode), needed_mem, n_img.mfree)
Verify N+1 Memory Resilience.
dataset/ETHPy150Open ganeti/ganeti/lib/cmdlib/cluster/verify.py/LUClusterVerifyGroup._VerifyNPlusOneMemory