On Mon, Jun 02, 2014 at 06:06:38PM +0400, Alexander Burluka wrote:
From: A.Burluka <aburluka(a)parallels.com>
OpenStack Nova requires this function
to start VM instance. Cpumask info is obtained via prlctl utility.
Unlike KVM, Parallels Cloud Server is unable to set cpu affinity
mask for every VCpu. Mask is unique for all VCpu. You can set it
using 'prlctl set <vm_id|vm_name> --cpumask <{n[,n,n1-n2]|all}>'
command. For example, 'prlctl set SomeDomain --cpumask 0,1,5-7'
would set this mask to yy---yyy.
---
src/parallels/parallels_driver.c | 169 +++++++++++++++++++++++++++++++++++++-
src/parallels/parallels_utils.h | 1 +
2 files changed, 167 insertions(+), 3 deletions(-)
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index ab59599..f1d5ecc 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -108,6 +108,7 @@ parallelsDomObjFreePrivate(void *p)
if (!pdom)
return;
+ VIR_FREE(pdom->cpumask);
VIR_FREE(pdom->uuid);
VIR_FREE(pdom->home);
VIR_FREE(p);
@@ -654,6 +655,9 @@ parallelsLoadDomain(parallelsConnPtr privconn, virJSONValuePtr jobj)
if (VIR_ALLOC(def) < 0)
goto cleanup;
+ if (VIR_ALLOC(pdom) < 0)
+ goto cleanup;
+
def->virtType = VIR_DOMAIN_VIRT_PARALLELS;
def->id = -1;
@@ -716,6 +720,17 @@ parallelsLoadDomain(parallelsConnPtr privconn, virJSONValuePtr
jobj)
goto cleanup;
}
+ if (!(tmp = virJSONValueObjectGetString(jobj3, "mask"))) {
+ /* Absence of this field means that all domains cpus are available */
+ if (VIR_STRDUP(pdom->cpumask, "all") < 0) {
+ goto cleanup;
+ }
+ } else {
+ if (VIR_STRDUP(pdom->cpumask, tmp) < 0) {
+ goto cleanup;
+ }
+ }
See my comment later about using 'virBitmap' - this is where you shoudl parse
the string into a bitmap instance.
+static int
+parallelsNodeGetCpuMask(parallelsDomObjPtr privatedomdata,
+ virBitmapPtr *cpumask,
+ int hostcpus)
+{
+ int ret = -1;
+ int cpunum = -1;
+ int prevcpunum = -1;
+ int offset = 0;
+ const char *it = privatedomdata->cpumask;
+ bool isrange = false;
+ size_t i;
+ int cpunums[512] = { 0 };
+ size_t count = 0;
+
+ if (STREQ(it, "all")) {
+ if (!(*cpumask = virBitmapNew(hostcpus)))
+ goto cleanup;
+ virBitmapSetAll(*cpumask);
+ } else {
+ while (sscanf(it, "%d%n", &cpunum, &offset)) {
+ char delim = 0;
+ if (isrange) {
+ for (i = prevcpunum + 1; i <= cpunum; ++i) {
+ cpunums[count++] = i;
+ }
+ } else {
+ cpunums[count++] = cpunum;
+ }
+
+ it += offset;
+
+ if (sscanf(it, "%c%n", &delim, &offset) == EOF) {
+ break;
What is the format that parallels uses for 'cpumask' - ideally
you would just use 'virBitmapParse' for parsing it, not write
another parser
+static int
+parallelsDomainGetVcpus(virDomainPtr domain,
+ virVcpuInfoPtr info,
+ int maxinfo,
+ unsigned char *cpumaps,
+ int maplen)
Generally parameters should all be aligned with the first
parameter
diff --git a/src/parallels/parallels_utils.h
b/src/parallels/parallels_utils.h
index 6215553..e88af1c 100644
--- a/src/parallels/parallels_utils.h
+++ b/src/parallels/parallels_utils.h
@@ -54,6 +54,7 @@ struct parallelsDomObj {
int id;
char *uuid;
char *home;
+ char *cpumask;
A while back we converted all 'char *cpumask' variables to be
'virBitmapPtr cpumask' since it makes the code nicer if we can
actually have things in fully parsed format internally, only
converting to string format when really needed.
Conceptually this looks ok - main issue is using virBitmap
for the internal data structure & changing the parser.
Regards,
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|