When attaching a device to a domain that's using separate mount
namespace we must maintain /dev entries in order for qemu process
to see them.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_domain.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++--
src/qemu/qemu_domain.h | 8 +++++++
src/qemu/qemu_hotplug.c | 10 ++++++++
3 files changed, 80 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d0ba316d2..a8cc8ecfa 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7470,6 +7470,10 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED,
goto cleanup;
} break;
+ case VIR_DOMAIN_DEVICE_CHR:
+ /* No labelling. */
+ break;
+
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LEASE:
case VIR_DOMAIN_DEVICE_FS:
@@ -7483,7 +7487,6 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED,
case VIR_DOMAIN_DEVICE_HUB:
case VIR_DOMAIN_DEVICE_REDIRDEV:
case VIR_DOMAIN_DEVICE_SMARTCARD:
- case VIR_DOMAIN_DEVICE_CHR:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_RNG:
@@ -7603,6 +7606,10 @@ qemuDomainDetachDeviceUnlink(virQEMUDriverPtr driver,
return -1;
} break;
+ case VIR_DOMAIN_DEVICE_CHR:
+ /* No labelling. */
+ break;
+
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LEASE:
case VIR_DOMAIN_DEVICE_FS:
@@ -7616,7 +7623,6 @@ qemuDomainDetachDeviceUnlink(virQEMUDriverPtr driver,
case VIR_DOMAIN_DEVICE_HUB:
case VIR_DOMAIN_DEVICE_REDIRDEV:
case VIR_DOMAIN_DEVICE_SMARTCARD:
- case VIR_DOMAIN_DEVICE_CHR:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_RNG:
@@ -7765,3 +7771,57 @@ qemuDomainNamespaceTeardownHostdev(virQEMUDriverPtr driver,
VIR_FREE(path);
return ret;
}
+
+
+int
+qemuDomainNamespaceSetupChardev(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainChrDefPtr chr)
+{
+ virDomainDeviceDef dev = {.type = VIR_DOMAIN_DEVICE_CHR, .data.chr = chr};
+ const char *path;
+ int ret = -1;
+
+ if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
+ return 0;
+
+ if (chr->source->type != VIR_DOMAIN_CHR_TYPE_DEV)
+ return 0;
+
+ path = chr->source->data.file.path;
+
+ if (qemuDomainAttachDeviceMknod(driver,
+ vm,
+ &dev,
+ path) < 0)
+ goto cleanup;
+ ret = 0;
+ cleanup:
+ return ret;
+}
+
+
+int
+qemuDomainNamespaceTeardownChardev(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainChrDefPtr chr)
+{
+ virDomainDeviceDef dev = {.type = VIR_DOMAIN_DEVICE_CHR, .data.chr = chr};
+ int ret = -1;
+ const char *path = NULL;
+
+ if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
+ return 0;
+
+ if (chr->source->type != VIR_DOMAIN_CHR_TYPE_DEV)
+ return 0;
+
+ path = chr->source->data.file.path;
+
+ if (qemuDomainDetachDeviceUnlink(driver, vm, &dev, path) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ return ret;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 7a3f31c18..7a774a543 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -821,4 +821,12 @@ int qemuDomainNamespaceSetupHostdev(virQEMUDriverPtr driver,
int qemuDomainNamespaceTeardownHostdev(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainHostdevDefPtr hostdev);
+
+int qemuDomainNamespaceSetupChardev(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainChrDefPtr chr);
+
+int qemuDomainNamespaceTeardownChardev(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainChrDefPtr chr);
#endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 09aca03e0..8b41edc56 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1851,6 +1851,7 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
bool chardevAttached = false;
bool tlsobjAdded = false;
bool teardowncgroup = false;
+ bool teardowndevice = false;
bool secobjAdded = false;
virJSONValuePtr tlsProps = NULL;
char *tlsAlias = NULL;
@@ -1872,6 +1873,10 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
if (rc == 1)
need_release = true;
+ if (qemuDomainNamespaceSetupChardev(driver, vm, chr) < 0)
+ goto cleanup;
+ teardowndevice = true;
+
if (qemuSetupChardevCgroup(vm, chr) < 0)
goto cleanup;
teardowncgroup = true;
@@ -1935,6 +1940,8 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL);
if (teardowncgroup && qemuTeardownChardevCgroup(vm, chr) < 0)
VIR_WARN("Unable to remove chr device cgroup ACL on hotplug
fail");
+ if (teardowndevice && qemuDomainNamespaceTeardownChardev(driver, vm, chr)
< 0)
+ VIR_WARN("Unable to remove chr device from /dev");
}
VIR_FREE(tlsAlias);
virJSONValueFree(tlsProps);
@@ -4021,6 +4028,9 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
if (qemuTeardownChardevCgroup(vm, chr) < 0)
VIR_WARN("Failed to remove chr device cgroup ACL");
+ if (qemuDomainNamespaceTeardownChardev(driver, vm, chr) < 0)
+ VIR_WARN("Unable to remove chr device from /dev");
+
event = virDomainEventDeviceRemovedNewFromObj(vm, chr->info.alias);
qemuDomainEventQueue(driver, event);
--
2.11.0