From nobody Tue Nov 26 19:41:41 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=1566577905; cv=none; d=zoho.com; s=zohoarc; b=oFS+F4pGZJ4j/M1Lx+8udJSjtJN2H7wASpFDGyOqPqMnCnzUc+6sIo3xjHG0wA7HuEzuZExEeqo1mmC93nlPuPxP7XwXEOnnO8tjhzhGxjF5T9vG48Zvkj/hJ4G9ZYBZC6RxGGRdrMXIebRo1uVLfJ3gcTY4TAAbm9VCud+D9tk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1566577905; 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=/nSY5C5dYyaEx88k18ao13aE4XVsEQ21Vn+msdq09LI=; b=WRz+anYOJY0iqLzPQ8cFL8h+YcV82GEFCPXh9En6inxecCQnPNCS5glcdQ4pqw1O8asBNZ25z5A98z/DDjg7sX1NdlRiEjVC+0oZYEZK0DYq6ffh/UTmD6YtqWAaTTIXYGkr/EjgGYeGx9YwzCWc2WUVwaUTuojIZ9NZaOc1j1o= 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 1566577905755928.5765585620506; Fri, 23 Aug 2019 09:31:45 -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 B4D21308427D; Fri, 23 Aug 2019 16:31:44 +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 3495A8519; Fri, 23 Aug 2019 16:31:44 +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 EC75DE208; Fri, 23 Aug 2019 16:31:43 +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 x7NGVaKn006886 for ; Fri, 23 Aug 2019 12:31:36 -0400 Received: by smtp.corp.redhat.com (Postfix) id DE1B55C3FA; 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 ABE3D5C28F 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:21 -0500 Message-Id: <20190823163123.21683-8-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 7/9] qemu: add helper for getting full 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.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Fri, 23 Aug 2019 16:31:45 +0000 (UTC) Content-Type: text/plain; charset="utf-8" This function adds the complete filesystem information returned by the qemu agent to an array of typed parameters with field names intended to to be returned by virDomainGetGuestInfo() Signed-off-by: Jonathon Jongsma Tested-by: Daniel Henrique Barboza --- src/qemu/qemu_agent.c | 90 ++++++++++++++++++ src/qemu/qemu_agent.h | 5 + tests/qemuagenttest.c | 210 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 292 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 8d54979f89..169ad74f6f 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -1953,6 +1953,96 @@ qemuAgentGetFSInfo(qemuAgentPtr mon, virDomainFSInfo= Ptr **info, return ret; } =20 +int +qemuAgentGetFSInfoParams(qemuAgentPtr mon, + virTypedParameterPtr *params, + int *nparams, int *maxparams, + virDomainDefPtr vmdef) +{ + int ret =3D -1; + qemuAgentFSInfoPtr *fsinfo =3D NULL; + size_t i, j; + int nfs; + + if ((nfs =3D qemuAgentGetFSInfoInternal(mon, &fsinfo, vmdef)) < 0) + return -1; + + if (virTypedParamsAddUInt(params, nparams, maxparams, + "fs.count", nfs) < 0) + goto cleanup; + + for (i =3D 0; i < nfs; i++) { + char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "fs.%zu.name", i); + if (virTypedParamsAddString(params, nparams, maxparams, + param_name, fsinfo[i]->name) < 0) + goto cleanup; + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "fs.%zu.mountpoint", i); + if (virTypedParamsAddString(params, nparams, maxparams, + param_name, fsinfo[i]->mountpoint) < 0) + goto cleanup; + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "fs.%zu.fstype", i); + if (virTypedParamsAddString(params, nparams, maxparams, + param_name, fsinfo[i]->fstype) < 0) + goto cleanup; + + /* disk usage values are not returned by older guest agents, so + * only add the params if the value is set */ + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "fs.%zu.total-bytes", i); + if (fsinfo[i]->total_bytes !=3D -1 && + virTypedParamsAddULLong(params, nparams, maxparams, + param_name, fsinfo[i]->total_bytes) < = 0) + goto cleanup; + + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "fs.%zu.used-bytes", i); + if (fsinfo[i]->used_bytes !=3D -1 && + virTypedParamsAddULLong(params, nparams, maxparams, + param_name, fsinfo[i]->used_bytes) < 0) + goto cleanup; + + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "fs.%zu.disk.count", i); + if (virTypedParamsAddUInt(params, nparams, maxparams, + param_name, fsinfo[i]->ndisks) < 0) + goto cleanup; + for (j =3D 0; j < fsinfo[i]->ndisks; j++) { + qemuAgentDiskInfoPtr d =3D fsinfo[i]->disks[j]; + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "fs.%zu.disk.%zu.alias", i, j); + if (d->alias && + virTypedParamsAddString(params, nparams, maxparams, + param_name, d->alias) < 0) + goto cleanup; + + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "fs.%zu.disk.%zu.serial", i, j); + if (d->serial && + virTypedParamsAddString(params, nparams, maxparams, + param_name, d->serial) < 0) + goto cleanup; + + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "fs.%zu.disk.%zu.device", i, j); + if (d->devnode && + virTypedParamsAddString(params, nparams, maxparams, + param_name, d->devnode) < 0) + goto cleanup; + } + } + ret =3D nfs; + + cleanup: + for (i =3D 0; i < nfs; i++) + qemuAgentFSInfoFree(fsinfo[i]); + VIR_FREE(fsinfo); + + return ret; +} =20 static int qemuAgentGetFSInfoInternal(qemuAgentPtr mon, qemuAgentFSInfoPtr **info, diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index 69b0176855..f6d74a2603 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -74,6 +74,11 @@ int qemuAgentFSThaw(qemuAgentPtr mon); int qemuAgentGetFSInfo(qemuAgentPtr mon, virDomainFSInfoPtr **info, virDomainDefPtr vmdef); =20 +int qemuAgentGetFSInfoParams(qemuAgentPtr mon, + virTypedParameterPtr *params, + int *nparams, int *maxparams, + virDomainDefPtr vmdef); + int qemuAgentSuspend(qemuAgentPtr mon, unsigned int target); =20 diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c index 0912a5f29a..105b32017a 100644 --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -168,38 +168,45 @@ testQemuAgentFSTrim(const void *data) =20 =20 static int -testQemuAgentGetFSInfo(const void *data) +testQemuAgentGetFSInfoCommon(virDomainXMLOptionPtr xmlopt, + qemuMonitorTestPtr *test, + virDomainDefPtr *def) { - virDomainXMLOptionPtr xmlopt =3D (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test =3D qemuMonitorTestNewAgent(xmlopt); + int ret =3D -1; char *domain_filename =3D NULL; - virDomainDefPtr def =3D NULL; - virDomainFSInfoPtr *info =3D NULL; - int ret =3D -1, ninfo =3D 0, i; + qemuMonitorTestPtr ret_test =3D NULL; + virDomainDefPtr ret_def =3D NULL; =20 - if (!test) + if (!test || !def) + return -1; + + if (!(ret_test =3D qemuMonitorTestNewAgent(xmlopt))) return -1; =20 if (virAsprintf(&domain_filename, "%s/qemuagentdata/fsinfo.xml", abs_srcdir) < 0) goto cleanup; =20 - if (!(def =3D virDomainDefParseFile(domain_filename, driver.caps, xmlo= pt, - NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE)= )) + if (!(ret_def =3D virDomainDefParseFile(domain_filename, driver.caps, = xmlopt, + NULL, VIR_DOMAIN_DEF_PARSE_INACT= IVE))) goto cleanup; =20 - if (qemuMonitorTestAddAgentSyncResponse(test) < 0) + if (qemuMonitorTestAddAgentSyncResponse(ret_test) < 0) goto cleanup; =20 - if (qemuMonitorTestAddItem(test, "guest-get-fsinfo", + if (qemuMonitorTestAddItem(ret_test, "guest-get-fsinfo", "{\"return\": [" " {\"name\": \"sda1\", \"mountpoint\": \"/= \"," + " \"total-bytes\":952840192," + " \"used-bytes\":229019648," " \"disk\": [" - " {\"bus-type\": \"ide\"," + " {\"serial\": \"ARBITRARYSTRING\"," + " \"bus-type\": \"ide\"," " \"bus\": 1, \"unit\": 0," " \"pci-controller\": {" " \"bus\": 0, \"slot\": 1," " \"domain\": 0, \"function\": 1}," + " \"dev\": \"/dev/sda1\"," " \"target\": 0}]," " \"type\": \"ext4\"}," " {\"name\": \"dm-1\"," @@ -221,6 +228,32 @@ testQemuAgentGetFSInfo(const void *data) " {\"name\": \"sdb1\"," " \"mountpoint\": \"/mnt/disk\"," " \"disk\": [], \"type\": \"xfs\"}]}") < = 0) + goto cleanup; + *test =3D ret_test; + ret_test =3D NULL; + *def =3D ret_def; + ret_def =3D NULL; + ret =3D 0; + + cleanup: + VIR_FREE(domain_filename); + if (ret_test) + qemuMonitorTestFree(ret_test); + virDomainDefFree(ret_def); + + return ret; +} + +static int +testQemuAgentGetFSInfo(const void *data) +{ + virDomainXMLOptionPtr xmlopt =3D (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test =3D NULL; + virDomainDefPtr def =3D NULL; + virDomainFSInfoPtr *info =3D NULL; + int ret =3D -1, ninfo =3D 0, i; + + if (testQemuAgentGetFSInfoCommon(xmlopt, &test, &def) < 0) goto cleanup; =20 if ((ninfo =3D qemuAgentGetFSInfo(qemuMonitorTestGetAgent(test), @@ -295,7 +328,157 @@ testQemuAgentGetFSInfo(const void *data) for (i =3D 0; i < ninfo; i++) virDomainFSInfoFree(info[i]); VIR_FREE(info); - VIR_FREE(domain_filename); + virDomainDefFree(def); + qemuMonitorTestFree(test); + return ret; +} + +static int +testQemuAgentGetFSInfoParams(const void *data) +{ + virDomainXMLOptionPtr xmlopt =3D (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test =3D NULL; + virDomainDefPtr def =3D NULL; + virTypedParameterPtr params =3D NULL; + int nparams =3D 0, maxparams =3D 0; + int ret =3D -1; + unsigned int count; + + if (testQemuAgentGetFSInfoCommon(xmlopt, &test, &def) < 0) + goto cleanup; + + if (qemuAgentGetFSInfoParams(qemuMonitorTestGetAgent(test), + ¶ms, &nparams, &maxparams, def) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Failed to execute qemuAgentGetFSInfoParams()"); + goto cleanup; + } + + if (virTypedParamsGetUInt(params, nparams, "fs.count", &count) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "expected filesystem count"); + goto cleanup; + } + + if (count !=3D 3) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "expected 3 filesystems information, got %d", count= ); + ret =3D -1; + goto cleanup; + } + const char *name, *mountpoint, *fstype, *alias, *serial; + unsigned int diskcount; + unsigned long long bytesused, bytestotal; + if (virTypedParamsGetString(params, nparams, "fs.2.name", &name) < 0 || + virTypedParamsGetString(params, nparams, "fs.2.mountpoint", &mount= point) < 0 || + virTypedParamsGetString(params, nparams, "fs.2.fstype", &fstype) <= 0 || + virTypedParamsGetULLong(params, nparams, "fs.2.used-bytes", &bytes= used) <=3D 0 || + virTypedParamsGetULLong(params, nparams, "fs.2.total-bytes", &byte= stotal) <=3D 0 || + virTypedParamsGetUInt(params, nparams, "fs.2.disk.count", &diskcou= nt) < 0 || + virTypedParamsGetString(params, nparams, "fs.2.disk.0.alias", &ali= as) < 0 || + virTypedParamsGetString(params, nparams, "fs.2.disk.0.serial", &se= rial) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Missing an expected parameter for sda1 (%s,%s)", + name, alias); + ret =3D -1; + goto cleanup; + } + if ( + STRNEQ(name, "sda1") || + STRNEQ(mountpoint, "/") || + STRNEQ(fstype, "ext4") || + bytesused !=3D 229019648 || + bytestotal !=3D 952840192 || + diskcount !=3D 1 || + STRNEQ(alias, "hdc") || + STRNEQ(serial, "ARBITRARYSTRING")) + { + virReportError(VIR_ERR_INTERNAL_ERROR, + "unexpected filesystems information returned for sda1 (%s,%s)", + name, alias); + ret =3D -1; + goto cleanup; + } + + const char *alias2; + if (virTypedParamsGetString(params, nparams, "fs.1.name", &name) < 0 || + virTypedParamsGetString(params, nparams, "fs.1.mountpoint", &mount= point) < 0 || + virTypedParamsGetString(params, nparams, "fs.1.fstype", &fstype) <= 0 || + virTypedParamsGetULLong(params, nparams, "fs.1.used-bytes", &bytes= used) =3D=3D 1 || + virTypedParamsGetULLong(params, nparams, "fs.1.total-bytes", &byte= stotal) =3D=3D 1 || + virTypedParamsGetUInt(params, nparams, "fs.1.disk.count", &diskcou= nt) < 0 || + virTypedParamsGetString(params, nparams, "fs.1.disk.0.alias", &ali= as) < 0 || + virTypedParamsGetString(params, nparams, "fs.1.disk.1.alias", &ali= as2) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Incorrect parameters for dm-1 (%s,%s)", + name, alias); + ret =3D -1; + goto cleanup; + } + if (STRNEQ(name, "dm-1") || + STRNEQ(mountpoint, "/opt") || + STRNEQ(fstype, "vfat") || + diskcount !=3D 2 || + STRNEQ(alias, "vda") || + STRNEQ(alias2, "vdb")) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "unexpected filesystems information returned for dm-1 (%s,%s)", + name, alias); + ret =3D -1; + goto cleanup; + } + + alias =3D NULL; + if (virTypedParamsGetString(params, nparams, "fs.0.name", &name) < 0 || + virTypedParamsGetString(params, nparams, "fs.0.mountpoint", &mount= point) < 0 || + virTypedParamsGetString(params, nparams, "fs.0.fstype", &fstype) <= 0 || + virTypedParamsGetULLong(params, nparams, "fs.0.used-bytes", &bytes= used) =3D=3D 1 || + virTypedParamsGetULLong(params, nparams, "fs.0.total-bytes", &byte= stotal) =3D=3D 1 || + virTypedParamsGetUInt(params, nparams, "fs.0.disk.count", &diskcou= nt) < 0 || + virTypedParamsGetString(params, nparams, "fs.0.disk.0.alias", &ali= as) =3D=3D 1) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Incorrect parameters for sdb1 (%s,%s)", + name, alias); + ret =3D -1; + goto cleanup; + } + if (STRNEQ(name, "sdb1") || + STRNEQ(mountpoint, "/mnt/disk") || + STRNEQ(fstype, "xfs") || + diskcount !=3D 0 || + alias !=3D NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "unexpected filesystems information returned for sdb1 (%s,%s)", + name, alias); + ret =3D -1; + goto cleanup; + } + + if (qemuMonitorTestAddAgentSyncResponse(test) < 0) + goto cleanup; + + if (qemuMonitorTestAddItem(test, "guest-get-fsinfo", + "{\"error\":" + " {\"class\":\"CommandDisabled\"," + " \"desc\":\"The command guest-get-fsin= fo " + "has been disabled for " + "this instance\"," + " \"data\":{\"name\":\"guest-get-fsinfo= \"}" + " }" + "}") < 0) + goto cleanup; + + if (qemuAgentGetFSInfoParams(qemuMonitorTestGetAgent(test), ¶ms, + &nparams, &maxparams, def) !=3D -1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "agent get-fsinfo command should have failed"); + goto cleanup; + } + + ret =3D 0; + + cleanup: + virTypedParamsFree(params, nparams); virDomainDefFree(def); qemuMonitorTestFree(test); return ret; @@ -1288,6 +1471,7 @@ mymain(void) DO_TEST(FSFreeze); DO_TEST(FSThaw); DO_TEST(FSTrim); + DO_TEST(GetFSInfoParams); DO_TEST(GetFSInfo); DO_TEST(Suspend); DO_TEST(Shutdown); --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list