]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu_conf: Check for namespaces availability more wisely
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 15 Feb 2017 09:06:09 +0000 (10:06 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 15 Feb 2017 11:43:23 +0000 (12:43 +0100)
The bare fact that mnt namespace is available is not enough for
us to allow/enable qemu namespaces feature. There are other
requirements: we must copy all the ACL & SELinux labels otherwise
we might grant access that is administratively forbidden or vice
versa.
At the same time, the check for namespace prerequisites is moved
from domain startup time to qemu.conf parser as it doesn't make
much sense to allow users to start misconfigured libvirt just to
find out they can't start a single domain.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_conf.c
src/qemu/qemu_conf.h
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_driver.c

index 0223a95d22b90e53404a043f64fee7a43c5b5544..ad482d0ee9703ec71c4c32503c1c030679a34b36 100644 (file)
@@ -321,12 +321,10 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
     if (!(cfg->namespaces = virBitmapNew(QEMU_DOMAIN_NS_LAST)))
         goto error;
 
-#if defined(__linux__)
     if (privileged &&
-        virProcessNamespaceAvailable(VIR_PROCESS_NAMESPACE_MNT) == 0 &&
+        qemuDomainNamespaceAvailable(QEMU_DOMAIN_NS_MOUNT) &&
         virBitmapSetBit(cfg->namespaces, QEMU_DOMAIN_NS_MOUNT) < 0)
         goto error;
-#endif /* defined(__linux__) */
 
 #ifdef DEFAULT_LOADER_NVRAM
     if (virFirmwareParseList(DEFAULT_LOADER_NVRAM,
@@ -438,7 +436,8 @@ virQEMUDriverConfigHugeTLBFSInit(virHugeTLBFSPtr hugetlbfs,
 
 
 int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
-                                const char *filename)
+                                const char *filename,
+                                bool privileged)
 {
     virConfPtr conf = NULL;
     int ret = -1;
@@ -832,6 +831,19 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
                 goto cleanup;
             }
 
+            if (!privileged) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("cannot use namespaces in session mode"));
+                goto cleanup;
+            }
+
+            if (qemuDomainNamespaceAvailable(ns) < 0) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("%s namespace is not available"),
+                               namespaces[i]);
+                goto cleanup;
+            }
+
             if (virBitmapSetBit(cfg->namespaces, ns) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("Unable to enable namespace: %s"),
index 91904ed4fdc477c2d8021e35ba99086a55fee4c4..e585f81afddcee43c494bb86c0d4d86820f33aa1 100644 (file)
@@ -294,7 +294,8 @@ void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def);
 virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged);
 
 int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
-                                const char *filename);
+                                const char *filename,
+                                bool privileged);
 
 virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver);
 bool virQEMUDriverIsPrivileged(virQEMUDriverPtr driver);
index 3adec5c14000f4361dd0a861bb3756c6f21476ab..be44843e59980c09ffd48e0762281b49c5ff80b1 100644 (file)
@@ -7643,21 +7643,8 @@ qemuDomainCreateNamespace(virQEMUDriverPtr driver,
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     int ret = -1;
 
-    if (!virBitmapIsBitSet(cfg->namespaces, QEMU_DOMAIN_NS_MOUNT)) {
-        ret = 0;
-        goto cleanup;
-    }
-
-    if (!virQEMUDriverIsPrivileged(driver)) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("cannot use namespaces in session mode"));
-        goto cleanup;
-    }
-
-    if (virProcessNamespaceAvailable(VIR_PROCESS_NAMESPACE_MNT) < 0)
-        goto cleanup;
-
-    if (qemuDomainEnableNamespace(vm, QEMU_DOMAIN_NS_MOUNT) < 0)
+    if (virBitmapIsBitSet(cfg->namespaces, QEMU_DOMAIN_NS_MOUNT) &&
+        qemuDomainEnableNamespace(vm, QEMU_DOMAIN_NS_MOUNT) < 0)
         goto cleanup;
 
     ret = 0;
@@ -7667,6 +7654,35 @@ qemuDomainCreateNamespace(virQEMUDriverPtr driver,
 }
 
 
+bool
+qemuDomainNamespaceAvailable(qemuDomainNamespace ns ATTRIBUTE_UNUSED)
+{
+#if !defined(__linux__)
+    /* Namespaces are Linux specific. */
+    return false;
+
+#else /* defined(__linux__) */
+
+    switch (ns) {
+    case QEMU_DOMAIN_NS_MOUNT:
+# if !defined(HAVE_SYS_ACL_H) || !defined(WITH_SELINUX)
+        /* We can't create the exact copy of paths if either of
+         * these is not available. */
+        return false;
+# else
+        if (virProcessNamespaceAvailable(VIR_PROCESS_NAMESPACE_MNT) < 0)
+            return false;
+# endif
+        break;
+    case QEMU_DOMAIN_NS_LAST:
+        break;
+    }
+
+    return true;
+#endif /* defined(__linux__) */
+}
+
+
 struct qemuDomainAttachDeviceMknodData {
     virQEMUDriverPtr driver;
     virDomainObjPtr vm;
index 5cfa3e114796c29a804e5a0f40ba35cd7ebb9f02..524a6729c2402c07d5004c1a915775994afeb618 100644 (file)
@@ -808,6 +808,8 @@ int qemuDomainBuildNamespace(virQEMUDriverPtr driver,
 int qemuDomainCreateNamespace(virQEMUDriverPtr driver,
                               virDomainObjPtr vm);
 
+bool qemuDomainNamespaceAvailable(qemuDomainNamespace ns);
+
 int qemuDomainNamespaceSetupDisk(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
                                  virStorageSourcePtr src);
index 89bc833deb6e7082425814c49dc3895c3384d382..afbcded93ffa7df6953392f15fca8f58e5e11cbd 100644 (file)
@@ -676,7 +676,7 @@ qemuStateInitialize(bool privileged,
     if (virAsprintf(&driverConf, "%s/qemu.conf", cfg->configBaseDir) < 0)
         goto error;
 
-    if (virQEMUDriverConfigLoadFile(cfg, driverConf) < 0)
+    if (virQEMUDriverConfigLoadFile(cfg, driverConf, privileged) < 0)
         goto error;
     VIR_FREE(driverConf);