~serge-hallyn/ubuntu/oneiric/libvirt/fix-shutdown

« back to all changes in this revision

Viewing changes to docs/api_extension/0008-support-new-xml.patch

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2010-11-02 16:26:51 UTC
  • mfrom: (1.2.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20101102162651-aq8tnbz58mdf01bf
Tags: 0.8.5-0ubuntu1
* New upstream release.
* Removed a slew of patches which have been
  applied upstream since 0.8.3.
  - 9012-apparmor-extra-tests.patch
  - 9013-apparmor-chardev.patch
  - 9015-Add-ubd-to-the-list-of-disk-prefixes.patch
  - 9016-Close-fd-s-of-persistent-tap-devices.patch
  - 9017-Make-sure-all-command-line-arguments-get-passed-to-U.patch
  - 9018-Make-umlConnectTapDevice-ask-brAddTap-for-a-persiste.patch
  - 9019-uml-fix-logic-bug-in-checking-reply-length.patch
  - 9021-Allow-chardev-of-type-file-for-UML-domains.patch
  - 9022-Rename-qemudShrinkDisks-to-virDomainDiskRemove-and-m.patch
  - 9023-Support-virDomainAttachDevice-and-virDomainDetachDev.patch
  - 9024-Explicitly-pass-uml_dir-argument-to-user-mode-linux.patch
  - 9025-Add-nwfilter-support-to-UML-driver.patch
  - 9026-Rebuild-network-filter-for-UML-guests-on-updates.patch
  - 9027-Make-newfilter-xml-transformations-endian-safe.patch
  - 9028-lp628055.patch
* Updated 9002-better_default_uri_virsh.patch to use vshStrdup,
  as now required in that file.  (use of strdup now causes compilation
  to fail)
* Removed 9008-run-as-root-by-default.patch, which has not been
  applied for awhile now, with no ill effects.
* Simple refresh of:
  - 0001-remove-RHism.diff.patch
  - 0003-allow-libvirt-group-to-access-the-socket.patch
  - 0004-fix-Debian-specific-path-to-hvm-loader.patch
  - 0006-patch-qemuMonitorTextGetMigrationStatus-to-intercept.patch
  - 9000-delayed_iff_up_bridge.patch
  - 9001-dont_clobber_existing_bridges.patch
  - 9003-better-default-arch.patch
  - 9004-libvirtd-group-name.patch
  - 9005-increase-unix-socket-timeout.patch
  - 9006-default-config-test-case.patch
  - 9009-autodetect-nc-params.patch
  - 9010-dont-disable-ipv6.patch
  - 9011-move-ebtables-script.patch
  - 9014-skip-nodeinfotest.patch
  - 9020-lp545795.patch
* Create a patch to include stdint.h so lxc_container.h, which
  #includes linux/fs.h, doesn't trip up on undefined uint64_t.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From 4617eedfaeee2b187a1f14691d25746ba3ff31b6 Mon Sep 17 00:00:00 2001
 
2
From: Eric Blake <eblake@redhat.com>
 
3
Date: Wed, 29 Sep 2010 10:20:07 -0600
 
4
Subject: [PATCH 07/15] vcpu: support maxvcpu in domain_conf
 
5
 
 
6
Although this patch adds a distinction between maximum vcpus and
 
7
current vcpus in the XML, the values should be identical for all
 
8
drivers at this point.  Only in subsequent per-driver patches will
 
9
a distinction be made.
 
10
 
 
11
In general, virDomainGetInfo should prefer the current vcpus.
 
12
 
 
13
* src/conf/domain_conf.h (_virDomainDef): Adjust vcpus to unsigned
 
14
short, to match virDomainGetInfo limit.  Add maxvcpus member.
 
15
* src/conf/domain_conf.c (virDomainDefParseXML)
 
16
(virDomainDefFormat): parse and print out vcpu details.
 
17
* src/xen/xend_internal.c (xenDaemonParseSxpr)
 
18
(xenDaemonFormatSxpr): Manage both vcpu numbers, and require them
 
19
to be equal for now.
 
20
* src/xen/xm_internal.c (xenXMDomainConfigParse)
 
21
(xenXMDomainConfigFormat): Likewise.
 
22
* src/phyp/phyp_driver.c (phypDomainDumpXML): Likewise.
 
23
* src/openvz/openvz_conf.c (openvzLoadDomains): Likewise.
 
24
* src/openvz/openvz_driver.c (openvzDomainDefineXML)
 
25
(openvzDomainCreateXML, openvzDomainSetVcpusInternal): Likewise.
 
26
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxDomainDefineXML):
 
27
Likewise.
 
28
* src/xenapi/xenapi_driver.c (xenapiDomainDumpXML): Likewise.
 
29
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
 
30
* src/esx/esx_vmx.c (esxVMX_ParseConfig, esxVMX_FormatConfig):
 
31
Likewise.
 
32
* src/qemu/qemu_conf.c (qemuBuildSmpArgStr)
 
33
(qemuParseCommandLineSmp, qemuParseCommandLine): Likewise.
 
34
* src/qemu/qemu_driver.c (qemudDomainHotplugVcpus): Likewise.
 
35
* src/opennebula/one_conf.c (xmlOneTemplate): Likewise.
 
36
---
 
37
 src/conf/domain_conf.c     |   45 +++++++++++++++++++++++++++++++++++++------
 
38
 src/conf/domain_conf.h     |    3 +-
 
39
 src/esx/esx_vmx.c          |   24 ++++++++++++++--------
 
40
 src/opennebula/one_conf.c  |    9 +++++--
 
41
 src/openvz/openvz_conf.c   |    7 +++--
 
42
 src/openvz/openvz_driver.c |   15 +++++++++----
 
43
 src/phyp/phyp_driver.c     |    2 +-
 
44
 src/qemu/qemu_conf.c       |   14 +++++++++++-
 
45
 src/qemu/qemu_driver.c     |    5 ++-
 
46
 src/vbox/vbox_tmpl.c       |   12 +++++++---
 
47
 src/xen/xend_internal.c    |    9 ++++---
 
48
 src/xen/xm_internal.c      |   11 ++++++---
 
49
 src/xenapi/xenapi_driver.c |    2 +-
 
50
 src/xenapi/xenapi_utils.c  |    4 +-
 
51
 14 files changed, 114 insertions(+), 48 deletions(-)
 
52
 
 
53
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
 
54
index 78d7a6a..a997e06 100644
 
55
--- a/src/conf/domain_conf.c
 
56
+++ b/src/conf/domain_conf.c
 
57
@@ -4203,6 +4203,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
 
58
     int i, n;
 
59
     long id = -1;
 
60
     virDomainDefPtr def;
 
61
+    unsigned long count;
 
62
 
 
63
     if (VIR_ALLOC(def) < 0) {
 
64
         virReportOOMError();
 
65
@@ -4287,8 +4288,37 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
 
66
                       &def->mem.swap_hard_limit) < 0)
 
67
         def->mem.swap_hard_limit = 0;
 
68
 
 
69
-    if (virXPathULong("string(./vcpu[1])", ctxt, &def->vcpus) < 0)
 
70
-        def->vcpus = 1;
 
71
+    n = virXPathULong("string(./vcpu[1])", ctxt, &count);
 
72
+    if (n == -2) {
 
73
+        virDomainReportError(VIR_ERR_XML_ERROR, "%s",
 
74
+                             _("maximum vcpus must be an integer"));
 
75
+        goto error;
 
76
+    } else if (n < 0) {
 
77
+        def->maxvcpus = 1;
 
78
+    } else {
 
79
+        def->maxvcpus = count;
 
80
+        if (def->maxvcpus != count || count == 0) {
 
81
+            virDomainReportError(VIR_ERR_XML_ERROR,
 
82
+                                 _("invalid maxvcpus %lu"), count);
 
83
+            goto error;
 
84
+        }
 
85
+    }
 
86
+
 
87
+    n = virXPathULong("string(./vcpu[1]/@current)", ctxt, &count);
 
88
+    if (n == -2) {
 
89
+        virDomainReportError(VIR_ERR_XML_ERROR, "%s",
 
90
+                             _("current vcpus must be an integer"));
 
91
+        goto error;
 
92
+    } else if (n < 0) {
 
93
+        def->vcpus = def->maxvcpus;
 
94
+    } else {
 
95
+        def->vcpus = count;
 
96
+        if (def->vcpus != count || count == 0 || def->maxvcpus < count) {
 
97
+            virDomainReportError(VIR_ERR_XML_ERROR,
 
98
+                                 _("invalid current vcpus %lu"), count);
 
99
+            goto error;
 
100
+        }
 
101
+    }
 
102
 
 
103
     tmp = virXPathString("string(./vcpu[1]/@cpuset)", ctxt);
 
104
     if (tmp) {
 
105
@@ -6462,17 +6492,18 @@ char *virDomainDefFormat(virDomainDefPtr def,
 
106
         if (def->cpumask[n] != 1)
 
107
             allones = 0;
 
108
 
 
109
-    if (allones) {
 
110
-        virBufferVSprintf(&buf, "  <vcpu>%lu</vcpu>\n", def->vcpus);
 
111
-    } else {
 
112
+    virBufferAddLit(&buf, "  <vcpu");
 
113
+    if (!allones) {
 
114
         char *cpumask = NULL;
 
115
         if ((cpumask =
 
116
              virDomainCpuSetFormat(def->cpumask, def->cpumasklen)) == NULL)
 
117
             goto cleanup;
 
118
-        virBufferVSprintf(&buf, "  <vcpu cpuset='%s'>%lu</vcpu>\n",
 
119
-                          cpumask, def->vcpus);
 
120
+        virBufferVSprintf(&buf, " cpuset='%s'", cpumask);
 
121
         VIR_FREE(cpumask);
 
122
     }
 
123
+    if (def->vcpus != def->maxvcpus)
 
124
+        virBufferVSprintf(&buf, " current='%u'", def->vcpus);
 
125
+    virBufferVSprintf(&buf, ">%u</vcpu>\n", def->maxvcpus);
 
126
 
 
127
     if (def->os.bootloader) {
 
128
         virBufferEscapeString(&buf, "  <bootloader>%s</bootloader>\n",
 
129
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
 
130
index db09c23..5499f28 100644
 
131
--- a/src/conf/domain_conf.h
 
132
+++ b/src/conf/domain_conf.h
 
133
@@ -885,7 +885,8 @@ struct _virDomainDef {
 
134
         unsigned long min_guarantee;
 
135
         unsigned long swap_hard_limit;
 
136
     } mem;
 
137
-    unsigned long vcpus;
 
138
+    unsigned short vcpus;
 
139
+    unsigned short maxvcpus;
 
140
     int cpumasklen;
 
141
     char *cpumask;
 
142
 
 
143
diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c
 
144
index 7ec8c0e..0a26614 100644
 
145
--- a/src/esx/esx_vmx.c
 
146
+++ b/src/esx/esx_vmx.c
 
147
@@ -50,7 +50,7 @@ def->uuid = <value>               <=>   uuid.bios = "<value>"
 
148
 def->name = <value>               <=>   displayName = "<value>"
 
149
 def->mem.max_balloon = <value kilobyte>    <=>   memsize = "<value megabyte>"            # must be a multiple of 4, defaults to 32
 
150
 def->mem.cur_balloon = <value kilobyte>    <=>   sched.mem.max = "<value megabyte>"      # defaults to "unlimited" -> def->mem.cur_balloon = def->mem.max_balloon
 
151
-def->vcpus = <value>              <=>   numvcpus = "<value>"                    # must be 1 or a multiple of 2, defaults to 1
 
152
+def->maxvcpus = <value>           <=>   numvcpus = "<value>"                    # must be 1 or a multiple of 2, defaults to 1
 
153
 def->cpumask = <uint list>        <=>   sched.cpu.affinity = "<uint list>"
 
154
 
 
155
 
 
156
@@ -1075,7 +1075,7 @@ esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
 
157
         goto cleanup;
 
158
     }
 
159
 
 
160
-    def->vcpus = numvcpus;
 
161
+    def->maxvcpus = def->vcpus = numvcpus;
 
162
 
 
163
     /* vmx:sched.cpu.affinity -> def:cpumask */
 
164
     // VirtualMachine:config.cpuAffinity.affinitySet
 
165
@@ -2609,16 +2609,22 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
 
166
                           (int)(def->mem.cur_balloon / 1024));
 
167
     }
 
168
 
 
169
-    /* def:vcpus -> vmx:numvcpus */
 
170
-    if (def->vcpus <= 0 || (def->vcpus % 2 != 0 && def->vcpus != 1)) {
 
171
+    /* def:maxvcpus -> vmx:numvcpus */
 
172
+    if (def->vcpus != def->maxvcpus) {
 
173
+        ESX_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
 
174
+                  _("No support for domain XML entry 'vcpu' attribute "
 
175
+                    "'current'"));
 
176
+        goto cleanup;
 
177
+    }
 
178
+    if (def->maxvcpus <= 0 || (def->maxvcpus % 2 != 0 && def->maxvcpus != 1)) {
 
179
         ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
 
180
                   _("Expecting domain XML entry 'vcpu' to be an unsigned "
 
181
                     "integer (1 or a multiple of 2) but found %d"),
 
182
-                  (int)def->vcpus);
 
183
+                  def->maxvcpus);
 
184
         goto cleanup;
 
185
     }
 
186
 
 
187
-    virBufferVSprintf(&buffer, "numvcpus = \"%d\"\n", (int)def->vcpus);
 
188
+    virBufferVSprintf(&buffer, "numvcpus = \"%d\"\n", def->maxvcpus);
 
189
 
 
190
     /* def:cpumask -> vmx:sched.cpu.affinity */
 
191
     if (def->cpumasklen > 0) {
 
192
@@ -2632,11 +2638,11 @@ esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
 
193
             }
 
194
         }
 
195
 
 
196
-        if (sched_cpu_affinity_length < def->vcpus) {
 
197
+        if (sched_cpu_affinity_length < def->maxvcpus) {
 
198
             ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
 
199
                       _("Expecting domain XML attribute 'cpuset' of entry "
 
200
-                        "'vcpu' to contains at least %d CPU(s)"),
 
201
-                      (int)def->vcpus);
 
202
+                        "'vcpu' to contain at least %d CPU(s)"),
 
203
+                      def->maxvcpus);
 
204
             goto cleanup;
 
205
         }
 
206
 
 
207
diff --git a/src/opennebula/one_conf.c b/src/opennebula/one_conf.c
 
208
index 44e28dc..2079c51 100644
 
209
--- a/src/opennebula/one_conf.c
 
210
+++ b/src/opennebula/one_conf.c
 
211
@@ -1,5 +1,7 @@
 
212
 /*----------------------------------------------------------------------------------*/
 
213
-/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
 
214
+/*
 
215
+ * Copyright (C) 2010 Red Hat, Inc.
 
216
+ * Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
 
217
  * Complutense de Madrid (dsa-research.org)
 
218
  *
 
219
  * This library is free software; you can redistribute it and/or
 
220
@@ -169,9 +171,10 @@ char* xmlOneTemplate(virDomainDefPtr def)
 
221
 {
 
222
     int i;
 
223
     virBuffer buf= VIR_BUFFER_INITIALIZER;
 
224
-    virBufferVSprintf(&buf,"#OpenNebula Template automatically generated by libvirt\nNAME = %s\nCPU = %ld\nMEMORY = %ld\n",
 
225
+    virBufferVSprintf(&buf,"#OpenNebula Template automatically generated "
 
226
+                      "by libvirt\nNAME = %s\nCPU = %d\nMEMORY = %ld\n",
 
227
                       def->name,
 
228
-                      def->vcpus,
 
229
+                      def->maxvcpus,
 
230
                       (def->mem.max_balloon)/1024);
 
231
 
 
232
     /*Optional Booting OpenNebula Information:*/
 
233
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
 
234
index ec11bbc..c84a6f3 100644
 
235
--- a/src/openvz/openvz_conf.c
 
236
+++ b/src/openvz/openvz_conf.c
 
237
@@ -507,11 +507,12 @@ int openvzLoadDomains(struct openvz_driver *driver) {
 
238
                         veid);
 
239
             goto cleanup;
 
240
         } else if (ret > 0) {
 
241
-            dom->def->vcpus = strtoI(temp);
 
242
+            dom->def->maxvcpus = strtoI(temp);
 
243
         }
 
244
 
 
245
-        if (ret == 0 || dom->def->vcpus == 0)
 
246
-            dom->def->vcpus = openvzGetNodeCPUs();
 
247
+        if (ret == 0 || dom->def->maxvcpus == 0)
 
248
+            dom->def->maxvcpus = openvzGetNodeCPUs();
 
249
+        dom->def->vcpus = dom->def->maxvcpus;
 
250
 
 
251
         /* XXX load rest of VM config data .... */
 
252
 
 
253
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
 
254
index 0f3cfdf..b7c2754 100644
 
255
--- a/src/openvz/openvz_driver.c
 
256
+++ b/src/openvz/openvz_driver.c
 
257
@@ -925,8 +925,13 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
 
258
     if (openvzDomainSetNetworkConfig(conn, vm->def) < 0)
 
259
         goto cleanup;
 
260
 
 
261
-    if (vm->def->vcpus > 0) {
 
262
-        if (openvzDomainSetVcpusInternal(vm, vm->def->vcpus) < 0) {
 
263
+    if (vm->def->vcpus != vm->def->maxvcpus) {
 
264
+        openvzError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 
265
+                    _("current vcpu count must equal maximum"));
 
266
+        goto cleanup;
 
267
+    }
 
268
+    if (vm->def->maxvcpus > 0) {
 
269
+        if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
 
270
             openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
 
271
                         _("Could not set number of virtual cpu"));
 
272
              goto cleanup;
 
273
@@ -1019,8 +1024,8 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
 
274
     vm->def->id = vm->pid;
 
275
     vm->state = VIR_DOMAIN_RUNNING;
 
276
 
 
277
-    if (vm->def->vcpus > 0) {
 
278
-        if (openvzDomainSetVcpusInternal(vm, vm->def->vcpus) < 0) {
 
279
+    if (vm->def->maxvcpus > 0) {
 
280
+        if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
 
281
             openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
 
282
                         _("Could not set number of virtual cpu"));
 
283
             goto cleanup;
 
284
@@ -1249,7 +1254,7 @@ static int openvzDomainSetVcpusInternal(virDomainObjPtr vm,
 
285
         return -1;
 
286
     }
 
287
 
 
288
-    vm->def->vcpus = nvcpus;
 
289
+    vm->def->maxvcpus = vm->def->vcpus = nvcpus;
 
290
     return 0;
 
291
 }
 
292
 
 
293
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
 
294
index e284ae0..3d0ed11 100644
 
295
--- a/src/phyp/phyp_driver.c
 
296
+++ b/src/phyp/phyp_driver.c
 
297
@@ -3540,7 +3540,7 @@ phypDomainDumpXML(virDomainPtr dom, int flags)
 
298
         goto err;
 
299
     }
 
300
 
 
301
-    if ((def.vcpus =
 
302
+    if ((def.maxvcpus = def.vcpus =
 
303
          phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) {
 
304
         VIR_ERROR0(_("Unable to determine domain's CPU."));
 
305
         goto err;
 
306
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
 
307
index 83c0f83..38c8351 100644
 
308
--- a/src/qemu/qemu_conf.c
 
309
+++ b/src/qemu/qemu_conf.c
 
310
@@ -3711,7 +3711,7 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
 
311
 {
 
312
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 
313
 
 
314
-    virBufferVSprintf(&buf, "%lu", def->vcpus);
 
315
+    virBufferVSprintf(&buf, "%u", def->vcpus);
 
316
 
 
317
     if ((qemuCmdFlags & QEMUD_CMD_FLAG_SMP_TOPOLOGY)) {
 
318
         /* sockets, cores, and threads are either all zero
 
319
@@ -3722,11 +3722,18 @@ qemuBuildSmpArgStr(const virDomainDefPtr def,
 
320
             virBufferVSprintf(&buf, ",threads=%u", def->cpu->threads);
 
321
         }
 
322
         else {
 
323
-            virBufferVSprintf(&buf, ",sockets=%lu", def->vcpus);
 
324
+            virBufferVSprintf(&buf, ",sockets=%u", def->maxvcpus);
 
325
             virBufferVSprintf(&buf, ",cores=%u", 1);
 
326
             virBufferVSprintf(&buf, ",threads=%u", 1);
 
327
         }
 
328
     }
 
329
+    if (def->vcpus != def->maxvcpus) {
 
330
+        virBufferFreeAndReset(&buf);
 
331
+        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 
332
+                        _("setting current vcpu count less than maximum is "
 
333
+                          "not supported yet"));
 
334
+        return NULL;
 
335
+    }
 
336
 
 
337
     if (virBufferError(&buf)) {
 
338
         virBufferFreeAndReset(&buf);
 
339
@@ -6178,6 +6185,8 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
 
340
         }
 
341
     }
 
342
 
 
343
+    dom->maxvcpus = dom->vcpus;
 
344
+
 
345
     if (sockets && cores && threads) {
 
346
         virCPUDefPtr cpu;
 
347
 
 
348
@@ -6247,6 +6256,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
 
349
 
 
350
     def->id = -1;
 
351
     def->mem.cur_balloon = def->mem.max_balloon = 64 * 1024;
 
352
+    def->maxvcpus = 1;
 
353
     def->vcpus = 1;
 
354
     def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
 
355
     def->features = (1 << VIR_DOMAIN_FEATURE_ACPI)
 
356
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 
357
index 7a2ea8f..c66dc04 100644
 
358
--- a/src/qemu/qemu_driver.c
 
359
+++ b/src/qemu/qemu_driver.c
 
360
@@ -2425,8 +2425,9 @@ qemuDetectVcpuPIDs(struct qemud_driver *driver,
 
361
 
 
362
     if (ncpupids != vm->def->vcpus) {
 
363
         qemuReportError(VIR_ERR_INTERNAL_ERROR,
 
364
-                        _("got wrong number of vCPU pids from QEMU monitor. got %d, wanted %d"),
 
365
-                        ncpupids, (int)vm->def->vcpus);
 
366
+                        _("got wrong number of vCPU pids from QEMU monitor. "
 
367
+                          "got %d, wanted %d"),
 
368
+                        ncpupids, vm->def->vcpus);
 
369
         VIR_FREE(cpupids);
 
370
         return -1;
 
371
     }
 
372
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
 
373
index 0cbe8b3..5a859a4 100644
 
374
--- a/src/vbox/vbox_tmpl.c
 
375
+++ b/src/vbox/vbox_tmpl.c
 
376
@@ -2028,7 +2028,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
 
377
             def->mem.max_balloon = memorySize * 1024;
 
378
 
 
379
             machine->vtbl->GetCPUCount(machine, &CPUCount);
 
380
-            def->vcpus = CPUCount;
 
381
+            def->maxvcpus = def->vcpus = CPUCount;
 
382
 
 
383
             /* Skip cpumasklen, cpumask, onReboot, onPoweroff, onCrash */
 
384
 
 
385
@@ -4598,11 +4598,15 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
 
386
                   def->mem.cur_balloon, (unsigned)rc);
 
387
     }
 
388
 
 
389
-    rc = machine->vtbl->SetCPUCount(machine, def->vcpus);
 
390
+    if (def->vcpus != def->maxvcpus) {
 
391
+        vboxError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 
392
+                    _("current vcpu count must equal maximum"));
 
393
+    }
 
394
+    rc = machine->vtbl->SetCPUCount(machine, def->maxvcpus);
 
395
     if (NS_FAILED(rc)) {
 
396
         vboxError(VIR_ERR_INTERNAL_ERROR,
 
397
-                  _("could not set the number of virtual CPUs to: %lu, rc=%08x"),
 
398
-                  def->vcpus, (unsigned)rc);
 
399
+                  _("could not set the number of virtual CPUs to: %u, rc=%08x"),
 
400
+                  def->maxvcpus, (unsigned)rc);
 
401
     }
 
402
 
 
403
 #if VBOX_API_VERSION < 3001
 
404
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
 
405
index 5ffc3c8..456b477 100644
 
406
--- a/src/xen/xend_internal.c
 
407
+++ b/src/xen/xend_internal.c
 
408
@@ -2190,7 +2190,8 @@ xenDaemonParseSxpr(virConnectPtr conn,
 
409
         }
 
410
     }
 
411
 
 
412
-    def->vcpus = sexpr_int(root, "domain/vcpus");
 
413
+    def->maxvcpus = sexpr_int(root, "domain/vcpus");
 
414
+    def->vcpus = def->maxvcpus;
 
415
 
 
416
     tmp = sexpr_node(root, "domain/on_poweroff");
 
417
     if (tmp != NULL) {
 
418
@@ -5649,7 +5650,7 @@ xenDaemonFormatSxprInput(virDomainInputDefPtr input,
 
419
  *
 
420
  * Generate an SEXPR representing the domain configuration.
 
421
  *
 
422
- * Returns the 0 terminatedi S-Expr string or NULL in case of error.
 
423
+ * Returns the 0 terminated S-Expr string or NULL in case of error.
 
424
  *         the caller must free() the returned value.
 
425
  */
 
426
 char *
 
427
@@ -5666,7 +5667,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
 
428
     virBufferVSprintf(&buf, "(name '%s')", def->name);
 
429
     virBufferVSprintf(&buf, "(memory %lu)(maxmem %lu)",
 
430
                       def->mem.cur_balloon/1024, def->mem.max_balloon/1024);
 
431
-    virBufferVSprintf(&buf, "(vcpus %lu)", def->vcpus);
 
432
+    virBufferVSprintf(&buf, "(vcpus %u)", def->maxvcpus);
 
433
 
 
434
     if (def->cpumask) {
 
435
         char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen);
 
436
@@ -5761,7 +5762,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
 
437
             else
 
438
                 virBufferVSprintf(&buf, "(kernel '%s')", def->os.loader);
 
439
 
 
440
-            virBufferVSprintf(&buf, "(vcpus %lu)", def->vcpus);
 
441
+            virBufferVSprintf(&buf, "(vcpus %u)", def->maxvcpus);
 
442
 
 
443
             for (i = 0 ; i < def->os.nBootDevs ; i++) {
 
444
                 switch (def->os.bootDevs[i]) {
 
445
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
 
446
index 8e42a1c..bf20a64 100644
 
447
--- a/src/xen/xm_internal.c
 
448
+++ b/src/xen/xm_internal.c
 
449
@@ -678,6 +678,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
 
450
     int i;
 
451
     const char *defaultArch, *defaultMachine;
 
452
     int vmlocaltime = 0;
 
453
+    unsigned long count;
 
454
 
 
455
     if (VIR_ALLOC(def) < 0) {
 
456
         virReportOOMError();
 
457
@@ -770,9 +771,11 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
 
458
     def->mem.cur_balloon *= 1024;
 
459
     def->mem.max_balloon *= 1024;
 
460
 
 
461
-
 
462
-    if (xenXMConfigGetULong(conf, "vcpus", &def->vcpus, 1) < 0)
 
463
+    if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 ||
 
464
+        (unsigned short) count != count)
 
465
         goto cleanup;
 
466
+    def->maxvcpus = count;
 
467
+    def->vcpus = def->maxvcpus;
 
468
 
 
469
     if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
 
470
         goto cleanup;
 
471
@@ -1650,7 +1653,7 @@ int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus) {
 
472
     if (!(entry = virHashLookup(priv->configCache, filename)))
 
473
         goto cleanup;
 
474
 
 
475
-    entry->def->vcpus = vcpus;
 
476
+    entry->def->maxvcpus = entry->def->vcpus = vcpus;
 
477
 
 
478
     /* If this fails, should we try to undo our changes to the
 
479
      * in-memory representation of the config file. I say not!
 
480
@@ -2241,7 +2244,7 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
 
481
     if (xenXMConfigSetInt(conf, "memory", def->mem.cur_balloon / 1024) < 0)
 
482
         goto no_memory;
 
483
 
 
484
-    if (xenXMConfigSetInt(conf, "vcpus", def->vcpus) < 0)
 
485
+    if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
 
486
         goto no_memory;
 
487
 
 
488
     if ((def->cpumask != NULL) &&
 
489
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
 
490
index 7d4ab8d..5ccdede 100644
 
491
--- a/src/xenapi/xenapi_driver.c
 
492
+++ b/src/xenapi/xenapi_driver.c
 
493
@@ -1335,7 +1335,7 @@ xenapiDomainDumpXML (virDomainPtr dom, int flags ATTRIBUTE_UNUSED)
 
494
     } else {
 
495
         defPtr->mem.cur_balloon = memory;
 
496
     }
 
497
-    defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
 
498
+    defPtr->maxvcpus = defPtr->vcpus = xenapiDomainGetMaxVcpus(dom);
 
499
     enum xen_on_normal_exit action;
 
500
     if (xen_vm_get_actions_after_shutdown(session, &action, vm)) {
 
501
         defPtr->onPoweroff = xenapiNormalExitEnum2virDomainLifecycle(action);
 
502
diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c
 
503
index be55491..a7e2a4b 100644
 
504
--- a/src/xenapi/xenapi_utils.c
 
505
+++ b/src/xenapi/xenapi_utils.c
 
506
@@ -510,8 +510,8 @@ createVMRecordFromXml (virConnectPtr conn, virDomainDefPtr def,
 
507
     else
 
508
         (*record)->memory_dynamic_max = (*record)->memory_static_max;
 
509
 
 
510
-    if (def->vcpus) {
 
511
-        (*record)->vcpus_max = (int64_t) def->vcpus;
 
512
+    if (def->maxvcpus) {
 
513
+        (*record)->vcpus_max = (int64_t) def->maxvcpus;
 
514
         (*record)->vcpus_at_startup = (int64_t) def->vcpus;
 
515
     }
 
516
     if (def->onPoweroff)
 
517
-- 
 
518
1.7.2.3
 
519