]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Store tapfd path in domstatus XML
authorWesley Hershberger <wesley.hershberger@canonical.com>
Mon, 13 Apr 2026 15:23:45 +0000 (10:23 -0500)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 14 Apr 2026 09:18:42 +0000 (11:18 +0200)
Introduce a read-only `tapfd` element for direct interfaces (macvtap),
which contains the path to the backing tapfd for that interface
(e.g. `/dev/tapXX`).

The element is only included when the domain is being formatted for
internal consumption (VIR_DOMAIN_DEF_FORMAT_STATUS) and is not accepted
in user-provided XML (!VIR_DOMAIN_DEF_PARSE_INACTIVE).

This will be used by the AppArmor security driver when re-generating
profiles.

Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Wesley Hershberger <wesley.hershberger@canonical.com>
src/conf/domain_conf.c
src/conf/domain_conf.h
src/hypervisor/domain_interface.c
src/lxc/lxc_process.c
src/qemu/qemu_interface.c
src/util/virnetdevmacvlan.c
src/util/virnetdevmacvlan.h
tests/qemustatusxml2xmldata/modern-in.xml

index b1ee519ff600e9fb53c6f81ca4f8c1b6aaad8029..3497e84bf590bcd24aa1c0feafed6fd9c3477837 100644 (file)
@@ -2971,6 +2971,7 @@ virDomainNetDefFree(virDomainNetDef *def)
     g_free(def->virtio);
     g_free(def->coalesce);
     g_free(def->sourceDev);
+    g_free(def->tapfdpath);
 
     virNetDevIPInfoClear(&def->guestIP);
     virNetDevIPInfoClear(&def->hostIP);
@@ -10635,6 +10636,10 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
             return NULL;
     }
 
+    if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) {
+        def->tapfdpath = virXPathString("string(./tapfd/@path)", ctxt);
+    }
+
     if (virNetworkPortOptionsParseXML(ctxt, &def->isolatedPort) < 0)
         return NULL;
 
@@ -26032,6 +26037,9 @@ virDomainNetDefFormat(virBuffer *buf,
     if (def->mtu)
         virBufferAsprintf(buf, "<mtu size='%u'/>\n", def->mtu);
 
+    if (def->tapfdpath && (flags & VIR_DOMAIN_DEF_FORMAT_STATUS))
+        virBufferEscapeString(buf, "<tapfd path='%s'/>\n", def->tapfdpath);
+
     virDomainNetDefCoalesceFormatXML(buf, def->coalesce);
 
     virDomainDeviceInfoFormat(buf, &def->info, flags | VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT
index 75acfc46bfc5f5391be2f7a542ce588d248e6d89..a8f90803da6be86676ad365a570e06e74073b40a 100644 (file)
@@ -1212,6 +1212,7 @@ struct _virDomainNetDef {
     char *downscript;
     char *domain_name; /* backend domain name */
     char *ifname; /* interface name on the host (<target dev='x'/>) */
+    char *tapfdpath; /* Path in /dev for macvtap (<tapfd path='/dev/tapXX'/>) */
     virTristateBool managed_tap;
     virNetDevIPInfo hostIP;
     char *ifname_guest_actual;
index 5bc698d2727e1142e9c5dc30ac00975f268f98e8..37e3d453a03943ee5729ad2d4b087b5e0ca37408 100644 (file)
@@ -111,7 +111,7 @@ virDomainInterfaceEthernetConnect(virDomainDef *def,
 
         if (virNetDevMacVLanIsMacvtap(net->ifname)) {
             auditdev = net->ifname;
-            if (virNetDevMacVLanTapOpen(net->ifname, tapfd, tapfdSize) < 0)
+            if (virNetDevMacVLanTapOpen(net->ifname, tapfd, tapfdSize, &net->tapfdpath) < 0)
                 goto cleanup;
             if (virNetDevMacVLanTapSetup(tapfd, tapfdSize,
                                          virDomainInterfaceIsVnetCompatModel(net)) < 0) {
index 1bca9e8daea2cb8f63bcf5c0a735252ff57af6f1..c731b28871b18329e633c42f2141d22063208d9f 100644 (file)
@@ -379,6 +379,7 @@ virLXCProcessSetupInterfaceDirect(virLXCDriver *driver,
             VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
             cfg->stateDir,
             NULL, 0,
+            &net->tapfdpath,
             macvlan_create_flags) < 0)
         return NULL;
 
index 23a23d201aec31a36431646551ae03a233606e30..edc53d53b3b34afbfb8662e809bc0898076fdfc5 100644 (file)
@@ -81,6 +81,7 @@ qemuInterfaceDirectConnect(virDomainDef *def,
                                                &res_ifname,
                                                vmop, cfg->stateDir,
                                                tapfd, tapfdSize,
+                                               &net->tapfdpath,
                                                macvlan_create_flags) < 0)
         goto cleanup;
 
index c981afad5a2cb74989c61ac0b052b57b68d5bb12..5054840fcf32b178216aba9579af58a900ed9b24 100644 (file)
@@ -158,25 +158,25 @@ int virNetDevMacVLanDelete(const char *ifname)
 int
 virNetDevMacVLanTapOpen(const char *ifname,
                         int *tapfd,
-                        size_t tapfdSize)
+                        size_t tapfdSize,
+                        char **tapname)
 {
     int ret = -1;
     int ifindex;
     size_t i = 0;
-    g_autofree char *tapname = NULL;
 
     if (virNetDevGetIndex(ifname, &ifindex) < 0)
         return -1;
 
-    tapname = g_strdup_printf("/dev/tap%d", ifindex);
+    *tapname = g_strdup_printf("/dev/tap%d", ifindex);
 
     for (i = 0; i < tapfdSize; i++) {
         int fd = -1;
 
-        if ((fd = open(tapname, O_RDWR)) < 0) {
+        if ((fd = open(*tapname, O_RDWR)) < 0) {
             virReportSystemError(errno,
                                  _("cannot open macvtap tap device %1$s"),
-                                 tapname);
+                                 *tapname);
             goto cleanup;
         }
         tapfd[i] = fd;
@@ -186,6 +186,7 @@ virNetDevMacVLanTapOpen(const char *ifname,
 
  cleanup:
     if (ret < 0) {
+        g_clear_pointer(tapname, g_free);
         while (i--)
             VIR_FORCE_CLOSE(tapfd[i]);
     }
@@ -657,6 +658,7 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
                                        char *stateDir,
                                        int *tapfd,
                                        size_t tapfdSize,
+                                       char **tapfdpath,
                                        unsigned int flags)
 {
     g_autofree char *ifname = NULL;
@@ -727,7 +729,7 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
     }
 
     if (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) {
-        if (virNetDevMacVLanTapOpen(ifname, tapfd, tapfdSize) < 0)
+        if (virNetDevMacVLanTapOpen(ifname, tapfd, tapfdSize, tapfdpath) < 0)
             goto disassociate_exit;
 
         if (virNetDevMacVLanTapSetup(tapfd, tapfdSize, vnet_hdr) < 0)
@@ -886,7 +888,8 @@ int virNetDevMacVLanDelete(const char *ifname G_GNUC_UNUSED)
 int
 virNetDevMacVLanTapOpen(const char *ifname G_GNUC_UNUSED,
                         int *tapfd G_GNUC_UNUSED,
-                        size_t tapfdSize G_GNUC_UNUSED)
+                        size_t tapfdSize G_GNUC_UNUSED,
+                        char **tapname G_GNUC_UNUSED)
 {
     virReportSystemError(ENOSYS, "%s",
                          _("Cannot create macvlan devices on this platform"));
@@ -915,6 +918,7 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *ifname G_GNUC_UNUSED,
                                            char *stateDir G_GNUC_UNUSED,
                                            int *tapfd G_GNUC_UNUSED,
                                            size_t tapfdSize G_GNUC_UNUSED,
+                                           char **tapfdpath G_GNUC_UNUSED,
                                            unsigned int unused_flags G_GNUC_UNUSED)
 {
     virReportSystemError(ENOSYS, "%s",
index 31e4804cdc0d7c4beb74ba66d204d0ff7ad83151..7424b8796529d6c6d1909eee81c88e8ded0ea84b 100644 (file)
@@ -72,13 +72,15 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *ifname,
                                            char *stateDir,
                                            int *tapfd,
                                            size_t tapfdSize,
+                                           char **tapfdpath,
                                            unsigned int flags)
     ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(6)
     ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(10) G_GNUC_WARN_UNUSED_RESULT;
 
 int virNetDevMacVLanTapOpen(const char *ifname,
                             int *tapfd,
-                            size_t tapfdSize)
+                            size_t tapfdSize,
+                            char **tapname)
    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
    G_GNUC_WARN_UNUSED_RESULT;
 
index 3b3e83175997a661668c26e0aa396cbb82d678e6..050669f554a051401a8acf5b990a46a31620aac1 100644 (file)
         <alias name='net0'/>
         <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
       </interface>
+      <interface type='direct'>
+        <mac address='52:54:00:36:bd:3c'/>
+        <source dev='eth0' mode='vepa'/>
+        <model type='rtl8139'/>
+        <tapfd path='/dev/tap8'/>
+        <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/>
+      </interface>
       <serial type='pty'>
         <source path='/dev/pts/67'/>
         <target type='isa-serial' port='0'>