ia64/xen-unstable

view tools/xfrd/xen_domain.c @ 3498:1d24a5b0b338

bitkeeper revision 1.1159.223.25 (41f2cb9aEKMZkZbvqBE0eXhpljlV4Q)

Description: fix path to python
There is no python2 in debian. Instead, use python.

From: Adam Heath <doogie@brainfood.com>
Signed-off-by: ian.pratt@cl.cam.ac.uk
author iap10@labyrinth.cl.cam.ac.uk
date Sat Jan 22 21:54:34 2005 +0000 (2005-01-22)
parents f65b65977b19
children 0a4b76b6b5a0 fff34e3e2b40 0dc3b8b8c298
line source
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <stdio.h>
5 #ifdef _XEN_XFR_STUB_
6 typedef unsigned long u32;
7 #else
8 #include "xc.h"
9 #include "xc_io.h"
10 #endif
12 #include "xen_domain.h"
13 #include "marshal.h"
14 #include "xdr.h"
15 #include "xfrd.h"
17 #define MODULE_NAME "XFRD"
18 #define DEBUG 1
19 #undef DEBUG
20 #include "debug.h"
22 int domain_suspend(void *data, u32 dom){
23 int err = 0;
24 Conn *xend = data;
26 dprintf("> dom=%lu data=%p\n", dom, data);
27 err = xfr_vm_suspend(xend, dom);
28 dprintf("< err=%d\n", err);
29 return err;
30 }
32 int domain_configure(void *data, u32 dom, char *vmconfig, int vmconfig_n){
33 return xen_domain_configure(dom, vmconfig, vmconfig_n);
34 }
36 #ifndef _XEN_XFR_STUB_
37 static int xc_handle = 0;
39 int xcinit(void){
40 if(xc_handle <= 0){
41 xc_handle = xc_interface_open();
42 }
43 dprintf("< xc_handle=%d\n", xc_handle);
44 return xc_handle;
45 }
47 void xcfini(void){
48 if(xc_handle > 0){
49 xc_interface_close(xc_handle);
50 xc_handle = 0;
51 }
52 }
53 #endif
55 /** Write domain state.
56 *
57 * At some point during this the domain is suspended, and then there's no way back.
58 * Even if something later goes wrong we can't restart the domain.
59 */
60 int xen_domain_snd(Conn *xend, IOStream *io,
61 uint32_t dom,
62 char *vmconfig, int vmconfig_n,
63 int live, int resource){
64 int err = 0;
65 #ifdef _XEN_XFR_STUB_
66 char buf[1024];
67 int n, k, d, buf_n;
68 dprintf("> dom=%d\n", dom);
69 err = marshal_uint32(io, dom);
70 if(err) goto exit;
71 err = marshal_string(io, vmconfig, vmconfig_n);
72 if(err) goto exit;
73 n = 32 * 1024 * 1024;
74 n = 32 * 1024;
75 buf_n = sizeof(buf);
76 err = marshal_uint32(io, n);
77 for(k = 0; k < n; k += d){
78 d = n - k;
79 if(d > buf_n) d = buf_n;
80 err = marshal_bytes(io, buf, d);
81 if(err) goto exit;
82 dprintf("> k=%d n=%d\n", k, n);
83 }
85 dom = 99;
86 err = domain_suspend(xend, dom);
87 IOStream_close(io);
88 exit:
89 #else
90 XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
91 ioctxt->domain = dom;
92 ioctxt->io = io;
93 ioctxt->info = iostdout;
94 ioctxt->err = iostderr;
95 ioctxt->data = xend;
96 ioctxt->suspend = domain_suspend;
97 ioctxt->vmconfig = vmconfig;
98 ioctxt->vmconfig_n = vmconfig_n;
99 if(live){
100 ioctxt->flags |= XCFLAGS_LIVE;
101 }
102 ioctxt->resource = resource;
103 err = xc_linux_save(xcinit(), ioctxt);
104 #endif
105 dprintf("< err=%d\n", err);
106 return err;
107 }
109 /** Receive domain state.
110 * Create a new domain and store the received state into it.
111 */
112 int xen_domain_rcv(IOStream *io,
113 uint32_t *dom,
114 char **vmconfig, int *vmconfig_n,
115 int *configured){
116 int err = 0;
117 #ifdef _XEN_XFR_STUB_
118 char buf[1024];
119 int n, k, d, buf_n;
120 dprintf(">\n");
121 err = unmarshal_uint32(io, dom);
122 if(err) goto exit;
123 err = unmarshal_new_string(io, vmconfig, vmconfig_n);
124 if(err) goto exit;
125 err = unmarshal_uint32(io, &n);
126 buf_n = sizeof(buf);
127 for(k = 0; k < n; k += d){
128 d = n - k;
129 if(d > buf_n) d = buf_n;
130 err = unmarshal_bytes(io, buf, d);
131 if(err) goto exit;
132 dprintf("> k=%d n=%d\n", k, n);
133 }
134 exit:
135 #else
136 XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
137 dprintf(">\n");
138 ioctxt->io = io;
139 ioctxt->info = iostdout;
140 ioctxt->err = iostderr;
141 ioctxt->configure = domain_configure;
142 if ( !*configured )
143 ioctxt->flags |= XCFLAGS_CONFIGURE;
145 err = xc_linux_restore(xcinit(), ioctxt);
146 *dom = ioctxt->domain;
147 *vmconfig = ioctxt->vmconfig;
148 *vmconfig_n = ioctxt->vmconfig_n;
149 *configured = (ioctxt->flags & XCFLAGS_CONFIGURE);
150 #endif
151 dprintf("< err=%d\n", err);
152 return err;
153 }
155 #include <curl/curl.h>
156 #include "http.h"
158 /** Flag indicating whether we need to initialize libcurl.
159 */
160 static int do_curl_global_init = 1;
162 /** Get a curl handle, initializing libcurl if needed.
163 *
164 * @return curl handle
165 */
166 static CURL *curlinit(void){
167 if(do_curl_global_init){
168 do_curl_global_init = 0;
169 // Stop libcurl using the proxy. There's a curl option to
170 // set the proxy - but no option to defeat it.
171 unsetenv("http_proxy");
172 curl_global_init(CURL_GLOBAL_ALL);
173 }
174 return curl_easy_init();
175 }
177 /** Curl debug function.
178 */
179 int curldebug(CURL *curl, curl_infotype ty, char *buf, size_t buf_n, void *data){
180 printf("%*s\n", buf_n, buf);
181 return 0;
182 }
184 /** Setup a curl handle with a url.
185 * Creates the url by formatting 'fmt' and the remaining arguments.
186 *
187 * @param pcurl return parameter for the curl handle
188 * @param url url buffer
189 * @param url_n size of url
190 * @param fmt url format string, followed by parameters
191 * @return 0 on success, error code otherwise
192 */
193 static int curlsetup(CURL **pcurl, struct curl_slist **pheaders, char *url, int url_n, char *fmt, ...){
194 int err = 0;
195 va_list args;
196 CURL *curl = NULL;
197 struct curl_slist *headers = NULL;
198 int n = 0;
200 curl = curlinit();
201 if(!curl){
202 eprintf("> Could not init libcurl\n");
203 err = -ENOMEM;
204 goto exit;
205 }
206 url_n -= 1;
207 va_start(args, fmt);
208 n = vsnprintf(url, url_n, fmt, args);
209 va_end(args);
210 if(n <= 0 || n >= url_n){
211 err = -ENOMEM;
212 eprintf("> Out of memory in url\n");
213 goto exit;
214 }
215 dprintf("> url=%s\n", url);
216 #if DEBUG
217 // Verbose.
218 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
219 // Call the debug function on data received.
220 curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curldebug);
221 #else
222 // No progress meter.
223 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
224 // Completely quiet.
225 curl_easy_setopt(curl, CURLOPT_MUTE, 1);
226 #endif
227 // Set the URL.
228 curl_easy_setopt(curl, CURLOPT_URL, url);
230 headers = curl_slist_append(headers, "Expect:");
231 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
233 exit:
234 if(err && curl){
235 curl_easy_cleanup(curl);
236 curl = NULL;
237 }
238 *pcurl = curl;
239 if (pheaders)
240 *pheaders = headers;
241 return err;
242 }
244 static void curlcleanup(CURL **pcurl, struct curl_slist **pheaders){
245 if (*pcurl)
246 curl_easy_cleanup(*pcurl);
247 if (*pheaders)
248 curl_slist_free_all(*pheaders);
249 *pcurl = NULL;
250 *pheaders = NULL;
251 }
252 /** Make the http request stored in the curl handle and get
253 * the result code from the curl code and the http return code.
254 *
255 * @param curl curl handle
256 * @return 0 for success, error code otherwise
257 */
258 int curlresult(CURL *curl){
259 int err = 0;
260 CURLcode curlcode = 0;
261 long httpcode = 0;
263 curlcode = curl_easy_perform(curl);
264 if(curlcode){
265 eprintf("> curlcode=%d\n", curlcode);
266 err = -EINVAL;
267 goto exit;
268 }
269 curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode);
270 if(httpcode != HTTP_OK){
271 eprintf("> httpcode=%d\n", (int)httpcode);
272 err = -EINVAL;
273 goto exit;
274 }
275 exit:
276 return err;
277 }
279 /** Get xend to list domains.
280 * We use this to force xend to refresh its domain list.
281 *
282 * @return 0 on success, error code otherwise
283 */
284 int xen_domain_ls(void){
285 int err = 0;
286 CURL *curl = NULL;
287 struct curl_slist *headers = NULL;
288 char url[128] = {};
289 int url_n = sizeof(url);
291 dprintf(">\n");
292 err = curlsetup(&curl, &headers, url, url_n, "http://localhost:%d/xend/domain", XEND_PORT);
293 if(err) goto exit;
294 err = curlresult(curl);
295 exit:
296 curlcleanup(&curl, &headers);
297 dprintf("< err=%d\n", err);
298 return err;
299 }
301 /** Get xend to configure a new domain.
302 *
303 * @param dom domain id
304 * @param vmconfig configuration string
305 * @param vmconfig_n length of vmconfig
306 * @return 0 on success, error code otherwise
307 */
308 int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){
309 int err = 0;
310 CURL *curl = NULL;
311 struct curl_slist *headers = NULL;
312 char url[128] = {};
313 int url_n = sizeof(url);
314 struct curl_httppost *form = NULL, *last = NULL;
315 CURLFORMcode formcode = 0;
317 dprintf("> dom=%u\n", dom);
318 // List domains so that xend will update its domain list and notice the new domain.
319 xen_domain_ls();
321 err = curlsetup(&curl, &headers, url, url_n, "http://localhost:%d/xend/domain/%u", XEND_PORT, dom);
322 if(err) goto exit;
324 // Config field - set from vmconfig.
325 formcode = curl_formadd(&form, &last,
326 CURLFORM_COPYNAME, "config",
327 CURLFORM_BUFFER, "config",
328 CURLFORM_BUFFERPTR, vmconfig,
329 CURLFORM_BUFFERLENGTH, vmconfig_n,
330 CURLFORM_CONTENTTYPE, "application/octet-stream",
331 CURLFORM_END);
332 if(formcode){
333 eprintf("> Error adding config field.\n");
334 goto exit;
335 }
336 // Op field.
337 formcode = curl_formadd(&form, &last,
338 CURLFORM_COPYNAME, "op",
339 CURLFORM_COPYCONTENTS, "configure",
340 CURLFORM_END);
341 if(formcode){
342 eprintf("> Error adding op field.\n");
343 err = -EINVAL;
344 goto exit;
345 }
346 // POST the form.
347 curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
348 err = curlresult(curl);
349 exit:
350 curlcleanup(&curl, &headers);
351 if(form) curl_formfree(form);
352 dprintf("< err=%d\n", err);
353 return err;
354 }
356 /** Get xend to unpause a domain.
357 *
358 * @param dom domain id
359 * @return 0 on success, error code otherwise
360 */
361 int xen_domain_unpause(uint32_t dom){
362 int err = 0;
363 CURL *curl = NULL;
364 struct curl_slist *headers = NULL;
365 char url[128] = {};
366 int url_n = sizeof(url);
367 struct curl_httppost *form = NULL, *last = NULL;
368 CURLFORMcode formcode = 0;
370 dprintf("> dom=%u\n", dom);
372 err = curlsetup(&curl, &headers, url, url_n, "http://localhost:%d/xend/domain/%u", XEND_PORT, dom);
373 if(err) goto exit;
375 // Op field.
376 formcode = curl_formadd(&form, &last,
377 CURLFORM_COPYNAME, "op",
378 CURLFORM_COPYCONTENTS, "unpause",
379 CURLFORM_END);
380 if(formcode){
381 eprintf("> Error adding op field.\n");
382 err = -EINVAL;
383 goto exit;
384 }
385 // POST the form.
386 curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
387 err = curlresult(curl);
388 exit:
389 curlcleanup(&curl, &headers);
390 if(form) curl_formfree(form);
391 dprintf("< err=%d\n", err);
392 return err;
393 }