/[dynamips]/upstream/dynamips-0.2.6-RC2/hv_vm.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.6-RC2/hv_vm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Sat Oct 6 16:05:34 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 15069 byte(s)
dynamips-0.2.6-RC2

1 /*
2 * Cisco 7200 (Predator) simulation platform.
3 * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)
4 *
5 * Hypervisor generic VM routines.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <sys/mman.h>
15 #include <signal.h>
16 #include <fcntl.h>
17 #include <errno.h>
18 #include <assert.h>
19 #include <stdarg.h>
20 #include <sys/ioctl.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <arpa/inet.h>
24 #include <pthread.h>
25
26 #include "mips64.h"
27 #include "cp0.h"
28 #include "dynamips.h"
29 #include "device.h"
30 #include "dev_c7200.h"
31 #include "dev_vtty.h"
32 #include "utils.h"
33 #include "base64.h"
34 #include "net.h"
35 #include "atm.h"
36 #include "frame_relay.h"
37 #include "crc.h"
38 #include "net_io.h"
39 #include "net_io_bridge.h"
40 #ifdef GEN_ETH
41 #include "gen_eth.h"
42 #endif
43 #include "registry.h"
44 #include "hypervisor.h"
45
46 /* Find the specified CPU */
47 static cpu_mips_t *find_cpu(hypervisor_conn_t *conn,vm_instance_t *vm,
48 u_int cpu_id)
49 {
50 cpu_mips_t *cpu;
51
52 cpu = cpu_group_find_id(vm->cpu_group,cpu_id);
53
54 if (!cpu) {
55 vm_release(vm);
56 hypervisor_send_reply(conn,HSC_ERR_BAD_OBJ,1,"Bad CPU specified");
57 return NULL;
58 }
59
60 return cpu;
61 }
62
63 /* Set debugging level */
64 static int cmd_set_debug_level(hypervisor_conn_t *conn,int argc,char *argv[])
65 {
66 vm_instance_t *vm;
67
68 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
69 return(-1);
70
71 vm->debug_level = atoi(argv[1]);
72
73 vm_release(vm);
74 hypervisor_send_reply(conn,HSC_INFO_OK,1,"O",argv[0]);
75 return(0);
76 }
77
78 /* Set IOS image filename */
79 static int cmd_set_ios(hypervisor_conn_t *conn,int argc,char *argv[])
80 {
81 vm_instance_t *vm;
82
83 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
84 return(-1);
85
86 if (vm_ios_set_image(vm,argv[1]) == -1) {
87 vm_release(vm);
88 hypervisor_send_reply(conn,HSC_ERR_CREATE,1,
89 "unable to store IOS image name for router '%s'",
90 argv[0]);
91 return(-1);
92 }
93
94 vm_release(vm);
95 hypervisor_send_reply(conn,HSC_INFO_OK,1,"IOS image set for '%s'",argv[0]);
96 return(0);
97 }
98
99 /* Set IOS configuration filename to load at startup */
100 static int cmd_set_config(hypervisor_conn_t *conn,int argc,char *argv[])
101 {
102 vm_instance_t *vm;
103
104 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
105 return(-1);
106
107 if (vm_ios_set_config(vm,argv[1]) == -1) {
108 vm_release(vm);
109 hypervisor_send_reply(conn,HSC_ERR_CREATE,1,
110 "unable to store IOS config for router '%s'",
111 argv[0]);
112 return(-1);
113 }
114
115 vm_release(vm);
116 hypervisor_send_reply(conn,HSC_INFO_OK,1,"IOS config file set for '%s'",
117 argv[0]);
118 return(0);
119 }
120
121 /* Set RAM size */
122 static int cmd_set_ram(hypervisor_conn_t *conn,int argc,char *argv[])
123 {
124 vm_instance_t *vm;
125
126 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
127 return(-1);
128
129 vm->ram_size = atoi(argv[1]);
130
131 vm_release(vm);
132 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
133 return(0);
134 }
135
136 /* Set NVRAM size */
137 static int cmd_set_nvram(hypervisor_conn_t *conn,int argc,char *argv[])
138 {
139 vm_instance_t *vm;
140
141 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
142 return(-1);
143
144 vm->nvram_size = atoi(argv[1]);
145
146 vm_release(vm);
147 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
148 return(0);
149 }
150
151 /* Enable/disable use of a memory-mapped file to simulate RAM */
152 static int cmd_set_ram_mmap(hypervisor_conn_t *conn,int argc,char *argv[])
153 {
154 vm_instance_t *vm;
155
156 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
157 return(-1);
158
159 vm->ram_mmap = atoi(argv[1]);
160
161 vm_release(vm);
162 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
163 return(0);
164 }
165
166 /* Set the clock divisor */
167 static int cmd_set_clock_divisor(hypervisor_conn_t *conn,int argc,char *argv[])
168 {
169 vm_instance_t *vm;
170 u_int clock_div;
171
172 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
173 return(-1);
174
175 if ((clock_div = atoi(argv[1])) != 0)
176 vm->clock_divisor = clock_div;
177
178 vm_release(vm);
179 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
180 return(0);
181 }
182
183 /* Set the idle PC */
184 static int cmd_set_idle_pc(hypervisor_conn_t *conn,int argc,char *argv[])
185 {
186 vm_instance_t *vm;
187
188 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
189 return(-1);
190
191 vm->idle_pc = strtoull(argv[1],NULL,0);
192
193 vm_release(vm);
194 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
195 return(0);
196 }
197
198 /* Set the idle PC value when the CPU is online */
199 static int cmd_set_idle_pc_online(hypervisor_conn_t *conn,
200 int argc,char *argv[])
201 {
202 vm_instance_t *vm;
203 cpu_mips_t *cpu;
204
205 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
206 return(-1);
207
208 if (!(cpu = find_cpu(conn,vm,atoi(argv[1]))))
209 return(-1);
210
211 cpu->idle_pc = strtoull(argv[2],NULL,0);
212
213 vm_release(vm);
214 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
215 return(0);
216 }
217
218 /* Get the idle PC proposals */
219 static int cmd_get_idle_pc_prop(hypervisor_conn_t *conn,int argc,char *argv[])
220 {
221 vm_instance_t *vm;
222 cpu_mips_t *cpu;
223 int i;
224
225 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
226 return(-1);
227
228 if (!(cpu = find_cpu(conn,vm,atoi(argv[1]))))
229 return(-1);
230
231 mips64_get_idling_pc(cpu);
232
233 for(i=0;i<cpu->idle_pc_prop_count;i++) {
234 hypervisor_send_reply(conn,HSC_INFO_MSG,0,"0x%llx [%d]",
235 cpu->idle_pc_prop[i].pc,
236 cpu->idle_pc_prop[i].count);
237 }
238
239 vm_release(vm);
240 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
241 return(0);
242 }
243
244 /* Dump the idle PC proposals */
245 static int cmd_show_idle_pc_prop(hypervisor_conn_t *conn,int argc,char *argv[])
246 {
247 vm_instance_t *vm;
248 cpu_mips_t *cpu;
249 int i;
250
251 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
252 return(-1);
253
254 if (!(cpu = find_cpu(conn,vm,atoi(argv[1]))))
255 return(-1);
256
257 for(i=0;i<cpu->idle_pc_prop_count;i++) {
258 hypervisor_send_reply(conn,HSC_INFO_MSG,0,"0x%llx [%d]",
259 cpu->idle_pc_prop[i].pc,
260 cpu->idle_pc_prop[i].count);
261 }
262
263 vm_release(vm);
264 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
265 return(0);
266 }
267
268 /* Set CPU idle max value */
269 static int cmd_set_idle_max(hypervisor_conn_t *conn,int argc,char *argv[])
270 {
271 vm_instance_t *vm;
272 cpu_mips_t *cpu;
273
274 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
275 return(-1);
276
277 if (!(cpu = find_cpu(conn,vm,atoi(argv[1]))))
278 return(-1);
279
280 cpu->idle_max = atoi(argv[2]);
281
282 vm_release(vm);
283 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
284 return(0);
285 }
286
287 /* Set CPU idle sleep time value */
288 static int cmd_set_idle_sleep_time(hypervisor_conn_t *conn,
289 int argc,char *argv[])
290 {
291 vm_instance_t *vm;
292 cpu_mips_t *cpu;
293
294 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
295 return(-1);
296
297 if (!(cpu = find_cpu(conn,vm,atoi(argv[1]))))
298 return(-1);
299
300 cpu->idle_sleep_time = atoi(argv[2]);
301
302 vm_release(vm);
303 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
304 return(0);
305 }
306
307 /* Set the exec area size */
308 static int cmd_set_exec_area(hypervisor_conn_t *conn,int argc,char *argv[])
309 {
310 vm_instance_t *vm;
311
312 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
313 return(-1);
314
315 vm->exec_area_size = atoi(argv[1]);
316
317 vm_release(vm);
318 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
319 return(0);
320 }
321
322 /* Set PCMCIA ATA disk0 size */
323 static int cmd_set_disk0(hypervisor_conn_t *conn,int argc,char *argv[])
324 {
325 vm_instance_t *vm;
326
327 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
328 return(-1);
329
330 vm->pcmcia_disk_size[0] = atoi(argv[1]);
331 vm_release(vm);
332 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
333 return(0);
334 }
335
336 /* Set PCMCIA ATA disk1 size */
337 static int cmd_set_disk1(hypervisor_conn_t *conn,int argc,char *argv[])
338 {
339 vm_instance_t *vm;
340
341 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
342 return(-1);
343
344 vm->pcmcia_disk_size[1] = atoi(argv[1]);
345 vm_release(vm);
346 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
347 return(0);
348 }
349
350 /* Set the config register used at startup */
351 static int cmd_set_conf_reg(hypervisor_conn_t *conn,int argc,char *argv[])
352 {
353 vm_instance_t *vm;
354
355 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
356 return(-1);
357
358 vm->conf_reg_setup = strtol(argv[1],NULL,0);
359 vm_release(vm);
360 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
361 return(0);
362 }
363
364 /* Set TCP port for console */
365 static int cmd_set_con_tcp_port(hypervisor_conn_t *conn,int argc,char *argv[])
366 {
367 vm_instance_t *vm;
368
369 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
370 return(-1);
371
372 vm->vtty_con_type = VTTY_TYPE_TCP;
373 vm->vtty_con_tcp_port = atoi(argv[1]);
374
375 vm_release(vm);
376 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
377 return(0);
378 }
379
380 /* Set TCP port for AUX port */
381 static int cmd_set_aux_tcp_port(hypervisor_conn_t *conn,int argc,char *argv[])
382 {
383 vm_instance_t *vm;
384
385 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
386 return(-1);
387
388 vm->vtty_aux_type = VTTY_TYPE_TCP;
389 vm->vtty_aux_tcp_port = atoi(argv[1]);
390
391 vm_release(vm);
392 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
393 return(0);
394 }
395
396 /* Read an IOS configuration file from a given router */
397 static int cmd_extract_config(hypervisor_conn_t *conn,int argc,char *argv[])
398 {
399 vm_instance_t *vm;
400 char *cfg_buffer,*cfg_base64;
401 ssize_t cfg_len;
402
403 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
404 return(-1);
405
406 if (!vm->nvram_extract_config)
407 goto err_no_extract_method;
408
409 /* Extract the IOS configuration */
410 if (((cfg_len = vm->nvram_extract_config(vm,&cfg_buffer)) < 0) ||
411 (cfg_buffer == NULL))
412 goto err_nvram_extract;
413
414 /*
415 * Convert config to base64. base64 is about 1/3 larger than input,
416 * let's be on the safe side with twice longer.
417 */
418 if (!(cfg_base64 = malloc(cfg_len * 2)))
419 goto err_alloc_base64;
420
421 base64_encode(cfg_base64,cfg_buffer,cfg_len);
422
423 vm_release(vm);
424 hypervisor_send_reply(conn,HSC_INFO_OK,1,"conf '%s' %s",argv[0],cfg_base64);
425
426 free(cfg_buffer);
427 free(cfg_base64);
428 return(0);
429
430 err_alloc_base64:
431 free(cfg_buffer);
432 err_nvram_extract:
433 err_no_extract_method:
434 vm_release(vm);
435 hypervisor_send_reply(conn,HSC_ERR_CREATE,1,
436 "unable to extract config of VM '%s'",argv[0]);
437 return(-1);
438 }
439
440 /* Push an IOS configuration file */
441 static int cmd_push_config(hypervisor_conn_t *conn,int argc,char *argv[])
442 {
443 vm_instance_t *vm;
444 char *cfg_buffer;
445 ssize_t len;
446
447 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
448 return(-1);
449
450 if (!vm->nvram_push_config)
451 goto err_no_push_method;
452
453 /* Convert base64 input to standard text */
454 if (!(cfg_buffer = malloc(3 * strlen(argv[1]))))
455 goto err_alloc_base64;
456
457 if ((len = base64_decode(cfg_buffer,argv[1],0)) < 0)
458 goto err_decode_base64;
459
460 /* Push configuration */
461 if (vm->nvram_push_config(vm,cfg_buffer,len) < 0)
462 goto err_nvram_push;
463
464 free(cfg_buffer);
465 vm_release(vm);
466 hypervisor_send_reply(conn,HSC_INFO_OK,1,
467 "IOS config file pushed tm VM '%s'",
468 argv[0]);
469 return(0);
470
471 err_nvram_push:
472 err_decode_base64:
473 free(cfg_buffer);
474 err_alloc_base64:
475 err_no_push_method:
476 vm_release(vm);
477 hypervisor_send_reply(conn,HSC_ERR_CREATE,1,
478 "unable to push IOS config for VM '%s'",
479 argv[0]);
480 return(-1);
481 }
482
483 /* Show info about the specified CPU */
484 static int cmd_show_cpu_info(hypervisor_conn_t *conn,int argc,char *argv[])
485 {
486 vm_instance_t *vm;
487 cpu_mips_t *cpu;
488
489 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
490 return(-1);
491
492 cpu = cpu_group_find_id(vm->cpu_group,atoi(argv[1]));
493
494 if (cpu) {
495 mips64_dump_regs(cpu);
496 tlb_dump(cpu);
497 }
498
499 vm_release(vm);
500 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
501 return(0);
502 }
503
504 /* Suspend a VM instance */
505 static int cmd_suspend(hypervisor_conn_t *conn,int argc,char *argv[])
506 {
507 vm_instance_t *vm;
508
509 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
510 return(-1);
511
512 vm_suspend(vm);
513
514 vm_release(vm);
515 hypervisor_send_reply(conn,HSC_INFO_OK,1,"VM '%s' suspended",argv[0]);
516 return(0);
517 }
518
519 /* Resume a VM instance */
520 static int cmd_resume(hypervisor_conn_t *conn,int argc,char *argv[])
521 {
522 vm_instance_t *vm;
523
524 if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
525 return(-1);
526
527 vm_resume(vm);
528
529 vm_release(vm);
530 hypervisor_send_reply(conn,HSC_INFO_OK,1,"VM '%s' resumed",argv[0]);
531 return(0);
532 }
533
534 /* Show info about VM object */
535 static void cmd_show_vm_list(registry_entry_t *entry,void *opt,int *err)
536 {
537 hypervisor_conn_t *conn = opt;
538 vm_instance_t *vm = entry->data;
539
540 hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%s (%s)",
541 entry->name,vm_get_type(vm));
542 }
543
544 /* VM List */
545 static int cmd_vm_list(hypervisor_conn_t *conn,int argc,char *argv[])
546 {
547 int err = 0;
548 registry_foreach_type(OBJ_TYPE_VM,cmd_show_vm_list,conn,&err);
549 hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK");
550 return(0);
551 }
552
553 /* VM commands */
554 static hypervisor_cmd_t vm_cmd_array[] = {
555 { "set_debug_level", 2, 2, cmd_set_debug_level, NULL },
556 { "set_ios", 2, 2, cmd_set_ios, NULL },
557 { "set_config", 2, 2, cmd_set_config, NULL },
558 { "set_ram", 2, 2, cmd_set_ram, NULL },
559 { "set_nvram", 2, 2, cmd_set_nvram, NULL },
560 { "set_ram_mmap", 2, 2, cmd_set_ram_mmap, NULL },
561 { "set_clock_divisor", 2, 2, cmd_set_clock_divisor, NULL },
562 { "set_exec_area", 2, 2, cmd_set_exec_area, NULL },
563 { "set_disk0", 2, 2, cmd_set_disk0, NULL },
564 { "set_disk1", 2, 2, cmd_set_disk1, NULL },
565 { "set_conf_reg", 2, 2, cmd_set_conf_reg, NULL },
566 { "set_idle_pc", 2, 2, cmd_set_idle_pc, NULL },
567 { "set_idle_pc_online", 3, 3, cmd_set_idle_pc_online, NULL },
568 { "get_idle_pc_prop", 2, 2, cmd_get_idle_pc_prop, NULL },
569 { "show_idle_pc_prop", 2, 2, cmd_show_idle_pc_prop, NULL },
570 { "set_idle_max", 3, 3, cmd_set_idle_max, NULL },
571 { "set_idle_sleep_time", 3, 3, cmd_set_idle_sleep_time, NULL },
572 { "set_con_tcp_port", 2, 2, cmd_set_con_tcp_port, NULL },
573 { "set_aux_tcp_port", 2, 2, cmd_set_aux_tcp_port, NULL },
574 { "extract_config", 1, 1, cmd_extract_config, NULL },
575 { "push_config", 2, 2, cmd_push_config, NULL },
576 { "cpu_info", 2, 2, cmd_show_cpu_info, NULL },
577 { "suspend", 1, 1, cmd_suspend, NULL },
578 { "resume", 1, 1, cmd_resume, NULL },
579 { "list", 0, 0, cmd_vm_list, NULL },
580 { NULL, -1, -1, NULL, NULL },
581 };
582
583 /* Hypervisor VM initialization */
584 int hypervisor_vm_init(void)
585 {
586 hypervisor_module_t *module;
587
588 module = hypervisor_register_module("vm");
589 assert(module != NULL);
590
591 hypervisor_register_cmd_array(module,vm_cmd_array);
592 return(0);
593 }

  ViewVC Help
Powered by ViewVC 1.1.26