ia64/xen-unstable

view tools/libxc/xc_domain.c @ 7238:971e7c7411b3

Raise an exception if an error appears on the pipes to our children, and make
sure that the child's pipes are closed even under that exception. Move the
handling of POLLHUP to the end of the loop, so that we guarantee to read any
remaining data from the child if POLLHUP and POLLIN appear at the same time.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@ewan
date Thu Oct 06 10:13:11 2005 +0100 (2005-10-06)
parents 06d84bf87159
children b3a255e88810
line source
1 /******************************************************************************
2 * xc_domain.c
3 *
4 * API for manipulating and obtaining information on domains.
5 *
6 * Copyright (c) 2003, K A Fraser.
7 */
9 #include "xc_private.h"
10 #include <xen/memory.h>
12 int xc_domain_create(int xc_handle,
13 u32 ssidref,
14 u32 *pdomid)
15 {
16 int err;
17 dom0_op_t op;
19 op.cmd = DOM0_CREATEDOMAIN;
20 op.u.createdomain.domain = (domid_t)*pdomid;
21 op.u.createdomain.ssidref = ssidref;
22 if ( (err = do_dom0_op(xc_handle, &op)) != 0 )
23 return err;
25 *pdomid = (u16)op.u.createdomain.domain;
26 return 0;
27 }
30 int xc_domain_pause(int xc_handle,
31 u32 domid)
32 {
33 dom0_op_t op;
34 op.cmd = DOM0_PAUSEDOMAIN;
35 op.u.pausedomain.domain = (domid_t)domid;
36 return do_dom0_op(xc_handle, &op);
37 }
40 int xc_domain_unpause(int xc_handle,
41 u32 domid)
42 {
43 dom0_op_t op;
44 op.cmd = DOM0_UNPAUSEDOMAIN;
45 op.u.unpausedomain.domain = (domid_t)domid;
46 return do_dom0_op(xc_handle, &op);
47 }
50 int xc_domain_destroy(int xc_handle,
51 u32 domid)
52 {
53 dom0_op_t op;
54 op.cmd = DOM0_DESTROYDOMAIN;
55 op.u.destroydomain.domain = (domid_t)domid;
56 return do_dom0_op(xc_handle, &op);
57 }
59 int xc_domain_pincpu(int xc_handle,
60 u32 domid,
61 int vcpu,
62 cpumap_t *cpumap)
63 {
64 dom0_op_t op;
65 op.cmd = DOM0_PINCPUDOMAIN;
66 op.u.pincpudomain.domain = (domid_t)domid;
67 op.u.pincpudomain.vcpu = vcpu;
68 op.u.pincpudomain.cpumap = cpumap;
69 return do_dom0_op(xc_handle, &op);
70 }
73 int xc_domain_getinfo(int xc_handle,
74 u32 first_domid,
75 unsigned int max_doms,
76 xc_dominfo_t *info)
77 {
78 unsigned int nr_doms;
79 u32 next_domid = first_domid;
80 dom0_op_t op;
81 int rc = 0;
83 memset(info, 0, max_doms*sizeof(xc_dominfo_t));
85 for ( nr_doms = 0; nr_doms < max_doms; nr_doms++ )
86 {
87 op.cmd = DOM0_GETDOMAININFO;
88 op.u.getdomaininfo.domain = (domid_t)next_domid;
89 if ( (rc = do_dom0_op(xc_handle, &op)) < 0 )
90 break;
91 info->domid = (u16)op.u.getdomaininfo.domain;
93 info->dying = !!(op.u.getdomaininfo.flags & DOMFLAGS_DYING);
94 info->shutdown = !!(op.u.getdomaininfo.flags & DOMFLAGS_SHUTDOWN);
95 info->paused = !!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED);
96 info->blocked = !!(op.u.getdomaininfo.flags & DOMFLAGS_BLOCKED);
97 info->running = !!(op.u.getdomaininfo.flags & DOMFLAGS_RUNNING);
99 info->shutdown_reason =
100 (op.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) &
101 DOMFLAGS_SHUTDOWNMASK;
103 if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
104 {
105 info->shutdown = 0;
106 info->crashed = 1;
107 }
109 info->ssidref = op.u.getdomaininfo.ssidref;
110 info->nr_pages = op.u.getdomaininfo.tot_pages;
111 info->max_memkb = op.u.getdomaininfo.max_pages << (PAGE_SHIFT - 10);
112 info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
113 info->cpu_time = op.u.getdomaininfo.cpu_time;
114 info->vcpus = op.u.getdomaininfo.n_vcpu;
115 memcpy(&info->vcpu_to_cpu, &op.u.getdomaininfo.vcpu_to_cpu,
116 sizeof(info->vcpu_to_cpu));
117 memcpy(&info->cpumap, &op.u.getdomaininfo.cpumap,
118 sizeof(info->cpumap));
120 next_domid = (u16)op.u.getdomaininfo.domain + 1;
121 info++;
122 }
124 if( !nr_doms ) return rc;
126 return nr_doms;
127 }
129 int xc_domain_getinfolist(int xc_handle,
130 u32 first_domain,
131 unsigned int max_domains,
132 xc_domaininfo_t *info)
133 {
134 int ret = 0;
135 dom0_op_t op;
137 if ( mlock(info, max_domains*sizeof(xc_domaininfo_t)) != 0 )
138 return -1;
140 op.cmd = DOM0_GETDOMAININFOLIST;
141 op.u.getdomaininfolist.first_domain = first_domain;
142 op.u.getdomaininfolist.max_domains = max_domains;
143 op.u.getdomaininfolist.buffer = info;
145 if ( xc_dom0_op(xc_handle, &op) < 0 )
146 ret = -1;
147 else
148 ret = op.u.getdomaininfolist.num_domains;
150 if ( munlock(info, max_domains*sizeof(xc_domaininfo_t)) != 0 )
151 ret = -1;
153 return ret;
154 }
156 int xc_domain_get_vcpu_context(int xc_handle,
157 u32 domid,
158 u32 vcpu,
159 vcpu_guest_context_t *ctxt)
160 {
161 int rc;
162 dom0_op_t op;
164 op.cmd = DOM0_GETVCPUCONTEXT;
165 op.u.getvcpucontext.domain = (domid_t)domid;
166 op.u.getvcpucontext.vcpu = (u16)vcpu;
167 op.u.getvcpucontext.ctxt = ctxt;
169 if ( (ctxt != NULL) &&
170 ((rc = mlock(ctxt, sizeof(*ctxt))) != 0) )
171 return rc;
173 rc = do_dom0_op(xc_handle, &op);
175 if ( ctxt != NULL )
176 safe_munlock(ctxt, sizeof(*ctxt));
178 if ( rc > 0 )
179 return -ESRCH;
180 else
181 return rc;
182 }
185 int xc_shadow_control(int xc_handle,
186 u32 domid,
187 unsigned int sop,
188 unsigned long *dirty_bitmap,
189 unsigned long pages,
190 xc_shadow_control_stats_t *stats )
191 {
192 int rc;
193 dom0_op_t op;
194 op.cmd = DOM0_SHADOW_CONTROL;
195 op.u.shadow_control.domain = (domid_t)domid;
196 op.u.shadow_control.op = sop;
197 op.u.shadow_control.dirty_bitmap = dirty_bitmap;
198 op.u.shadow_control.pages = pages;
200 rc = do_dom0_op(xc_handle, &op);
202 if ( stats )
203 memcpy(stats, &op.u.shadow_control.stats,
204 sizeof(xc_shadow_control_stats_t));
206 return (rc == 0) ? op.u.shadow_control.pages : rc;
207 }
209 int xc_domain_setcpuweight(int xc_handle,
210 u32 domid,
211 float weight)
212 {
213 int sched_id;
214 int ret;
216 /* Figure out which scheduler is currently used: */
217 if ( (ret = xc_sched_id(xc_handle, &sched_id)) != 0 )
218 return ret;
220 switch ( sched_id )
221 {
222 case SCHED_BVT:
223 {
224 u32 mcuadv;
225 int warpback;
226 s32 warpvalue;
227 long long warpl;
228 long long warpu;
230 /* Preserve all the scheduling parameters apart
231 of MCU advance. */
232 if ( (ret = xc_bvtsched_domain_get(
233 xc_handle, domid, &mcuadv,
234 &warpback, &warpvalue, &warpl, &warpu)) != 0 )
235 return ret;
237 /* The MCU advance is inverse of the weight.
238 Default value of the weight is 1, default mcuadv 10.
239 The scaling factor is therefore 10. */
240 if ( weight > 0 )
241 mcuadv = 10 / weight;
243 ret = xc_bvtsched_domain_set(xc_handle, domid, mcuadv,
244 warpback, warpvalue, warpl, warpu);
245 break;
246 }
247 }
249 return ret;
250 }
252 int xc_domain_setmaxmem(int xc_handle,
253 u32 domid,
254 unsigned int max_memkb)
255 {
256 dom0_op_t op;
257 op.cmd = DOM0_SETDOMAINMAXMEM;
258 op.u.setdomainmaxmem.domain = (domid_t)domid;
259 op.u.setdomainmaxmem.max_memkb = max_memkb;
260 return do_dom0_op(xc_handle, &op);
261 }
263 int xc_domain_memory_increase_reservation(int xc_handle,
264 u32 domid,
265 unsigned long nr_extents,
266 unsigned int extent_order,
267 unsigned int address_bits,
268 unsigned long *extent_start)
269 {
270 int err;
271 struct xen_memory_reservation reservation = {
272 .extent_start = extent_start, /* may be NULL */
273 .nr_extents = nr_extents,
274 .extent_order = extent_order,
275 .address_bits = address_bits,
276 .domid = domid
277 };
279 err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
280 if ( err == nr_extents )
281 return 0;
283 if ( err > 0 )
284 {
285 fprintf(stderr, "Failed allocation for dom %d: "
286 "%ld pages order %d addr_bits %d\n",
287 domid, nr_extents, extent_order, address_bits);
288 errno = ENOMEM;
289 err = -1;
290 }
292 return err;
293 }
295 int xc_domain_memory_decrease_reservation(int xc_handle,
296 u32 domid,
297 unsigned long nr_extents,
298 unsigned int extent_order,
299 unsigned long *extent_start)
300 {
301 int err;
302 struct xen_memory_reservation reservation = {
303 .extent_start = extent_start,
304 .nr_extents = nr_extents,
305 .extent_order = extent_order,
306 .address_bits = 0,
307 .domid = domid
308 };
310 if ( extent_start == NULL )
311 {
312 fprintf(stderr,"decrease_reservation extent_start is NULL!\n");
313 errno = EINVAL;
314 return -1;
315 }
317 err = xc_memory_op(xc_handle, XENMEM_decrease_reservation, &reservation);
318 if ( err == nr_extents )
319 return 0;
321 if ( err > 0 )
322 {
323 fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n",
324 domid, nr_extents, extent_order);
325 errno = EBUSY;
326 err = -1;
327 }
329 return err;
330 }
332 /*
333 * Local variables:
334 * mode: C
335 * c-set-style: "BSD"
336 * c-basic-offset: 4
337 * tab-width: 4
338 * indent-tabs-mode: nil
339 * End:
340 */