[libvirt] [PATCH] perf: introduce option --reset

Currently you can either enable or disable a perf event. This patch allows you to reset the perf event using command line option --reset. Eg: virsh perf domainName --reset cpu_cycles Signed-off-by: Nitesh Konkar <nitkon12@linux.vnet.ibm.com> --- Example: virsh domstats Fedora --perf Domain: 'Fedora' virsh perf Fedora --enable cpu_cycles,cache_references cpu_cycles : enabled cache_references: enabled virsh domstats Fedora --perf Domain: 'Fedora' perf.cpu_cycles=107559185 perf.cache_references=563288 virsh perf Fedora --reset cache_misses,cpu_cycles,cache_references cache_misses : reset cpu_cycles : reset cache_references: reset virsh domstats Fedora --perf Domain: 'Fedora' perf.cpu_cycles=0 perf.cache_references=0 perf.cache_misses=0 virsh perf Fedora --reset cache_misses,cpu_cycles,cache_references --config error: Options --reset and --config are mutually exclusive Should reset option be made available in the domainxml along with enabled=yes/no ? I have not included any such change in this patch as I think that there is no need to reset a perf counter as its value for the VM's pid shall start by default at zero unless enabled. include/libvirt/libvirt-domain.h | 6 +++++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 52 ++++++++++++++++++++-------------------- src/qemu/qemu_process.c | 22 +++++++++++++---- src/util/virperf.c | 52 ++++++++++++++++++++++++++++------------ src/util/virperf.h | 12 ++++++---- tools/virsh-domain.c | 37 ++++++++++++++++++---------- 7 files changed, 120 insertions(+), 62 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index e303140..6072f00 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -2188,6 +2188,12 @@ void virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats); */ # define VIR_PERF_PARAM_REF_CPU_CYCLES "ref_cpu_cycles" +enum { +VIR_PERF_STATE_DISABLED, +VIR_PERF_STATE_ENABLED, +VIR_PERF_STATE_RESET, +}; + int virDomainGetPerfEvents(virDomainPtr dom, virTypedParameterPtr *params, int *nparams, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index cfeb43c..61bd207 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2229,6 +2229,7 @@ virPCIStubDriverTypeToString; virPerfEventDisable; virPerfEventEnable; virPerfEventIsEnabled; +virPerfEventSetFd; virPerfEventTypeFromString; virPerfEventTypeToString; virPerfFree; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 516a851..8dd3ab7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9530,25 +9530,25 @@ qemuDomainSetPerfEvents(virDomainPtr dom, virDomainDefPtr persistentDef; int ret = -1; virPerfEventType type; - bool enabled; + int state; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); if (virTypedParamsValidate(params, nparams, - VIR_PERF_PARAM_CMT, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_MBMT, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_MBML, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_CPU_CYCLES, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_INSTRUCTIONS, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_CACHE_REFERENCES, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_CACHE_MISSES, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_BRANCH_INSTRUCTIONS, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_BRANCH_MISSES, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_BUS_CYCLES, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_STALLED_CYCLES_BACKEND, VIR_TYPED_PARAM_BOOLEAN, - VIR_PERF_PARAM_REF_CPU_CYCLES, VIR_TYPED_PARAM_BOOLEAN, + VIR_PERF_PARAM_CMT, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_MBMT, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_MBML, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_CPU_CYCLES, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_INSTRUCTIONS, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_CACHE_REFERENCES, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_CACHE_MISSES, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_BRANCH_INSTRUCTIONS, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_BRANCH_MISSES, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_BUS_CYCLES, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_STALLED_CYCLES_BACKEND, VIR_TYPED_PARAM_INT, + VIR_PERF_PARAM_REF_CPU_CYCLES, VIR_TYPED_PARAM_INT, NULL) < 0) return -1; @@ -9570,16 +9570,17 @@ qemuDomainSetPerfEvents(virDomainPtr dom, if (def) { for (i = 0; i < nparams; i++) { virTypedParameterPtr param = ¶ms[i]; - enabled = param->value.b; + state = param->value.i; type = virPerfEventTypeFromString(param->field); - if (!enabled && virPerfEventDisable(priv->perf, type) < 0) - goto endjob; - if (enabled && virPerfEventEnable(priv->perf, type, vm->pid) < 0) + if ((state == VIR_PERF_STATE_DISABLED) && virPerfEventDisable(priv->perf, type) < 0) { goto endjob; + } else { + if (virPerfEventSetFd(priv->perf, type, vm->pid, state) < 0) + goto endjob; + } - def->perf.events[type] = enabled ? - VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO; + def->perf.events[type] = state; } if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) @@ -9589,11 +9590,10 @@ qemuDomainSetPerfEvents(virDomainPtr dom, if (persistentDef) { for (i = 0; i < nparams; i++) { virTypedParameterPtr param = ¶ms[i]; - enabled = param->value.b; + state = param->value.i; type = virPerfEventTypeFromString(param->field); - persistentDef->perf.events[type] = enabled ? - VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO; + persistentDef->perf.events[type] = state; } if (virDomainSaveConfig(cfg->configDir, driver->caps, persistentDef) < 0) @@ -9649,14 +9649,14 @@ qemuDomainGetPerfEvents(virDomainPtr dom, priv = vm->privateData; for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { - bool perf_enabled; + int perf_enabled; if (flags & VIR_DOMAIN_AFFECT_CONFIG) - perf_enabled = def->perf.events[i] == VIR_TRISTATE_BOOL_YES; + perf_enabled = def->perf.events[i]; else perf_enabled = virPerfEventIsEnabled(priv->perf, i); - if (virTypedParamsAddBoolean(&par, &npar, &maxpar, + if (virTypedParamsAddInt(&par, &npar, &maxpar, virPerfEventTypeToString(i), perf_enabled) < 0) goto endjob; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 184440d..1bd7979 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3200,11 +3200,19 @@ qemuDomainPerfRestart(virDomainObjPtr vm) for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { if (def->perf.events[i] && - def->perf.events[i] == VIR_TRISTATE_BOOL_YES) { + def->perf.events[i] == VIR_PERF_STATE_ENABLED) { /* Failure to re-enable the perf event should not be fatal */ - if (virPerfEventEnable(priv->perf, i, vm->pid) < 0) - def->perf.events[i] = VIR_TRISTATE_BOOL_NO; + if (virPerfEventSetFd(priv->perf, i, vm->pid, VIR_PERF_STATE_ENABLED) < 0) + def->perf.events[i] = VIR_PERF_STATE_DISABLED; + } + + if (def->perf.events[i] && + def->perf.events[i] == VIR_PERF_STATE_RESET) { + + /* Failure to reset the perf event should not be fatal */ + if (virPerfEventSetFd(priv->perf, i, vm->pid, VIR_PERF_STATE_RESET) < 0) + def->perf.events[i] = VIR_PERF_STATE_DISABLED; } } @@ -5563,8 +5571,12 @@ qemuProcessLaunch(virConnectPtr conn, goto cleanup; for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { - if (vm->def->perf.events[i] == VIR_TRISTATE_BOOL_YES && - virPerfEventEnable(priv->perf, i, vm->pid) < 0) + if (vm->def->perf.events[i] == VIR_PERF_STATE_ENABLED && + virPerfEventSetFd(priv->perf, i, vm->pid, VIR_PERF_STATE_ENABLED) < 0) + goto cleanup; + + if (vm->def->perf.events[i] == VIR_PERF_STATE_RESET && + virPerfEventSetFd(priv->perf, i, vm->pid, VIR_PERF_STATE_RESET) < 0) goto cleanup; } diff --git a/src/util/virperf.c b/src/util/virperf.c index f64692b..125166b 100644 --- a/src/util/virperf.c +++ b/src/util/virperf.c @@ -48,7 +48,7 @@ VIR_ENUM_IMPL(virPerfEvent, VIR_PERF_EVENT_LAST, struct virPerfEvent { int type; int fd; - bool enabled; + int state; union { /* cmt */ struct { @@ -186,9 +186,25 @@ virPerfGetEvent(virPerfPtr perf, } int -virPerfEventEnable(virPerfPtr perf, +virPerfEventEnable(int fd) +{ + if (ioctl(fd, PERF_EVENT_IOC_ENABLE) < 0) + return -1; + return 0; +} + +int +virPerfEventReset(int fd) +{ + if (ioctl(fd, PERF_EVENT_IOC_RESET) < 0) + return -1; + return 0; +} + +int +virPerfEventSetFd(virPerfPtr perf, virPerfEventType type, - pid_t pid) + pid_t pid, int state) { char *buf = NULL; struct perf_event_attr attr; @@ -237,14 +253,20 @@ virPerfEventEnable(virPerfPtr perf, goto error; } - if (ioctl(event->fd, PERF_EVENT_IOC_ENABLE) < 0) { + if (state == VIR_PERF_STATE_ENABLED && virPerfEventEnable(event->fd) < 0) { virReportSystemError(errno, _("unable to enable host cpu perf event for %s"), virPerfEventTypeToString(event->type)); goto error; } - event->enabled = true; + if (state == VIR_PERF_STATE_RESET && virPerfEventReset(event->fd) < 0) { + virReportSystemError(errno, + _("unable to reset host cpu perf event for %s"), + virPerfEventTypeToString(event->type)); + goto error; + } + event->state = state; return 0; error: @@ -261,7 +283,7 @@ virPerfEventDisable(virPerfPtr perf, if (event == NULL) return -1; - if (!event->enabled) + if (!event->state) return 0; if (ioctl(event->fd, PERF_EVENT_IOC_DISABLE) < 0) { @@ -271,19 +293,19 @@ virPerfEventDisable(virPerfPtr perf, return -1; } - event->enabled = false; + event->state = VIR_PERF_STATE_DISABLED; VIR_FORCE_CLOSE(event->fd); return 0; } -bool virPerfEventIsEnabled(virPerfPtr perf, +int virPerfEventIsEnabled(virPerfPtr perf, virPerfEventType type) { virPerfEventPtr event = virPerfGetEvent(perf, type); if (event == NULL) return false; - return event->enabled; + return event->state; } int @@ -292,7 +314,7 @@ virPerfReadEvent(virPerfPtr perf, uint64_t *value) { virPerfEventPtr event = virPerfGetEvent(perf, type); - if (event == NULL || !event->enabled) + if (event == NULL || !event->state) return -1; if (saferead(event->fd, value, sizeof(uint64_t)) < 0) { @@ -316,7 +338,7 @@ virPerfRdtAttrInit(void) int -virPerfEventEnable(virPerfPtr perf ATTRIBUTE_UNUSED, +virPerfEventSetFd(virPerfPtr perf ATTRIBUTE_UNUSED, virPerfEventType type ATTRIBUTE_UNUSED, pid_t pid ATTRIBUTE_UNUSED) { @@ -334,11 +356,11 @@ virPerfEventDisable(virPerfPtr perf ATTRIBUTE_UNUSED, return -1; } -bool +int virPerfEventIsEnabled(virPerfPtr perf ATTRIBUTE_UNUSED, virPerfEventType type ATTRIBUTE_UNUSED) { - return false; + return 0; } int @@ -365,7 +387,7 @@ virPerfNew(void) for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { perf->events[i].type = i; perf->events[i].fd = -1; - perf->events[i].enabled = false; + perf->events[i].state = VIR_PERF_STATE_DISABLED; } if (virPerfRdtAttrInit() < 0) @@ -383,7 +405,7 @@ virPerfFree(virPerfPtr perf) return; for (i = 0; i < VIR_PERF_EVENT_LAST; i++) { - if (perf->events[i].enabled) + if (perf->events[i].state >= VIR_PERF_STATE_ENABLED) virPerfEventDisable(perf, i); } diff --git a/src/util/virperf.h b/src/util/virperf.h index 1f43c92..f79ef31 100644 --- a/src/util/virperf.h +++ b/src/util/virperf.h @@ -60,14 +60,18 @@ virPerfPtr virPerfNew(void); void virPerfFree(virPerfPtr perf); -int virPerfEventEnable(virPerfPtr perf, - virPerfEventType type, - pid_t pid); +int virPerfEventSetFd(virPerfPtr perf, + virPerfEventType type, + pid_t pid, int state); + +int virPerfEventEnable(int fd); + +int virPerfEventReset(int fd); int virPerfEventDisable(virPerfPtr perf, virPerfEventType type); -bool virPerfEventIsEnabled(virPerfPtr perf, +int virPerfEventIsEnabled(virPerfPtr perf, virPerfEventType type); int virPerfReadEvent(virPerfPtr perf, diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 93587e8..806490b 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -8794,7 +8794,7 @@ cmdMemtune(vshControl *ctl, const vshCmd *cmd) */ static const vshCmdInfo info_perf[] = { {.name = "help", - .data = N_("Get or set perf event") + .data = N_("Get, set or reset perf event") }, {.name = "desc", .data = N_("Get or set the current perf events for a guest" @@ -8815,6 +8815,10 @@ static const vshCmdOptDef opts_perf[] = { .type = VSH_OT_STRING, .help = N_("perf events which will be disabled") }, + {.name = "reset", + .type = VSH_OT_STRING, + .help = N_("perf events which will be reset") + }, VIRSH_COMMON_OPT_DOMAIN_CONFIG, VIRSH_COMMON_OPT_DOMAIN_LIVE, VIRSH_COMMON_OPT_DOMAIN_CURRENT, @@ -8823,7 +8827,7 @@ static const vshCmdOptDef opts_perf[] = { static int virshParseEventStr(const char *event, - bool state, + int state, virTypedParameterPtr *params, int *nparams, int *maxparams) @@ -8837,7 +8841,7 @@ virshParseEventStr(const char *event, for (i = 0; i < ntok; i++) { if ((*tok[i] != '\0') && - virTypedParamsAddBoolean(params, nparams, + virTypedParamsAddInt(params, nparams, maxparams, tok[i], state) < 0) goto cleanup; } @@ -8854,9 +8858,11 @@ virshPrintPerfStatus(vshControl *ctl, virTypedParameterPtr params, int nparams) size_t i; for (i = 0; i < nparams; i++) { - if (params[i].type == VIR_TYPED_PARAM_BOOLEAN && - params[i].value.b) { + if (params[i].type == VIR_TYPED_PARAM_INT && + params[i].value.i == VIR_PERF_STATE_ENABLED) { vshPrintExtra(ctl, "%-15s: %s\n", params[i].field, _("enabled")); + } else if (params[i].value.i == VIR_PERF_STATE_RESET) { + vshPrintExtra(ctl, "%-15s: %s\n", params[i].field, _("reset")); } else { vshPrintExtra(ctl, "%-15s: %s\n", params[i].field, _("disabled")); } @@ -8871,14 +8877,16 @@ cmdPerf(vshControl *ctl, const vshCmd *cmd) int maxparams = 0; virTypedParameterPtr params = NULL; bool ret = false; - const char *enable = NULL, *disable = NULL; + const char *enable = NULL, *disable = NULL, *resett = NULL; unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT; bool current = vshCommandOptBool(cmd, "current"); bool config = vshCommandOptBool(cmd, "config"); bool live = vshCommandOptBool(cmd, "live"); + bool reset = vshCommandOptBool(cmd, "reset"); VSH_EXCLUSIVE_OPTIONS_VAR(current, live); VSH_EXCLUSIVE_OPTIONS_VAR(current, config); + VSH_EXCLUSIVE_OPTIONS_VAR(reset, config); if (config) flags |= VIR_DOMAIN_AFFECT_CONFIG; @@ -8886,18 +8894,23 @@ cmdPerf(vshControl *ctl, const vshCmd *cmd) flags |= VIR_DOMAIN_AFFECT_LIVE; if (vshCommandOptStringReq(ctl, cmd, "enable", &enable) < 0 || - vshCommandOptStringReq(ctl, cmd, "disable", &disable) < 0) + vshCommandOptStringReq(ctl, cmd, "disable", &disable) < 0 || + vshCommandOptStringReq(ctl, cmd, "reset", &resett) < 0) return false; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) return false; - if (enable && virshParseEventStr(enable, true, ¶ms, - &nparams, &maxparams) < 0) + if (enable && virshParseEventStr(enable, VIR_PERF_STATE_ENABLED, + ¶ms, &nparams, &maxparams) < 0) + goto cleanup; + + if (disable && virshParseEventStr(disable, VIR_PERF_STATE_DISABLED, + ¶ms, &nparams, &maxparams) < 0) goto cleanup; - if (disable && virshParseEventStr(disable, false, ¶ms, - &nparams, &maxparams) < 0) + if (resett && virshParseEventStr(resett, VIR_PERF_STATE_RESET, + ¶ms, &nparams, &maxparams) < 0) goto cleanup; if (nparams == 0) { @@ -8908,7 +8921,7 @@ cmdPerf(vshControl *ctl, const vshCmd *cmd) virshPrintPerfStatus(ctl, params, nparams); } else { if (virDomainSetPerfEvents(dom, params, nparams, flags) != 0) { - vshError(ctl, "%s", _("Unable to enable/disable perf events")); + vshError(ctl, "%s", _("Unable to enable/disable/reset perf events")); goto cleanup; } else { virshPrintPerfStatus(ctl, params, nparams); -- 1.9.3

On Mon, Jan 23, 2017 at 04:03:21PM +0530, Nitesh Konkar wrote:
@@ -9570,16 +9570,17 @@ qemuDomainSetPerfEvents(virDomainPtr dom, if (def) { for (i = 0; i < nparams; i++) { virTypedParameterPtr param = ¶ms[i]; - enabled = param->value.b; + state = param->value.i;
NACK, this semantic change is not backwards compatible - this will break all applications & language bindings currently using libvirt perf events. In addition "reset" is not really a state - "enabled" / "disabled" are stats - 'reset' is an action that is applied to an existing state. So modelling 'reset' as a state is wrong too IMHO. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

Hi Daniel, On Mon, Jan 23, 2017 at 4:08 PM, Daniel P. Berrange <berrange@redhat.com> wrote:
On Mon, Jan 23, 2017 at 04:03:21PM +0530, Nitesh Konkar wrote:
@@ -9570,16 +9570,17 @@ qemuDomainSetPerfEvents(virDomainPtr dom, if (def) { for (i = 0; i < nparams; i++) { virTypedParameterPtr param = ¶ms[i]; - enabled = param->value.b; + state = param->value.i;
NACK, this semantic change is not backwards compatible - this will break all applications & language bindings currently using libvirt perf events.
Oh I see . I didn't realize that. Any other API/place you suggest, through which we can get this functionality in?
In addition "reset" is not really a state - "enabled" / "disabled" are stats - 'reset' is an action that is applied to an existing state. So modelling 'reset' as a state is wrong too IMHO.
Regards, Daniel
Thanks, Nitesh.
-- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

On Mon, Jan 23, 2017 at 07:26:58PM +0530, Nitesh Konkar wrote:
Hi Daniel,
On Mon, Jan 23, 2017 at 4:08 PM, Daniel P. Berrange <berrange@redhat.com> wrote:
On Mon, Jan 23, 2017 at 04:03:21PM +0530, Nitesh Konkar wrote:
@@ -9570,16 +9570,17 @@ qemuDomainSetPerfEvents(virDomainPtr dom, if (def) { for (i = 0; i < nparams; i++) { virTypedParameterPtr param = ¶ms[i]; - enabled = param->value.b; + state = param->value.i;
NACK, this semantic change is not backwards compatible - this will break all applications & language bindings currently using libvirt perf events.
Oh I see . I didn't realize that. Any other API/place you suggest, through which we can get this functionality in?
Why not just reset counters to zero when first enabling the perf event. If people want to reset them again later, they can just disable+enable the event to get the reset Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

On Mon, Jan 23, 2017 at 7:34 PM, Daniel P. Berrange <berrange@redhat.com> wrote:
Hi Daniel,
On Mon, Jan 23, 2017 at 4:08 PM, Daniel P. Berrange <berrange@redhat.com
wrote:
On Mon, Jan 23, 2017 at 04:03:21PM +0530, Nitesh Konkar wrote:
@@ -9570,16 +9570,17 @@ qemuDomainSetPerfEvents(virDomainPtr dom, if (def) { for (i = 0; i < nparams; i++) { virTypedParameterPtr param = ¶ms[i]; - enabled = param->value.b; + state = param->value.i;
NACK, this semantic change is not backwards compatible - this will break all applications & language bindings currently using libvirt perf events.
Oh I see . I didn't realize that. Any other API/place you suggest,
On Mon, Jan 23, 2017 at 07:26:58PM +0530, Nitesh Konkar wrote: through
which we can get this functionality in?
Why not just reset counters to zero when first enabling the perf event. If people want to reset them again later, they can just disable+enable the event to get the reset
I think, if this patch gets in: https://www.redhat.com/ archives/libvir-list/2017-January/msg00956.html then disable+enable would be equivalent to a reset operation. As of today, every enable request is creating a new fd, thus leaking the previous one. Thanks, Nitesh
Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
participants (2)
-
Daniel P. Berrange
-
Nitesh Konkar