From nobody Mon Sep 16 19:36:51 2024 Delivered-To: importer@patchew.org Received-SPF: none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=none (zohomail.com: 8.43.85.245 is neither permitted nor denied by domain of lists.libvirt.org) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=reject dis=none) header.from=linux.ibm.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1705683878936508.36009077005815; Fri, 19 Jan 2024 09:04:38 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id C37541C2B; Fri, 19 Jan 2024 12:04:37 -0500 (EST) Received: from lists.libvirt.org.85.43.8.in-addr.arpa (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 1803F1C2D; Fri, 19 Jan 2024 11:58:28 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id 5D58E1B1A; Fri, 19 Jan 2024 11:58:17 -0500 (EST) Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id B4E3B1A73 for ; Fri, 19 Jan 2024 11:55:51 -0500 (EST) Received: from pps.filterd (m0353727.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 40JGVxr2022905 for ; Fri, 19 Jan 2024 16:39:00 GMT Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3vqvav8tcw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 19 Jan 2024 16:39:00 +0000 Received: from m0353727.ppops.net (m0353727.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 40JG83EC013785 for ; Fri, 19 Jan 2024 16:38:59 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3vqvav8tcb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Jan 2024 16:38:59 +0000 Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 40JEJSvb005800; Fri, 19 Jan 2024 16:38:58 GMT Received: from smtprelay02.fra02v.mail.ibm.com ([9.218.2.226]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 3vm6bm2g0m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Jan 2024 16:38:58 +0000 Received: from smtpav05.fra02v.mail.ibm.com (smtpav05.fra02v.mail.ibm.com [10.20.54.104]) by smtprelay02.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 40JGctOp45089168 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 19 Jan 2024 16:38:55 GMT Received: from smtpav05.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4B93D2004B; Fri, 19 Jan 2024 16:38:55 +0000 (GMT) Received: from smtpav05.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2438120043; Fri, 19 Jan 2024 16:38:55 +0000 (GMT) Received: from fiuczyvm.. (unknown [9.171.151.33]) by smtpav05.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 19 Jan 2024 16:38:55 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 From: Boris Fiuczynski To: devel@lists.libvirt.org Subject: [PATCH 10/11] nodedev: Implement virNodeDeviceUpdateXML Date: Fri, 19 Jan 2024 17:38:52 +0100 Message-ID: <20240119163853.10191-11-fiuczy@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240119163853.10191-1-fiuczy@linux.ibm.com> References: <20240119163853.10191-1-fiuczy@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: qRIk4gKtkvao-C756eBy_ubf7Z2Wv3JD X-Proofpoint-ORIG-GUID: rL0k0Z4VJ7EHN7HVi1vKPcKkfMQsU9X0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-01-19_10,2024-01-19_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 clxscore=1015 spamscore=0 bulkscore=0 mlxlogscore=919 priorityscore=1501 mlxscore=0 adultscore=0 suspectscore=0 impostorscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311290000 definitions=main-2401190095 Message-ID-Hash: 6ZYVMEETRLL3SMNNJOV4VRHKP7CCPZ4J X-Message-ID-Hash: 6ZYVMEETRLL3SMNNJOV4VRHKP7CCPZ4J X-MailFrom: fiuczy@linux.ibm.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: jjongsma@redhat.com, mhartmay@linux.ibm.com X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1705683881156100001 Implement the API functions in the node device driver by using mdevctl modify with the options defined and live. Increase the minimum mdevctl version to 1.3.0 in spec file to ensure support exists in mdevctl. Signed-off-by: Boris Fiuczynski Reviewed-by: Jonathon Jongsma =3D 185 # For managing persistent mediated devices -Requires: mdevctl +Requires: mdevctl >=3D 1.3.0 # for modprobe of pci devices Requires: module-init-tools =20 diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_de= vice_driver.c index d67c95d68d..dd57e9ca5b 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -54,7 +54,7 @@ virNodeDeviceDriverState *driver; =20 VIR_ENUM_IMPL(virMdevctlCommand, MDEVCTL_CMD_LAST, - "start", "stop", "define", "undefine", "create" + "start", "stop", "define", "undefine", "create", "modify" ); =20 =20 @@ -754,6 +754,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def, case MDEVCTL_CMD_START: case MDEVCTL_CMD_DEFINE: case MDEVCTL_CMD_UNDEFINE: + case MDEVCTL_CMD_MODIFY: cmd =3D virCommandNewArgList(MDEVCTL, subcommand, NULL); break; case MDEVCTL_CMD_LAST: @@ -767,6 +768,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def, switch (cmd_type) { case MDEVCTL_CMD_CREATE: case MDEVCTL_CMD_DEFINE: + case MDEVCTL_CMD_MODIFY: if (!def->caps->data.mdev.parent_addr) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unable to find parent device '%1$s'"), def->= parent); @@ -783,7 +785,8 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def, virCommandAddArgPair(cmd, "--jsonfile", "/dev/stdin"); =20 virCommandSetInputBuffer(cmd, inbuf); - virCommandSetOutputBuffer(cmd, outbuf); + if (outbuf) + virCommandSetOutputBuffer(cmd, outbuf); break; =20 case MDEVCTL_CMD_UNDEFINE: @@ -868,6 +871,61 @@ virMdevctlDefine(virNodeDeviceDef *def, char **uuid) } =20 =20 +/* gets a virCommand object that executes a mdevctl command to modify a + * a device to an updated version + */ +virCommand* +nodeDeviceGetMdevctlModifyCommand(virNodeDeviceDef *def, + bool defined, + bool live, + char **errmsg) +{ + virCommand *cmd =3D nodeDeviceGetMdevctlCommand(def, + MDEVCTL_CMD_MODIFY, + NULL, errmsg); + + if (!cmd) + return NULL; + + if (defined) + virCommandAddArg(cmd, "--defined"); + + if (live) + virCommandAddArg(cmd, "--live"); + + return cmd; +} + + +static int +virMdevctlModify(virNodeDeviceDef *def, + bool defined, + bool live) +{ + int status; + g_autofree char *errmsg =3D NULL; + g_autoptr(virCommand) cmd =3D nodeDeviceGetMdevctlModifyCommand(def, + defined, + live, + &errmsg); + + if (!cmd) + return -1; + + if (virCommandRun(cmd, &status) < 0) + return -1; + + if (status !=3D 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to modify mediated device: %1$s"), + MDEVCTL_ERROR(errmsg)); + return -1; + } + + return 0; +} + + static virNodeDevicePtr nodeDeviceCreateXMLMdev(virConnectPtr conn, virNodeDeviceDef *def) @@ -2108,3 +2166,122 @@ nodeDeviceIsActive(virNodeDevice *device) virNodeDeviceObjEndAPI(&obj); return ret; } + + +static int +nodeDeviceDefCompareMdevs(virNodeDeviceDef *def_cur, + virNodeDeviceDef *def_upd, + bool live) +{ + virNodeDevCapsDef *caps =3D NULL; + virNodeDevCapMdev *cap_mdev_cur =3D NULL; + virNodeDevCapMdev *cap_mdev_upd =3D NULL; + + for (caps =3D def_cur->caps; caps !=3D NULL; caps =3D caps->next) { + if (caps->data.type =3D=3D VIR_NODE_DEV_CAP_MDEV) { + cap_mdev_cur =3D &caps->data.mdev; + } + } + if (!cap_mdev_cur) + return -1; + + for (caps =3D def_upd->caps; caps !=3D NULL; caps =3D caps->next) { + if (caps->data.type =3D=3D VIR_NODE_DEV_CAP_MDEV) { + cap_mdev_upd =3D &caps->data.mdev; + } + } + if (!cap_mdev_upd) + return -1; + + if (STRNEQ_NULLABLE(cap_mdev_cur->uuid, cap_mdev_upd->uuid)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("uuid mismatch (mdev:'%1$s' update:'%2$s')"), + cap_mdev_cur->uuid, + cap_mdev_upd->uuid); + return -1; + } + // for a live update the types of the active configs must match! + if (live && + STRNEQ_NULLABLE(cap_mdev_cur->active_config.type, cap_mdev_upd->ac= tive_config.type)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("type mismatch (mdev:'%1$s' update:'%2$s')"), + cap_mdev_cur->active_config.type, + cap_mdev_upd->active_config.type); + return -1; + } + if (STRNEQ_NULLABLE(cap_mdev_cur->parent_addr, cap_mdev_upd->parent_ad= dr)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("parent address mismatch (mdev:'%1$s' update:'%2$= s')"), + cap_mdev_cur->parent_addr, + cap_mdev_upd->parent_addr); + return -1; + } + + return 0; +} + + +int +nodeDeviceUpdateXML(virNodeDevice *device, + const char *xmlDesc, + unsigned int flags) +{ + int ret =3D -1; + virNodeDeviceObj *obj =3D NULL; + virNodeDeviceDef *def_cur; + g_autoptr(virNodeDeviceDef) def_upd =3D NULL; + const char *virt_type =3D NULL; + bool updated =3D false; + + virCheckFlags(VIR_NODE_DEVICE_UPDATE_XML_AFFECT_LIVE | + VIR_NODE_DEVICE_UPDATE_XML_AFFECT_CONFIG, -1); + + if (nodeDeviceInitWait() < 0) + return -1; + + if (!(obj =3D nodeDeviceObjFindByName(device->name))) + return -1; + def_cur =3D virNodeDeviceObjGetDef(obj); + + virt_type =3D virConnectGetType(device->conn); + + if (virNodeDeviceUpdateXMLEnsureACL(device->conn, def_cur, flags) < 0) + goto cleanup; + + if (!(def_upd =3D virNodeDeviceDefParse(xmlDesc, NULL, EXISTING_DEVICE= , virt_type, + &driver->parserCallbacks, NULL, = true))) + goto cleanup; + + if (nodeDeviceHasCapability(def_cur, VIR_NODE_DEV_CAP_MDEV) && + nodeDeviceHasCapability(def_upd, VIR_NODE_DEV_CAP_MDEV)) { + // Checks flags are valid for the state and sets flags for current= if flags not set + if (virNodeDeviceObjUpdateModificationImpact(obj, &flags) < 0) + goto cleanup; + + // Compare def_cur and def_upd for compatibleness e.g. parent, typ= e and uuid + if (nodeDeviceDefCompareMdevs(def_cur, def_upd, + (flags & VIR_NODE_DEVICE_UPDATE_XML_= AFFECT_LIVE)) < 0) + goto cleanup; + + // Update now + VIR_DEBUG("Update node device '%s' with mdevctl", def_cur->name); + if (virMdevctlModify(def_upd, + (flags & VIR_NODE_DEVICE_UPDATE_XML_AFFECT_CO= NFIG), + (flags & VIR_NODE_DEVICE_UPDATE_XML_AFFECT_LI= VE)) < 0) { + goto cleanup; + }; + // Detect updates and also trigger events + updated =3D true; + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Unsupported device type")); + } + + ret =3D 0; + cleanup: + virNodeDeviceObjEndAPI(&obj); + if (updated) + nodeDeviceUpdateMediatedDevices(); + + return ret; +} diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_de= vice_driver.h index 4dce7e6f17..5751625eda 100644 --- a/src/node_device/node_device_driver.h +++ b/src/node_device/node_device_driver.h @@ -39,6 +39,7 @@ typedef enum { * separation makes our code more readable in terms of knowing when we= 're * starting a defined device and when we're creating a transient one */ MDEVCTL_CMD_CREATE, + MDEVCTL_CMD_MODIFY, =20 MDEVCTL_CMD_LAST, } virMdevctlCommand; @@ -186,3 +187,13 @@ virCommand* nodeDeviceGetMdevctlSetAutostartCommand(virNodeDeviceDef *def, bool autostart, char **errmsg); + +virCommand* +nodeDeviceGetMdevctlModifyCommand(virNodeDeviceDef *def, + bool defined, + bool live, + char **errmsg); +int +nodeDeviceUpdateXML(virNodeDevice *dev, + const char *xmlDesc, + unsigned int flags); diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index 57368a96c3..4cd9d285fa 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -2403,6 +2403,7 @@ static virNodeDeviceDriver udevNodeDeviceDriver =3D { .nodeDeviceGetAutostart =3D nodeDeviceGetAutostart, /* 7.8.0 */ .nodeDeviceIsPersistent =3D nodeDeviceIsPersistent, /* 7.8.0 */ .nodeDeviceIsActive =3D nodeDeviceIsActive, /* 7.8.0 */ + .nodeDeviceUpdateXML =3D nodeDeviceUpdateXML, /* 10.1.0 */ }; =20 =20 diff --git a/tests/nodedevmdevctldata/mdevctl-modify.argv b/tests/nodedevmd= evctldata/mdevctl-modify.argv new file mode 100644 index 0000000000..6acb9ca0bf --- /dev/null +++ b/tests/nodedevmdevctldata/mdevctl-modify.argv @@ -0,0 +1,19 @@ +mdevctl \ +modify \ +--parent=3D0.0.0052 \ +--jsonfile=3D/dev/stdin \ +--uuid=3Dc60cc60c-c60c-c60c-c60c-c60cc60cc60c \ +--defined +mdevctl \ +modify \ +--parent=3D0.0.0052 \ +--jsonfile=3D/dev/stdin \ +--uuid=3Dc60cc60c-c60c-c60c-c60c-c60cc60cc60c \ +--live +mdevctl \ +modify \ +--parent=3D0.0.0052 \ +--jsonfile=3D/dev/stdin \ +--uuid=3Dc60cc60c-c60c-c60c-c60c-c60cc60cc60c \ +--defined \ +--live diff --git a/tests/nodedevmdevctltest.c b/tests/nodedevmdevctltest.c index 852d9ed6e7..37978c9a5c 100644 --- a/tests/nodedevmdevctltest.c +++ b/tests/nodedevmdevctltest.c @@ -63,6 +63,7 @@ testMdevctlCmd(virMdevctlCommand cmd_type, case MDEVCTL_CMD_START: case MDEVCTL_CMD_STOP: case MDEVCTL_CMD_UNDEFINE: + case MDEVCTL_CMD_MODIFY: create =3D EXISTING_DEVICE; break; case MDEVCTL_CMD_LAST: @@ -173,6 +174,64 @@ testMdevctlAutostart(const void *data G_GNUC_UNUSED) return ret; } =20 + +static int +testMdevctlModify(const void *data G_GNUC_UNUSED) +{ + g_autoptr(virNodeDeviceDef) def =3D NULL; + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + const char *actualCmdline =3D NULL; + int ret =3D -1; + g_autoptr(virCommand) definedcmd =3D NULL; + g_autoptr(virCommand) livecmd =3D NULL; + g_autoptr(virCommand) bothcmd =3D NULL; + g_autofree char *errmsg =3D NULL; + /* just concatenate both calls into the same output file */ + g_autofree char *cmdlinefile =3D + g_strdup_printf("%s/nodedevmdevctldata/mdevctl-modify.argv", + abs_srcdir); + g_autofree char *mdevxml =3D + g_strdup_printf("%s/nodedevschemadata/mdev_c60cc60c_c60c_c60c_c60c= _c60cc60cc60c.xml", + abs_srcdir); + g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); + + if (!(def =3D virNodeDeviceDefParse(NULL, mdevxml, CREATE_DEVICE, VIRT= _TYPE, + &parser_callbacks, NULL, false))) + return -1; + + virCommandSetDryRun(dryRunToken, &buf, true, true, NULL, NULL); + + if (!(definedcmd =3D nodeDeviceGetMdevctlModifyCommand(def, true, fals= e, &errmsg))) + goto cleanup; + + if (virCommandRun(definedcmd, NULL) < 0) + goto cleanup; + + if (!(livecmd =3D nodeDeviceGetMdevctlModifyCommand(def, false, true, = &errmsg))) + goto cleanup; + + if (virCommandRun(livecmd, NULL) < 0) + goto cleanup; + + if (!(bothcmd =3D nodeDeviceGetMdevctlModifyCommand(def, true, true, &= errmsg))) + goto cleanup; + + if (virCommandRun(bothcmd, NULL) < 0) + goto cleanup; + + if (!(actualCmdline =3D virBufferCurrentContent(&buf))) + goto cleanup; + + if (virTestCompareToFileFull(actualCmdline, cmdlinefile, false) < 0) + goto cleanup; + + ret =3D 0; + + cleanup: + virBufferFreeAndReset(&buf); + return ret; +} + static int testMdevctlListDefined(const void *data G_GNUC_UNUSED) { @@ -457,6 +516,9 @@ mymain(void) #define DO_TEST_AUTOSTART() \ DO_TEST_FULL("autostart mdevs", testMdevctlAutostart, NULL) =20 +#define DO_TEST_MODIFY() \ + DO_TEST_FULL("modify mdevs", testMdevctlModify, NULL) + #define DO_TEST_PARSE_JSON(filename) \ DO_TEST_FULL("parse mdevctl json " filename, testMdevctlParse, filenam= e) =20 @@ -485,6 +547,8 @@ mymain(void) =20 DO_TEST_AUTOSTART(); =20 + DO_TEST_MODIFY(); + done: nodedevTestDriverFree(driver); =20 --=20 2.42.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org