'Returns the config objects for the guest NUMA specs.
Determines the CPUs that the guest can be pinned to if the guest
specifies a cell topology and the host supports it. Constructs the
libvirt XML config object representing the NUMA topology selected
for the guest. Returns a tuple of:
(cpu_set, guest_cpu_tune, guest_cpu_numa, guest_numa_tune)
With the following caveats:
a) If there is no specified guest NUMA topology, then
all tuple elements except cpu_set shall be None. cpu_set
will be populated with the chosen CPUs that the guest
allowed CPUs fit within, which could be the supplied
allowed_cpus value if the host doesn\'t support NUMA
topologies.
b) If there is a specified guest NUMA topology, then
cpu_set will be None and guest_cpu_numa will be the
LibvirtConfigGuestCPUNUMA object representing the guest\'s
NUMA topology. If the host supports NUMA, then guest_cpu_tune
will contain a LibvirtConfigGuestCPUTune object representing
the optimized chosen cells that match the host capabilities
with the instance\'s requested topology. If the host does
not support NUMA, then guest_cpu_tune and guest_numa_tune
will be None.'

def _get_guest_numa_config(self, instance_numa_topology, flavor, allowed_cpus=None, image_meta=None):

    if ((not self._has_numa_support()) and (instance_numa_topology is not None)):
        raise exception.NUMATopologyUnsupported()
    topology = self._get_host_numa_topology()
    guest_cpu_numa_config = self._get_cpu_numa_config_from_instance(instance_numa_topology, self._wants_hugepages(topology, instance_numa_topology))
    if (not guest_cpu_numa_config):
        return GuestNumaConfig(allowed_cpus, None, None, None)
    elif topology:
        guest_cpu_tune = vconfig.LibvirtConfigGuestCPUTune()
        guest_numa_tune = vconfig.LibvirtConfigGuestNUMATune()
        emupcpus = []
        numa_mem = vconfig.LibvirtConfigGuestNUMATuneMemory()
        numa_memnodes = [vconfig.LibvirtConfigGuestNUMATuneMemNode() for _ in guest_cpu_numa_config.cells]
        emulator_threads_isolated = instance_numa_topology.emulator_threads_isolated
        vcpus_rt = set([])
        wants_realtime = hardware.is_realtime_enabled(flavor)
        if wants_realtime:
            if (not self._host.has_min_version(MIN_LIBVIRT_REALTIME_VERSION)):
                raise exception.RealtimePolicyNotSupported()
            vcpus_rt = hardware.vcpus_realtime_topology(flavor, image_meta)
            vcpusched = vconfig.LibvirtConfigGuestCPUTuneVCPUSched()
            vcpusched.vcpus = vcpus_rt
            vcpusched.scheduler = 'fifo'
            vcpusched.priority = CONF.libvirt.realtime_scheduler_priority
            guest_cpu_tune.vcpusched.append(vcpusched)
        for host_cell in topology.cells:
            for (guest_node_id, guest_config_cell) in enumerate(guest_cpu_numa_config.cells):
                if (guest_config_cell.id == host_cell.id):
                    node = numa_memnodes[guest_node_id]
                    node.cellid = guest_node_id
                    node.nodeset = [host_cell.id]
                    node.mode = 'strict'
                    numa_mem.nodeset.append(host_cell.id)
                    object_numa_cell = instance_numa_topology.cells[guest_node_id]
                    for cpu in guest_config_cell.cpus:
                        pin_cpuset = vconfig.LibvirtConfigGuestCPUTuneVCPUPin()
                        pin_cpuset.id = cpu
                        if (object_numa_cell.cpu_pinning and self._has_cpu_policy_support()):
                            pcpu = object_numa_cell.cpu_pinning[cpu]
                            pin_cpuset.cpuset = set([pcpu])
                        else:
                            pin_cpuset.cpuset = host_cell.cpuset
                        if emulator_threads_isolated:
                            emupcpus.extend(object_numa_cell.cpuset_reserved)
                        elif ((not wants_realtime) or (cpu not in vcpus_rt)):
                            emupcpus.extend(pin_cpuset.cpuset)
                        guest_cpu_tune.vcpupin.append(pin_cpuset)
        emulatorpin = vconfig.LibvirtConfigGuestCPUTuneEmulatorPin()
        emulatorpin.cpuset = set(emupcpus)
        guest_cpu_tune.emulatorpin = emulatorpin
        guest_cpu_tune.vcpupin.sort(key=operator.attrgetter('id'))
        guest_numa_tune.memory = numa_mem
        guest_numa_tune.memnodes = numa_memnodes
        for (i, (cell, memnode)) in enumerate(zip(guest_cpu_numa_config.cells, guest_numa_tune.memnodes)):
            cell.id = i
            memnode.cellid = i
        return GuestNumaConfig(None, guest_cpu_tune, guest_cpu_numa_config, guest_numa_tune)
    else:
        return GuestNumaConfig(allowed_cpus, None, guest_cpu_numa_config, None)
