From nobody Tue Dec 16 08:39:19 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1528450378517707.7839616954203; Fri, 8 Jun 2018 02:32:58 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CE85A36807; Fri, 8 Jun 2018 09:32:56 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 91DFA62527; Fri, 8 Jun 2018 09:32:56 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 448504CA80; Fri, 8 Jun 2018 09:32:56 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w589WsQt010300 for ; Fri, 8 Jun 2018 05:32:54 -0400 Received: by smtp.corp.redhat.com (Postfix) id 646FC1001F45; Fri, 8 Jun 2018 09:32:54 +0000 (UTC) Received: from mx1.redhat.com (ext-mx10.extmail.prod.ext.phx2.redhat.com [10.5.110.39]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 59B8A100191B for ; Fri, 8 Jun 2018 09:32:51 +0000 (UTC) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 43CDA5D697 for ; Fri, 8 Jun 2018 09:32:49 +0000 (UTC) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Jun 2018 02:32:48 -0700 Received: from david-unc.bj.intel.com ([10.238.145.77]) by fmsmga004.fm.intel.com with ESMTP; 08 Jun 2018 02:32:47 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,490,1520924400"; d="scan'208";a="61461057" From: Wang Huaqiang To: libvir-list@redhat.com Date: Fri, 8 Jun 2018 17:02:18 +0800 Message-Id: <1528448539-25588-3-git-send-email-huaqiang.wang@intel.com> In-Reply-To: <1528448539-25588-1-git-send-email-huaqiang.wang@intel.com> References: <1528448539-25588-1-git-send-email-huaqiang.wang@intel.com> X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 08 Jun 2018 09:32:49 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 08 Jun 2018 09:32:49 +0000 (UTC) for IP:'192.55.52.120' DOMAIN:'mga04.intel.com' HELO:'mga04.intel.com' FROM:'huaqiang.wang@intel.com' RCPT:'' X-RedHat-Spam-Score: -2.301 (RCVD_IN_DNSWL_MED, SPF_PASS) 192.55.52.120 mga04.intel.com 192.55.52.120 mga04.intel.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.39 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com Cc: shaohe.feng@intel.com, Wang Huaqiang , bing.niu@intel.com, jian-feng.ding@intel.com, rui.zang@intel.com Subject: [libvirt] [PATCH 2/3] tools: virsh: add command for controling/monitoring resctrl X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 08 Jun 2018 09:32:57 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" --- include/libvirt/libvirt-domain.h | 9 +++ src/conf/domain_conf.c | 28 +++++++ src/conf/domain_conf.h | 3 + src/driver-hypervisor.h | 8 ++ src/libvirt-domain.c | 81 +++++++++++++++++++++ src/libvirt_public.syms | 6 ++ src/qemu/qemu_driver.c | 141 ++++++++++++++++++++++++++++++++= ++++ src/qemu/qemu_process.c | 65 ++++++++++++++++- src/remote/remote_daemon_dispatch.c | 45 ++++++++++++ src/remote/remote_driver.c | 2 + src/remote/remote_protocol.x | 28 ++++++- src/remote_protocol-structs | 12 +++ tools/virsh-domain.c | 74 +++++++++++++++++++ 13 files changed, 499 insertions(+), 3 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-dom= ain.h index da773b7..598db28 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -4767,4 +4767,13 @@ int virDomainSetLifecycleAction(virDomainPtr domain, unsigned int action, unsigned int flags); =20 +/* + * resctrl API + */ +int virDomainSetResctrlMon(virDomainPtr domain, + int enable, int disable); + +int virDomainGetResctrlMonSts(virDomainPtr domain, + char **sts); + #endif /* __VIR_LIBVIRT_DOMAIN_H__ */ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5be773c..0ada3dc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18885,6 +18885,7 @@ virDomainCachetuneDefParse(virDomainDefPtr def, xmlNodePtr *nodes =3D NULL; virBitmapPtr vcpus =3D NULL; virResctrlAllocPtr alloc =3D virResctrlAllocNew(); + virResctrlMonPtr mon=3D virResctrlMonNew(); virDomainCachetuneDefPtr tmp_cachetune =3D NULL; char *tmp =3D NULL; char *vcpus_str =3D NULL; @@ -18898,6 +18899,9 @@ virDomainCachetuneDefParse(virDomainDefPtr def, if (!alloc) goto cleanup; =20 + if (!mon) + goto cleanup; + if (VIR_ALLOC(tmp_cachetune) < 0) goto cleanup; =20 @@ -18970,8 +18974,12 @@ virDomainCachetuneDefParse(virDomainDefPtr def, if (virResctrlAllocSetID(alloc, alloc_id) < 0) goto cleanup; =20 + if (virResctrlMonSetID(mon, alloc_id) < 0) + goto cleanup; + VIR_STEAL_PTR(tmp_cachetune->vcpus, vcpus); VIR_STEAL_PTR(tmp_cachetune->alloc, alloc); + VIR_STEAL_PTR(tmp_cachetune->mon, mon); =20 if (VIR_APPEND_ELEMENT(def->cachetunes, def->ncachetunes, tmp_cachetun= e) < 0) goto cleanup; @@ -18990,6 +18998,20 @@ virDomainCachetuneDefParse(virDomainDefPtr def, } =20 =20 +static int +virDomainResctrlDefParse(virDomainDefPtr def, + xmlXPathContextPtr ctxr ATTRIBUTE_UNUSED) +{ + virResctrlMonPtr mon=3D virResctrlMonNew(); + if (virResctrlMonSetID(mon, "vcpu-rest") < 0) + return -1; + + def->resctrlmon_noalloc =3D mon; + + return 0; +} + + static virDomainDefPtr virDomainDefParseXML(xmlDocPtr xml, xmlNodePtr root, @@ -19585,6 +19607,12 @@ virDomainDefParseXML(xmlDocPtr xml, } VIR_FREE(nodes); =20 + if (virDomainResctrlDefParse(def, ctxt) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot extract resctrl")); + goto error; + } + if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &def->cpu)= < 0) goto error; =20 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8a8121b..2febe62 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2234,6 +2234,7 @@ typedef virDomainCachetuneDef *virDomainCachetuneDefP= tr; struct _virDomainCachetuneDef { virBitmapPtr vcpus; virResctrlAllocPtr alloc; + virResctrlMonPtr mon; }; =20 =20 @@ -2389,6 +2390,8 @@ struct _virDomainDef { =20 virDomainCputune cputune; =20 + virResctrlMonPtr resctrlmon_noalloc; + virDomainCachetuneDefPtr *cachetunes; size_t ncachetunes; =20 diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index aa99cbb..c2e5d2a 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1309,6 +1309,12 @@ typedef int unsigned int action, unsigned int flags); =20 +typedef int +(*virDrvDomainSetResctrlMon)(virDomainPtr domain, + int enable, int disable); + +typedef char * +(*virDrvDomainGetResctrlMonSts)(virDomainPtr domain); =20 typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1558,6 +1564,8 @@ struct _virHypervisorDriver { virDrvDomainSetLifecycleAction domainSetLifecycleAction; virDrvConnectCompareHypervisorCPU connectCompareHypervisorCPU; virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU; + virDrvDomainSetResctrlMon domainSetResctrlMon; + virDrvDomainGetResctrlMonSts domainGetResctrlMonSts; }; =20 =20 diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index d44b553..07a19a6 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -12154,3 +12154,84 @@ int virDomainSetLifecycleAction(virDomainPtr domai= n, virDispatchError(domain->conn); return -1; } + + +/** + * virDomainSetResctrlMon: + * @domain: a domain object + * @enable: true(non-zero) for enbling resctrl mon group. + * @disable: true(non-zero) for disbling resctrl mon group. + * valid if @enable is false + * + * Enable or disable resctrl monitoring. + * + * Returns -1 in case of failure, 0 in case of success. + */ +int +virDomainSetResctrlMon(virDomainPtr domain, + int enable, int disable) +{ + int ret; + virConnectPtr conn; + + virResetLastError(); + + if(!disable && !enable) + return 0; + + virCheckDomainReturn(domain, -1); + + conn =3D domain->conn; + + if (conn->driver->domainSetResctrlMon) { + ret =3D conn->driver->domainSetResctrlMon(domain, + enable, disable); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} + + +/** + * virDomainGetResctrlMonSts: + * @domain: a domain object + * @status: pointer of a string buffer for holding resctrl mon + * group status string, caller is responsible for free it. + * + * Get domain resctrl status. + * + * Returns -1 in case of failure, 0 in case of success. + */ +int +virDomainGetResctrlMonSts(virDomainPtr domain, + char **status) +{ + int ret =3D -1; + virConnectPtr conn; + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + + conn =3D domain->conn; + + if (conn->driver->domainGetResctrlMonSts) { + *status =3D conn->driver->domainGetResctrlMonSts(domain); + if (*status) + ret =3D 0; + + goto done; + } + + virReportUnsupportedError(); + done: + virDispatchError(domain->conn); + return ret; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 4f54b84..fb3eef5 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -798,4 +798,10 @@ LIBVIRT_4.5.0 { virGetLastErrorDomain; } LIBVIRT_4.4.0; =20 +LIBVIRT_4.6.0 { + global: + virDomainSetResctrlMon; + virDomainGetResctrlMonSts; +} LIBVIRT_4.5.0; + # .... define new API here using predicted next version number .... diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 38ea865..4075daa 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -108,6 +108,7 @@ #include "virnuma.h" #include "dirname.h" #include "netdev_bandwidth_conf.h" +#include "virresctrl.h" =20 #define VIR_FROM_THIS VIR_FROM_QEMU =20 @@ -21437,6 +21438,144 @@ qemuDomainSetLifecycleAction(virDomainPtr dom, } =20 =20 +static int +qemuDomainSetResctrlMon(virDomainPtr dom, + int enable ,int disable) +{ + int ret =3D -1; + virDomainObjPtr vm; + virResctrlMonAct act =3D VIR_RESCTRL_MONACT_NONE;; + int i =3D 0; + unsigned int maxvcpus =3D 0; + + /* The 'enable' action will override the 'disable' one */ + if(disable) + act =3D VIR_RESCTRL_MONACT_DISABLE; + if(enable) + act =3D VIR_RESCTRL_MONACT_ENABLE; + + if (act =3D=3D VIR_RESCTRL_MONACT_NONE) + return 0; + + if (!(vm =3D qemuDomObjFromDomain(dom))) + return ret; + + qemuDomainObjPrivatePtr priv =3D vm->privateData; + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain is not running")); + goto cleanup; + } + + /* If 'resctrl' is enabled in xml configuation file through 'cachetune' + * section, this interface doesn't work. return 1 for this case */ + if (vm->def->ncachetunes !=3D 0){ + VIR_DEBUG("resctrl monitoring interface is governed by domain " + "configration 'cachetune' sections. Interface disabled.\n"); + ret =3D 1; + goto cleanup; + } + + if (act =3D=3D VIR_RESCTRL_MONACT_ENABLE) { + + if (!vm->def->resctrlmon_noalloc){ + virReportError(VIR_ERR_NO_DOMAIN, + _("resctrlmon_noalloc should be allocated.")); + goto cleanup; + } + + if(!virResctrlMonIsRunning(vm->def->resctrlmon_noalloc)) { + + if (virResctrlMonCreate(NULL, + vm->def->resctrlmon_noalloc, priv->machineName) < = 0) + goto cleanup; + + /* Set vcpus */ + maxvcpus =3D virDomainDefGetVcpusMax(vm->def); + for (i =3D 0; i < maxvcpus; i++) { + virDomainVcpuDefPtr vcpu + =3D virDomainDefGetVcpu(vm->def, i); + + if (!vcpu->online) + continue; + + pid_t vcpupid =3D qemuDomainGetVcpuPid(vm, i); + if (virResctrlMonAddPID(vm->def->resctrlmon_noalloc, + vcpupid) < 0) + goto cleanup; + } + } + + VIR_DEBUG("resctrl monitoring is enabled"); + } else if (act =3D=3D VIR_RESCTRL_MONACT_DISABLE){ + if (!vm->def->resctrlmon_noalloc){ + virReportError(VIR_ERR_NO_DOMAIN, + _("resctrlmon_noalloc should be allocated.")); + goto cleanup; + } + + if(virResctrlMonIsRunning(vm->def->resctrlmon_noalloc)) { + if (virResctrlMonRemove(vm->def->resctrlmon_noalloc) < 0){ + virReportError(VIR_ERR_NO_DOMAIN, + _("Error in remove resctrl mon group.")); + goto cleanup; + } + } + + VIR_DEBUG("resctrl monitoring is disabled\n"); + } + + ret =3D 0; +cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + + +static char * +qemuDomainGetResctrlMonSts(virDomainPtr dom) +{ + virDomainObjPtr vm; + char *sts =3D NULL; + + if (!(vm =3D qemuDomObjFromDomain(dom))) + return sts; + + if (vm->def->ncachetunes !=3D 0){ + VIR_DEBUG("resctrl monitoring interface is governed by domain " + "'cachetune' sections. resctrl monitoring is compulsively enabled.\= n"); + + /* only check cachetune[0] for domain resctrl mon group status */ + if (!virResctrlMonIsRunning(vm->def->cachetunes[0]->mon)) { + if (virAsprintf(&sts, "Disabled") < 0) + goto cleanup; + } else { + if (virAsprintf(&sts, "Enabled (forced by cachetune)") < 0) + goto cleanup; + } + + } else { + + if (vm->def->resctrlmon_noalloc && + virResctrlMonIsRunning(vm->def->resctrlmon_noalloc)){ + if (virAsprintf(&sts, "Enabled") < 0) + goto cleanup; + + } else { + if (virAsprintf(&sts, "Disabled") < 0) + goto cleanup; + } + } + + VIR_DEBUG("resctrl monitoring status: %s\n", sts); + +cleanup: + virDomainObjEndAPI(&vm); + return sts; +} + + static virHypervisorDriver qemuHypervisorDriver =3D { .name =3D QEMU_DRIVER_NAME, .connectURIProbe =3D qemuConnectURIProbe, @@ -21660,6 +21799,8 @@ static virHypervisorDriver qemuHypervisorDriver =3D= { .domainSetLifecycleAction =3D qemuDomainSetLifecycleAction, /* 3.9.0 */ .connectCompareHypervisorCPU =3D qemuConnectCompareHypervisorCPU, /* 4= .4.0 */ .connectBaselineHypervisorCPU =3D qemuConnectBaselineHypervisorCPU, /*= 4.4.0 */ + .domainSetResctrlMon =3D qemuDomainSetResctrlMon, /*FIXME: assign prop= er ver string */ + .domainGetResctrlMonSts =3D qemuDomainGetResctrlMonSts, /*FIXME: assig= n proper ver string */ }; =20 =20 diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 1606f4c..4fab0e1 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2461,6 +2461,11 @@ qemuProcessResctrlCreate(virQEMUDriverPtr driver, vm->def->cachetunes[i]->alloc, priv->machineName) < 0) goto cleanup; + + if (virResctrlMonCreate(vm->def->cachetunes[i]->alloc, + vm->def->cachetunes[i]->mon, + priv->machineName) < 0) + goto cleanup; } =20 ret =3D 0; @@ -5259,6 +5264,7 @@ qemuProcessSetupVcpu(virDomainObjPtr vm, &vcpu->sched) < 0) return -1; =20 + =20 for (i =3D 0; i < vm->def->ncachetunes; i++) { virDomainCachetuneDefPtr ct =3D vm->def->cachetunes[i]; =20 @@ -5279,6 +5285,10 @@ qemuProcessSetupVcpus(virDomainObjPtr vm) virDomainVcpuDefPtr vcpu; unsigned int maxvcpus =3D virDomainDefGetVcpusMax(vm->def); size_t i; + virBitmapPtr vcpuleft =3D NULL; + int ret =3D -1; + + qemuDomainObjPrivatePtr priv =3D vm->privateData; =20 if ((vm->def->cputune.period || vm->def->cputune.quota) && !virCgroupHasController(((qemuDomainObjPrivatePtr) vm->privateData= )->cgroup, @@ -5308,17 +5318,52 @@ qemuProcessSetupVcpus(virDomainObjPtr vm) return 0; } =20 + /* To monitor whole domain's cache occupancy information + * create mon group for un-covered VCPUs */ + if (!(vcpuleft =3D virBitmapNew(maxvcpus + 1))) + goto cleanup; + + virBitmapClearAll(vcpuleft); + for (i =3D 0; i < maxvcpus; i++) { vcpu =3D virDomainDefGetVcpu(vm->def, i); =20 if (!vcpu->online) continue; =20 + if ( virBitmapSetBit(vcpuleft, i) < 0) + goto cleanup; + if (qemuProcessSetupVcpu(vm, i) < 0) return -1; } =20 - return 0; + for (i =3D 0; i < vm->def->ncachetunes; i++) { + virDomainCachetuneDefPtr ct =3D vm->def->cachetunes[i]; + virBitmapSubtract(vcpuleft, ct->vcpus); + } + + + if (vm->def->ncachetunes && + !virBitmapIsAllClear(vcpuleft)){ + + if (virResctrlMonCreate(NULL, vm->def->resctrlmon_noalloc, priv->mach= ineName) < 0) + goto cleanup; + + for (i =3D 0; i < maxvcpus; i++) { + if (virBitmapIsBitSet(vcpuleft, i)){ + pid_t vcpupid =3D qemuDomainGetVcpuPid(vm, i); + + if (virResctrlMonAddPID(vm->def->resctrlmon_noalloc, vcpupid) < 0) + goto cleanup; + } + } + } + + ret =3D 0; +cleanup: + virBitmapFree(vcpuleft); + return ret; } =20 =20 @@ -6895,8 +6940,14 @@ void qemuProcessStop(virQEMUDriverPtr driver, /* Remove resctrl allocation after cgroups are cleaned up which makes = it * kind of safer (although removing the allocation should work even wi= th * pids in tasks file */ - for (i =3D 0; i < vm->def->ncachetunes; i++) + for (i =3D 0; i < vm->def->ncachetunes; i++){ virResctrlAllocRemove(vm->def->cachetunes[i]->alloc); + virResctrlMonRemove(vm->def->cachetunes[i]->mon); + } + + if(vm->def->resctrlmon_noalloc) + virResctrlMonRemove(vm->def->resctrlmon_noalloc); + =20 qemuProcessRemoveDomainStatus(driver, vm); =20 @@ -7620,8 +7671,18 @@ qemuProcessReconnect(void *opaque) if (virResctrlAllocDeterminePath(obj->def->cachetunes[i]->alloc, priv->machineName) < 0) goto error; + + if (virResctrlMonDeterminePath(obj->def->cachetunes[i]->mon, + priv->machineName) < 0) + goto error; + } =20 + if(obj->def->resctrlmon_noalloc && + virResctrlMonDeterminePath(obj->def->resctrlmon_noalloc, + priv->machineName) < 0) + goto error; + /* update domain state XML with possibly updated state in virDomainObj= */ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->ca= ps) < 0) goto error; diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon= _dispatch.c index 81d0445..2ef0e5e 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -7107,3 +7107,48 @@ remoteSerializeDomainDiskErrors(virDomainDiskErrorPt= r errors, } return -1; } + +static int remoteDispatchDomainGetResctrlMonSts( + virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_get_resctrl_mon_sts_args *args, + remote_domain_get_resctrl_mon_sts_ret *ret) +{ + int rv =3D -1; + virDomainPtr dom =3D NULL; + char *sts =3D NULL; + char **sts_p =3D NULL; + struct daemonClientPrivate *priv =3D + virNetServerClientGetPrivateData(client); + + if (!priv->conn) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not ope= n")); + goto cleanup; + } + + if (!(dom =3D get_nonnull_domain(priv->conn, args->dom))) + goto cleanup; + + if ((rv =3D virDomainGetResctrlMonSts(dom, &sts)) < 0) + goto cleanup; + + if (VIR_ALLOC(sts_p) < 0) + goto cleanup; + + if (VIR_STRDUP(*sts_p, sts) < 0) + goto cleanup; + + ret->sts =3D sts_p; + rv =3D 0; + +cleanup: + if (rv < 0) { + virNetMessageSaveError(rerr); + VIR_FREE(sts_p); + } + virObjectUnref(dom); + VIR_FREE(sts); + return rv; +} diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index c22993c..4a6b101 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8451,6 +8451,8 @@ static virHypervisorDriver hypervisor_driver =3D { .domainSetLifecycleAction =3D remoteDomainSetLifecycleAction, /* 3.9.0= */ .connectCompareHypervisorCPU =3D remoteConnectCompareHypervisorCPU, /*= 4.4.0 */ .connectBaselineHypervisorCPU =3D remoteConnectBaselineHypervisorCPU, = /* 4.4.0 */ + .domainSetResctrlMon =3D remoteDomainSetResctrlMon, /*FIXME: assign pr= oper ver string */ + .domainGetResctrlMonSts =3D remoteDomainGetResctrlMonSts, /*FIXME: ass= ign proper ver string */ }; =20 static virNetworkDriver network_driver =3D { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index a0ab7e9..9242a61 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3480,6 +3480,20 @@ struct remote_connect_baseline_hypervisor_cpu_ret { remote_nonnull_string cpu; }; =20 +struct remote_domain_set_resctrl_mon_args { + remote_nonnull_domain dom; + int enable; + int disable; +}; + +struct remote_domain_get_resctrl_mon_sts_args { + remote_nonnull_domain dom; +}; + +struct remote_domain_get_resctrl_mon_sts_ret { /* insert@1 */ + remote_string sts; +}; + /*----- Protocol. -----*/ =20 /* Define the program number, protocol version and procedure numbers here.= */ @@ -6187,5 +6201,17 @@ enum remote_procedure { * @generate: both * @acl: connect:write */ - REMOTE_PROC_CONNECT_BASELINE_HYPERVISOR_CPU =3D 394 + REMOTE_PROC_CONNECT_BASELINE_HYPERVISOR_CPU =3D 394, + + /** + * @generate: both + * @acl: domain:write + */ + REMOTE_PROC_DOMAIN_SET_RESCTRL_MON =3D 395, + + /** + * @generate: client + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_GET_RESCTRL_MON_STS =3D 396 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 0c4cfc6..ed6a782 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2907,6 +2907,16 @@ struct remote_connect_baseline_hypervisor_cpu_args { struct remote_connect_baseline_hypervisor_cpu_ret { remote_nonnull_string cpu; }; +struct remote_domain_set_resctrl_mon_args { + remote_nonnull_domain dom; + int enable; + int disable; +} +struct remote_domain_get_resctrl_mon_sts_args { + remote_nonnull_domain dom; +}; +struct remote_domain_get_resctrl_mon_sts_ret { + remote_string sts; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN =3D 1, REMOTE_PROC_CONNECT_CLOSE =3D 2, @@ -3302,4 +3312,6 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_DETACH_DEVICE_ALIAS =3D 392, REMOTE_PROC_CONNECT_COMPARE_HYPERVISOR_CPU =3D 393, REMOTE_PROC_CONNECT_BASELINE_HYPERVISOR_CPU =3D 394, + REMOTE_PROC_DOMAIN_SET_RESCTRL_MON =3D 395, + REMOTE_PROC_DOMAIN_GET_RESCTRL_MON_STS =3D 396, }; diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 6aa79f1..4ae8ed2 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -7677,6 +7677,74 @@ cmdIOThreadDel(vshControl *ctl, const vshCmd *cmd) return ret; } =20 +static const vshCmdInfo info_resctrl[] =3D { + {.name =3D "help", + .data =3D N_("get or set hardware CPU resource monitoring functions") + }, + {.name =3D "desc", + .data =3D N_("Enable or disable resctrl monitoring for a guest domain= .\n" + " To get resctrl status use following" + " command: \n\n" + " virsh # resctrl ") + }, + {.name =3D NULL} +}; + +static const vshCmdOptDef opts_resctrl[] =3D { + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), + {.name =3D "enable", + .type =3D VSH_OT_BOOL, + .help =3D N_("Enable resctrl function such as monitoring cache occupa= ncy " + "or memory bandwidth.") + }, + {.name =3D "disable", + .type =3D VSH_OT_BOOL, + .help =3D N_("Disable hardware function such as monitoring cache occu= pancy " + "or memory bandwidth.") + }, + {.name =3D NULL} +}; + + +static bool +cmdResctrl(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool ret =3D false; + char *ressts =3D NULL; + + bool enable =3D vshCommandOptBool(cmd, "enable"); + bool disable=3D vshCommandOptBool(cmd, "disable"); + + if (!(dom =3D virshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if(!enable && !disable){ + if (virDomainGetResctrlMonSts(dom, &ressts) < 0) + goto cleanup; + + if (!ressts) + goto cleanup; + + } else { + if (virDomainSetResctrlMon(dom, enable, disable) < 0) + goto cleanup; + + if (virDomainGetResctrlMonSts(dom, &ressts) < 0) + goto cleanup; + + if (!ressts) + goto cleanup; + } + + vshPrint(ctl,"RDT Monitoring Status: %s\n", ressts); + ret =3D true; +cleanup: + VIR_FREE(ressts); + virshDomainFree(dom); + return ret; +} + /* * "cpu-stats" command */ @@ -13799,6 +13867,12 @@ const vshCmdDef domManagementCmds[] =3D { .flags =3D 0 }, #endif + {.name =3D "resctrl", + .handler =3D cmdResctrl, + .opts =3D opts_resctrl, + .info =3D info_resctrl, + .flags =3D 0 + }, {.name =3D "cpu-stats", .handler =3D cmdCPUStats, .opts =3D opts_cpu_stats, --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list