ia64/xen-unstable

view tools/xfrd/xen_domain.c @ 1820:3d4f8eb89670

bitkeeper revision 1.1106.1.2 (40faa780dekT3E5arFwcbQDu1MbX6g)

Cleaned up Xen's instruction emulator.
author kaf24@scramble.cl.cam.ac.uk
date Sun Jul 18 16:38:24 2004 +0000 (2004-07-18)
parents 095e969226c4
children 51b2d77c6d1f dae98734f12e
line source
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <stdio.h>
5 #ifndef _XEN_XFR_STUB_
6 #include "xc.h"
7 #include "xc_io.h"
8 #endif
10 #include "xen_domain.h"
11 #include "marshal.h"
12 #include "xdr.h"
13 #include "xfrd.h"
15 #define MODULE_NAME "XFRD"
16 #define DEBUG 1
17 #include "debug.h"
19 #ifndef _XEN_XFR_STUB_
20 static int domain_suspend(u32 dom, void *data){
21 int err = 0;
22 Conn *xend = data;
24 dprintf("> dom=%lu data=%p\n", dom, data);
25 err = xfr_vm_suspend(xend, dom);
26 dprintf("< err=%d\n", err);
27 return err;
28 }
30 static int xc_handle = 0;
32 int xcinit(void){
33 if(xc_handle <= 0){
34 xc_handle = xc_interface_open();
35 }
36 dprintf("< xc_handle=%d\n", xc_handle);
37 return xc_handle;
38 }
40 void xcfini(void){
41 if(xc_handle > 0){
42 xc_interface_close(xc_handle);
43 xc_handle = 0;
44 }
45 }
46 #endif
48 /** Write domain state.
49 *
50 * At some point during this the domain is suspended, and then there's no way back.
51 * Even if something later goes wrong we can't restart the domain.
52 */
53 int xen_domain_snd(Conn *xend, IOStream *io, uint32_t dom, char *vmconfig, int vmconfig_n){
54 int err = 0;
55 #ifdef _XEN_XFR_STUB_
56 char buf[1024];
57 int n, k, d, buf_n;
58 dprintf("> dom=%d\n", dom);
59 err = marshal_uint32(io, dom);
60 if(err) goto exit;
61 err = marshal_string(io, vmconfig, vmconfig_n);
62 if(err) goto exit;
63 n = 32 * 1024 * 1024;
64 buf_n = sizeof(buf);
65 err = marshal_uint32(io, n);
66 for(k = 0; k < n; k += d){
67 d = n - k;
68 if(d > buf_n) d = buf_n;
69 err = marshal_bytes(io, buf, d);
70 if(err) goto exit;
71 dprintf("> k=%d n=%d\n", k, n);
72 }
74 dom = 99;
75 err = xfr_vm_suspend(xend, dom);
76 exit:
77 #else
78 XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
79 dprintf("> dom=%d\n", dom);
80 ioctxt->domain = dom;
81 ioctxt->io = io;
82 ioctxt->info = iostdout;
83 ioctxt->err = iostderr;
84 ioctxt->data = xend;
85 ioctxt->suspend = domain_suspend;
87 err = xc_linux_save(xcinit(), ioctxt);
88 #endif
89 dprintf("< err=%d\n", err);
90 return err;
91 }
93 /** Receive domain state.
94 * Create a new domain and store the received state into it.
95 */
96 int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n){
97 int err = 0;
98 #ifdef _XEN_XFR_STUB_
99 char buf[1024];
100 int n, k, d, buf_n;
101 dprintf(">\n");
102 err = unmarshal_uint32(io, dom);
103 if(err) goto exit;
104 err = unmarshal_new_string(io, vmconfig, vmconfig_n);
105 if(err) goto exit;
106 err = unmarshal_uint32(io, &n);
107 buf_n = sizeof(buf);
108 for(k = 0; k < n; k += d){
109 d = n - k;
110 if(d > buf_n) d = buf_n;
111 err = unmarshal_bytes(io, buf, d);
112 if(err) goto exit;
113 dprintf("> k=%d n=%d\n", k, n);
114 }
115 exit:
116 #else
117 XcIOContext _ioctxt = {}, *ioctxt = &_ioctxt;
118 dprintf(">\n");
119 ioctxt->io = io;
120 ioctxt->info = iostdout;
121 ioctxt->err = iostderr;
123 err = xc_linux_restore(xcinit(), ioctxt);
124 #endif
125 dprintf("< err=%d\n", err);
126 return err;
127 }
129 #include <curl/curl.h>
131 static int do_curl_global_init = 1;
133 static CURL *curlinit(void){
134 if(do_curl_global_init){
135 do_curl_global_init = 0;
136 curl_global_init(CURL_GLOBAL_ALL);
137 }
138 return curl_easy_init();
139 }
141 /** Configure a new domain. Talk to xend using libcurl.
142 */
143 int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){
144 int err = 0;
145 CURL *curl = NULL;
146 CURLcode curlcode = 0;
147 char domainurl[128] = {};
148 int domainurl_n = sizeof(domainurl) - 1;
149 int n;
150 struct curl_httppost *form = NULL, *last = NULL;
151 CURLFORMcode formcode = 0;
153 dprintf("> dom=%u\n", dom);
154 curl = curlinit();
155 if(!curl){
156 eprintf("> Could not init libcurl\n");
157 err = -ENOMEM;
158 goto exit;
159 }
160 n = snprintf(domainurl, domainurl_n,
161 "http://localhost:%d/xend/domain/%u", XEND_PORT, dom);
162 if(n <= 0 || n >= domainurl_n){
163 err = -ENOMEM;
164 eprintf("Out of memory in url.\n");
165 goto exit;
166 }
167 // Config field - set from vmconfig.
168 formcode = curl_formadd(&form, &last,
169 CURLFORM_COPYNAME, "config",
170 CURLFORM_BUFFER, "config",
171 CURLFORM_BUFFERPTR, vmconfig,
172 CURLFORM_BUFFERLENGTH, vmconfig_n,
173 CURLFORM_CONTENTTYPE, "application/octet-stream",
174 CURLFORM_END);
175 if(formcode){
176 eprintf("> Error adding config field.\n");
177 goto exit;
178 }
179 // Op field.
180 formcode = curl_formadd(&form, &last,
181 CURLFORM_COPYNAME, "op",
182 CURLFORM_COPYCONTENTS, "configure",
183 CURLFORM_END);
185 if(formcode){
186 eprintf("> Error adding op field.\n");
187 goto exit;
188 }
189 // No progress meter.
190 //curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
191 // Completely quiet.
192 //curl_easy_setopt(curl, CURLOPT_MUTE, 1);
193 // Set the URL.
194 curl_easy_setopt(curl, CURLOPT_URL, domainurl);
195 // POST the form.
196 curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
197 dprintf("> curl perform...\n");
198 #ifdef _XEN_XFR_STUB_
199 dprintf("> _XEN_XFR_STUB_ defined - not calling xend\n");
200 curlcode = 0;
201 #else
202 curlcode = curl_easy_perform(curl);
203 #endif
204 exit:
205 if(curl) curl_easy_cleanup(curl);
206 if(form) curl_formfree(form);
207 if(formcode){
208 dprintf("> formcode=%d\n", formcode);
209 err = -EINVAL;
210 }
211 if(curlcode){
212 dprintf("> curlcode=%d\n", curlcode);
213 err = -EINVAL;
214 }
215 dprintf("< err=%d\n", err);
216 return err;
217 }