[libvirt] [PATCH 3/4] qemu driver implementation

Hong Xiang hxiang at linux.vnet.ibm.com
Thu Nov 3 10:23:36 UTC 2011


* src/qemu/qemu_conf.h: qemud_driver data structure extension.
* src/qemu/qemu_driver.c: qemu driver API extension.

Signed-off-by: Hong Xiang <hxiang at linux.vnet.ibm.com>
---
 src/qemu/qemu_conf.h   |    2 +
 src/qemu/qemu_driver.c |  176 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 176 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index ff5cf23..56e9972 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -138,6 +138,8 @@ struct qemud_driver {
      * of guests which will be automatically killed
      * when the virConnectPtr is closed*/
     virHashTablePtr autodestroy;
+
+    char *managedCoreDumpDir;
 };
 
 typedef struct _qemuDomainCmdlineDef qemuDomainCmdlineDef;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5e49ff4..cccfc92 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -472,6 +472,9 @@ qemudStartup(int privileged) {
         if (virAsprintf(&qemu_driver->autoDumpPath,
                         "%s/lib/libvirt/qemu/dump", LOCALSTATEDIR) == -1)
             goto out_of_memory;
+        if (virAsprintf(&qemu_driver->managedCoreDumpDir,
+                        "%s/lib/libvirt/qemu/managed-core-dump", LOCALSTATEDIR) == -1)
+            goto out_of_memory;
     } else {
         uid_t uid = geteuid();
         char *userdir = virGetUserDirectory(uid);
@@ -502,6 +505,9 @@ qemudStartup(int privileged) {
             goto out_of_memory;
         if (virAsprintf(&qemu_driver->autoDumpPath, "%s/qemu/dump", base) == -1)
             goto out_of_memory;
+        if (virAsprintf(&qemu_driver->managedCoreDumpDir,
+                        "%s/lib/libvirt/qemu/managed-core-dump", base) == -1)
+            goto out_of_memory;
     }
 
     if (virFileMakePath(qemu_driver->stateDir) < 0) {
@@ -540,6 +546,13 @@ qemudStartup(int privileged) {
                   qemu_driver->autoDumpPath, virStrerror(errno, ebuf, sizeof ebuf));
         goto error;
     }
+    if (virFileMakePath(qemu_driver->managedCoreDumpDir) < 0) {
+        char ebuf[1024];
+        VIR_ERROR(_("Failed to create managed-core-dump dir '%s': %s"),
+                  qemu_driver->managedCoreDumpDir,
+                  virStrerror(errno, ebuf, sizeof ebuf));
+        goto error;
+    }
 
     /* Configuration paths are either ~/.libvirt/qemu/... (session) or
      * /etc/libvirt/qemu/... (system).
@@ -606,6 +619,13 @@ qemudStartup(int privileged) {
                                  qemu_driver->snapshotDir, qemu_driver->user, qemu_driver->group);
             goto error;
         }
+        if (chown(qemu_driver->managedCoreDumpDir, qemu_driver->user, qemu_driver->group) < 0) {
+            virReportSystemError(errno,
+                                 _("unable to set ownership of '%s' to %d:%d"),
+                                 qemu_driver->managedCoreDumpDir,
+                                 qemu_driver->user, qemu_driver->group);
+            goto error;
+        }
     }
 
     /* If hugetlbfs is present, then we need to create a sub-directory within
@@ -801,6 +821,7 @@ qemudShutdown(void) {
     VIR_FREE(qemu_driver->hugepage_path);
     VIR_FREE(qemu_driver->saveImageFormat);
     VIR_FREE(qemu_driver->dumpImageFormat);
+    VIR_FREE(qemu_driver->managedCoreDumpDir);
 
     virSecurityManagerFree(qemu_driver->securityManager);
 
@@ -2843,6 +2864,19 @@ cleanup:
     return ret;
 }
 
+static char *
+qemuDomainManagedCoreDumpPath(struct qemud_driver *driver, virDomainObjPtr vm) {
+    char *ret;
+
+    if (virAsprintf(&ret, "%s/%s.core", driver->managedCoreDumpDir,
+                    vm->def->name) < 0) {
+        virReportOOMError();
+        return(NULL);
+    }
+
+    return(ret);
+}
+
 static int
 doCoreDump(struct qemud_driver *driver,
            virDomainObjPtr vm,
@@ -2928,7 +2962,7 @@ getCompressionType(struct qemud_driver *driver)
     return compress;
 }
 
-static int qemudDomainCoreDump(virDomainPtr dom,
+static int qemudDomainCoreDumpInternal(virDomainPtr dom,
                                const char *path,
                                unsigned int flags)
 {
@@ -2938,6 +2972,7 @@ static int qemudDomainCoreDump(virDomainPtr dom,
     int resume = 0, paused = 0;
     int ret = -1;
     virDomainEventPtr event = NULL;
+    char * real_path = NULL;
 
     virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
                   VIR_DUMP_BYPASS_CACHE | VIR_DUMP_RESET, -1);
@@ -2952,6 +2987,13 @@ static int qemudDomainCoreDump(virDomainPtr dom,
                         _("no domain with matching uuid '%s'"), uuidstr);
         goto cleanup;
     }
+    if (NULL == path) {
+        real_path = qemuDomainManagedCoreDumpPath(driver, vm);
+        if(NULL == real_path)
+            goto cleanup;
+    } else {
+        real_path = (char *)path;
+    }
 
     if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm,
                                              QEMU_ASYNC_JOB_DUMP) < 0)
@@ -2982,7 +3024,7 @@ static int qemudDomainCoreDump(virDomainPtr dom,
         }
     }
 
-    ret = doCoreDump(driver, vm, path, getCompressionType(driver),
+    ret = doCoreDump(driver, vm, real_path, getCompressionType(driver),
                      (flags & VIR_DUMP_BYPASS_CACHE) != 0);
     if (ret < 0)
         goto endjob;
@@ -3027,6 +3069,8 @@ endjob:
     }
 
 cleanup:
+    if(NULL == path)
+        VIR_FREE(real_path);
     if (vm)
         virDomainObjUnlock(vm);
     if (event)
@@ -3035,6 +3079,130 @@ cleanup:
     return ret;
 }
 
+static int qemudDomainCoreDump(virDomainPtr dom,
+                               const char *path,
+                               unsigned int flags)
+{
+    return qemudDomainCoreDumpInternal(dom, path, flags);
+}
+
+static int
+qemuDomainManagedCoreDump(virDomainPtr dom, unsigned int flags)
+{
+    return qemudDomainCoreDumpInternal(dom, NULL, flags);
+}
+
+static int
+qemuDomainHasManagedCoreDump(virDomainPtr dom, unsigned int flags)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    virDomainObjPtr vm = NULL;
+    int ret = -1;
+    char *name = NULL;
+
+    virCheckFlags(0, -1);
+
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(dom->uuid, uuidstr);
+        qemuReportError(VIR_ERR_NO_DOMAIN,
+                        _("no domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    name = qemuDomainManagedCoreDumpPath(driver, vm);
+    if (name == NULL)
+        goto cleanup;
+
+    ret = virFileExists(name);
+
+cleanup:
+    VIR_FREE(name);
+    if (vm)
+        virDomainObjUnlock(vm);
+    qemuDriverUnlock(driver);
+    return ret;
+}
+
+static int
+qemuDomainManagedCoreDumpRemove(virDomainPtr dom, unsigned int flags)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    virDomainObjPtr vm = NULL;
+    int ret = -1;
+    char *name = NULL;
+
+    virCheckFlags(0, -1);
+
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(dom->uuid, uuidstr);
+        qemuReportError(VIR_ERR_NO_DOMAIN,
+                        _("no domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    name = qemuDomainManagedCoreDumpPath(driver, vm);
+    if (name == NULL)
+        goto cleanup;
+
+    ret = unlink(name);
+
+cleanup:
+    VIR_FREE(name);
+    if (vm)
+        virDomainObjUnlock(vm);
+    qemuDriverUnlock(driver);
+    return ret;
+}
+
+static int
+qemuDomainManagedCoreDumpDownload(virDomainPtr dom,
+                     virStreamPtr st,
+                     unsigned int flags)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    virDomainObjPtr vm;
+    int ret = -1;
+    char *name = NULL;
+
+    virCheckFlags(0, -1);
+
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(dom->uuid, uuidstr);
+        qemuReportError(VIR_ERR_NO_DOMAIN,
+                        _("no domain matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    name = qemuDomainManagedCoreDumpPath(driver, vm);
+    if (NULL == name)
+        goto cleanup;
+
+    if (virFDStreamOpenFile(st, name, 0, 0, O_RDONLY) < 0) {
+        qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                        _("unable to open stream"));
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(name);
+    if (vm)
+        virDomainObjUnlock(vm);
+    qemuDriverUnlock(driver);
+    return ret;
+}
+
 static char *
 qemuDomainScreenshot(virDomainPtr dom,
                      virStreamPtr st,
@@ -10904,6 +11072,10 @@ static virDriver qemuDriver = {
     .domainGetBlockJobInfo = qemuDomainGetBlockJobInfo, /* 0.9.4 */
     .domainBlockJobSetSpeed = qemuDomainBlockJobSetSpeed, /* 0.9.4 */
     .domainBlockPull = qemuDomainBlockPull, /* 0.9.4 */
+    .domainManagedCoreDump = qemuDomainManagedCoreDump, /* 0.9.8 */
+    .domainHasManagedCoreDump = qemuDomainHasManagedCoreDump, /* 0.9.8 */
+    .domainManagedCoreDumpRemove = qemuDomainManagedCoreDumpRemove, /* 0.9.8 */
+    .domainManagedCoreDumpDownload = qemuDomainManagedCoreDumpDownload, /* 0.9.8 */
 };
 
 
-- 
1.7.1




More information about the libvir-list mailing list