From nobody Tue May 21 18:07:46 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 1699528638232489.5923756814176; Thu, 9 Nov 2023 03:17:18 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id C478419FC; Thu, 9 Nov 2023 06:17:16 -0500 (EST) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 8BEFD19F5; Thu, 9 Nov 2023 06:14:54 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id C5F8119E9; Thu, 9 Nov 2023 06:14:48 -0500 (EST) Received: from mx0a-002c1b01.pphosted.com (mx0a-002c1b01.pphosted.com [148.163.151.68]) (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 7C6C019D9 for ; Thu, 9 Nov 2023 06:14:47 -0500 (EST) Received: from pps.filterd (m0127840.ppops.net [127.0.0.1]) by mx0a-002c1b01.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 3A918N3S028664 for ; Thu, 9 Nov 2023 03:14:46 -0800 Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2168.outbound.protection.outlook.com [104.47.57.168]) by mx0a-002c1b01.pphosted.com (PPS) with ESMTPS id 3u7w27bsgv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 09 Nov 2023 03:14:45 -0800 (PST) Received: from DM8PR02MB8005.namprd02.prod.outlook.com (2603:10b6:8:16::16) by SJ0PR02MB7711.namprd02.prod.outlook.com (2603:10b6:a03:326::9) 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:14:43 +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:14:43 +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=WIJXZSintMiUrQzrsOh5oGeR9YNSEE01Gsuwin/Ds0gyU2jeVfTaKSzPI8ChUk+HKQBbew2I6axArS2WdqRoh/uoxP6lkQqSG8qB3iG4/VEAAXmkVzuc9qYlSYvxFHUnaGgNaT4Mj8aIoyPwVvdvW2duTrMLSRWAjp0Jj5QqF6s/0ShY9W8xX7U53zdMVMFxa4QfsIqkOij0skqtLOanWOHSP6R6vV4N8bMs8vgPCf+94bZdhA8vNnsBbopKCjxkuJldA/4DNPxeW82DRNMUkLCtNsITAC1qVf2xafJAFTNdtA5CIMKHYawr9Np45RlkpYOEYodeVuA4vTc+ubDfWQ== 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=BqfWMT9AYU1J+C7L3i/4h5RkO8+8pPJHasd1z6Bz7Hg=; b=GelvND16xAh2SwucIKmkGXztwQ5Gi84EIzUaJ1NetgC7h042tNIaX/SOCidizeY5PZ/wjllTNYqMT8MC9LZZnmYsJiG/P+oTvpaLZLbOfzR1X30l6BvJu1wWSuz2a9h7NbICHc3LkQbKD5t8eV8StnVKtg1ScooDcBuy4hB6EdrQt+0Hu6t2L40fKG8RN4vZukQcVk6W8BQ8/OSk5ySkng6KJh6m8Tc9orsXZ/t06mRQubZ1Mpfx0Eo7gohlvcgy2+dbZkui8jsbN9eeMoxlJx67SiHbd7owLFG6Y7I/BMtPh/eH56LbsAV26lWKVgjnzD9NcbRUELo2n6c2efC2DQ== 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 V5] support for hotplug/hotunplug in test hypervisor Date: Thu, 9 Nov 2023 11:14:39 +0000 Message-Id: <20231109111439.145764-1-thanos.makatos@nutanix.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: References: X-ClientProxiedBy: PH0P220CA0013.NAMP220.PROD.OUTLOOK.COM (2603:10b6:510:d3::11) To DM8PR02MB8005.namprd02.prod.outlook.com (2603:10b6:8:16::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM8PR02MB8005:EE_|SJ0PR02MB7711:EE_ X-MS-Office365-Filtering-Correlation-Id: b598b9c4-d790-445d-c946-08dbe11512e7 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: Q4tGMsQPm4oIenPUbx8dIDOS9yBYfzzlDAayvdg6r2y7NPGK0GpmUfHT8PJWuYTSqBcTbTT4H4TqCZ50RknDLnT0yv+oE8guPMdBhNMqkGvFC8sGdGGfIJGFumqoWh1kZHYdHuRI8e0WCrS3ixfmPOUJ5zGkpGR9LW3Dqo1UnR7EySmuCIxtnltOdAHpsL5/z1Q6/FEtm+EfogIH1adxQvDSyVltv9Dcxlbru3rZf52/yiEgtSmm6r0hB2+TzPJBudAslw5X07tEFJz7Lk7STXmVbForsMwN8KzAJQT+LIqLXEu/utEqVxcs5Uezvo1Kn35Q0/a6o5KidMXtqBQ7EtkEHdOxpmd3qIWJNlbMmJSzMeKTlBEcyvqmAsmdp3YGKGrDQVAq04CskoAjAGo9ehUMs3nQp3ByF8jO7OY0gKV1NB3R4CRU3a83CFxt9rPPpODp+4b5tEFXCZLbls8HkeuK8BspBVzfQPeHxJuT0ePtruCQmTaQiXghf/od+csIlFtLEaNfGVJYLFp43KUwVzjabmgae59KaWdVc6wXMl3pMW3os9Du0jDQwBZsIw0BEpwf7jI7LWhCcfvFn6Tl3CAhGNmfU7Gm87K/uP+eGLAeL/dxHh5LI6FawD7OVYeQ 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)(136003)(346002)(376002)(366004)(396003)(39860400002)(230922051799003)(64100799003)(451199024)(1800799009)(186009)(26005)(6512007)(2616005)(107886003)(478600001)(6486002)(8936002)(8676002)(5660300002)(36756003)(4326008)(44832011)(41300700001)(86362001)(2906002)(30864003)(66556008)(66946007)(38350700005)(6916009)(66476007)(316002)(52116002)(6666004)(6506007)(1076003)(38100700002)(83380400001);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?t1ESivDJeSNjYXAKvqsiCK4rbIQDpZMwXxGYNaeTkZi0o9lOOk7KXl7yjSOv?= =?us-ascii?Q?trkzcqwcyyT0q3RRvqqTW9NPdXt8MaticH2RIRP5rQ/cjLNJvjMfPlgfz/Rd?= =?us-ascii?Q?ZCUjdsZ4f8y5XS3gjdp26uhvoIiKYi6LJsz8HJMRofc/8LXeqb85vLwwGPJg?= =?us-ascii?Q?vZA/KoZuNe/3CqxpTkTe5FNkswTLGfWn2T7tG1oOiSFSZIvluUJnAulEwJKx?= =?us-ascii?Q?eCnbPeb+IivwKp9iYW7QjIquBTA2/6/DGbLXEkjraOxabEFH2kQPEBqcsERZ?= =?us-ascii?Q?LenbVwo28XaDc1cnZfYS4HujsyZti/Or2dkk/UMsQZalApPFYOqqdsvI6awe?= =?us-ascii?Q?Th+BlNSpp1K31KrACUCsCWE1F3eRlkTK17ChGJ/GFunLRLem/UsQXZbV4+A7?= =?us-ascii?Q?H37pcF28qz/DuDXKG/7zoDWTtiMwboyZ6DYhQv5FyHyJ/8T6OoqdUGD0HcWq?= =?us-ascii?Q?ZNnaBJ8g2h2LBUXtFNI4oy2u1+XWSKAD7G7iWk/9zCS5LrclIiq3NBw1xR77?= =?us-ascii?Q?eCPFG8ICgV4Erv+KyVoTXPGJkkHP6Hd5W5anHTjiQAGEv60iXecw46wznVJu?= =?us-ascii?Q?pGQ5XO8tixQsBy4DLk8pFNobrcTkW70HbItPMOKsay3FWJO7rOldoMUpLG8E?= =?us-ascii?Q?toZwBahNqBepmqDlwHwCJKWu2bA7waOfz5GYz0m8hwtCjXlhdQPi7YPwmBDm?= =?us-ascii?Q?U42VDERQJvZi7QYZ4bYW0+grdi/bpyo7Xng94tnO8Q9ORpGQgSAExjKPOd4u?= =?us-ascii?Q?OjKqVqsvifUnSbSoAdD6bsvqJ7rssKDLqRC8mc0QKI8LDmIgtu1lLVK/9UxE?= =?us-ascii?Q?MwgN3vnkZXeAP5Nfvcv3x97upfQZRj2vZXkAjsqsmOrr3UgdkVJaZDhxEqEW?= =?us-ascii?Q?6pVweq93mQpA1QZHlrtsRWnTtGb2rEBq0vd0GkkIgXY78Omt1ggR9jg03l/0?= =?us-ascii?Q?fy15VHn/h1XcS7fcQb8eHExEgz+u08bzJNXErsaK3ocU7veMh9EI1YAXw8q6?= =?us-ascii?Q?51B4y6bN7d1ycMJt+S9NB8xB5KdNWs3L9h9fe8tXHuCZ8Om6et/EQbGtDrDc?= =?us-ascii?Q?EdjwKya7gOvMmPD9snsPpaG8HVrF7lG5se+eByIW6WHOzqh+dA6/BDPN2E5W?= =?us-ascii?Q?dSoZVfc7r4+2ti4fW9PXx562VQEagWriOF1nwuClPH59+BO//wBAjb/yjwyu?= =?us-ascii?Q?D+/IE8U/7PAlLu3Y2RSrceXK6mg3VWbizOZ6uczB4uSzoi1B7h3l8HPQqZ4C?= =?us-ascii?Q?oa6OiHUFwnsgqhuKqG5hAfJAVyBA7OaRIlMJ9Nr6i2EmKviyY0BWJJPowGjX?= =?us-ascii?Q?L9NWOnImoSgWTKIPZvuU1k5sH2lu2wNqjTRTdc32vbNiFLr9MpmXtHfsu/K7?= =?us-ascii?Q?auMmwlszXiFlhBC+jnwys0SsPi8H/5broDYa4o9ULy4VmbJUVMq8Z+FyxS+U?= =?us-ascii?Q?QDmUQRmsnGgE8MI/RhQ9JTKX2fByZBMr1Eya+irgdntypAyW/1xfyUzHbBU0?= =?us-ascii?Q?BlrOirm4vNmGi25VVQXsWL6krVaBhN5VPFf5o/gM1lA8VNuweMeEMtaPJp0c?= =?us-ascii?Q?aBqkLuHljt9ojoy1aFJxOOFyvjUDQmuCIExOjZg+ovy5+ua0iTwk0f4xw360?= =?us-ascii?Q?Qw=3D=3D?= X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: b598b9c4-d790-445d-c946-08dbe11512e7 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:14:43.2355 (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: S/H1tXRyVVhSZSXy+eQRbkwQIVJ8NJPAnO39bPs7Z43xv2gdy+y78rN+mcHeGTtcpMNQHNmJCSTGt6JuzF2ZeUQgxsPnbOFnFf2rJZKgpSU= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR02MB7711 X-Proofpoint-GUID: 60XKplIXnkZ86TjQOeFUnPFqW0lzfw4s X-Proofpoint-ORIG-GUID: 60XKplIXnkZ86TjQOeFUnPFqW0lzfw4s 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: TSKLBB3NDXHHTL7RDLU5YXJ2ZGEQK6Y4 X-Message-ID-Hash: TSKLBB3NDXHHTL7RDLU5YXJ2ZGEQK6Y4 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: 1699528638833100001 Signed-off-by: Thanos Makatos --- Changed since v4: * removed inadvertent calls to functions virNWFilterReadLockFilterUpdates/v= irNWFilterUnlockFilterUpdates (original patch was based on v8.0.0) --- src/test/test_driver.c | 382 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 380 insertions(+), 2 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index e87d7cfd44..effb7f9880 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,9 +36,12 @@ #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 "snapshot_conf.h" #include "virfdstream.h" @@ -50,6 +51,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 +10037,379 @@ 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; + + 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); + 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 +10433,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