From nobody Sat Feb 7 15:11:13 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) client-ip=207.211.31.81; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.81 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=1578652496; cv=none; d=zohomail.com; s=zohoarc; b=ITSaDC0U+KdNMBv8twcaP5LQXVKut1FwUimPmhLmD6ktFP7DI5IY4wEV6ZQnkESBLXrOc+acqOn+NjCfE5eyaxnAiKe8arS+6v6ImHVrJ4Oy0cnRxq49wFzmGQBcxmQarhyc1INqqpAxGvlC3WjRVsR59LTza0DDKDCHc7TsQ1o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1578652496; h=Content-Type:Content-Transfer-Encoding:Cc: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=G4ZVRv7WKlPc+jS9M/Lg61y9BL06fgjO4MO4lPX7L/U=; b=JeUS8ejjKcXoo2Nr/BBGRyyrYR4bVNGm+2jBjmrmn3UnGRldWT6ZT0bmv1iGhKY+G2EJWNsvlJFnHHu4g9wGQLUoz/QAObS/HLe5ulGQYDKv9nGdeN1OTKoFT6gv6IsbLHkAOpUeT2oZrMVEIgE7d42mkfB/K3ThoZcII6AEhBI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.81 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-delivery-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) by mx.zohomail.com with SMTPS id 1578652496310609.6597913260722; Fri, 10 Jan 2020 02:34:56 -0800 (PST) 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-29-M8R9-O7POj2MlKq8gj1FFQ-1; Fri, 10 Jan 2020 05:34:53 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 58749107ACCC; Fri, 10 Jan 2020 10:34:48 +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 2F1A580629; Fri, 10 Jan 2020 10:34: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 D9BCA503DC; Fri, 10 Jan 2020 10:34:47 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 00AAYe4F001921 for ; Fri, 10 Jan 2020 05:34:40 -0500 Received: by smtp.corp.redhat.com (Postfix) id 391BA86CA5; Fri, 10 Jan 2020 10:34:40 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-65.ams2.redhat.com [10.36.112.65]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3D76884665; Fri, 10 Jan 2020 10:34:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1578652495; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc: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=G4ZVRv7WKlPc+jS9M/Lg61y9BL06fgjO4MO4lPX7L/U=; b=gmI4qN52/KwN6gb+dfBlFvkAs1tkeq1SC8EkwvXBpfMbSs8rUgZ0tZs5ieQy+tNDm0g4bz 0K1bq9CJ4o7wXwv3qiNug25nUUvjCVJV7XzS7YuliXGTSQKHXwa7U5yQWRpWyEF+8XReJZ fOq+kkORCZi/MZmPIi+iSOy4ijCCFuk= From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Fri, 10 Jan 2020 10:34:27 +0000 Message-Id: <20200110103430.3564679-4-berrange@redhat.com> In-Reply-To: <20200110103430.3564679-1-berrange@redhat.com> References: <20200110103430.3564679-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Cc: Michal Privoznik Subject: [libvirt] [PATCH v4 3/6] libvirt: support an "embed" URI path selector for opening drivers 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.11 X-MC-Unique: M8R9-O7POj2MlKq8gj1FFQ-1 X-Mimecast-Spam-Score: 0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) The driver URI scheme: "$drivername:///embed?root=3D/some/path" enables a new way to use the drivers by embedding them directly in the calling process. To use this the process must have a thread running the libvirt event loop. This URI will then cause libvirt to dynamically load the driver module and call its global initialization function. This syntax is applicable to any driver, but only those will have been modified to support a custom root directory and embed URI path will successfully open. The application can now make normal libvirt API calls which are all serviced in-process with no RPC layer involved. It is required to specify an explicit root directory, and locks will be acquired on this directory to avoid conflicting with another app that might accidentally pick the same directory. Use of '/' is not explicitly forbidden, but note that the file layout used underneath the embedded driver root does not match the file layout used by system/session mode drivers. So this cannot be used as a backdoor to interact with, or fake, the system/session mode drivers. Libvirt will create arbitrary files underneath this root directory. The root directory can be kept untouched across connection open attempts if the application needs persistence. The application is responsible for purging everything underneath this root directory when finally no longer required. Even when a virt driver is used in embedded mode, it is still possible for it to in turn use functionality that calls out to other secondary drivers in libvirtd. For example an embedded instance of QEMU can open the network, secret or storage drivers in the system libvirtd. That said, the application would typically want to at least open an embedded secret driver ("secret:///embed?root=3D/some/path"). Note that multiple different embedded drivers can use the same root prefix and co-operate just as they would inside a normal libvirtd daemon. A key thing to note is that for this to work, the application that links to libvirt *MUST* be built with -Wl,--export-dynamic to ensure that symbols from libvirt.so are exported & thus available to the dynamically loaded driver module. If libvirt.so itself was dynamically loaded then RTLD_GLOBAL must be passed to dlopen(). Reviewed-by: Michal Privoznik Signed-off-by: Daniel P. Berrang=C3=A9 --- src/driver-state.h | 1 + src/driver.h | 2 ++ src/libvirt.c | 72 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/driver-state.h b/src/driver-state.h index 1e2f6ed247..6b3f501e05 100644 --- a/src/driver-state.h +++ b/src/driver-state.h @@ -50,6 +50,7 @@ typedef virStateDriver *virStateDriverPtr; =20 struct _virStateDriver { const char *name; + bool initialized; virDrvStateInitialize stateInitialize; virDrvStateCleanup stateCleanup; virDrvStateReload stateReload; diff --git a/src/driver.h b/src/driver.h index ca82ac974b..6278aa05b3 100644 --- a/src/driver.h +++ b/src/driver.h @@ -82,6 +82,8 @@ struct _virConnectDriver { bool localOnly; /* Whether driver needs a server in the URI */ bool remoteOnly; + /* Whether driver can be used in embedded mode */ + bool embeddable; /* * NULL terminated list of supported URI schemes. * - Single element { NULL } list indicates no supported schemes diff --git a/src/libvirt.c b/src/libvirt.c index 4de87cdecd..5599d5ff31 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -49,6 +49,7 @@ # include "rpc/virnettlscontext.h" #endif #include "vircommand.h" +#include "virevent.h" #include "virfile.h" #include "virrandom.h" #include "viruri.h" @@ -78,6 +79,7 @@ #ifdef WITH_BHYVE # include "bhyve/bhyve_driver.h" #endif +#include "access/viraccessmanager.h" =20 #define VIR_FROM_THIS VIR_FROM_NONE =20 @@ -648,10 +650,12 @@ virStateInitialize(bool privileged, return -1; =20 for (i =3D 0; i < virStateDriverTabCount; i++) { - if (virStateDriverTab[i]->stateInitialize) { + if (virStateDriverTab[i]->stateInitialize && + !virStateDriverTab[i]->initialized) { virDrvStateInitResult ret; VIR_DEBUG("Running global init for %s state driver", virStateDriverTab[i]->name); + virStateDriverTab[i]->initialized =3D true; ret =3D virStateDriverTab[i]->stateInitialize(privileged, root, callback, @@ -844,6 +848,7 @@ virConnectOpenInternal(const char *name, virConnectPtr ret; g_autoptr(virConf) conf =3D NULL; char *uristr =3D NULL; + bool embed =3D false; =20 ret =3D virGetConnect(); if (ret =3D=3D NULL) @@ -934,6 +939,52 @@ virConnectOpenInternal(const char *name, ret->uri) < 0) { goto failed; } + + if (STREQ(ret->uri->path, "/embed")) { + const char *root =3D NULL; + g_autofree char *regMethod =3D NULL; + VIR_DEBUG("URI path requests %s driver embedded mode", + ret->uri->scheme); + if (strspn(ret->uri->scheme, "abcdefghijklmnopqrstuvwxyz") != =3D + strlen(ret->uri->scheme)) { + virReportError(VIR_ERR_NO_CONNECT, + _("URI scheme '%s' for embedded driver is n= ot valid"), + ret->uri->scheme); + goto failed; + } + + for (i =3D 0; i < ret->uri->paramsCount; i++) { + virURIParamPtr var =3D &ret->uri->params[i]; + if (STREQ(var->name, "root")) + root =3D var->value; + } + + if (!root) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("root parameter required for embedded dri= ver")); + goto failed; + } + + if (virEventRequireImpl() < 0) + goto failed; + + regMethod =3D g_strdup_printf("%sRegister", ret->uri->scheme); + + if (virDriverLoadModule(ret->uri->scheme, regMethod, false) < = 0) + goto failed; + + if (virAccessManagerGetDefault() =3D=3D NULL) { + virAccessManagerPtr acl =3D virAccessManagerNew("none"); + if (!acl) + goto failed; + virAccessManagerSetDefault(acl); + } + + if (virStateInitialize(geteuid() =3D=3D 0, true, root, NULL, N= ULL) < 0) + goto failed; + + embed =3D true; + } } else { VIR_DEBUG("no name, allowing driver auto-select"); } @@ -987,6 +1038,12 @@ virConnectOpenInternal(const char *name, VIR_DEBUG("No URI, skipping driver with URI whitelist"); continue; } + if (embed && !virConnectDriverTab[i]->embeddable) { + VIR_DEBUG("Ignoring non-embeddable driver %s", + virConnectDriverTab[i]->hypervisorDriver->name); + continue; + } + VIR_DEBUG("Checking for supported URI schemes"); for (s =3D 0; virConnectDriverTab[i]->uriSchemes[s] !=3D NULL;= s++) { if (STREQ(ret->uri->scheme, virConnectDriverTab[i]->uriSch= emes[s])) { @@ -1000,9 +1057,20 @@ virConnectOpenInternal(const char *name, continue; } } else { - VIR_DEBUG("Matching any URI scheme for '%s'", ret->uri ? ret->= uri->scheme : ""); + if (embed) { + VIR_DEBUG("Skipping wildcard for embedded URI"); + continue; + } else { + VIR_DEBUG("Matching any URI scheme for '%s'", ret->uri ? r= et->uri->scheme : ""); + } } =20 + if (embed && !virConnectDriverTab[i]->embeddable) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Driver %s cannot be used in embedded mode"), + virConnectDriverTab[i]->hypervisorDriver->name); + goto failed; + } /* before starting the new connection, check if the driver only wo= rks * with a server, and so return an error if the server is missing = */ if (virConnectDriverTab[i]->remoteOnly && ret->uri && !ret->uri->s= erver) { --=20 2.23.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list