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

[libvirt] [PATCH 5/6] unpriv_sgio: Do not restore unpriv_sgio if the disk is being used



This prevents restoring the unpriv_sgio if the disk is shared,
and is being used by other active domain. Because we don't want
to fall into the corruption situation.

* src/conf/domain_conf.h (Declare virDomainDiskIsUsed, which is to
                          detect if a disk is using by domain)
* src/conf/domain_conf.c (Implement virDomainDiskIsUsed)
* src/libvirt_private.syms: (Export virDomainDIskIsUsed)
* src/qemu/qemu_process.c (Don't restore unpriv_sgio if the disk
                           is shared, and is being used by other
                           active domain).
---
 src/conf/domain_conf.c   |   66 ++++++++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h   |    4 +++
 src/libvirt_private.syms |    1 +
 src/qemu/qemu_process.c  |   11 +++++++
 4 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b25229a..02df96e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -15697,3 +15697,69 @@ virDomainDefAddSecurityLabelDef(virDomainDefPtr def, const char *model)
 
     return seclabel;
 }
+
+struct virDomainDiskIsUsedData {
+    char *diskSrc;
+    char *name; /* Want to exclude some domain? */
+    bool active; /* Want to only iterate the active domains? */
+};
+
+static int
+virDomainObjListSearchDiskPath(const void *payload,
+                               const void *name ATTRIBUTE_UNUSED,
+                               const void *opaque)
+{
+    virDomainObjPtr obj = (virDomainObjPtr)payload;
+    const struct virDomainDiskIsUsedData *data = opaque;
+    int i;
+    int ret = 0;
+
+    virDomainObjLock(obj);
+
+    if (data->active &&
+        !virDomainObjIsActive(obj))
+        goto cleanup;
+
+    if (data->name &&
+        STREQ(data->name, obj->def->name))
+        goto cleanup;
+
+    for (i = 0; i < obj->def->ndisks; i++) {
+        virDomainDiskDefPtr disk = obj->def->disks[i];
+
+        if (STREQ(disk->src, data->diskSrc)) {
+            ret = 1;
+            goto cleanup;
+        }
+    }
+
+cleanup:
+    virDomainObjUnlock(obj);
+    return ret;
+}
+
+/**
+ * virDomainDiskIsUsed:
+ * @doms: List of domain objects
+ * @name: The domain name want to exclude
+ * @diskSrc: The disk path
+ * @active: Whether to exclude inactive domains
+ *
+ * Returns true if the disk is being used. Otherwise returns false.
+ */
+bool
+virDomainDiskIsUsed(const virDomainObjList doms,
+                    char *name,
+                    char *diskSrc,
+                    bool active)
+{
+    virDomainObjPtr obj;
+
+    struct virDomainDiskIsUsedData data = { diskSrc, name, active };
+
+    obj = virHashSearch(doms.objs, virDomainObjListSearchDiskPath, &data);
+    if (obj)
+        return true;
+
+    return false;
+}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1a8de71..3105e05 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1874,6 +1874,10 @@ virDomainObjPtr virDomainFindByUUID(const virDomainObjListPtr doms,
                                     const unsigned char *uuid);
 virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms,
                                     const char *name);
+bool virDomainDiskIsUsed(const virDomainObjList doms,
+                         char *name,
+                         char *diskSrc,
+                         bool active);
 
 bool virDomainObjTaint(virDomainObjPtr obj,
                        enum virDomainTaintFlags taint);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c756130..b9019b7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -319,6 +319,7 @@ virDomainDefFormatInternal;
 virDomainDefFree;
 virDomainDefGetSecurityLabelDef;
 virDomainDiskDefGetSecurityLabelDef;
+virDomainDiskIsUsed;
 virDomainDefAddSecurityLabelDef;
 virDomainDefParseFile;
 virDomainDefParseNode;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e48eed0..eeaaea0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4120,6 +4120,17 @@ void qemuProcessStop(struct qemud_driver *driver,
         if (!disk->unpriv_sgio)
             continue;
 
+        /* Don't try to restore the unpriv_sgio if the disk is shared
+         * by other active domain(s). We don't want to fall into the
+         * corruptions.
+         */
+        if (disk->shared &&
+            virDomainDiskIsUsed(driver->domains,
+                                vm->def->name,
+                                disk->src,
+                                true))
+            continue;
+
         if (virSetDeviceUnprivSGIO(disk->src, disk->old_unpriv_sgio) < 0)
             VIR_WARN("Unable to restore unpriv_sgio for disk '%s'", disk->src);
     }
-- 
1.7.7.6


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