Blob Blame History Raw
From c5e142b3b9bc25ed508b8b7b62907ed99daba84d Mon Sep 17 00:00:00 2001
Message-Id: <c5e142b3b9bc25ed508b8b7b62907ed99daba84d@dist-git>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 11 May 2017 15:38:40 +0200
Subject: [PATCH] qemuDomainAttachDeviceMknodRecursive: Don't try to create
 devices under preserved mount points

https://bugzilla.redhat.com/show_bug.cgi?id=1449510

Just like in previous commit, this fixes the same issue for
hotplug.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Cedric Bosdonnat <cbosdonnat@suse.com>
(cherry picked from commit b3418f36be75eb4bdecd6aa37cda7a268519ee46)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_domain.c | 114 ++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 98 insertions(+), 16 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 9217747d5..671569f6f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8314,6 +8314,8 @@ static int
 qemuDomainAttachDeviceMknodRecursive(virQEMUDriverPtr driver,
                                      virDomainObjPtr vm,
                                      const char *file,
+                                     char * const *devMountsPath,
+                                     size_t ndevMountsPath,
                                      unsigned int ttl)
 {
     struct qemuDomainAttachDeviceMknodData data;
@@ -8391,20 +8393,36 @@ qemuDomainAttachDeviceMknodRecursive(virQEMUDriverPtr driver,
 #endif
 
     if (STRPREFIX(file, DEVPREFIX)) {
-        if (qemuSecurityPreFork(driver->securityManager) < 0)
-            goto cleanup;
+        size_t i;
 
-        if (virProcessRunInMountNamespace(vm->pid,
-                                          qemuDomainAttachDeviceMknodHelper,
-                                          &data) < 0) {
-            qemuSecurityPostFork(driver->securityManager);
-            goto cleanup;
+        for (i = 0; i < ndevMountsPath; i++) {
+            if (STREQ(devMountsPath[i], "/dev"))
+                continue;
+            if (STRPREFIX(file, devMountsPath[i]))
+                break;
+        }
+
+        if (i == ndevMountsPath) {
+            if (qemuSecurityPreFork(driver->securityManager) < 0)
+                goto cleanup;
+
+            if (virProcessRunInMountNamespace(vm->pid,
+                                              qemuDomainAttachDeviceMknodHelper,
+                                              &data) < 0) {
+                qemuSecurityPostFork(driver->securityManager);
+                goto cleanup;
+            }
+            qemuSecurityPostFork(driver->securityManager);
+        } else {
+            VIR_DEBUG("Skipping dev %s because of %s mount point",
+                      file, devMountsPath[i]);
         }
-        qemuSecurityPostFork(driver->securityManager);
     }
 
     if (isLink &&
-        qemuDomainAttachDeviceMknodRecursive(driver, vm, target, ttl -1) < 0)
+        qemuDomainAttachDeviceMknodRecursive(driver, vm, target,
+                                             devMountsPath, ndevMountsPath,
+                                             ttl -1) < 0)
         goto cleanup;
 
     ret = 0;
@@ -8421,11 +8439,15 @@ qemuDomainAttachDeviceMknodRecursive(virQEMUDriverPtr driver,
 static int
 qemuDomainAttachDeviceMknod(virQEMUDriverPtr driver,
                             virDomainObjPtr vm,
-                            const char *file)
+                            const char *file,
+                            char * const *devMountsPath,
+                            size_t ndevMountsPath)
 {
     long symloop_max = sysconf(_SC_SYMLOOP_MAX);
 
-    return qemuDomainAttachDeviceMknodRecursive(driver, vm, file, symloop_max);
+    return qemuDomainAttachDeviceMknodRecursive(driver, vm, file,
+                                                devMountsPath, ndevMountsPath,
+                                                symloop_max);
 }
 
 
@@ -8465,6 +8487,9 @@ qemuDomainNamespaceSetupDisk(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              virStorageSourcePtr src)
 {
+    virQEMUDriverConfigPtr cfg = NULL;
+    char **devMountsPath = NULL;
+    size_t ndevMountsPath = 0;
     virStorageSourcePtr next;
     struct stat sb;
     int ret = -1;
@@ -8472,6 +8497,12 @@ qemuDomainNamespaceSetupDisk(virQEMUDriverPtr driver,
     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
         return 0;
 
+    cfg = virQEMUDriverGetConfig(driver);
+    if (qemuDomainGetPreservedMounts(cfg, vm,
+                                     &devMountsPath, NULL,
+                                     &ndevMountsPath) < 0)
+        goto cleanup;
+
     for (next = src; next; next = next->backingStore) {
         if (virStorageSourceIsEmpty(next) ||
             !virStorageSourceIsLocalStorage(next)) {
@@ -8490,12 +8521,15 @@ qemuDomainNamespaceSetupDisk(virQEMUDriverPtr driver,
 
         if (qemuDomainAttachDeviceMknod(driver,
                                         vm,
-                                        next->path) < 0)
+                                        next->path,
+                                        devMountsPath, ndevMountsPath) < 0)
             goto cleanup;
     }
 
     ret = 0;
  cleanup:
+    virStringListFreeCount(devMountsPath, ndevMountsPath);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -8520,6 +8554,9 @@ qemuDomainNamespaceSetupHostdev(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
                                 virDomainHostdevDefPtr hostdev)
 {
+    virQEMUDriverConfigPtr cfg = NULL;
+    char **devMountsPath = NULL;
+    size_t ndevMountsPath = 0;
     int ret = -1;
     char **path = NULL;
     size_t i, npaths = 0;
@@ -8530,10 +8567,17 @@ qemuDomainNamespaceSetupHostdev(virQEMUDriverPtr driver,
     if (qemuDomainGetHostdevPath(NULL, hostdev, false, &npaths, &path, NULL) < 0)
         goto cleanup;
 
+    cfg = virQEMUDriverGetConfig(driver);
+    if (qemuDomainGetPreservedMounts(cfg, vm,
+                                     &devMountsPath, NULL,
+                                     &ndevMountsPath) < 0)
+        goto cleanup;
+
     for (i = 0; i < npaths; i++) {
         if (qemuDomainAttachDeviceMknod(driver,
                                         vm,
-                                        path[i]) < 0)
+                                        path[i],
+                                        devMountsPath, ndevMountsPath) < 0)
         goto cleanup;
     }
 
@@ -8542,6 +8586,8 @@ qemuDomainNamespaceSetupHostdev(virQEMUDriverPtr driver,
     for (i = 0; i < npaths; i++)
         VIR_FREE(path[i]);
     VIR_FREE(path);
+    virStringListFreeCount(devMountsPath, ndevMountsPath);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -8581,6 +8627,9 @@ qemuDomainNamespaceSetupMemory(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
                                virDomainMemoryDefPtr mem)
 {
+    virQEMUDriverConfigPtr cfg = NULL;
+    char **devMountsPath = NULL;
+    size_t ndevMountsPath = 0;
     int ret = -1;
 
     if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM)
@@ -8589,10 +8638,19 @@ qemuDomainNamespaceSetupMemory(virQEMUDriverPtr driver,
     if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
         return 0;
 
-    if (qemuDomainAttachDeviceMknod(driver, vm, mem->nvdimmPath) < 0)
+    cfg = virQEMUDriverGetConfig(driver);
+    if (qemuDomainGetPreservedMounts(cfg, vm,
+                                     &devMountsPath, NULL,
+                                     &ndevMountsPath) < 0)
+        goto cleanup;
+
+    if (qemuDomainAttachDeviceMknod(driver, vm, mem->nvdimmPath,
+                                    devMountsPath, ndevMountsPath) < 0)
         goto cleanup;
     ret = 0;
  cleanup:
+    virStringListFreeCount(devMountsPath, ndevMountsPath);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -8623,6 +8681,9 @@ qemuDomainNamespaceSetupChardev(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
                                 virDomainChrDefPtr chr)
 {
+    virQEMUDriverConfigPtr cfg = NULL;
+    char **devMountsPath = NULL;
+    size_t ndevMountsPath = 0;
     const char *path;
     int ret = -1;
 
@@ -8634,12 +8695,21 @@ qemuDomainNamespaceSetupChardev(virQEMUDriverPtr driver,
 
     path = chr->source->data.file.path;
 
+    cfg = virQEMUDriverGetConfig(driver);
+    if (qemuDomainGetPreservedMounts(cfg, vm,
+                                     &devMountsPath, NULL,
+                                     &ndevMountsPath) < 0)
+        goto cleanup;
+
     if (qemuDomainAttachDeviceMknod(driver,
                                     vm,
-                                    path) < 0)
+                                    path,
+                                    devMountsPath, ndevMountsPath) < 0)
         goto cleanup;
     ret = 0;
  cleanup:
+    virStringListFreeCount(devMountsPath, ndevMountsPath);
+    virObjectUnref(cfg);
     return ret;
 }
 
@@ -8674,6 +8744,9 @@ qemuDomainNamespaceSetupRNG(virQEMUDriverPtr driver,
                             virDomainObjPtr vm,
                             virDomainRNGDefPtr rng)
 {
+    virQEMUDriverConfigPtr cfg = NULL;
+    char **devMountsPath = NULL;
+    size_t ndevMountsPath = 0;
     const char *path = NULL;
     int ret = -1;
 
@@ -8691,12 +8764,21 @@ qemuDomainNamespaceSetupRNG(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
+    cfg = virQEMUDriverGetConfig(driver);
+    if (qemuDomainGetPreservedMounts(cfg, vm,
+                                     &devMountsPath, NULL,
+                                     &ndevMountsPath) < 0)
+        goto cleanup;
+
     if (qemuDomainAttachDeviceMknod(driver,
                                     vm,
-                                    path) < 0)
+                                    path,
+                                    devMountsPath, ndevMountsPath) < 0)
         goto cleanup;
     ret = 0;
  cleanup:
+    virStringListFreeCount(devMountsPath, ndevMountsPath);
+    virObjectUnref(cfg);
     return ret;
 }
 
-- 
2.13.0