]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu_hotplug: Relabel memdev
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 4 Aug 2016 13:26:09 +0000 (15:26 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 15 Mar 2017 15:55:23 +0000 (16:55 +0100)
Now that we have APIs for relabel memdevs on hotplug, fill in the
missing implementation in qemu hotplug code.

The qemuSecurity wrappers might look like overkill for now,
because qemu namespace code does not deal with the nvdimms yet.
Nor does our cgroup code.  But hey, there's cgroup_device_acl
variable in qemu.conf. If users add their /dev/pmem* device in
there, the device is allowed in cgroups and created in the
namespace so they can successfully passthrough it to the domain.
It doesn't look like overkill after all, does it?

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_hotplug.c
src/qemu/qemu_security.c
src/qemu/qemu_security.h

index b50f44cf347d9d32c4afe39247cbfe1de5d94499..20bdeada6f0c1094669924abe2b664b76ee899d1 100644 (file)
@@ -2215,6 +2215,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     char *objalias = NULL;
     const char *backendType;
     bool objAdded = false;
+    bool teardownlabel = false;
     virJSONValuePtr props = NULL;
     virObjectEventPtr event;
     int id;
@@ -2244,15 +2245,15 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
                                   priv->qemuCaps, vm->def, mem, NULL, true) < 0)
         goto cleanup;
 
-    if (virDomainMemoryInsert(vm->def, mem) < 0) {
-        virJSONValueFree(props);
+    if (qemuSecuritySetMemoryLabel(driver, vm, mem) < 0)
         goto cleanup;
-    }
+    teardownlabel = true;
 
-    if (qemuDomainAdjustMaxMemLock(vm) < 0) {
-        virJSONValueFree(props);
+    if (virDomainMemoryInsert(vm->def, mem) < 0)
+        goto cleanup;
+
+    if (qemuDomainAdjustMaxMemLock(vm) < 0)
         goto removedef;
-    }
 
     qemuDomainObjEnterMonitor(driver, vm);
     rv = qemuMonitorAddObject(priv->mon, backendType, objalias, props);
@@ -2288,6 +2289,12 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
  audit:
     virDomainAuditMemory(vm, oldmem, newmem, "update", ret == 0);
  cleanup:
+    if (mem && ret < 0) {
+        if (teardownlabel && qemuSecurityRestoreMemoryLabel(driver, vm, mem) < 0)
+            VIR_WARN("Unable to restore security label on memdev");
+    }
+
+    virJSONValueFree(props);
     virObjectUnref(cfg);
     VIR_FREE(devstr);
     VIR_FREE(objalias);
@@ -3748,6 +3755,9 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
     if ((idx = virDomainMemoryFindByDef(vm->def, mem)) >= 0)
         virDomainMemoryRemove(vm->def, idx);
 
+    if (qemuSecurityRestoreMemoryLabel(driver, vm, mem) < 0)
+        VIR_WARN("Unable to restore security label on memdev");
+
     virDomainMemoryDefFree(mem);
 
     /* fix the balloon size */
index f2931976b55d437215e6073b0eb8ef1fd561319c..61934f9905b218f334371401829e9a55a4f7b728 100644 (file)
@@ -245,3 +245,59 @@ qemuSecurityRestoreHostdevLabel(virQEMUDriverPtr driver,
     virSecurityManagerTransactionAbort(driver->securityManager);
     return ret;
 }
+
+
+int
+qemuSecuritySetMemoryLabel(virQEMUDriverPtr driver,
+                           virDomainObjPtr vm,
+                           virDomainMemoryDefPtr mem)
+{
+    int ret = -1;
+
+    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
+        virSecurityManagerTransactionStart(driver->securityManager) < 0)
+        goto cleanup;
+
+    if (virSecurityManagerSetMemoryLabel(driver->securityManager,
+                                         vm->def,
+                                         mem) < 0)
+        goto cleanup;
+
+    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
+        virSecurityManagerTransactionCommit(driver->securityManager,
+                                            vm->pid) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    virSecurityManagerTransactionAbort(driver->securityManager);
+    return ret;
+}
+
+
+int
+qemuSecurityRestoreMemoryLabel(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               virDomainMemoryDefPtr mem)
+{
+    int ret = -1;
+
+    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
+        virSecurityManagerTransactionStart(driver->securityManager) < 0)
+        goto cleanup;
+
+    if (virSecurityManagerRestoreMemoryLabel(driver->securityManager,
+                                             vm->def,
+                                             mem) < 0)
+        goto cleanup;
+
+    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
+        virSecurityManagerTransactionCommit(driver->securityManager,
+                                            vm->pid) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    virSecurityManagerTransactionAbort(driver->securityManager);
+    return ret;
+}
index d86db3f6b83339179413a4d976a3993a862920e9..7b25855bf98594fb390c43ccedecb32abb951a47 100644 (file)
@@ -62,6 +62,14 @@ int qemuSecurityRestoreHostdevLabel(virQEMUDriverPtr driver,
                                     virDomainObjPtr vm,
                                     virDomainHostdevDefPtr hostdev);
 
+int qemuSecuritySetMemoryLabel(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               virDomainMemoryDefPtr mem);
+
+int qemuSecurityRestoreMemoryLabel(virQEMUDriverPtr driver,
+                                   virDomainObjPtr vm,
+                                   virDomainMemoryDefPtr mem);
+
 /* Please note that for these APIs there is no wrapper yet. Do NOT blindly add
  * new APIs here. If an API can touch a /dev file add a proper wrapper instead.
  */