Markus Groß wrote: > The nodeGetInfo code had to be moved into a helper > function to reuse it without a virConnectPtr. >
Sounds good. > --- > src/libxl/libxl_driver.c | 143 > ++++++++++++++++++++++++++++++++++------------ > 1 files changed, 107 insertions(+), 36 deletions(-) > > diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c > index c760a23..1539385 100644 > --- a/src/libxl/libxl_driver.c > +++ b/src/libxl/libxl_driver.c > @@ -199,6 +199,46 @@ libxlAutostartDomain(void *payload, const void *name > ATTRIBUTE_UNUSED, > virDomainObjUnlock(vm); > } > > +static int > +libxlDoNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info) > +{ > + libxl_physinfo phy_info; > + const libxl_version_info* ver_info; > + struct utsname utsname; > + > + if (libxl_get_physinfo(&driver->ctx, &phy_info)) { > + libxlError(VIR_ERR_INTERNAL_ERROR, > + _("libxl_get_physinfo_info failed")); > + return -1; > + } > + > + if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { > + libxlError(VIR_ERR_INTERNAL_ERROR, > + _("libxl_get_version_info failed")); > + return -1; > + } > + > + uname(&utsname); > + if (virStrncpy(info->model, > + utsname.machine, > + strlen(utsname.machine), > + sizeof(info->model)) == NULL) { > + libxlError(VIR_ERR_INTERNAL_ERROR, > + _("machine type %s too big for destination"), > + utsname.machine); > + return -1; > + } > + > + info->memory = phy_info.total_pages * (ver_info->pagesize / 1024); > + info->cpus = phy_info.nr_cpus; > + info->nodes = phy_info.nr_nodes; > + info->cores = phy_info.cores_per_socket; > + info->threads = phy_info.threads_per_core; > + info->sockets = 1; > + info->mhz = phy_info.cpu_khz / 1000; > + return 0; > +} > + > /* > * Cleanup function for domain that has reached shutoff state. > * > @@ -391,6 +431,62 @@ error: > return -1; > } > > +static int > +libxlDomainSetVcpuAffinites(libxlDriverPrivatePtr driver, virDomainObjPtr vm) > +{ > + libxlDomainObjPrivatePtr priv = vm->privateData; > + virDomainDefPtr def = vm->def; > + libxl_cpumap map; > + uint8_t *cpumask = NULL; > + uint8_t *cpumap = NULL; > + virNodeInfo nodeinfo; > + size_t cpumaplen; > + unsigned int pos; > + int vcpu, i; > + int ret = -1; > + > + if (libxlDoNodeGetInfo(driver, &nodeinfo) < 0) > + goto cleanup; > + > + cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo)); > + > + for (vcpu = 0; vcpu < def->cputune.nvcpupin; ++vcpu) { > + if (vcpu != def->cputune.vcpupin[vcpu]->vcpuid) > + continue; > + > + if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) { > + virReportOOMError(); > + goto cleanup; > + } > + > + cpumask = (uint8_t*) def->cputune.vcpupin[vcpu]->cpumask; > + > + for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; ++i) { > + if (cpumask[i]) { > + pos = i / 8; > + cpumap[pos] |= 1 << (i % 8); > + } > + } > + > + map.size = cpumaplen; > + map.map = cpumap; > + > + if (libxl_set_vcpuaffinity(&priv->ctx, def->id, vcpu, &map) != 0) { > + libxlError(VIR_ERR_INTERNAL_ERROR, > + _("Failed to pin vcpu '%d' with libxenlight"), vcpu); > + goto cleanup; > + } > + > + VIR_FREE(cpumap); > + } > + > + ret = 0; > + > +cleanup: > + VIR_FREE(cpumap); > + return ret; > +} > + > /* > * Start a domain through libxenlight. > * > @@ -440,6 +536,9 @@ libxlVmStart(libxlDriverPrivatePtr driver, > if (libxlCreateDomEvents(vm) < 0) > goto error; > > + if (libxlDomainSetVcpuAffinites(driver, vm) < 0) > + goto error; > + > if (!start_paused) { > libxl_domain_unpause(&priv->ctx, domid); > vm->state = VIR_DOMAIN_RUNNING; > @@ -869,42 +968,7 @@ libxlGetMaxVcpus(virConnectPtr conn, const char *type > ATTRIBUTE_UNUSED) > static int > libxlNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) > { > - libxl_physinfo phy_info; > - const libxl_version_info* ver_info; > - libxlDriverPrivatePtr driver = conn->privateData; > - struct utsname utsname; > - > - if (libxl_get_physinfo(&driver->ctx, &phy_info)) { > - libxlError(VIR_ERR_INTERNAL_ERROR, > - _("libxl_get_physinfo_info failed")); > - return -1; > - } > - > - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { > - libxlError(VIR_ERR_INTERNAL_ERROR, > - _("libxl_get_version_info failed")); > - return -1; > - } > - > - uname(&utsname); > - if (virStrncpy(info->model, > - utsname.machine, > - strlen(utsname.machine), > - sizeof(info->model)) == NULL) { > - libxlError(VIR_ERR_INTERNAL_ERROR, > - _("machine type %s too big for destination"), > - utsname.machine); > - return -1; > - } > - > - info->memory = phy_info.total_pages * (ver_info->pagesize / 1024); > - info->cpus = phy_info.nr_cpus; > - info->nodes = phy_info.nr_nodes; > - info->cores = phy_info.cores_per_socket; > - info->threads = phy_info.threads_per_core; > - info->sockets = 1; > - info->mhz = phy_info.cpu_khz / 1000; > - return 0; > + return libxlDoNodeGetInfo(conn->privateData, info); > } > > static char * > @@ -1712,6 +1776,13 @@ libxlDomainPinVcpu(virDomainPtr dom, unsigned int > vcpu, unsigned char *cpumap, > _("Failed to pin vcpu '%d' with libxenlight"), vcpu); > goto cleanup; > } > + > + if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu) < 0) { > + libxlError(VIR_ERR_INTERNAL_ERROR, > + "%s", _("failed to update or add vcpupin xml")); > + goto cleanup; > + } > + > I'm not sure about this hunk. The cputune info is in memory but not saved anywhere. E.g. # virsh start domU # virsh vcpupin domU 0 0,1,2 # virsh dumpxml domU | grep vcpupin <vcpupin vcpu='0' cpuset='0-2'/> # restart libvirtd # virsh dumpxml domU | grep vcpupin # I think config in driver->stateDir needs updated to handle this case. # virsh start domU # virsh vcpuping domU 0 0,1,2 # virsh shutdown domU # wait for shutdown # virsh dumpxml domU | grep vcpupin <vcpupin vcpu='0' cpuset='0-2'/> # restart libvirtd # virsh dumpxml domU | grep vcpupin # Once the domain is shutdown, the affinitiy config should be removed right? Documentation for virDomainPinVcpu states: "This command only changes the runtime configuration of the domain, so can only be called on an active domain". Regards, Jim -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list