From nobody Mon May 13 15:26:02 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; arc=fail (BodyHash is different from the expected one); dmarc=fail(p=none dis=none) header.from=nutanix.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1699527778044628.6192895573522; Thu, 9 Nov 2023 03:02:58 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id B7AC01A33; Thu, 9 Nov 2023 06:02:56 -0500 (EST) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id AB6E619D9; Thu, 9 Nov 2023 06:00:21 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id 1301F19DF; Thu, 9 Nov 2023 06:00:17 -0500 (EST) Received: from mx0b-002c1b01.pphosted.com (mx0b-002c1b01.pphosted.com [148.163.155.12]) (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 B826B19CA for ; Thu, 9 Nov 2023 06:00:12 -0500 (EST) Received: from pps.filterd (m0127843.ppops.net [127.0.0.1]) by mx0b-002c1b01.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 3A92KF4R017973 for ; Thu, 9 Nov 2023 03:00:12 -0800 Received: from nam12-dm6-obe.outbound.protection.outlook.com (mail-dm6nam12lp2169.outbound.protection.outlook.com [104.47.59.169]) by mx0b-002c1b01.pphosted.com (PPS) with ESMTPS id 3u7w22usg0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 09 Nov 2023 03:00:11 -0800 (PST) Received: from DM8PR02MB8005.namprd02.prod.outlook.com (2603:10b6:8:16::16) by PH0PR02MB7255.namprd02.prod.outlook.com (2603:10b6:510:16::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6954.29; Thu, 9 Nov 2023 11:00:08 +0000 Received: from DM8PR02MB8005.namprd02.prod.outlook.com ([fe80::15a2:dbd4:5ae7:aa7b]) by DM8PR02MB8005.namprd02.prod.outlook.com ([fe80::15a2:dbd4:5ae7:aa7b%4]) with mapi id 15.20.6977.019; Thu, 9 Nov 2023 11:00:08 +0000 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,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Vj8yEEL4QeZTb2n5zzkqGax9AK2ahnnfwWrOOv0AreGbdA/6+k51uba4YA65neEmIXvQI9mk7i0Lmvz7/v8ro0sTe2dMyV7KF8QZVWZqWioNu0KPS523jHiRd1f06xvlUB4+V2+OmXqIGFr/eRBqjt7DKxUDPeipUWAyuDipF4Wf7+ICkILbDPXiM54HkL8NbZAiPwi5W2aXh8pV/iW0lZMWhWITZmMm4szxQM4kr9RLu4xuXHdYgixRTthP1uhkats8G4fwDwfNqIsnG3oKWTG4ZXIW33dYCofu2ijG0EWFKl6s2ds+ZNflvmztJTjFYAKd73JohbC+ubZN+CmHUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RpZ7x9j/HsiRG++go3GFD/6AbugTArSXDa5f25t5NlU=; b=dLA7Z5WINRQjdJQB7MZwcZbhvkGseNt2UHznatM+0O/Nj8apDMCsX5EpNQa254jiZNEs2IkGqPCAd8iEpSIWKTEw51WxStA1IVcBmPMzeBDp/O/albKzDpWwJd71ywk5nhOq+3z6KXMMtl58189/3cnGvqFN6PUlepfVrOsrG/FAClF9LmCUvC0kgmru1MkjNpj9I+n/r2tTK+AtLjRA+U8xhIu1vFrUGSssNNe68E7VqR/bVoFJY2gM74Kd/txXGiwq99dyB4MOzCGPe/SndiuvgFvPtjVTBBzjwbRFC/bE2p4iT+ps97rfN/2I36ZRajPRtQpJkeYPQp/fYX0dLA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nutanix.com; dmarc=pass action=none header.from=nutanix.com; dkim=pass header.d=nutanix.com; arc=none From: Thanos Makatos To: devel@lists.libvirt.org Subject: [PATCH V4] support for hotplug/hotunplug in test hypervisor Date: Thu, 9 Nov 2023 11:00:05 +0000 Message-Id: <20231109110005.137372-1-thanos.makatos@nutanix.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: References: X-ClientProxiedBy: PH7PR13CA0001.namprd13.prod.outlook.com (2603:10b6:510:174::7) To DM8PR02MB8005.namprd02.prod.outlook.com (2603:10b6:8:16::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM8PR02MB8005:EE_|PH0PR02MB7255:EE_ X-MS-Office365-Filtering-Correlation-Id: e48d2981-6f5e-4db6-100a-08dbe11309b2 x-proofpoint-crosstenant: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: D74ryurjZipsvMY1T03MiUQIam7PaIptOCP/u3WOMo2/Ykd5NWhrl9IVZtTCqRR65pLO/DzM5glHieZ8i7oteSuCAB2XZF373zBKw9zXhq6BYLxZBE6dxFN94YnoBuNMwAiJc5IQGeYBSF3fIVpIVKllv0kKave0NI90GjVggxWJm97RjanfBH/TyA3pznivZXQPJDe+LEZ1FZPa8wgFQKBPhh3F/PKDmax4AUw7UOYx1Uq2e91865bdzYAuuHOHGKNLXkQen2e3TEsF7DhVnlZSXR5aFsaXjCEmXGcotx+c3ceZMopSmLun8Uf0TXpO64HHt17Uv0w2Aqta2Wu25YZWXcQpFGcn9AvCtLd+aX85DSRM3Lp7MYHQv+D70tX5s9esUibwFkcSGQjbXGr2sCbvnkBH7C+hpuWP4775jxgB107exu1siPp+Py0zkMP6iuYMCPnQBTpG9wPRxU6A+ub+s1jkuYel/XBDTWMrPhAz1p6ceufp4E/I+Pee0m5aXD1oat0Qe09sLJ9I+JZBgTXJu+4zQ/bpmRJBbCydghWoKtD0Zb5rGeAUbthTLOjgVqqqVfbAIeR9Lk5HpxrL5sG4HzMWSmhqbH4UwI9cHOgZ0lugjOWk7YcpMeGXeG06 X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM8PR02MB8005.namprd02.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(376002)(396003)(39860400002)(346002)(366004)(136003)(230922051799003)(1800799009)(186009)(451199024)(64100799003)(26005)(1076003)(38100700002)(83380400001)(5660300002)(107886003)(2616005)(6486002)(6666004)(478600001)(52116002)(6506007)(6512007)(38350700005)(36756003)(6916009)(316002)(8936002)(66946007)(66556008)(66476007)(8676002)(4326008)(86362001)(30864003)(44832011)(2906002)(41300700001);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?jrVytvm/FEuy8PTo8ztTnVUo8ByEqf3ErmsJDoSXVVH8BzYVFFQROC4JH3A9?= =?us-ascii?Q?87VkTMDy+lGzd9esXeLbszRQUKxAgLC1vV2ABiEyO3111ZgQpUmgan1ZCIeV?= =?us-ascii?Q?zwZPKZiyThzLnkZ/u1WJxmvKrUzCOytVblkOulNGLBCpO0GGYxMpRSqK+Bd7?= =?us-ascii?Q?9k2GOD2a6iOXlchcUHOcZTniIa5n5AtoeUD8XTiQzzB2w8kh0BeUAw95p+al?= =?us-ascii?Q?WMfXPbcpIxWSnOvNWKkVxnTHs5Dg23YcAKl7nODa+GaE92aQHxI/QHtbV1rR?= =?us-ascii?Q?wKjaVNMuh9H7WM3zks6smxp8ztiZUKBg/J/QgcFm2xeSs9iOZOo5/80plOfz?= =?us-ascii?Q?42zLjsHKYhWSoh4zRrIUPy/csS7NFjXEETXT4kF3v30tZp8qdZaYXqqB/6on?= =?us-ascii?Q?QVUZ+OWZ6FkRcmRaCrlNbT2jywC0zRAvfAYBbfM9ciy8Yh29V41bZuVmLGSg?= =?us-ascii?Q?V9ol0T0UXyflL3yvjNZO95xhGbbEZ4z0b1DSKyd1YgUGi3zQP1wvNlB732+y?= =?us-ascii?Q?SbnG1r84OGPEWxkCfCjqg3Fo/qh4qrpgFwPVALOuUsGyXwWu47FFMf88r2wD?= =?us-ascii?Q?8FipiXo70jasQlBE5A/VTvg+HxdQyBYQvkkBpKhFOvx8/hT7KRzsAUxmr04o?= =?us-ascii?Q?jgH6c+/R4lcSSoPEqDEMfujGuIRpnDasupfZub3UOzYUcC2SAJzyx4m+ixRs?= =?us-ascii?Q?Ej7l3WAo8fikth+yfP1G8yZ4FpbkMSxcMV+iJthQ8Md3jllB2pPjBm2mFh2u?= =?us-ascii?Q?ofVn2tw22MGQ3lmDPvkvCPG3WIvDDtjj/FUj4ap4CvsmwtGJz/apzZHl2tiK?= =?us-ascii?Q?G8I2eNyNlm8hHJ1r0VkxdW8yQc600+fWUAYTbbK5JX7l1aQzxbijDXUDkYCS?= =?us-ascii?Q?7mWGhA2LRmDygVh57wh7l58iRJq1r4ColO7Mnsxq1LR3jUmc+mcklcR2/F6v?= =?us-ascii?Q?CkBkxgQOv4iZoh5ljxBNrm4jqfMgnlbqrsHb7+fCwwnupkVBG1/ilWpshez4?= =?us-ascii?Q?13NdM7A5NQvcqY4wsfLMIrwhub2OWzEuRlaA8uMy0STbEiwQ/+K9cUSdBVP7?= =?us-ascii?Q?ajwfam9MxCNNWhjcOefQAvfbjuzBaHOpcSme7Ze3btytWZEr0gRK5pZRB05x?= =?us-ascii?Q?y373pA7fqrjrS/yXx5ANdhiyOIeNhlxSxaT/4u08ySnfVwsdD6LYjVt1YeAe?= =?us-ascii?Q?uCaomd7zTOumCqJUS9Nfq2Of3+/HOwdFyVG+S5dBYv44f826aWR6zPZwPSKx?= =?us-ascii?Q?cvaibCWRWF0mTUGPiIZKeswzQFzIz6RbG7L2yguiI7gfhZ4NzKmbMEv/UZ7G?= =?us-ascii?Q?H7OsW1x6sUzNM6NsqoHKa3XL0IdL3TkQ0ys/gRxOIArIrwZShpeYlNw5W78T?= =?us-ascii?Q?EuXQGUk2hpc7rmAdw0zH2JzUrNJuENt/Z7qY9z0luDALhGH0OR1x6Q6GcRLO?= =?us-ascii?Q?op+U1Szdvk4SoxKfu+6YsyLKudTiBMLj4ZEOjSSJ+dRf9Tnb9D8a7CCvMtyR?= =?us-ascii?Q?UBo4WguqPKJ6EBiqoT+70/8gzztFcUflSfktpVdYAu/53DEt6PrVEWNAGY4u?= =?us-ascii?Q?EAgeFob5rQYyMm4OvKH+JPaFTT/gOJXsVbqSQf1gQT5jPws2A7dw5dD8xwql?= =?us-ascii?Q?0A=3D=3D?= X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: e48d2981-6f5e-4db6-100a-08dbe11309b2 X-MS-Exchange-CrossTenant-AuthSource: DM8PR02MB8005.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Nov 2023 11:00:08.7431 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bb047546-786f-4de1-bd75-24e5b6f79043 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: WEDY5fSQtjt0mtHH9piCP95UiFuTvwz/Il4IGm/LxY5EUZPOGcncZuqssbSWYZYKyu+JlOp/Edd4oVlbAjphsHQZqYQ25rBe7cdQnS3kbwo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR02MB7255 X-Proofpoint-ORIG-GUID: taYdttbYcHsvyfAkFj_Hx9jhNHU1KhKt X-Proofpoint-GUID: taYdttbYcHsvyfAkFj_Hx9jhNHU1KhKt X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-09_09,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Reason: safe Message-ID-Hash: 4GYGB7COD4RV7LQCZ6GIDYNMJBVMTLB3 X-Message-ID-Hash: 4GYGB7COD4RV7LQCZ6GIDYNMJBVMTLB3 X-MailFrom: thanos.makatos@nutanix.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: Thanos Makatos 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: 1699527778753100001 Signed-off-by: Thanos Makatos --- src/test/test_driver.c | 387 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 385 insertions(+), 2 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index e87d7cfd44..a3b4799a0f 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -26,8 +26,6 @@ #include #include #include - - #include "virerror.h" #include "datatypes.h" #include "test_driver.h" @@ -38,10 +36,14 @@ #include "virnetworkobj.h" #include "interface_conf.h" #include "checkpoint_conf.h" +#include "domain_addr.h" +#include "domain_audit.h" #include "domain_conf.h" #include "domain_driver.h" #include "domain_event.h" +#include "domain_validate.h" #include "network_event.h" +#include "nwfilter_conf.h" #include "snapshot_conf.h" #include "virfdstream.h" #include "storage_conf.h" @@ -50,6 +52,7 @@ #include "node_device_conf.h" #include "virnodedeviceobj.h" #include "node_device_event.h" +#include "vircgroup.h" #include "virxml.h" #include "virthread.h" #include "virlog.h" @@ -10035,6 +10038,383 @@ testConnectGetDomainCapabilities(virConnectPtr co= nn G_GNUC_UNUSED, return virDomainCapsFormat(domCaps); } =20 +static int +testDomainAttachHostPCIDevice(testDriver *driver G_GNUC_UNUSED, + virDomainObj *vm, + virDomainHostdevDef *hostdev) +{ + int backend =3D hostdev->source.subsys.u.pci.backend; + + switch ((virDomainHostdevSubsysPCIBackendType)backend) { + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT: + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM: + break; + + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN: + case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("test hypervisor does not support device assignme= nt mode '%s'"), + virDomainHostdevSubsysPCIBackendTypeToString(backen= d)); + return -1; + } + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("guest unexpectedly quit during hotplug")); + return -1; + } + + VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1); + + virDomainAuditHostdev(vm, hostdev, "attach", true); + + vm->def->hostdevs[vm->def->nhostdevs++] =3D hostdev; + + return 0; +} + +static int +testDomainAttachHostDevice(testDriver *driver, + virDomainObj *vm, + virDomainHostdevDef *hostdev) +{ + if (hostdev->mode !=3D VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("hotplug is not supported for hostdev mode '%s'"), + virDomainHostdevModeTypeToString(hostdev->mode)); + return -1; + } + + if (hostdev->source.subsys.type !=3D VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PC= I) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("hotplug is not supported for hostdev subsys type= '%s'"), + virDomainHostdevSubsysTypeToString(hostdev->source.= subsys.type)); + return -1; + } + + return testDomainAttachHostPCIDevice(driver, vm, hostdev); +} + +static int +testDomainAttachDeviceLive(virDomainObj *vm, + virDomainDeviceDef *dev, + testDriver *driver) +{ + int ret =3D -1; + const char *alias =3D NULL; + + if ((virDomainDeviceType)dev->type !=3D VIR_DOMAIN_DEVICE_HOSTDEV) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("live attach of device '%s' is not supported"), + virDomainDeviceTypeToString(dev->type)); + return -1; + } + + testDomainObjCheckHostdevTaint(vm, dev->data.hostdev); + if ((ret =3D testDomainAttachHostDevice(driver, vm, dev->data.hostdev)= ) !=3D 0) + return ret; + + alias =3D dev->data.hostdev->info->alias; + dev->data.hostdev =3D NULL; + + if (alias) { + virObjectEvent *event; + event =3D virDomainEventDeviceAddedNewFromObj(vm, alias); + virObjectEventStateQueue(driver->eventState, event); + } + + return 0; +} + +static int +testDomainAttachDeviceLiveAndConfig(virDomainObj *vm, + testDriver *driver, + const char *xml, + unsigned int flags) +{ + g_autoptr(virDomainDeviceDef) devConf =3D NULL; + g_autoptr(virDomainDeviceDef) devLive =3D NULL; + unsigned int parse_flags =3D VIR_DOMAIN_DEF_PARSE_INACTIVE | + VIR_DOMAIN_DEF_PARSE_ABI_UPDATE; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE, -1); + + if (flags & VIR_DOMAIN_AFFECT_LIVE) { + if (!(devLive =3D virDomainDeviceDefParse(xml, vm->def, + driver->xmlopt, NULL, + parse_flags))) + return -1; + + if (virDomainDeviceValidateAliasForHotplug(vm, devLive, + VIR_DOMAIN_AFFECT_LIVE)= < 0) + return -1; + + if (virDomainDefCompatibleDevice(vm->def, devLive, NULL, + VIR_DOMAIN_DEVICE_ACTION_ATTACH, + true) < 0) + return -1; + + if (testDomainAttachDeviceLive(vm, devLive, driver) < 0) + return -1; + } + + return 0; +} + +static int +testDomainAttachDeviceFlags(virDomainPtr domain, + const char *xml, + unsigned int flags) { + + testDriver *driver =3D domain->conn->privateData; + virDomainObj *vm =3D NULL; + int ret =3D -1; + + virNWFilterReadLockFilterUpdates(); + + if (!(vm =3D testDomObjFromDomain(domain))) + return -1; + + if (virDomainObjUpdateModificationImpact(vm, &flags) < 0) + goto cleanup; + + if (testDomainAttachDeviceLiveAndConfig(vm, driver, xml, flags) < 0) + goto cleanup; + + ret =3D 0; + + cleanup: + virDomainObjEndAPI(&vm); + virNWFilterUnlockFilterUpdates(); + return ret; + +} + +static int +testDomainAttachDevice(virDomainPtr domain, const char *xml) +{ + return testDomainAttachDeviceFlags(domain, xml, 0); +} + +/* search for a hostdev matching dev and detach it */ +static int +testDomainDetachPrepHostdev(virDomainObj *vm, + virDomainHostdevDef *match, + virDomainHostdevDef **detach) +{ + virDomainHostdevSubsys *subsys =3D &match->source.subsys; + virDomainHostdevSubsysPCI *pcisrc =3D &subsys->u.pci; + virDomainHostdevDef *hostdev =3D NULL; + + if (match->mode !=3D VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("hot unplug is not supported for hostdev mode '%s= '"), + virDomainHostdevModeTypeToString(match->mode)); + return -1; + } + + if (virDomainHostdevFind(vm->def, match, &hostdev) < 0) { + if (subsys->type =3D=3D VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { + virReportError(VIR_ERR_DEVICE_MISSING, + _("host pci device " VIR_PCI_DEVICE_ADDRESS_FMT + " not found"), + pcisrc->addr.domain, pcisrc->addr.bus, + pcisrc->addr.slot, pcisrc->addr.function); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected hostdev type %d"), subsys->type); + } + return -1; + } + + *detach =3D hostdev; + + return 0; +} + +static int +testDomainRemoveHostDevice(testDriver *driver G_GNUC_UNUSED, + virDomainObj *vm, + virDomainHostdevDef *hostdev) +{ + virDomainNetDef *net =3D NULL; + size_t i; + + VIR_DEBUG("Removing host device %s from domain %p %s", + hostdev->info->alias, vm, vm->def->name); + + if (hostdev->parentnet) { + net =3D hostdev->parentnet; + for (i =3D 0; i < vm->def->nnets; i++) { + if (vm->def->nets[i] =3D=3D hostdev->parentnet) { + virDomainNetRemove(vm->def, i); + break; + } + } + } + + for (i =3D 0; i < vm->def->nhostdevs; i++) { + if (vm->def->hostdevs[i] =3D=3D hostdev) { + virDomainHostdevRemove(vm->def, i); + break; + } + } + + virDomainAuditHostdev(vm, hostdev, "detach", true); + + virDomainHostdevDefFree(hostdev); + + if (net) { + if (net->type =3D=3D VIR_DOMAIN_NET_TYPE_NETWORK) { + g_autoptr(virConnect) conn =3D virGetConnectNetwork(); + if (conn) + virDomainNetReleaseActualDevice(conn, vm->def, net); + else + VIR_WARN("Unable to release network device '%s'", NULLSTR(= net->ifname)); + } + virDomainNetDefFree(net); + } + + return 0; +} + +static int +testDomainRemoveDevice(testDriver *driver, + virDomainObj *vm, + virDomainDeviceDef *dev) +{ + virDomainDeviceInfo *info; + virObjectEvent *event; + g_autofree char *alias =3D NULL; + + /* + * save the alias to use when sending a DEVICE_REMOVED event after + * all other teardown is complete + */ + if ((info =3D virDomainDeviceGetInfo(dev))) + alias =3D g_strdup(info->alias); + info =3D NULL; + + if ((virDomainDeviceType)dev->type !=3D VIR_DOMAIN_DEVICE_HOSTDEV) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("don't know how to remove a %s device"), + virDomainDeviceTypeToString(dev->type)); + goto out; + } + + if (testDomainRemoveHostDevice(driver, vm, dev->data.hostdev) < 0) + return -1; + +out: + event =3D virDomainEventDeviceRemovedNewFromObj(vm, alias); + virObjectEventStateQueue(driver->eventState, event); + + return 0; +} + +static int +testDomainDetachDeviceLive(virDomainObj *vm, + virDomainDeviceDef *match, + testDriver *driver) +{ + virDomainDeviceDef detach =3D { .type =3D match->type }; + virDomainDeviceInfo *info =3D NULL; + + if ((virDomainDeviceType)match->type !=3D VIR_DOMAIN_DEVICE_HOSTDEV) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("live detach of device '%s' is not supported"), + virDomainDeviceTypeToString(match->type)); + return -1; + } + + if (testDomainDetachPrepHostdev(vm, match->data.hostdev, + &detach.data.hostdev) < 0) + return -1; + + /* "detach" now points to the actual device we want to detach */ + + if (!(info =3D virDomainDeviceGetInfo(&detach))) { + /* + * This should never happen, since all of the device types in + * the switch cases that end with a "break" instead of a + * return have a virDeviceInfo in them. + */ + virReportError(VIR_ERR_INTERNAL_ERROR, + _("device of type '%s' has no device info"), + virDomainDeviceTypeToString(detach.type)); + return -1; + } + + /* Make generic validation checks common to all device types */ + + if (!info->alias) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot detach %s device with no alias"), + virDomainDeviceTypeToString(detach.type)); + return -1; + } + + return testDomainRemoveDevice(driver, vm, &detach); +} + +static int +testDomainDetachDeviceAliasLiveAndConfig(testDriver *driver, + virDomainObj *vm, + const char *alias, + unsigned int flags) +{ + virDomainDef *def =3D NULL; + g_autoptr(virDomainDef) vmdef =3D NULL; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE, -1); + + if (virDomainObjGetDefs(vm, flags, &def, NULL) < 0) + return -1; + + if (def) { + virDomainDeviceDef dev; + + if (virDomainDefFindDevice(def, alias, &dev, true) < 0) + return -1; + + if (testDomainDetachDeviceLive(vm, &dev, driver) < 0) + return -1; + } + + if (vmdef) { + if (virDomainDefSave(vmdef, driver->xmlopt, NULL) < 0) + return -1; + virDomainObjAssignDef(vm, &vmdef, false, NULL); + } + + return 0; +} + +static int +testDomainDetachDeviceAlias(virDomainPtr dom, + const char *alias, + unsigned int flags) +{ + testDriver *driver =3D dom->conn->privateData; + virDomainObj *vm =3D NULL; + int ret =3D -1; + + if (!(vm =3D testDomObjFromDomain(dom))) + return -1; + + if (virDomainObjUpdateModificationImpact(vm, &flags) < 0) + goto cleanup; + + if (testDomainDetachDeviceAliasLiveAndConfig(driver, vm, alias, flags)= < 0) + goto cleanup; + + ret =3D 0; + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} =20 /* * Test driver @@ -10058,6 +10438,9 @@ static virHypervisorDriver testHypervisorDriver =3D= { .connectListDomains =3D testConnectListDomains, /* 0.1.1 */ .connectNumOfDomains =3D testConnectNumOfDomains, /* 0.1.1 */ .connectListAllDomains =3D testConnectListAllDomains, /* 0.9.13 */ + .domainAttachDevice =3D testDomainAttachDevice, /* 9.10.0 */ + .domainAttachDeviceFlags =3D testDomainAttachDeviceFlags, /* 9.10.0 */ + .domainDetachDeviceAlias =3D testDomainDetachDeviceAlias, /* 9.10.0 */ .domainCreateXML =3D testDomainCreateXML, /* 0.1.4 */ .domainCreateXMLWithFiles =3D testDomainCreateXMLWithFiles, /* 5.7.0 */ .domainLookupByID =3D testDomainLookupByID, /* 0.1.1 */ --=20 2.27.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org