From nobody Tue Nov 26 19:42:50 2024 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=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1566577912; cv=none; d=zoho.com; s=zohoarc; b=g5aFqp+0djg3tiOCxHOZt9sbkBAC2HWI5K1Dt8NzuyhQVF7fyTZMfLPdWNieb50b6m5ePBjhSGnq7mLLtFuvaivSWqtfGSHI0SDQsVD3zwb9GkIWX5dTkDYLu+Bbzqk1xG+iNTuSyMarVNPb+Vb5T7hi57qkITsSFk5Rkn237R8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1566577912; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=iP8xONgbLJIDIZVSRmR1K1kXsP9bX9DAg22mzC9hsJw=; b=atGWv6Tn0IVtiEL+pKrOaR0igCah4sedoET90xyb/cGQEo4u8x5HNkrOj4Mly1AY9gO1c5q4Ggzp3bcc4zv/paSm2aHUqx2SO1uxh+qb58vDFhVaGGaWnbV/W9sLZNzzMz+R0UWGj+TPuaJgSFLesrP1FX0hn7LYjZZ7idx5pAo= ARC-Authentication-Results: i=1; mx.zoho.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=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1566577912544652.0504459023996; Fri, 23 Aug 2019 09:31:52 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1AEBD301E11C; Fri, 23 Aug 2019 16:31:51 +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 E7A8460606; Fri, 23 Aug 2019 16:31:50 +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 A845DE202; Fri, 23 Aug 2019 16:31:50 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x7NGVaGm006878 for ; Fri, 23 Aug 2019 12:31:36 -0400 Received: by smtp.corp.redhat.com (Postfix) id 8D0D55C28F; Fri, 23 Aug 2019 16:31:36 +0000 (UTC) Received: from himantopus.redhat.com (ovpn-117-62.phx2.redhat.com [10.3.117.62]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5B8E45C3FA for ; Fri, 23 Aug 2019 16:31:36 +0000 (UTC) From: Jonathon Jongsma To: libvir-list@redhat.com Date: Fri, 23 Aug 2019 11:31:20 -0500 Message-Id: <20190823163123.21683-7-jjongsma@redhat.com> In-Reply-To: <20190823163123.21683-1-jjongsma@redhat.com> References: <20190823163123.21683-1-jjongsma@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 6/9] qemu: add support for new fields in FSInfo 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: , 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.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 23 Aug 2019 16:31:51 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Since version 3.0, qemu has returned disk usage statistics in guest-get-fsinfo. And since 3.1, it has returned information about the disk serial number and device node of disks that are targeted by the filesystem. Unfortunately, the public API virDomainGetFSInfo() returns the filesystem info using a virDomainFSInfo struct, and due to API/ABI guaranteeds it cannot be extended. So this new information cannot easily be added to the public API. However, it is possible to add this new filesystem information to a new virDomainGetGuestInfo() API which will be based on typed parameters and is thus more extensible. In order to support these two use cases, I added an internal struct which the agent code uses to return all of the new data fields. This internal struct can be converted to the public struct at a cost of some extra memory allocation. In a following commit, this additional information will be used within virDomainGetGuestInfo(). Signed-off-by: Jonathon Jongsma Reviewed-by: Daniel Henrique Barboza Tested-by: Daniel Henrique Barboza --- src/qemu/qemu_agent.c | 203 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 182 insertions(+), 21 deletions(-) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index e986204162..8d54979f89 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -1827,19 +1827,144 @@ qemuAgentSetTime(qemuAgentPtr mon, return ret; } =20 +typedef struct _qemuAgentDiskInfo qemuAgentDiskInfo; +typedef qemuAgentDiskInfo *qemuAgentDiskInfoPtr; +struct _qemuAgentDiskInfo { + char *alias; + char *serial; + char *devnode; +}; + +typedef struct _qemuAgentFSInfo qemuAgentFSInfo; +typedef qemuAgentFSInfo *qemuAgentFSInfoPtr; +struct _qemuAgentFSInfo { + char *mountpoint; /* path to mount point */ + char *name; /* device name in the guest (e.g. "sda1") */ + char *fstype; /* filesystem type */ + long long total_bytes; + long long used_bytes; + size_t ndisks; + qemuAgentDiskInfoPtr *disks; +}; + +static void +qemuAgentDiskInfoFree(qemuAgentDiskInfoPtr info) +{ + if (!info) + return; + + VIR_FREE(info->serial); + VIR_FREE(info->alias); + VIR_FREE(info->devnode); + VIR_FREE(info); +} + +static void +qemuAgentFSInfoFree(qemuAgentFSInfoPtr info) +{ + size_t i; + + if (!info) + return; + + VIR_FREE(info->mountpoint); + VIR_FREE(info->name); + VIR_FREE(info->fstype); + + for (i =3D 0; i < info->ndisks; i++) + qemuAgentDiskInfoFree(info->disks[i]); + VIR_FREE(info->disks); + + VIR_FREE(info); +} + +static virDomainFSInfoPtr +qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent) +{ + virDomainFSInfoPtr ret =3D NULL; + size_t n; + + if (VIR_ALLOC(ret) < 0) + return NULL; =20 + if (VIR_STRDUP(ret->name, agent->name) < 0) + goto error; + if (VIR_STRDUP(ret->mountpoint, agent->mountpoint) < 0) + goto error; + if (VIR_STRDUP(ret->fstype, agent->fstype) < 0) + goto error; + + ret->ndevAlias =3D agent->ndisks; + + if (ret->ndevAlias =3D=3D 0) + return ret; + + if (VIR_ALLOC_N(ret->devAlias, ret->ndevAlias) < 0) + goto error; + + for (n =3D 0; n < ret->ndevAlias; n++) { + if (VIR_STRDUP(ret->devAlias[n], agent->disks[n]->alias) < 0) + goto error; + } + + return ret; + + error: + virDomainFSInfoFree(ret); + return NULL; +} + +static int +qemuAgentGetFSInfoInternal(qemuAgentPtr mon, qemuAgentFSInfoPtr **info, + virDomainDefPtr vmdef); int qemuAgentGetFSInfo(qemuAgentPtr mon, virDomainFSInfoPtr **info, virDomainDefPtr vmdef) +{ + int ret =3D -1; + qemuAgentFSInfoPtr *agentinfo =3D NULL; + virDomainFSInfoPtr *info_ret =3D NULL; + size_t i; + int nfs; + + nfs =3D qemuAgentGetFSInfoInternal(mon, &agentinfo, vmdef); + if (nfs < 0) + return ret; + if (VIR_ALLOC_N(info_ret, nfs) < 0) + goto cleanup; + + for (i =3D 0; i < nfs; i++) { + if (!(info_ret[i] =3D qemuAgentFSInfoToPublic(agentinfo[i]))) + goto cleanup; + } + + *info =3D info_ret; + info_ret =3D NULL; + ret =3D nfs; + + cleanup: + for (i =3D 0; i < nfs; i++) { + qemuAgentFSInfoFree(agentinfo[i]); + /* if there was an error, free any memory we've allocated for the + * return value */ + if (info_ret) + virDomainFSInfoFree(info_ret[i]); + } + return ret; +} + + +static int +qemuAgentGetFSInfoInternal(qemuAgentPtr mon, qemuAgentFSInfoPtr **info, + virDomainDefPtr vmdef) { size_t i, j, k; int ret =3D -1; - size_t ndata =3D 0, ndisk; - char **alias; + size_t ndata =3D 0; virJSONValuePtr cmd; virJSONValuePtr reply =3D NULL; virJSONValuePtr data; - virDomainFSInfoPtr *info_ret =3D NULL; + qemuAgentFSInfoPtr *info_ret =3D NULL; virPCIDeviceAddress pci_address; const char *result =3D NULL; =20 @@ -1915,6 +2040,33 @@ qemuAgentGetFSInfo(qemuAgentPtr mon, virDomainFSInfo= Ptr **info, if (VIR_STRDUP(info_ret[i]->fstype, result) < 0) goto cleanup; =20 + + /* 'used-bytes' and 'total-bytes' were added in qemu-ga 3.0 */ + unsigned long long bytes_val; + if (virJSONValueObjectHasKey(entry, "used-bytes")) { + if (virJSONValueObjectGetNumberUlong(entry, "used-bytes", + &bytes_val) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Error getting 'used-bytes' in reply of g= uest-get-fsinfo")); + goto cleanup; + } + info_ret[i]->used_bytes =3D bytes_val; + } else { + info_ret[i]->used_bytes =3D -1; + } + + if (virJSONValueObjectHasKey(entry, "total-bytes")) { + if (virJSONValueObjectGetNumberUlong(entry, "total-bytes", + &bytes_val) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Error getting 'total-bytes' in reply of = guest-get-fsinfo")); + goto cleanup; + } + info_ret[i]->total_bytes =3D bytes_val; + } else { + info_ret[i]->total_bytes =3D -1; + } + if (!(entry =3D virJSONValueObjectGet(entry, "disk"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'disk' missing in reply of guest-get-fsinfo"= )); @@ -1927,31 +2079,45 @@ qemuAgentGetFSInfo(qemuAgentPtr mon, virDomainFSInf= oPtr **info, goto cleanup; } =20 - ndisk =3D virJSONValueArraySize(entry); - if (ndisk =3D=3D 0) + info_ret[i]->ndisks =3D virJSONValueArraySize(entry); + if (info_ret[i]->ndisks =3D=3D 0) continue; - if (VIR_ALLOC_N(info_ret[i]->devAlias, ndisk) < 0) + if (VIR_ALLOC_N(info_ret[i]->disks, info_ret[i]->ndisks) < 0) goto cleanup; =20 - alias =3D info_ret[i]->devAlias; - info_ret[i]->ndevAlias =3D 0; - for (j =3D 0; j < ndisk; j++) { - virJSONValuePtr disk =3D virJSONValueArrayGet(entry, j); + for (j =3D 0; j < info_ret[i]->ndisks; j++) { + virJSONValuePtr jsondisk =3D virJSONValueArrayGet(entry, j); virJSONValuePtr pci; int diskaddr[3], pciaddr[4]; const char *diskaddr_comp[] =3D {"bus", "target", "unit"}; const char *pciaddr_comp[] =3D {"domain", "bus", "slot", "func= tion"}; + const char *val; virDomainDiskDefPtr diskDef; =20 - if (!disk) { + if (VIR_ALLOC(info_ret[i]->disks[j]) < 0) + goto cleanup; + + qemuAgentDiskInfoPtr disk =3D info_ret[i]->disks[j]; + + if (!jsondisk) { virReportError(VIR_ERR_INTERNAL_ERROR, _("array element '%zd' of '%zd' missing in " "guest-get-fsinfo 'disk' data"), - j, ndisk); + j, info_ret[i]->ndisks); goto cleanup; } =20 - if (!(pci =3D virJSONValueObjectGet(disk, "pci-controller"))) { + if ((val =3D virJSONValueObjectGetString(jsondisk, "serial")))= { + if (VIR_STRDUP(disk->serial, val) < 0) + goto cleanup; + } + + if ((val =3D virJSONValueObjectGetString(jsondisk, "dev"))) { + if (VIR_STRDUP(disk->devnode, val) < 0) + goto cleanup; + } + + if (!(pci =3D virJSONValueObjectGet(jsondisk, "pci-controller"= ))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'pci-controller' missing in guest-get-fs= info " "'disk' data")); @@ -1960,7 +2126,7 @@ qemuAgentGetFSInfo(qemuAgentPtr mon, virDomainFSInfoP= tr **info, =20 for (k =3D 0; k < 3; k++) { if (virJSONValueObjectGetNumberInt( - disk, diskaddr_comp[k], &diskaddr[k]) < 0) { + jsondisk, diskaddr_comp[k], &diskaddr[k]) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("'%s' missing in guest-get-fsinfo " "'disk' data"), diskaddr_comp[k]); @@ -1986,13 +2152,8 @@ qemuAgentGetFSInfo(qemuAgentPtr mon, virDomainFSInfo= Ptr **info, diskaddr[0], diskaddr[1], diskaddr[2]))) continue; =20 - if (VIR_STRDUP(*alias, diskDef->dst) < 0) + if (VIR_STRDUP(disk->alias, diskDef->dst) < 0) goto cleanup; - - if (*alias) { - alias++; - info_ret[i]->ndevAlias++; - } } } =20 @@ -2003,7 +2164,7 @@ qemuAgentGetFSInfo(qemuAgentPtr mon, virDomainFSInfoP= tr **info, cleanup: if (info_ret) { for (i =3D 0; i < ndata; i++) - virDomainFSInfoFree(info_ret[i]); + qemuAgentFSInfoFree(info_ret[i]); VIR_FREE(info_ret); } virJSONValueFree(cmd); --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list