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

[Libvir] [PATCH] Implement memory operations for qemu driver



The attached patch implements the following operations for the qemu driver:

virDomainGetMaxMemory
virDomainSetMaxMemory
virDomainSetMemory

A few questions/comments:

1) I changed maxmem and memory in the qemu_vm_def struct to unsigned long
   to match the public api for memory values. Seems to work, but not sure
   if there are any undesirable side effects to this.

2) Should SetMaxMem be able to be called on a running guest? This code
   allows it, since maxmem is basically a metavalue that doesn't directly
   affect a guest.

3) Should maxmem be able to be set lower than the currently allocated mem?
   This code does not allow this. If this changed, would also need to take
   into account how we would handle this if we can change the maxmem while
   the guest is running. After rethinking, we probably should be able to
   do this, but I haven't changed the code.

Thanks,
Cole

diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index a196bb8..f6ae06b 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -1650,7 +1650,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
          (vm->def->graphicsType == QEMUD_GRAPHICS_SDL ? 0 : 1)) + /* graphics */
         (vm->migrateFrom[0] ? 3 : 0); /* migrateFrom */
 
-    snprintf(memory, sizeof(memory), "%d", vm->def->memory/1024);
+    snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
     snprintf(vcpus, sizeof(vcpus), "%d", vm->def->vcpus);
 
     if (!(*argv = malloc(sizeof(**argv) * (len+1))))
@@ -2820,9 +2820,9 @@ char *qemudGenerateXML(virConnectPtr conn,
     virUUIDFormat(uuid, uuidstr);
     if (virBufferVSprintf(buf, "  <uuid>%s</uuid>\n", uuidstr) < 0)
         goto no_memory;
-    if (virBufferVSprintf(buf, "  <memory>%d</memory>\n", def->maxmem) < 0)
+    if (virBufferVSprintf(buf, "  <memory>%lu</memory>\n", def->maxmem) < 0)
         goto no_memory;
-    if (virBufferVSprintf(buf, "  <currentMemory>%d</currentMemory>\n", def->memory) < 0)
+    if (virBufferVSprintf(buf, "  <currentMemory>%lu</currentMemory>\n", def->memory) < 0)
         goto no_memory;
     if (virBufferVSprintf(buf, "  <vcpu>%d</vcpu>\n", def->vcpus) < 0)
         goto no_memory;
diff --git a/src/qemu_conf.h b/src/qemu_conf.h
index 12aa6ae..c1aae75 100644
--- a/src/qemu_conf.h
+++ b/src/qemu_conf.h
@@ -193,8 +193,8 @@ struct qemud_vm_def {
     unsigned char uuid[VIR_UUID_BUFLEN];
     char name[QEMUD_MAX_NAME_LEN];
 
-    int memory;
-    int maxmem;
+    unsigned long memory;
+    unsigned long maxmem;
     int vcpus;
 
     int noReboot;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 2b4c2a6..215f4c4 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1765,6 +1765,66 @@ static char *qemudDomainGetOSType(virDomainPtr dom) {
     return type;
 }
 
+/* Returns max memory in kb, 0 if error */
+static unsigned long qemudDomainGetMaxMemory(virDomainPtr dom) {
+    struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
+    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+
+    if (!vm) {
+        qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+                         "no domain with matching uuid '%s'", dom->uuid);
+        return 0;
+    }
+
+    return vm->def->maxmem;
+}
+
+static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long memory) {
+    struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
+    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+
+    if (!vm) {
+        qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+                         "no domain with matching uuid '%s'", dom->uuid);
+        return -1;
+    }
+
+    if (memory < vm->def->maxmem) {
+        qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
+                         "cannot set max memory lower than current memory");
+        return -1;
+    }
+
+    vm->def->maxmem = memory;
+    return 0;
+}
+
+static int qemudDomainSetMemory(virDomainPtr dom, unsigned long memory) {
+    struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
+    struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
+
+    if (!vm) {
+        qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+                         "no domain with matching uuid '%s'", dom->uuid);
+        return -1;
+    }
+
+    if (qemudIsActiveVM(vm)) {
+        qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+                         "cannot set memory of an active domain");
+        return -1;
+    }
+
+    if (memory > vm->def->maxmem) {
+        qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
+                         "cannot set memory higher than max memory");
+        return -1;
+    }
+
+    vm->def->memory = memory;
+    return 0;
+}
+
 static int qemudDomainGetInfo(virDomainPtr dom,
                        virDomainInfoPtr info) {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
@@ -2886,9 +2946,9 @@ static virDriver qemuDriver = {
     NULL, /* domainReboot */
     qemudDomainDestroy, /* domainDestroy */
     qemudDomainGetOSType, /* domainGetOSType */
-    NULL, /* domainGetMaxMemory */
-    NULL, /* domainSetMaxMemory */
-    NULL, /* domainSetMemory */
+    qemudDomainGetMaxMemory, /* domainGetMaxMemory */
+    qemudDomainSetMaxMemory, /* domainSetMaxMemory */
+    qemudDomainSetMemory, /* domainSetMemory */
     qemudDomainGetInfo, /* domainGetInfo */
     qemudDomainSave, /* domainSave */
     qemudDomainRestore, /* domainRestore */

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