/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (hide 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 dpavlin 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 dpavlin 3 /* 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 dpavlin 1 /* 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 dpavlin 3 /* 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 dpavlin 1 /* 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 dpavlin 3 { "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 dpavlin 1 { "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