From nobody Tue Nov 26 16:28:11 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 207.211.31.120 as permitted sender) client-ip=207.211.31.120; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of redhat.com designates 207.211.31.120 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=1571793959; cv=none; d=zoho.com; s=zohoarc; b=U2FBvhA18CcGElS6eOOAaGJV0jVbzmWHGqN/5qPFWbSJCuKXcnNwMWsaY2UmGvuOlfB6y7Fflb68AkdsaA7h28ZwEtFVs/PkHrEi5r8xlq2mD+QLDlyT+wRKN4QsEqCunqn6ddWv/TvccfO2jp6aEojZHDGZVuGi9pykx1AadJk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1571793959; 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; bh=4J1RdsEhKXb1no2RwjYJXsk00v0cPtk1+0gwf60QRfE=; b=P7V6fs2fU8KNU5axissX++3e+PrWXaGud6cABiBLylETL1LXTY5joI9W+Avp9lVxR804/mEgxGzhcGVc+x0DVqx5HBt2H2TA/8W7vDvFDBGhZBQgvYkPjEPJ7950ukqzYEeL8U5O/eo9vA4qtwSxbf4sm36r1/M3i1dGkAYtcbk= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of redhat.com designates 207.211.31.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by mx.zohomail.com with SMTPS id 1571793959781600.1507407391448; Tue, 22 Oct 2019 18:25:59 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-125-9Dh1vOwvOROZ1beBiIIVcA-1; Tue, 22 Oct 2019 21:25:56 -0400 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 95ADE476; Wed, 23 Oct 2019 01:25: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 AB63060C4E; Wed, 23 Oct 2019 01:25:48 +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 A30504A486; Wed, 23 Oct 2019 01:25:44 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x9N1OUUS030905 for ; Tue, 22 Oct 2019 21:24:30 -0400 Received: by smtp.corp.redhat.com (Postfix) id 4874C5D6C8; Wed, 23 Oct 2019 01:24:30 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-114.phx2.redhat.com [10.3.117.114]) by smtp.corp.redhat.com (Postfix) with ESMTP id 051BA5D6B2 for ; Wed, 23 Oct 2019 01:24:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571793958; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=4J1RdsEhKXb1no2RwjYJXsk00v0cPtk1+0gwf60QRfE=; b=RbNwpwNY7CC7mn1XyWUdxV5tnP8oKPkDgoGTs8kqmpU+xu3bmD2BAJFQplcPG+3aB2QsLk 58lh2QH2MPIa6ciOzsV4gXq+IJQz8sDtlWTvoZCkR9dmeIYjcoszSTjaWMM13CBvLo//AZ q0PFUuZ4zxw9V8j8+SocgNrBB8Loe6M= From: Laine Stump To: libvir-list@redhat.com Date: Tue, 22 Oct 2019 21:24:19 -0400 Message-Id: <20191023012420.21128-7-laine@redhat.com> In-Reply-To: <20191023012420.21128-1-laine@redhat.com> References: <20191023012420.21128-1-laine@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 6/7] conf: add hypervisor agnostic, domain start-time, validation function for NetDef 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: , 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-MC-Unique: 9Dh1vOwvOROZ1beBiIIVcA-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" devices (virDomainNetDef) are a bit different from other types of devices in that their actual type may come from a network (in the form of a port connection), and that doesn't happen until the domain is started. This means that any validation of an at parse time needs to be a bit liberal in what it accepts - when type=3D'network', you could think that something is/isn't allowed, but once the domain is started and a port is created by the configured network, the opposite might be true. To solve this problem hypervisor drivers need to do an extra validation step when the domain is being started. I recently (commit 3cff23f7, libvirt 5.7.0) added a function to peform such validation for all interfaces to the QEMU driver - qemuDomainValidateActualNetDef() - but while that function is a good single point to call for the multiple places that need to "start" an interface (domain startup, device hotplug, device update), it can't be called by the other hypervisor drivers, since 1) it's in the QEMU driver, and 2) it contains some checks specific to QEMU. For validation that applies to network devices on *all* hypervisors, we need yet another interface validation function that can be called by any hypervisor driver (not just QEMU) right after its network port has been created during domain startup or hotplug. This patch adds that function - virDomainNetDefRuntimeValidate(), in the conf directory, and calls it in appropriate places in the QEMU, lxc, and libxl drivers. The new function, virDomainNetDefRuntimeValidate(), should contain network device validation that 1) is hypervisor agnostic, and 2) can't be done until we know the "actual type" of an interface. There is no framework for validation at domain startup as there is for post-parse validation, but I don't want to create a whole elaborate system that will only be used by one type of device. For that reason, I just made a single function that should be called directly from the hypervisors, when they are initializing interfaces to start a domain, right after conditionally allocating the network port (and regardless of whether or not that was actually needed). In the case of the QEMU driver, qemuDomainValidateActualNetDef() is already called in all the appropriate places, so we can just call the new function from there. In the case of the other hypervisors, we search for virDomainNetAllocateActualDevice() (which is the hypervisor-agnostic function that calls virNetworkPortCreateXML()), and add the call to our new function right after that. The new function itself could be plunked down into many places in the code, but we already have 3 validation functions for network devices in 2 different places (not counting any basic validation done in virDomainNetDefParseXML() itself): 1) post-parse hypervisor-agnostic (virDomainNetDefValidate() - domain_conf.c:6145) 2) post-parse hypervisor-specific (qemuDomainDeviceDefValidateNetwork() - qemu_domain.c:5498) 3) domain-start hypervisor-specific (qemuDomainValidateActualNetDef() - qemu_domain.c:5390) I placed (3) right next to (2) when I added it, specifically to avoid spreading validation all over the code. For the same reason, I decided to put this new function right next to (1) - this way if someone needs to add validation specific to qemu, they go to one location, and if they need to add validation applying to everyone, they go to the other. It looks a bit strange to have a public function in between a bunch of statics, but I think it's better than the alternative of further fragmentation. (I'm open to other ideas though, of course.) Signed-off-by: Laine Stump Reviewed-by: Cole Robinson --- src/conf/domain_conf.c | 22 ++++++++++++++++++++++ src/conf/domain_conf.h | 3 +++ src/libvirt_private.syms | 1 + src/libxl/libxl_domain.c | 4 ++++ src/libxl/libxl_driver.c | 4 ++++ src/lxc/lxc_driver.c | 4 ++++ src/lxc/lxc_process.c | 4 ++++ src/qemu/qemu_domain.c | 6 ++++++ 8 files changed, 48 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 01a1a74946..c063f40a4c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6094,6 +6094,28 @@ virDomainRedirdevDefValidate(const virDomainDef *def, } =20 =20 +int +virDomainNetDefRuntimeValidate(const virDomainNetDef *net G_GNUC_UNUSED) +{ + /* Unlike virDomainNetDefValidate(), which is a static function + * called internally to this file, virDomainActualNetDefValidate() + * is a public function that can be called from a hypervisor after + * it has completely setup the NetDef for use by a domain, + * including possibly allocating a port from the network driver + * (which could change the effective/"actual" type of the NetDef, + * thus changing what should/shouldn't be allowed by validation). + * + * This function should contain validations not specific to a + * particular hypervisor (e.g. whether or not specifying bandwidth + * is allowed for a type of interface), but *not* + * hypervisor-specific things. + */ + + return 0; + +} + + static int virDomainNetDefValidate(const virDomainNetDef *net) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 4a7010e8a5..dc0226e6da 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2802,6 +2802,9 @@ int virDomainDefValidate(virDomainDefPtr def, unsigned int parseFlags, virDomainXMLOptionPtr xmlopt); =20 +int +virDomainNetDefRuntimeValidate(const virDomainNetDef *net); + static inline bool virDomainObjIsActive(virDomainObjPtr dom) { diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 12cb3b5bf7..811d01c4f5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -479,6 +479,7 @@ virDomainNetDefClear; virDomainNetDefFormat; virDomainNetDefFree; virDomainNetDefNew; +virDomainNetDefRuntimeValidate; virDomainNetDefToNetworkPort; virDomainNetFind; virDomainNetFindByName; diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index d79c3c1ed7..57d2a4aeb5 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -1065,6 +1065,10 @@ libxlNetworkPrepareDevices(virDomainDefPtr def) goto cleanup; } =20 + /* final validation now that actual type is known */ + if (virDomainNetDefRuntimeValidate(net) < 0) + return -1; + actualType =3D virDomainNetGetActualType(net); if (actualType =3D=3D VIR_DOMAIN_NET_TYPE_HOSTDEV && net->type =3D=3D VIR_DOMAIN_NET_TYPE_NETWORK) { diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 5cc6b87b8c..323cb92c04 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3425,6 +3425,10 @@ libxlDomainAttachNetDevice(libxlDriverPrivatePtr dri= ver, goto cleanup; } =20 + /* final validation now that actual type is known */ + if (virDomainNetDefRuntimeValidate(net) < 0) + return -1; + actualType =3D virDomainNetGetActualType(net); =20 if (virDomainHasNet(vm->def, net)) { diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 1a1239b1bd..8d519d282a 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -3860,6 +3860,10 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn, virObjectUnref(netconn); } =20 + /* final validation now that actual type is known */ + if (virDomainNetDefRuntimeValidate(net) < 0) + return -1; + actualType =3D virDomainNetGetActualType(net); =20 switch (actualType) { diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 1a565b6358..13547abec4 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -574,6 +574,10 @@ static int virLXCProcessSetupInterfaces(virConnectPtr = conn, goto cleanup; } =20 + /* final validation now that actual type is known */ + if (virDomainNetDefRuntimeValidate(net) < 0) + return -1; + type =3D virDomainNetGetActualType(net); switch (type) { case VIR_DOMAIN_NET_TYPE_NETWORK: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0181b62602..a8a7907546 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5389,6 +5389,12 @@ qemuDomainValidateActualNetDef(const virDomainNetDef= *net, =20 virMacAddrFormat(&net->mac, macstr); =20 + /* hypervisor-agnostic validation */ + if (virDomainNetDefRuntimeValidate(net) < 0) + return -1; + + /* QEMU-specific validation */ + /* Only tap/macvtap devices support multiqueue. */ if (net->driver.virtio.queues > 0) { =20 --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list