[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCHv4 51/51] snapshot: use SELinux and lock manager with external snapshots



With this, it is now possible to create external snapshots even
when SELinux is enforcing, and to protect the new file with a
lock manager.

* src/qemu/qemu_driver.c
(qemuDomainSnapshotCreateSingleDiskActive): Create and register
new file with proper permissions and locks.
(qemuDomainSnapshotCreateDiskActive): Update caller.
---
 src/qemu/qemu_driver.c |   46 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4862c95..09d6542 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -87,6 +87,7 @@
 #include "configmake.h"
 #include "threadpool.h"
 #include "locking/lock_manager.h"
+#include "locking/domain_lock.h"
 #include "virkeycode.h"

 #define VIR_FROM_THIS VIR_FROM_QEMU
@@ -8839,7 +8840,8 @@ cleanup:

 /* The domain is expected to hold monitor lock.  */
 static int
-qemuDomainSnapshotCreateSingleDiskActive(virDomainObjPtr vm,
+qemuDomainSnapshotCreateSingleDiskActive(struct qemud_driver *driver,
+                                         virDomainObjPtr vm,
                                          virDomainSnapshotDiskDefPtr snap,
                                          virDomainDiskDefPtr disk)
 {
@@ -8848,6 +8850,10 @@ qemuDomainSnapshotCreateSingleDiskActive(virDomainObjPtr vm,
     char *source = NULL;
     char *driverType = NULL;
     int ret = -1;
+    int fd = -1;
+    char *origsrc = NULL;
+    char *origdriver = NULL;
+    bool need_unlink = false;

     if (snap->snapshot != VIR_DOMAIN_DISK_SNAPSHOT_EXTERNAL) {
         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -8863,7 +8869,35 @@ qemuDomainSnapshotCreateSingleDiskActive(virDomainObjPtr vm,
         goto cleanup;
     }

-    /* XXX create new file and set selinux labels */
+    /* create the stub file and set selinux labels; manipulate disk in
+     * place, in a way that can be reverted on failure. */
+    fd = qemuOpenFile(driver, source, O_WRONLY | O_TRUNC | O_CREAT,
+                      &need_unlink, NULL);
+    if (fd < 0)
+        goto cleanup;
+    VIR_FORCE_CLOSE(fd);
+
+    origsrc = disk->src;
+    disk->src = source;
+    origdriver = disk->driverType;
+    disk->driverType = driverType;
+
+    if (virDomainLockDiskAttach(driver->lockManager, vm, disk) < 0)
+        goto cleanup;
+    if (virSecurityManagerSetImageLabel(driver->securityManager, vm,
+                                        disk) < 0) {
+        if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
+            VIR_WARN("Unable to release lock on %s", source);
+        goto cleanup;
+    }
+    need_unlink = false;
+
+    disk->src = origsrc;
+    origsrc = NULL;
+    disk->driverType = origdriver;
+    origdriver = NULL;
+
+    /* create the actual snapshot */
     ret = qemuMonitorDiskSnapshot(priv->mon, device, source);
     virDomainAuditDisk(vm, disk->src, source, "snapshot", ret >= 0);
     if (ret < 0)
@@ -8883,6 +8917,12 @@ qemuDomainSnapshotCreateSingleDiskActive(virDomainObjPtr vm,
      * configuration changes awaiting the next boot?  */

 cleanup:
+    if (origsrc) {
+        disk->src = origsrc;
+        disk->driverType = origdriver;
+    }
+    if (need_unlink && unlink(source))
+        VIR_WARN("unable to unlink just-created %s", source);
     VIR_FREE(device);
     VIR_FREE(source);
     VIR_FREE(driverType);
@@ -8934,7 +8974,7 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
         if (snap->def->disks[i].snapshot == VIR_DOMAIN_DISK_SNAPSHOT_NO)
             continue;

-        ret = qemuDomainSnapshotCreateSingleDiskActive(vm,
+        ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm,
                                                        &snap->def->disks[i],
                                                        vm->def->disks[i]);
         if (ret < 0)
-- 
1.7.4.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]