daemon: Move TLS initialization to virInitialize
[libvirt/zwu.git] / docs / api_extension / 0014-improve-setting-xen-vcpu-counts.patch
blob76dc948b23ebb38e51dc0f0b7704e0a033eb4886
1 From e443a003129a172a7332f3cb6e40b3c39363ed5e Mon Sep 17 00:00:00 2001
2 From: Eric Blake <eblake@redhat.com>
3 Date: Thu, 14 Oct 2010 16:17:18 -0600
4 Subject: [PATCH 14/15] vcpu: improve support for setting xen vcpu counts
6 Tested with RHEL 5.6 (xendConfigVersion 2, where xend_internal
7 controls live domains and xm_internal controls inactive domains).
8 Hopefully this works with xendConfigVersion 3 (where xend_internal
9 controls everything).
11 * src/xen/xen_driver.c (xenUnifiedDomainSetVcpusFlags): Support
12 more flags.
13 (xenUnifiedGetMaxVcpus): Export.
14 * src/xen/xm_internal.h (xenXMDomainSetVcpusFlags): New prototype.
15 * src/xen/xend_internal.h (xenDaemonDomainSetVcpusFlags): Likewise.
16 * src/xen/xen_driver.h (xenUnifiedGetMaxVcpus): Likewise.
17 * src/xen/xm_internal.c (xenXMDomainSetVcpusFlags): New function.
18 * src/xen/xend_internal.c (xenDaemonDomainSetVcpusFlags): Likewise.
19 ---
20 src/xen/xen_driver.c | 60 ++++++++++++++++++++++++---------
21 src/xen/xen_driver.h | 1 +
22 src/xen/xend_internal.c | 76 +++++++++++++++++++++++++++++++++++++++++++
23 src/xen/xend_internal.h | 3 ++
24 src/xen/xm_internal.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++
25 src/xen/xm_internal.h | 2 +
26 6 files changed, 208 insertions(+), 17 deletions(-)
28 diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
29 index fe2ff86..66e8518 100644
30 --- a/src/xen/xen_driver.c
31 +++ b/src/xen/xen_driver.c
32 @@ -508,7 +508,7 @@ xenUnifiedIsSecure(virConnectPtr conn)
33 return ret;
36 -static int
37 +int
38 xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type)
40 GET_PRIVATE(conn);
41 @@ -1073,36 +1073,62 @@ xenUnifiedDomainSetVcpusFlags (virDomainPtr dom, unsigned int nvcpus,
42 unsigned int flags)
44 GET_PRIVATE(dom->conn);
45 - int i;
46 + int ret;
48 + virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
49 + VIR_DOMAIN_VCPU_CONFIG |
50 + VIR_DOMAIN_VCPU_MAXIMUM, -1);
52 - if (flags != VIR_DOMAIN_VCPU_LIVE) {
53 - xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
54 - flags);
55 + /* At least one of LIVE or CONFIG must be set. MAXIMUM cannot be
56 + * mixed with LIVE. */
57 + if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
58 + (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
59 + (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
60 + xenUnifiedError(VIR_ERR_INVALID_ARG,
61 + _("invalid flag combination: (0x%x)"), flags);
62 + return -1;
63 + }
64 + if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
65 + xenUnifiedError(VIR_ERR_INVALID_ARG,
66 + _("argument out of range: %d"), nvcpus);
67 return -1;
70 /* Try non-hypervisor methods first, then hypervisor direct method
71 * as a last resort.
73 - for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
74 - if (i != XEN_UNIFIED_HYPERVISOR_OFFSET &&
75 - priv->opened[i] &&
76 - drivers[i]->domainSetVcpus &&
77 - drivers[i]->domainSetVcpus (dom, nvcpus) == 0)
78 - return 0;
80 - if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET] &&
81 - drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainSetVcpus &&
82 - drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainSetVcpus (dom, nvcpus) == 0)
83 - return 0;
84 + if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
85 + ret = xenDaemonDomainSetVcpusFlags(dom, nvcpus, flags);
86 + if (ret != -2)
87 + return ret;
88 + }
89 + if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
90 + ret = xenXMDomainSetVcpusFlags(dom, nvcpus, flags);
91 + if (ret != -2)
92 + return ret;
93 + }
94 + if (flags == VIR_DOMAIN_VCPU_LIVE)
95 + return xenHypervisorSetVcpus(dom, nvcpus);
97 + xenUnifiedError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
98 return -1;
101 static int
102 xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
104 - return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
105 + unsigned int flags = VIR_DOMAIN_VCPU_LIVE;
106 + xenUnifiedPrivatePtr priv;
108 + /* Per the documented API, it is hypervisor-dependent whether this
109 + * affects just _LIVE or _LIVE|_CONFIG; in xen's case, that
110 + * depends on xendConfigVersion. */
111 + if (dom) {
112 + priv = dom->conn->privateData;
113 + if (priv->xendConfigVersion >= 3)
114 + flags |= VIR_DOMAIN_VCPU_CONFIG;
116 + return xenUnifiedDomainSetVcpusFlags(dom, nvcpus, flags);
119 static int
120 diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
121 index 3e7c1d0..115a26a 100644
122 --- a/src/xen/xen_driver.h
123 +++ b/src/xen/xen_driver.h
124 @@ -220,6 +220,7 @@ int xenUnifiedRemoveDomainInfo(xenUnifiedDomainInfoListPtr info,
125 void xenUnifiedDomainEventDispatch (xenUnifiedPrivatePtr priv,
126 virDomainEventPtr event);
127 unsigned long xenUnifiedVersion(void);
128 +int xenUnifiedGetMaxVcpus(virConnectPtr conn, const char *type);
130 # ifndef PROXY
131 void xenUnifiedLock(xenUnifiedPrivatePtr priv);
132 diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
133 index 3642296..55c2cc4 100644
134 --- a/src/xen/xend_internal.c
135 +++ b/src/xen/xend_internal.c
136 @@ -3535,6 +3535,82 @@ xenDaemonLookupByID(virConnectPtr conn, int id) {
140 + * xenDaemonDomainSetVcpusFlags:
141 + * @domain: pointer to domain object
142 + * @nvcpus: the new number of virtual CPUs for this domain
143 + * @flags: bitwise-ORd from virDomainVcpuFlags
145 + * Change virtual CPUs allocation of domain according to flags.
147 + * Returns 0 on success, -1 if an error message was issued, and -2 if
148 + * the unified driver should keep trying.
149 + */
150 +int
151 +xenDaemonDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
152 + unsigned int flags)
154 + char buf[VIR_UUID_BUFLEN];
155 + xenUnifiedPrivatePtr priv;
156 + int max;
158 + if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
159 + || (vcpus < 1)) {
160 + virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
161 + return (-1);
164 + priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
166 + if ((domain->id < 0 && priv->xendConfigVersion < 3) ||
167 + (flags & VIR_DOMAIN_VCPU_MAXIMUM))
168 + return -2;
170 + /* With xendConfigVersion 2, only _LIVE is supported. With
171 + * xendConfigVersion 3, only _LIVE|_CONFIG is supported for
172 + * running domains, or _CONFIG for inactive domains. */
173 + if (priv->xendConfigVersion < 3) {
174 + if (flags & VIR_DOMAIN_VCPU_CONFIG) {
175 + virXendError(VIR_ERR_OPERATION_INVALID, "%s",
176 + _("Xend version does not support modifying "
177 + "persistent config"));
178 + return -1;
180 + } else if (domain->id < 0) {
181 + if (flags & VIR_DOMAIN_VCPU_LIVE) {
182 + virXendError(VIR_ERR_OPERATION_INVALID, "%s",
183 + _("domain not running"));
184 + return -1;
186 + } else {
187 + if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) !=
188 + (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) {
189 + virXendError(VIR_ERR_OPERATION_INVALID, "%s",
190 + _("Xend only supports modifying both live and "
191 + "persistent config"));
195 + /* Unfortunately, xend_op does not validate whether this exceeds
196 + * the maximum. */
197 + flags |= VIR_DOMAIN_VCPU_MAXIMUM;
198 + if ((max = xenDaemonDomainGetVcpusFlags(domain, flags)) < 0) {
199 + virXendError(VIR_ERR_OPERATION_INVALID, "%s",
200 + _("could not determin max vcpus for the domain"));
201 + return -1;
203 + if (vcpus > max) {
204 + virXendError(VIR_ERR_INVALID_ARG,
205 + _("requested vcpus is greater than max allowable"
206 + " vcpus for the domain: %d > %d"), vcpus, max);
207 + return -1;
210 + snprintf(buf, sizeof(buf), "%d", vcpus);
211 + return xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus",
212 + buf, NULL);
215 +/**
216 * xenDaemonDomainSetVcpus:
217 * @domain: pointer to domain object
218 * @nvcpus: the new number of virtual CPUs for this domain
219 diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
220 index 923cebd..53f5d2c 100644
221 --- a/src/xen/xend_internal.h
222 +++ b/src/xen/xend_internal.h
223 @@ -151,6 +151,9 @@ int xenDaemonDomainUndefine(virDomainPtr domain);
225 int xenDaemonDomainSetVcpus (virDomainPtr domain,
226 unsigned int vcpus);
227 +int xenDaemonDomainSetVcpusFlags (virDomainPtr domain,
228 + unsigned int vcpus,
229 + unsigned int flags);
230 int xenDaemonDomainPinVcpu (virDomainPtr domain,
231 unsigned int vcpu,
232 unsigned char *cpumap,
233 diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
234 index 4ea4245..2b8e51e 100644
235 --- a/src/xen/xm_internal.c
236 +++ b/src/xen/xm_internal.c
237 @@ -1670,6 +1670,89 @@ cleanup:
238 return ret;
242 + * xenXMDomainSetVcpusFlags:
243 + * @domain: pointer to domain object
244 + * @nvcpus: number of vcpus
245 + * @flags: bitwise-ORd from virDomainVcpuFlags
247 + * Change virtual CPUs allocation of domain according to flags.
249 + * Returns 0 on success, -1 if an error message was issued, and -2 if
250 + * the unified driver should keep trying.
251 + */
252 +int
253 +xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
254 + unsigned int flags)
256 + xenUnifiedPrivatePtr priv;
257 + const char *filename;
258 + xenXMConfCachePtr entry;
259 + int ret = -1;
260 + int max;
262 + if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
263 + xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
264 + return -1;
266 + if (domain->conn->flags & VIR_CONNECT_RO) {
267 + xenXMError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
268 + return -1;
270 + if (domain->id != -1)
271 + return -2;
272 + if (flags & VIR_DOMAIN_VCPU_LIVE) {
273 + xenXMError(VIR_ERR_OPERATION_INVALID, "%s",
274 + _("domain is not running"));
275 + return -1;
278 + priv = domain->conn->privateData;
279 + xenUnifiedLock(priv);
281 + if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
282 + goto cleanup;
284 + if (!(entry = virHashLookup(priv->configCache, filename)))
285 + goto cleanup;
287 + /* Hypervisor maximum. */
288 + if ((max = xenUnifiedGetMaxVcpus(domain->conn, NULL)) < 0) {
289 + xenXMError(VIR_ERR_INTERNAL_ERROR, "%s",
290 + _("could not determin max vcpus for the domain"));
291 + goto cleanup;
293 + /* Can't specify a current larger than stored maximum; but
294 + * reducing maximum can silently reduce current. */
295 + if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM))
296 + max = entry->def->maxvcpus;
297 + if (vcpus > max) {
298 + xenXMError(VIR_ERR_INVALID_ARG,
299 + _("requested vcpus is greater than max allowable"
300 + " vcpus for the domain: %d > %d"), vcpus, max);
301 + goto cleanup;
304 + if (flags & VIR_DOMAIN_VCPU_MAXIMUM) {
305 + entry->def->maxvcpus = vcpus;
306 + if (entry->def->vcpus > vcpus)
307 + entry->def->vcpus = vcpus;
308 + } else {
309 + entry->def->vcpus = vcpus;
312 + /* If this fails, should we try to undo our changes to the
313 + * in-memory representation of the config file. I say not!
314 + */
315 + if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
316 + goto cleanup;
317 + ret = 0;
319 +cleanup:
320 + xenUnifiedUnlock(priv);
321 + return ret;
325 * xenXMDomainGetVcpusFlags:
326 * @domain: pointer to domain object
327 diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
328 index 3295fbd..a46e1a2 100644
329 --- a/src/xen/xm_internal.h
330 +++ b/src/xen/xm_internal.h
331 @@ -45,6 +45,8 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
332 int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
333 unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain);
334 int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus);
335 +int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
336 + unsigned int flags);
337 int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags);
338 int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
339 unsigned char *cpumap, int maplen);
341 1.7.2.3