Re: [libvirt] [PATCH v5 09/10] qemu: Add support to Add/Delete IOThreads
On 04/27/2015 10:45 AM, Peter Krempa wrote: > On Fri, Apr 24, 2015 at 12:06:01 -0400, John Ferlan wrote: >> Add qemuDomainAddIOThread and qemuDomainDelIOThread in order to add or >> remove an IOThread to/from the host either for live or config optoins >> >> The implementation for the 'live' option will use the iothreadpids list >> in order to make decision, while the 'config' option will use the >> iothreadids list. Additionally, for deletion each may have to adjust >> the iothreadpin list. >> >> IOThreads are implemented by qmp objects, the code makes use of the existing >> qemuMonitorAddObject or qemuMonitorDelObject APIs. >> >> Signed-off-by: John Ferlan >> --- >> src/conf/domain_audit.c | 9 ++ >> src/conf/domain_audit.h | 6 + >> src/libvirt_private.syms | 1 + >> src/qemu/qemu_driver.c | 380 >> +++ >> 4 files changed, 396 insertions(+) >> > > ... > >> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c >> index 1fac0b8..4ae63c6 100644 >> --- a/src/qemu/qemu_driver.c >> +++ b/src/qemu/qemu_driver.c >> @@ -6154,6 +6154,384 @@ qemuDomainPinIOThread(virDomainPtr dom, >> return ret; >> } >> >> +static int >> +qemuDomainHotplugAddIOThread(virQEMUDriverPtr driver, >> + virDomainObjPtr vm, >> + unsigned int iothread_id) >> +{ >> +qemuDomainObjPrivatePtr priv = vm->privateData; >> +char *alias = NULL; >> +size_t idx; >> +int rc = -1; >> +int ret = -1; >> +unsigned int orig_niothreads = vm->def->iothreads; >> +unsigned int exp_niothreads = vm->def->iothreads; >> +int new_niothreads = 0; >> +qemuMonitorIOThreadInfoPtr *new_iothreads = NULL; >> +virCgroupPtr cgroup_iothread = NULL; >> +char *mem_mask = NULL; >> +virDomainIOThreadIDDefPtr iothrid; >> +virBitmapPtr cpumask; >> + >> +if (virDomainIOThreadIDFind(vm->def, iothread_id)) { >> +virReportError(VIR_ERR_INVALID_ARG, >> + _("an IOThread is already using iothread_id '%u'"), >> + iothread_id); >> +goto cleanup; >> +} >> + >> +if (virAsprintf(&alias, "iothread%u", iothread_id) < 0) >> +return -1; >> + >> +qemuDomainObjEnterMonitor(driver, vm); >> + >> +rc = qemuMonitorAddObject(priv->mon, "iothread", alias, NULL); >> +exp_niothreads++; >> +if (rc < 0) >> +goto exit_monitor; >> + >> +/* After hotplugging the IOThreads we need to re-detect the >> + * IOThreads thread_id's, adjust the cgroups, thread affinity, >> + * and add the thread_id to the vm->def->iothreadids list. >> + */ >> +if ((new_niothreads = qemuMonitorGetIOThreads(priv->mon, >> + &new_iothreads)) < 0) >> +goto exit_monitor; >> + >> +if (qemuDomainObjExitMonitor(driver, vm) < 0) >> +goto cleanup; >> + >> +if (new_niothreads != exp_niothreads) { >> +virReportError(VIR_ERR_INTERNAL_ERROR, >> + _("got wrong number of IOThread ids from QEMU >> monitor. " >> + "got %d, wanted %d"), >> + new_niothreads, exp_niothreads); >> +vm->def->iothreads = new_niothreads; >> +goto cleanup; >> +} >> +vm->def->iothreads = exp_niothreads; >> + >> +if (virDomainNumatuneGetMode(vm->def->numa, -1) == >> +VIR_DOMAIN_NUMATUNE_MEM_STRICT && >> +virDomainNumatuneMaybeFormatNodeset(vm->def->numa, >> +priv->autoNodeset, >> +&mem_mask, -1) < 0) >> +goto cleanup; >> + >> + >> +/* >> + * If we've successfully added an IOThread, find out where we added it >> + * in the QEMU IOThread list, so we can add it to our iothreadids list >> + */ >> +for (idx = 0; idx < new_niothreads; idx++) { >> +if (STREQ(new_iothreads[idx]->name, alias)) >> +break; >> +} >> + >> +if (idx == new_niothreads) { >> +virReportError(VIR_ERR_INTERNAL_ERROR, >> + _("cannot find new IOThread '%u' in QEMU monitor."), >> + iothread_id); >> +goto cleanup; >> +} >> + >> +if (!(iothrid = virDomainIOThreadIDAdd(vm->def, iothread_id))) >> +goto cleanup; >> + >> +iothrid->thread_id = new_iothreads[idx]->thread_id; >> + >> +/* Add IOThread to cgroup if present */ >> +if (priv->cgroup) { >> +cgroup_iothread = >> +qemuDomainAddCgroupForThread(priv->cgroup, >> + VIR_CGROUP_THREAD_IOTHREAD, >> + iothread_id, mem_mask, >> + iothrid->thread_id); >> +if (!cgroup_iothread) >> +goto cleanup; >> +} >> + >> +if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) >> +cpumask =
Re: [libvirt] [PATCH v5 09/10] qemu: Add support to Add/Delete IOThreads
On Fri, Apr 24, 2015 at 12:06:01 -0400, John Ferlan wrote: > Add qemuDomainAddIOThread and qemuDomainDelIOThread in order to add or > remove an IOThread to/from the host either for live or config optoins > > The implementation for the 'live' option will use the iothreadpids list > in order to make decision, while the 'config' option will use the > iothreadids list. Additionally, for deletion each may have to adjust > the iothreadpin list. > > IOThreads are implemented by qmp objects, the code makes use of the existing > qemuMonitorAddObject or qemuMonitorDelObject APIs. > > Signed-off-by: John Ferlan > --- > src/conf/domain_audit.c | 9 ++ > src/conf/domain_audit.h | 6 + > src/libvirt_private.syms | 1 + > src/qemu/qemu_driver.c | 380 > +++ > 4 files changed, 396 insertions(+) > ... > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 1fac0b8..4ae63c6 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -6154,6 +6154,384 @@ qemuDomainPinIOThread(virDomainPtr dom, > return ret; > } > > +static int > +qemuDomainHotplugAddIOThread(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + unsigned int iothread_id) > +{ > +qemuDomainObjPrivatePtr priv = vm->privateData; > +char *alias = NULL; > +size_t idx; > +int rc = -1; > +int ret = -1; > +unsigned int orig_niothreads = vm->def->iothreads; > +unsigned int exp_niothreads = vm->def->iothreads; > +int new_niothreads = 0; > +qemuMonitorIOThreadInfoPtr *new_iothreads = NULL; > +virCgroupPtr cgroup_iothread = NULL; > +char *mem_mask = NULL; > +virDomainIOThreadIDDefPtr iothrid; > +virBitmapPtr cpumask; > + > +if (virDomainIOThreadIDFind(vm->def, iothread_id)) { > +virReportError(VIR_ERR_INVALID_ARG, > + _("an IOThread is already using iothread_id '%u'"), > + iothread_id); > +goto cleanup; > +} > + > +if (virAsprintf(&alias, "iothread%u", iothread_id) < 0) > +return -1; > + > +qemuDomainObjEnterMonitor(driver, vm); > + > +rc = qemuMonitorAddObject(priv->mon, "iothread", alias, NULL); > +exp_niothreads++; > +if (rc < 0) > +goto exit_monitor; > + > +/* After hotplugging the IOThreads we need to re-detect the > + * IOThreads thread_id's, adjust the cgroups, thread affinity, > + * and add the thread_id to the vm->def->iothreadids list. > + */ > +if ((new_niothreads = qemuMonitorGetIOThreads(priv->mon, > + &new_iothreads)) < 0) > +goto exit_monitor; > + > +if (qemuDomainObjExitMonitor(driver, vm) < 0) > +goto cleanup; > + > +if (new_niothreads != exp_niothreads) { > +virReportError(VIR_ERR_INTERNAL_ERROR, > + _("got wrong number of IOThread ids from QEMU > monitor. " > + "got %d, wanted %d"), > + new_niothreads, exp_niothreads); > +vm->def->iothreads = new_niothreads; > +goto cleanup; > +} > +vm->def->iothreads = exp_niothreads; > + > +if (virDomainNumatuneGetMode(vm->def->numa, -1) == > +VIR_DOMAIN_NUMATUNE_MEM_STRICT && > +virDomainNumatuneMaybeFormatNodeset(vm->def->numa, > +priv->autoNodeset, > +&mem_mask, -1) < 0) > +goto cleanup; > + > + > +/* > + * If we've successfully added an IOThread, find out where we added it > + * in the QEMU IOThread list, so we can add it to our iothreadids list > + */ > +for (idx = 0; idx < new_niothreads; idx++) { > +if (STREQ(new_iothreads[idx]->name, alias)) > +break; > +} > + > +if (idx == new_niothreads) { > +virReportError(VIR_ERR_INTERNAL_ERROR, > + _("cannot find new IOThread '%u' in QEMU monitor."), > + iothread_id); > +goto cleanup; > +} > + > +if (!(iothrid = virDomainIOThreadIDAdd(vm->def, iothread_id))) > +goto cleanup; > + > +iothrid->thread_id = new_iothreads[idx]->thread_id; > + > +/* Add IOThread to cgroup if present */ > +if (priv->cgroup) { > +cgroup_iothread = > +qemuDomainAddCgroupForThread(priv->cgroup, > + VIR_CGROUP_THREAD_IOTHREAD, > + iothread_id, mem_mask, > + iothrid->thread_id); > +if (!cgroup_iothread) > +goto cleanup; > +} > + > +if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) > +cpumask = priv->autoCpuset; > +else > +cpumask = vm->def->cpumask; > + > +if (cpumask) { > +if (qemuDomainHotplugPinThread(cpumask, iothread_id, > +