debuggers.hg

view tools/misc/xen-hptool.c @ 22906:700ac6445812

Now add KDB to the non-kdb tree
author Mukesh Rathor
date Thu Feb 03 15:42:41 2011 -0800 (2011-02-03)
parents c3b5924919e3
children
line source
1 #include <xenctrl.h>
2 #include <xc_private.h>
3 #include <xc_core.h>
4 #include <errno.h>
5 #include <unistd.h>
7 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
9 static xc_interface *xch;
11 void show_help(void)
12 {
13 fprintf(stderr,
14 "xen-hptool: Xen CPU/memory hotplug tool\n"
15 "Usage: xen-hptool <command> [args]\n"
16 "Commands:\n"
17 " help display this help\n"
18 " cpu-online <cpuid> online CPU <cpuid>\n"
19 " cpu-offline <cpuid> offline CPU <cpuid>\n"
20 " mem-online <mfn> online MEMORY <mfn>\n"
21 " mem-offline <mfn> offline MEMORY <mfn>\n"
22 " mem-status <mfn> query Memory status<mfn>\n"
23 );
24 }
26 /* wrapper function */
27 static int help_func(int argc, char *argv[])
28 {
29 show_help();
30 return 0;
31 }
33 static int hp_mem_online_func(int argc, char *argv[])
34 {
35 uint32_t status;
36 int ret;
37 unsigned long mfn;
39 if (argc != 1)
40 {
41 show_help();
42 return -1;
43 }
45 sscanf(argv[0], "%lx", &mfn);
46 printf("Prepare to online MEMORY mfn %lx\n", mfn);
48 ret = xc_mark_page_online(xch, mfn, mfn, &status);
50 if (ret < 0)
51 fprintf(stderr, "Onlining page mfn %lx failed, error %x", mfn, ret);
52 else if (status & (PG_ONLINE_FAILED |PG_ONLINE_BROKEN)) {
53 fprintf(stderr, "Onlining page mfn %lx is broken, "
54 "Memory online failed\n", mfn);
55 ret = -1;
56 }
57 else if (status & PG_ONLINE_ONLINED)
58 printf("Memory mfn %lx onlined successfully\n", mfn);
59 else
60 printf("Memory is already onlined!\n");
62 return ret;
63 }
65 static int hp_mem_query_func(int argc, char *argv[])
66 {
67 uint32_t status;
68 int ret;
69 unsigned long mfn;
71 if (argc != 1)
72 {
73 show_help();
74 return -1;
75 }
77 sscanf(argv[0], "%lx", &mfn);
78 printf("Querying MEMORY mfn %lx status\n", mfn);
79 ret = xc_query_page_offline_status(xch, mfn, mfn, &status);
81 if (ret < 0)
82 fprintf(stderr, "Querying page mfn %lx failed, error %x", mfn, ret);
83 else
84 {
85 printf("Memory Status %x: [", status);
86 if ( status & PG_OFFLINE_STATUS_OFFLINE_PENDING)
87 printf(" PAGE_OFFLINE_PENDING ");
88 if ( status & PG_OFFLINE_STATUS_BROKEN )
89 printf(" PAGE_BROKEND ");
90 if ( status & PG_OFFLINE_STATUS_OFFLINED )
91 printf(" PAGE_OFFLINED ");
92 else
93 printf(" PAGE_ONLINED ");
94 printf("]\n");
95 }
97 return ret;
98 }
100 extern int xs_suspend_evtchn_port(int domid);
102 static int suspend_guest(xc_interface *xch, xc_evtchn *xce, int domid, int *evtchn)
103 {
104 int port, rc, suspend_evtchn = -1;
106 if (!evtchn)
107 return -1;
109 port = xs_suspend_evtchn_port(domid);
110 if (port < 0)
111 {
112 fprintf(stderr, "DOM%d: No suspend port, try live migration\n", domid);
113 goto failed;
114 }
115 suspend_evtchn = xc_suspend_evtchn_init(xch, xce, domid, port);
116 if (suspend_evtchn < 0)
117 {
118 fprintf(stderr, "Suspend evtchn initialization failed\n");
119 goto failed;
120 }
121 *evtchn = suspend_evtchn;
123 rc = xc_evtchn_notify(xce, suspend_evtchn);
124 if (rc < 0)
125 {
126 fprintf(stderr, "Failed to notify suspend channel: errno %d\n", rc);
127 goto failed;
128 }
129 if (xc_await_suspend(xch, xce, suspend_evtchn) < 0)
130 {
131 fprintf(stderr, "Suspend Failed\n");
132 goto failed;
133 }
134 return 0;
136 failed:
137 if (suspend_evtchn != -1)
138 xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
140 return -1;
141 }
143 static int hp_mem_offline_func(int argc, char *argv[])
144 {
145 uint32_t status, domid;
146 int ret;
147 unsigned long mfn;
149 if (argc != 1)
150 {
151 show_help();
152 return -1;
153 }
155 sscanf(argv[0], "%lx", &mfn);
156 printf("Prepare to offline MEMORY mfn %lx\n", mfn);
157 ret = xc_mark_page_offline(xch, mfn, mfn, &status);
158 if (ret < 0) {
159 fprintf(stderr, "Offlining page mfn %lx failed, error %x\n", mfn, ret);
160 if (status & (PG_OFFLINE_XENPAGE | PG_OFFLINE_FAILED))
161 fprintf(stderr, "XEN_PAGE is not permitted be offlined\n");
162 else if (status & (PG_OFFLINE_FAILED | PG_OFFLINE_NOT_CONV_RAM))
163 fprintf(stderr, "RESERVED RAM is not permitted to be offlined\n");
164 }
165 else
166 {
167 switch(status & PG_OFFLINE_STATUS_MASK)
168 {
169 case PG_OFFLINE_OFFLINED:
170 {
171 printf("Memory mfn %lx offlined successfully, current state is"
172 " [PG_OFFLINE_OFFLINED]\n", mfn);
173 if (status & PG_OFFLINE_BROKEN)
174 printf("And this offlined PAGE is already marked broken"
175 " before!\n");
176 break;
177 }
178 case PG_OFFLINE_FAILED:
179 {
180 fprintf(stderr, "Memory mfn %lx offline failed\n", mfn);
181 if ( status & PG_OFFLINE_ANONYMOUS)
182 fprintf(stderr, "the memory is an anonymous page!\n");
183 ret = -1;
184 break;
185 }
186 case PG_OFFLINE_PENDING:
187 {
188 if (status & PG_OFFLINE_XENPAGE) {
189 ret = -1;
190 fprintf(stderr, "Memory mfn %lx offlined succssefully,"
191 "this page is xen page, current state is"
192 " [PG_OFFLINE_PENDING, PG_OFFLINE_XENPAGE]\n", mfn);
193 }
194 else if (status & PG_OFFLINE_OWNED)
195 {
196 int result, suspend_evtchn = -1;
197 xc_evtchn *xce;
198 xce = xc_evtchn_open(NULL, 0);
200 if (xce == NULL)
201 {
202 fprintf(stderr, "When exchange page, fail"
203 " to open evtchn\n");
204 return -1;
205 }
207 domid = status >> PG_OFFLINE_OWNER_SHIFT;
208 if (suspend_guest(xch, xce, domid, &suspend_evtchn))
209 {
210 fprintf(stderr, "Failed to suspend guest %d for"
211 " mfn %lx\n", domid, mfn);
212 xc_evtchn_close(xce);
213 return -1;
214 }
216 result = xc_exchange_page(xch, domid, mfn);
218 /* Exchange page successfully */
219 if (result == 0)
220 printf("Memory mfn %lx offlined successfully, this "
221 "page is DOM%d page and being swapped "
222 "successfully, current state is "
223 "[PG_OFFLINE_OFFLINED, PG_OFFLINE_OWNED]\n",
224 mfn, domid);
225 else {
226 ret = -1;
227 fprintf(stderr, "Memory mfn %lx offlined successfully"
228 " , this page is DOM%d page yet failed to be "
229 "exchanged. current state is "
230 "[PG_OFFLINE_PENDING, PG_OFFLINE_OWNED]\n",
231 mfn, domid);
232 }
233 xc_domain_resume(xch, domid, 1);
234 xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
235 xc_evtchn_close(xce);
236 }
237 break;
238 }
239 }//end of switch
240 }//end of if
242 return ret;
243 }
245 static int exec_cpu_hp_fn(int (*hp_fn)(xc_interface *, int), int cpu)
246 {
247 int ret;
249 for ( ; ; )
250 {
251 ret = (*hp_fn)(xch, cpu);
252 if ( (ret >= 0) || (errno != EBUSY) )
253 break;
254 usleep(100000); /* 100ms */
255 }
257 return ret;
258 }
260 static int hp_cpu_online_func(int argc, char *argv[])
261 {
262 int cpu, ret;
264 if ( argc != 1 )
265 {
266 show_help();
267 return -1;
268 }
270 cpu = atoi(argv[0]);
271 printf("Prepare to online CPU %d\n", cpu);
272 ret = exec_cpu_hp_fn(xc_cpu_online, cpu);
273 if (ret < 0)
274 fprintf(stderr, "CPU %d online failed (error %d: %s)\n",
275 cpu, errno, strerror(errno));
276 else
277 printf("CPU %d onlined successfully\n", cpu);
279 return ret;
281 }
282 static int hp_cpu_offline_func(int argc, char *argv[])
283 {
284 int cpu, ret;
286 if (argc != 1 )
287 {
288 show_help();
289 return -1;
290 }
291 cpu = atoi(argv[0]);
292 printf("Prepare to offline CPU %d\n", cpu);
293 ret = exec_cpu_hp_fn(xc_cpu_offline, cpu);
294 if (ret < 0)
295 fprintf(stderr, "CPU %d offline failed (error %d: %s)\n",
296 cpu, errno, strerror(errno));
297 else
298 printf("CPU %d offlined successfully\n", cpu);
300 return ret;
301 }
303 struct {
304 const char *name;
305 int (*function)(int argc, char *argv[]);
306 } main_options[] = {
307 { "help", help_func },
308 { "cpu-online", hp_cpu_online_func },
309 { "cpu-offline", hp_cpu_offline_func },
310 { "mem-status", hp_mem_query_func},
311 { "mem-online", hp_mem_online_func},
312 { "mem-offline", hp_mem_offline_func},
313 };
316 int main(int argc, char *argv[])
317 {
318 int i, ret;
320 if (argc < 2)
321 {
322 show_help();
323 return 0;
324 }
326 xch = xc_interface_open(0,0,0);
327 if ( !xch )
328 {
329 fprintf(stderr, "failed to get the handler\n");
330 return 0;
331 }
333 for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
334 if (!strncmp(main_options[i].name, argv[1], strlen(argv[1])))
335 break;
336 if ( i == ARRAY_SIZE(main_options) )
337 {
338 fprintf(stderr, "Unrecognised command '%s' -- try "
339 "'xen-hptool help'\n", argv[1]);
340 return 1;
341 }
343 ret = main_options[i].function(argc -2, argv + 2);
345 xc_interface_close(xch);
347 return !!ret;
348 }