[libvirt] [PATCH 0/6] test: Implement GetVcpus and PinVcpu

Using the recently committed support for driver specific domain data blobs[1], carry around VCPU pinning info for running test domains, which enables supporting GetVcpus and PinVcpu, which makes my life easier when adding support in virt-manager. [1] http://libvirt.org/git/?p=libvirt.git;a=commit;h=3505790b85da55c16191a9dca46... Cole Robinson (6): test: Fixes for SetVcpus test: Break out wrapper for setting up started domain state. test: Use privateData to track running VM vcpu state test: Update vcpu runtime info in SetVcpus test: Implement virDomainGetVcpus test: Implement virDomainPinVcpu src/test/test_driver.c | 354 +++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 337 insertions(+), 17 deletions(-)

- Implement DomainGetMaxVCPUs - Use GetMaxVCPUs to validate requested CPU amount - Deny the 'hotplug' for a running domain. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 26 ++++++++++++++++++++++---- 1 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 31b5ad3..2c61cf1 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1801,11 +1801,21 @@ cleanup: return ret; } +static int testDomainGetMaxVcpus(virDomainPtr domain) +{ + return testGetMaxVCPUs(domain->conn, "test"); +} + static int testSetVcpus(virDomainPtr domain, unsigned int nrCpus) { testConnPtr privconn = domain->conn->privateData; virDomainObjPtr privdom; - int ret = -1; + int ret = -1, maxvcpus; + + /* Do this first before locking */ + maxvcpus = testDomainGetMaxVcpus(domain); + if (maxvcpus < 0) + goto cleanup; testDriverLock(privconn); privdom = virDomainFindByName(&privconn->domains, @@ -1817,9 +1827,17 @@ static int testSetVcpus(virDomainPtr domain, goto cleanup; } + if (!virDomainIsActive(privdom)) { + testError(domain->conn, VIR_ERR_OPERATION_INVALID, + "%s", _("cannot hotplug vcpus for an inactive domain")); + goto cleanup; + } + /* We allow more cpus in guest than host */ - if (nrCpus > 32) { - testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + if (nrCpus > maxvcpus) { + testError(domain->conn, VIR_ERR_INVALID_ARG, + "requested cpu amount exceeds maximum (%d > %d)", + nrCpus, maxvcpus); goto cleanup; } @@ -4686,7 +4704,7 @@ static virDriver testDriver = { testSetVcpus, /* domainSetVcpus */ NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ - NULL, /* domainGetMaxVcpus */ + testDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ NULL, /* nodeGetSecurityModel */ testDomainDumpXML, /* domainDumpXML */ -- 1.6.5.1

On Mon, Nov 02, 2009 at 03:02:42PM -0500, Cole Robinson wrote:
- Implement DomainGetMaxVCPUs - Use GetMaxVCPUs to validate requested CPU amount - Deny the 'hotplug' for a running domain.
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 26 ++++++++++++++++++++++---- 1 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 31b5ad3..2c61cf1 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1801,11 +1801,21 @@ cleanup: return ret; }
+static int testDomainGetMaxVcpus(virDomainPtr domain) +{ + return testGetMaxVCPUs(domain->conn, "test"); +} + static int testSetVcpus(virDomainPtr domain, unsigned int nrCpus) { testConnPtr privconn = domain->conn->privateData; virDomainObjPtr privdom; - int ret = -1; + int ret = -1, maxvcpus; + + /* Do this first before locking */ + maxvcpus = testDomainGetMaxVcpus(domain); + if (maxvcpus < 0) + goto cleanup;
testDriverLock(privconn); privdom = virDomainFindByName(&privconn->domains, @@ -1817,9 +1827,17 @@ static int testSetVcpus(virDomainPtr domain, goto cleanup; }
+ if (!virDomainIsActive(privdom)) { + testError(domain->conn, VIR_ERR_OPERATION_INVALID, + "%s", _("cannot hotplug vcpus for an inactive domain")); + goto cleanup; + } + /* We allow more cpus in guest than host */ - if (nrCpus > 32) { - testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + if (nrCpus > maxvcpus) { + testError(domain->conn, VIR_ERR_INVALID_ARG, + "requested cpu amount exceeds maximum (%d > %d)", + nrCpus, maxvcpus); goto cleanup; }
@@ -4686,7 +4704,7 @@ static virDriver testDriver = { testSetVcpus, /* domainSetVcpus */ NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ - NULL, /* domainGetMaxVcpus */ + testDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ NULL, /* nodeGetSecurityModel */ testDomainDumpXML, /* domainDumpXML */
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

This should be a no op for now, but we will use this function to set up transient state in the future. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++---------- 1 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 2c61cf1..8472e27 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -325,6 +325,17 @@ testDomainGenerateIfnames(virConnectPtr conn, return 0; } +static int +testDomainStartState(virConnectPtr conn, + virDomainObjPtr dom) +{ + testConnPtr privconn = conn->privateData; + + dom->state = VIR_DOMAIN_RUNNING; + dom->def->id = privconn->nextDomID++; + + return 0; +} static int testOpenDefault(virConnectPtr conn) { int u; @@ -391,8 +402,12 @@ static int testOpenDefault(virConnectPtr conn) { &privconn->domains, domdef))) goto error; domdef = NULL; - domobj->def->id = privconn->nextDomID++; - domobj->state = VIR_DOMAIN_RUNNING; + + if (testDomainStartState(conn, domobj) < 0) { + virDomainObjUnlock(domobj); + goto error; + } + domobj->persistent = 1; virDomainObjUnlock(domobj); @@ -746,8 +761,11 @@ static int testOpenFromFile(virConnectPtr conn, goto error; } - dom->state = VIR_DOMAIN_RUNNING; - dom->def->id = privconn->nextDomID++; + if (testDomainStartState(conn, dom) < 0) { + virDomainObjUnlock(dom); + goto error; + } + dom->persistent = 1; virDomainObjUnlock(dom); } @@ -1083,8 +1101,9 @@ testDomainCreateXML(virConnectPtr conn, const char *xml, &privconn->domains, def))) goto cleanup; def = NULL; - dom->state = VIR_DOMAIN_RUNNING; - dom->def->id = privconn->nextDomID++; + + if (testDomainStartState(conn, dom) < 0) + goto cleanup; event = virDomainEventNewFromObj(dom, VIR_DOMAIN_EVENT_STARTED, @@ -1633,8 +1652,9 @@ static int testDomainRestore(virConnectPtr conn, goto cleanup; def = NULL; - dom->state = VIR_DOMAIN_RUNNING; - dom->def->id = privconn->nextDomID++; + if (testDomainStartState(conn, dom) < 0) + goto cleanup; + event = virDomainEventNewFromObj(dom, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_RESTORED); @@ -1993,8 +2013,10 @@ static int testDomainCreate(virDomainPtr domain) { goto cleanup; } - domain->id = privdom->def->id = privconn->nextDomID++; - privdom->state = VIR_DOMAIN_RUNNING; + if (testDomainStartState(domain->conn, privdom) < 0) + goto cleanup; + domain->id = privdom->def->id; + event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_BOOTED); -- 1.6.5.1

On Mon, Nov 02, 2009 at 03:02:43PM -0500, Cole Robinson wrote:
This should be a no op for now, but we will use this function to set up transient state in the future.
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 42 ++++++++++++++++++++++++++++++++---------- 1 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 2c61cf1..8472e27 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -325,6 +325,17 @@ testDomainGenerateIfnames(virConnectPtr conn, return 0; }
+static int +testDomainStartState(virConnectPtr conn, + virDomainObjPtr dom) +{ + testConnPtr privconn = conn->privateData; + + dom->state = VIR_DOMAIN_RUNNING; + dom->def->id = privconn->nextDomID++; + + return 0; +}
static int testOpenDefault(virConnectPtr conn) { int u; @@ -391,8 +402,12 @@ static int testOpenDefault(virConnectPtr conn) { &privconn->domains, domdef))) goto error; domdef = NULL; - domobj->def->id = privconn->nextDomID++; - domobj->state = VIR_DOMAIN_RUNNING; + + if (testDomainStartState(conn, domobj) < 0) { + virDomainObjUnlock(domobj); + goto error; + } + domobj->persistent = 1; virDomainObjUnlock(domobj);
@@ -746,8 +761,11 @@ static int testOpenFromFile(virConnectPtr conn, goto error; }
- dom->state = VIR_DOMAIN_RUNNING; - dom->def->id = privconn->nextDomID++; + if (testDomainStartState(conn, dom) < 0) { + virDomainObjUnlock(dom); + goto error; + } + dom->persistent = 1; virDomainObjUnlock(dom); } @@ -1083,8 +1101,9 @@ testDomainCreateXML(virConnectPtr conn, const char *xml, &privconn->domains, def))) goto cleanup; def = NULL; - dom->state = VIR_DOMAIN_RUNNING; - dom->def->id = privconn->nextDomID++; + + if (testDomainStartState(conn, dom) < 0) + goto cleanup;
event = virDomainEventNewFromObj(dom, VIR_DOMAIN_EVENT_STARTED, @@ -1633,8 +1652,9 @@ static int testDomainRestore(virConnectPtr conn, goto cleanup; def = NULL;
- dom->state = VIR_DOMAIN_RUNNING; - dom->def->id = privconn->nextDomID++; + if (testDomainStartState(conn, dom) < 0) + goto cleanup; + event = virDomainEventNewFromObj(dom, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_RESTORED); @@ -1993,8 +2013,10 @@ static int testDomainCreate(virDomainPtr domain) { goto cleanup; }
- domain->id = privdom->def->id = privconn->nextDomID++; - privdom->state = VIR_DOMAIN_RUNNING; + if (testDomainStartState(domain->conn, privdom) < 0) + goto cleanup; + domain->id = privdom->def->id; + event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED_BOOTED);
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 133 insertions(+), 2 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 8472e27..a8bec58 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -53,6 +53,15 @@ #define VIR_FROM_THIS VIR_FROM_TEST +/* Driver specific info to carry with a domain */ +struct _testDomainObjPrivate { + virVcpuInfoPtr vcpu_infos; + + unsigned char *cpumaps; +}; +typedef struct _testDomainObjPrivate testDomainObjPrivate; +typedef struct _testDomainObjPrivate *testDomainObjPrivatePtr; + #define MAX_CPUS 128 struct _testCell { @@ -126,6 +135,24 @@ static void testDriverUnlock(testConnPtr driver) virMutexUnlock(&driver->lock); } +static void *testDomainObjPrivateAlloc(void) +{ + testDomainObjPrivatePtr priv; + + if (VIR_ALLOC(priv) < 0) + return NULL; + + return priv; +} + +static void testDomainObjPrivateFree(void *data) +{ + testDomainObjPrivatePtr priv = data; + + VIR_FREE(priv); +} + + static virCapsPtr testBuildCapabilities(virConnectPtr conn) { testConnPtr privconn = conn->privateData; @@ -173,6 +200,9 @@ testBuildCapabilities(virConnectPtr conn) { goto no_memory; } + caps->privateDataAllocFunc = testDomainObjPrivateAlloc; + caps->privateDataFreeFunc = testDomainObjPrivateFree; + return caps; no_memory: @@ -269,7 +299,9 @@ static const char *defaultNodeXML = static const unsigned long long defaultPoolCap = (100 * 1024 * 1024 * 1024ull); static const unsigned long long defaultPoolAlloc = 0; -static int testStoragePoolObjSetDefaults(virConnectPtr conn, virStoragePoolObjPtr pool); +static int testStoragePoolObjSetDefaults(virConnectPtr conn, + virStoragePoolObjPtr pool); +static int testNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info); static char * testDomainGenerateIfname(virConnectPtr conn, @@ -325,16 +357,115 @@ testDomainGenerateIfnames(virConnectPtr conn, return 0; } +/* Helper to update info for a single VCPU */ +static int +testDomainUpdateVCPU(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainObjPtr dom, + int vcpu, + int maplen, + int maxcpu) +{ + testDomainObjPrivatePtr privdata = dom->privateData; + virVcpuInfoPtr info = &privdata->vcpu_infos[vcpu]; + unsigned char *cpumap = VIR_GET_CPUMAP(privdata->cpumaps, maplen, vcpu); + int j; + + memset(info, 0, sizeof(virVcpuInfo)); + memset(cpumap, 0, maplen); + + info->number = vcpu; + info->state = VIR_VCPU_RUNNING; + info->cpuTime = 5000000; + info->cpu = 0; + + if (dom->def->cpumask) { + for (j = 0; j < maxcpu && j < VIR_DOMAIN_CPUMASK_LEN; ++j) { + if (dom->def->cpumask[j]) { + VIR_USE_CPU(cpumap, j); + info->cpu = j; + } + } + } else { + for (j = 0; j < maxcpu; ++j) { + if ((j % 3) == 0) { + /* Mark of every third CPU as usable */ + VIR_USE_CPU(cpumap, j); + info->cpu = j; + } + } + } + + return 0; +} + +/* + * Update domain VCPU amount and info + * + * @conn: virConnectPtr + * @dom : domain needing updates + * @nvcpus: New amount of vcpus for the domain + * @clear_all: If true, rebuild info for ALL vcpus, not just newly added vcpus + */ +static int +testDomainUpdateVCPUs(virConnectPtr conn, + virDomainObjPtr dom, + int nvcpus, + unsigned int clear_all) +{ + testConnPtr privconn = conn->privateData; + testDomainObjPrivatePtr privdata = dom->privateData; + int i, ret = -1; + int cpumaplen, maxcpu; + + maxcpu = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo); + cpumaplen = VIR_CPU_MAPLEN(maxcpu); + + if (VIR_REALLOC_N(privdata->vcpu_infos, nvcpus) < 0) { + virReportOOMError(conn); + goto cleanup; + } + + if (VIR_REALLOC_N(privdata->cpumaps, nvcpus * cpumaplen) < 0) { + virReportOOMError(conn); + goto cleanup; + } + + /* Set running VCPU and cpumap state */ + if (clear_all) { + for (i = 0; i < nvcpus; ++i) + if (testDomainUpdateVCPU(conn, dom, i, cpumaplen, maxcpu) < 0) + goto cleanup; + + } else if (nvcpus > dom->def->vcpus) { + /* VCPU amount has grown, populate info for the new vcpus */ + for (i = dom->def->vcpus; i < nvcpus; ++i) + if (testDomainUpdateVCPU(conn, dom, i, cpumaplen, maxcpu) < 0) + goto cleanup; + } + + ret = 0; +cleanup: + return ret; +} + +/* Set up domain runtime state */ static int testDomainStartState(virConnectPtr conn, virDomainObjPtr dom) { testConnPtr privconn = conn->privateData; + int ret = -1; + + if (testDomainUpdateVCPUs(conn, dom, dom->def->vcpus, 1) < 0) + goto cleanup; + /* Set typical run state */ dom->state = VIR_DOMAIN_RUNNING; dom->def->id = privconn->nextDomID++; - return 0; + ret = 0; +cleanup: + return ret; } static int testOpenDefault(virConnectPtr conn) { -- 1.6.5.1

On Mon, Nov 02, 2009 at 03:02:44PM -0500, Cole Robinson wrote:
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 133 insertions(+), 2 deletions(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 8472e27..a8bec58 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -53,6 +53,15 @@
#define VIR_FROM_THIS VIR_FROM_TEST
+/* Driver specific info to carry with a domain */ +struct _testDomainObjPrivate { + virVcpuInfoPtr vcpu_infos; + + unsigned char *cpumaps; +}; +typedef struct _testDomainObjPrivate testDomainObjPrivate; +typedef struct _testDomainObjPrivate *testDomainObjPrivatePtr; + #define MAX_CPUS 128
struct _testCell { @@ -126,6 +135,24 @@ static void testDriverUnlock(testConnPtr driver) virMutexUnlock(&driver->lock); }
+static void *testDomainObjPrivateAlloc(void) +{ + testDomainObjPrivatePtr priv; + + if (VIR_ALLOC(priv) < 0) + return NULL; + + return priv; +} + +static void testDomainObjPrivateFree(void *data) +{ + testDomainObjPrivatePtr priv = data; + + VIR_FREE(priv); +}
This needs to free 'cpumaps' field I believe.
+ + static virCapsPtr testBuildCapabilities(virConnectPtr conn) { testConnPtr privconn = conn->privateData; @@ -173,6 +200,9 @@ testBuildCapabilities(virConnectPtr conn) { goto no_memory; }
+ caps->privateDataAllocFunc = testDomainObjPrivateAlloc; + caps->privateDataFreeFunc = testDomainObjPrivateFree; + return caps;
no_memory: @@ -269,7 +299,9 @@ static const char *defaultNodeXML = static const unsigned long long defaultPoolCap = (100 * 1024 * 1024 * 1024ull); static const unsigned long long defaultPoolAlloc = 0;
-static int testStoragePoolObjSetDefaults(virConnectPtr conn, virStoragePoolObjPtr pool); +static int testStoragePoolObjSetDefaults(virConnectPtr conn, + virStoragePoolObjPtr pool); +static int testNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
static char * testDomainGenerateIfname(virConnectPtr conn, @@ -325,16 +357,115 @@ testDomainGenerateIfnames(virConnectPtr conn, return 0; }
+/* Helper to update info for a single VCPU */ +static int +testDomainUpdateVCPU(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainObjPtr dom, + int vcpu, + int maplen, + int maxcpu) +{ + testDomainObjPrivatePtr privdata = dom->privateData; + virVcpuInfoPtr info = &privdata->vcpu_infos[vcpu]; + unsigned char *cpumap = VIR_GET_CPUMAP(privdata->cpumaps, maplen, vcpu); + int j; + + memset(info, 0, sizeof(virVcpuInfo)); + memset(cpumap, 0, maplen); + + info->number = vcpu; + info->state = VIR_VCPU_RUNNING; + info->cpuTime = 5000000; + info->cpu = 0; + + if (dom->def->cpumask) { + for (j = 0; j < maxcpu && j < VIR_DOMAIN_CPUMASK_LEN; ++j) { + if (dom->def->cpumask[j]) { + VIR_USE_CPU(cpumap, j); + info->cpu = j; + } + } + } else { + for (j = 0; j < maxcpu; ++j) { + if ((j % 3) == 0) { + /* Mark of every third CPU as usable */ + VIR_USE_CPU(cpumap, j); + info->cpu = j; + } + } + } + + return 0; +} + +/* + * Update domain VCPU amount and info + * + * @conn: virConnectPtr + * @dom : domain needing updates + * @nvcpus: New amount of vcpus for the domain + * @clear_all: If true, rebuild info for ALL vcpus, not just newly added vcpus + */ +static int +testDomainUpdateVCPUs(virConnectPtr conn, + virDomainObjPtr dom, + int nvcpus, + unsigned int clear_all) +{ + testConnPtr privconn = conn->privateData; + testDomainObjPrivatePtr privdata = dom->privateData; + int i, ret = -1; + int cpumaplen, maxcpu; + + maxcpu = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo); + cpumaplen = VIR_CPU_MAPLEN(maxcpu); + + if (VIR_REALLOC_N(privdata->vcpu_infos, nvcpus) < 0) { + virReportOOMError(conn); + goto cleanup; + } + + if (VIR_REALLOC_N(privdata->cpumaps, nvcpus * cpumaplen) < 0) { + virReportOOMError(conn); + goto cleanup; + } + + /* Set running VCPU and cpumap state */ + if (clear_all) { + for (i = 0; i < nvcpus; ++i) + if (testDomainUpdateVCPU(conn, dom, i, cpumaplen, maxcpu) < 0) + goto cleanup; + + } else if (nvcpus > dom->def->vcpus) { + /* VCPU amount has grown, populate info for the new vcpus */ + for (i = dom->def->vcpus; i < nvcpus; ++i) + if (testDomainUpdateVCPU(conn, dom, i, cpumaplen, maxcpu) < 0) + goto cleanup; + } + + ret = 0; +cleanup: + return ret; +} + +/* Set up domain runtime state */ static int testDomainStartState(virConnectPtr conn, virDomainObjPtr dom) { testConnPtr privconn = conn->privateData; + int ret = -1; + + if (testDomainUpdateVCPUs(conn, dom, dom->def->vcpus, 1) < 0) + goto cleanup;
+ /* Set typical run state */ dom->state = VIR_DOMAIN_RUNNING; dom->def->id = privconn->nextDomID++;
- return 0; + ret = 0; +cleanup: + return ret; }
static int testOpenDefault(virConnectPtr conn) {
Looks good apart from the tiny leak Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On 11/03/2009 03:59 PM, Daniel P. Berrange wrote:
On Mon, Nov 02, 2009 at 03:02:44PM -0500, Cole Robinson wrote:
Looks good apart from the tiny leak
Daniel
I've pushed this series with the leak fix you mentioned above. Thanks, Cole

Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index a8bec58..078658f 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1992,6 +1992,10 @@ static int testSetVcpus(virDomainPtr domain, goto cleanup; } + /* Update VCPU state for the running domain */ + if (testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0) < 0) + goto cleanup; + privdom->def->vcpus = nrCpus; ret = 0; -- 1.6.5.1

On Mon, Nov 02, 2009 at 03:02:45PM -0500, Cole Robinson wrote:
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c index a8bec58..078658f 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1992,6 +1992,10 @@ static int testSetVcpus(virDomainPtr domain, goto cleanup; }
+ /* Update VCPU state for the running domain */ + if (testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0) < 0) + goto cleanup; + privdom->def->vcpus = nrCpus; ret = 0;
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 89 insertions(+), 1 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 078658f..5b871aa 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2005,6 +2005,94 @@ cleanup: return ret; } +static int testDomainGetVcpus(virDomainPtr domain, + virVcpuInfoPtr info, + int maxinfo, + unsigned char *cpumaps, + int maplen) +{ + testConnPtr privconn = domain->conn->privateData; + testDomainObjPrivatePtr privdomdata; + virDomainObjPtr privdom; + int i, v, maxcpu, hostcpus; + int ret = -1; + struct timeval tv; + unsigned long long statbase; + + testDriverLock(privconn); + privdom = virDomainFindByName(&privconn->domains, domain->name); + testDriverUnlock(privconn); + + if (privdom == NULL) { + testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto cleanup; + } + + if (!virDomainIsActive(privdom)) { + testError(domain->conn, VIR_ERR_OPERATION_INVALID, + "%s",_("cannot list vcpus for an inactive domain")); + goto cleanup; + } + + privdomdata = privdom->privateData; + + if (gettimeofday(&tv, NULL) < 0) { + virReportSystemError(domain->conn, errno, + "%s", _("getting time of day")); + goto cleanup; + } + + statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec; + + + hostcpus = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo); + maxcpu = maplen * 8; + if (maxcpu > hostcpus) + maxcpu = hostcpus; + + /* Clamp to actual number of vcpus */ + if (maxinfo > privdom->def->vcpus) + maxinfo = privdom->def->vcpus; + + /* Populate virVcpuInfo structures */ + if (info != NULL) { + memset(info, 0, sizeof(*info) * maxinfo); + + for (i = 0 ; i < maxinfo ; i++) { + virVcpuInfo privinfo = privdomdata->vcpu_infos[i]; + + info[i].number = privinfo.number; + info[i].state = privinfo.state; + info[i].cpu = privinfo.cpu; + + /* Fake an increasing cpu time value */ + info[i].cpuTime = statbase / 10; + } + } + + /* Populate cpumaps */ + if (cpumaps != NULL) { + int privmaplen = VIR_CPU_MAPLEN(hostcpus); + memset(cpumaps, 0, maplen * maxinfo); + + for (v = 0 ; v < maxinfo ; v++) { + unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v); + + for (i = 0 ; i < maxcpu ; i++) { + if (VIR_CPU_USABLE(privdomdata->cpumaps, privmaplen, v, i)) { + VIR_USE_CPU(cpumap, i); + } + } + } + } + + ret = maxinfo; +cleanup: + if (privdom) + virDomainObjUnlock(privdom); + return ret; +} + static char *testDomainDumpXML(virDomainPtr domain, int flags) { testConnPtr privconn = domain->conn->privateData; @@ -4860,7 +4948,7 @@ static virDriver testDriver = { testDomainCoreDump, /* domainCoreDump */ testSetVcpus, /* domainSetVcpus */ NULL, /* domainPinVcpu */ - NULL, /* domainGetVcpus */ + testDomainGetVcpus, /* domainGetVcpus */ testDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ NULL, /* nodeGetSecurityModel */ -- 1.6.5.1

On Mon, Nov 02, 2009 at 03:02:46PM -0500, Cole Robinson wrote:
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 89 insertions(+), 1 deletions(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 078658f..5b871aa 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2005,6 +2005,94 @@ cleanup: return ret; }
+static int testDomainGetVcpus(virDomainPtr domain, + virVcpuInfoPtr info, + int maxinfo, + unsigned char *cpumaps, + int maplen) +{ + testConnPtr privconn = domain->conn->privateData; + testDomainObjPrivatePtr privdomdata; + virDomainObjPtr privdom; + int i, v, maxcpu, hostcpus; + int ret = -1; + struct timeval tv; + unsigned long long statbase; + + testDriverLock(privconn); + privdom = virDomainFindByName(&privconn->domains, domain->name); + testDriverUnlock(privconn); + + if (privdom == NULL) { + testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto cleanup; + } + + if (!virDomainIsActive(privdom)) { + testError(domain->conn, VIR_ERR_OPERATION_INVALID, + "%s",_("cannot list vcpus for an inactive domain")); + goto cleanup; + } + + privdomdata = privdom->privateData; + + if (gettimeofday(&tv, NULL) < 0) { + virReportSystemError(domain->conn, errno, + "%s", _("getting time of day")); + goto cleanup; + } + + statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec; + + + hostcpus = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo); + maxcpu = maplen * 8; + if (maxcpu > hostcpus) + maxcpu = hostcpus; + + /* Clamp to actual number of vcpus */ + if (maxinfo > privdom->def->vcpus) + maxinfo = privdom->def->vcpus; + + /* Populate virVcpuInfo structures */ + if (info != NULL) { + memset(info, 0, sizeof(*info) * maxinfo); + + for (i = 0 ; i < maxinfo ; i++) { + virVcpuInfo privinfo = privdomdata->vcpu_infos[i]; + + info[i].number = privinfo.number; + info[i].state = privinfo.state; + info[i].cpu = privinfo.cpu; + + /* Fake an increasing cpu time value */ + info[i].cpuTime = statbase / 10; + } + } + + /* Populate cpumaps */ + if (cpumaps != NULL) { + int privmaplen = VIR_CPU_MAPLEN(hostcpus); + memset(cpumaps, 0, maplen * maxinfo); + + for (v = 0 ; v < maxinfo ; v++) { + unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v); + + for (i = 0 ; i < maxcpu ; i++) { + if (VIR_CPU_USABLE(privdomdata->cpumaps, privmaplen, v, i)) { + VIR_USE_CPU(cpumap, i); + } + } + } + } + + ret = maxinfo; +cleanup: + if (privdom) + virDomainObjUnlock(privdom); + return ret; +} + static char *testDomainDumpXML(virDomainPtr domain, int flags) { testConnPtr privconn = domain->conn->privateData; @@ -4860,7 +4948,7 @@ static virDriver testDriver = { testDomainCoreDump, /* domainCoreDump */ testSetVcpus, /* domainSetVcpus */ NULL, /* domainPinVcpu */ - NULL, /* domainGetVcpus */ + testDomainGetVcpus, /* domainGetVcpus */ testDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ NULL, /* nodeGetSecurityModel */
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 58 insertions(+), 1 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 5b871aa..6ea4aa9 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2093,6 +2093,63 @@ cleanup: return ret; } +static int testDomainPinVcpu(virDomainPtr domain, + unsigned int vcpu, + unsigned char *cpumap, + int maplen) +{ + testConnPtr privconn = domain->conn->privateData; + testDomainObjPrivatePtr privdomdata; + virDomainObjPtr privdom; + unsigned char *privcpumap; + int i, maxcpu, hostcpus, privmaplen; + int ret = -1; + + testDriverLock(privconn); + privdom = virDomainFindByName(&privconn->domains, domain->name); + testDriverUnlock(privconn); + + if (privdom == NULL) { + testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto cleanup; + } + + if (!virDomainIsActive(privdom)) { + testError(domain->conn, VIR_ERR_OPERATION_INVALID, + "%s",_("cannot pin vcpus on an inactive domain")); + goto cleanup; + } + + if (vcpu > privdom->def->vcpus) { + testError(domain->conn, VIR_ERR_INVALID_ARG, "%s", + _("requested vcpu is higher than allocated vcpus")); + goto cleanup; + } + + privdomdata = privdom->privateData; + hostcpus = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo); + privmaplen = VIR_CPU_MAPLEN(hostcpus); + + maxcpu = maplen * 8; + if (maxcpu > hostcpus) + maxcpu = hostcpus; + + privcpumap = VIR_GET_CPUMAP(privdomdata->cpumaps, privmaplen, vcpu); + memset(privcpumap, 0, privmaplen); + + for (i = 0 ; i < maxcpu ; i++) { + if (VIR_CPU_USABLE(cpumap, maplen, 0, i)) { + VIR_USE_CPU(privcpumap, i); + } + } + + ret = 0; +cleanup: + if (privdom) + virDomainObjUnlock(privdom); + return ret; +} + static char *testDomainDumpXML(virDomainPtr domain, int flags) { testConnPtr privconn = domain->conn->privateData; @@ -4947,7 +5004,7 @@ static virDriver testDriver = { testDomainRestore, /* domainRestore */ testDomainCoreDump, /* domainCoreDump */ testSetVcpus, /* domainSetVcpus */ - NULL, /* domainPinVcpu */ + testDomainPinVcpu, /* domainPinVcpu */ testDomainGetVcpus, /* domainGetVcpus */ testDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ -- 1.6.5.1

On Mon, Nov 02, 2009 at 03:02:47PM -0500, Cole Robinson wrote:
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 5b871aa..6ea4aa9 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2093,6 +2093,63 @@ cleanup: return ret; }
+static int testDomainPinVcpu(virDomainPtr domain, + unsigned int vcpu, + unsigned char *cpumap, + int maplen) +{ + testConnPtr privconn = domain->conn->privateData; + testDomainObjPrivatePtr privdomdata; + virDomainObjPtr privdom; + unsigned char *privcpumap; + int i, maxcpu, hostcpus, privmaplen; + int ret = -1; + + testDriverLock(privconn); + privdom = virDomainFindByName(&privconn->domains, domain->name); + testDriverUnlock(privconn); + + if (privdom == NULL) { + testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto cleanup; + } + + if (!virDomainIsActive(privdom)) { + testError(domain->conn, VIR_ERR_OPERATION_INVALID, + "%s",_("cannot pin vcpus on an inactive domain")); + goto cleanup; + } + + if (vcpu > privdom->def->vcpus) { + testError(domain->conn, VIR_ERR_INVALID_ARG, "%s", + _("requested vcpu is higher than allocated vcpus")); + goto cleanup; + } + + privdomdata = privdom->privateData; + hostcpus = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo); + privmaplen = VIR_CPU_MAPLEN(hostcpus); + + maxcpu = maplen * 8; + if (maxcpu > hostcpus) + maxcpu = hostcpus; + + privcpumap = VIR_GET_CPUMAP(privdomdata->cpumaps, privmaplen, vcpu); + memset(privcpumap, 0, privmaplen); + + for (i = 0 ; i < maxcpu ; i++) { + if (VIR_CPU_USABLE(cpumap, maplen, 0, i)) { + VIR_USE_CPU(privcpumap, i); + } + } + + ret = 0; +cleanup: + if (privdom) + virDomainObjUnlock(privdom); + return ret; +} + static char *testDomainDumpXML(virDomainPtr domain, int flags) { testConnPtr privconn = domain->conn->privateData; @@ -4947,7 +5004,7 @@ static virDriver testDriver = { testDomainRestore, /* domainRestore */ testDomainCoreDump, /* domainCoreDump */ testSetVcpus, /* domainSetVcpus */ - NULL, /* domainPinVcpu */ + testDomainPinVcpu, /* domainPinVcpu */ testDomainGetVcpus, /* domainGetVcpus */ testDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ --
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
participants (2)
-
Cole Robinson
-
Daniel P. Berrange