/[dynamips]/trunk/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 /trunk/vm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (hide annotations)
Sat Oct 6 16:08:03 2007 UTC (11 years, 8 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC4/vm.c
File MIME type: text/plain
File size: 18897 byte(s)
dynamips-0.2.6-RC4

1 dpavlin 1 /*
2     * Cisco 7200 (Predator) simulation platform.
3     * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4     *
5     * Virtual machine abstraction.
6     *
7     * TODO: IRQ Routing.
8     */
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12     #include <string.h>
13     #include <unistd.h>
14 dpavlin 4 #include <errno.h>
15 dpavlin 1 #include <fcntl.h>
16     #include <sys/types.h>
17     #include <assert.h>
18    
19     #include "registry.h"
20     #include "device.h"
21     #include "pci_dev.h"
22     #include "pci_io.h"
23     #include "vm.h"
24     #include "dev_vtty.h"
25    
26     #include ARCH_INC_FILE
27    
28     #define DEBUG_VM 1
29    
30     /* Type of VM file naming (0=use VM name, 1=use instance ID) */
31     int vm_file_naming_type = 0;
32    
33     /* Initialize a VM object */
34     void vm_object_init(vm_obj_t *obj)
35     {
36     memset(obj,0,sizeof(*obj));
37     }
38    
39     /* Add a VM object to an instance */
40     void vm_object_add(vm_instance_t *vm,vm_obj_t *obj)
41     {
42     obj->next = vm->vm_object_list;
43     obj->pprev = &vm->vm_object_list;
44    
45     if (vm->vm_object_list)
46     vm->vm_object_list->pprev = &obj->next;
47    
48     vm->vm_object_list = obj;
49     }
50    
51     /* Remove a VM object from an instance */
52     void vm_object_remove(vm_instance_t *vm,vm_obj_t *obj)
53     {
54     if (obj->next)
55     obj->next->pprev = obj->pprev;
56     *(obj->pprev) = obj->next;
57 dpavlin 4
58     obj->shutdown(vm,obj->data);
59 dpavlin 1 }
60    
61     /* Find an object given its name */
62     vm_obj_t *vm_object_find(vm_instance_t *vm,char *name)
63     {
64     vm_obj_t *obj;
65    
66     for(obj=vm->vm_object_list;obj;obj=obj->next)
67     if (!strcmp(obj->name,name))
68     return obj;
69    
70     return NULL;
71     }
72    
73     /* Check that a mandatory object is present */
74     int vm_object_check(vm_instance_t *vm,char *name)
75     {
76     return(vm_object_find(vm,name) ? 0 : -1);
77     }
78    
79     /* Shut down all objects of an instance */
80     void vm_object_free_list(vm_instance_t *vm)
81     {
82     vm_obj_t *obj,*next;
83    
84     for(obj=vm->vm_object_list;obj;obj=next) {
85     next = obj->next;
86    
87     if (obj->shutdown != NULL) {
88     #if DEBUG_VM
89     vm_log(vm,"VM_OBJECT","Shutdown of object \"%s\"\n",obj->name);
90     #endif
91     obj->shutdown(vm,obj->data);
92     }
93     }
94    
95     vm->vm_object_list = NULL;
96     }
97    
98     /* Dump the object list of an instance */
99     void vm_object_dump(vm_instance_t *vm)
100     {
101     vm_obj_t *obj;
102    
103     printf("VM \"%s\" (%u) object list:\n",vm->name,vm->instance_id);
104    
105     for(obj=vm->vm_object_list;obj;obj=obj->next) {
106     printf(" - %-15s [data=%p]\n",obj->name,obj->data);
107     }
108    
109     printf("\n");
110     }
111    
112     /* Get VM type */
113     char *vm_get_type(vm_instance_t *vm)
114     {
115     char *machine;
116    
117     switch(vm->type) {
118     case VM_TYPE_C3600:
119     machine = "c3600";
120     break;
121     case VM_TYPE_C7200:
122     machine = "c7200";
123     break;
124 dpavlin 4 case VM_TYPE_C2691:
125     machine = "c2691";
126     break;
127     case VM_TYPE_C3725:
128     machine = "c3725";
129     break;
130     case VM_TYPE_C3745:
131     machine = "c3745";
132     break;
133 dpavlin 1 default:
134     machine = "unknown";
135     break;
136     }
137    
138     return machine;
139     }
140    
141     /* Get platform type */
142     char *vm_get_platform_type(vm_instance_t *vm)
143     {
144     char *machine;
145    
146     switch(vm->type) {
147     case VM_TYPE_C3600:
148     machine = "C3600";
149     break;
150     case VM_TYPE_C7200:
151     machine = "C7200";
152 dpavlin 4 break;
153     case VM_TYPE_C2691:
154     machine = "C2691";
155 dpavlin 1 break;
156 dpavlin 4 case VM_TYPE_C3725:
157     machine = "C3725";
158     break;
159     case VM_TYPE_C3745:
160     machine = "C3745";
161     break;
162 dpavlin 1 default:
163     machine = "VM";
164     break;
165     }
166    
167     return machine;
168     }
169    
170 dpavlin 4 /* Get MAC address MSB */
171     u_int vm_get_mac_addr_msb(vm_instance_t *vm)
172     {
173     switch(vm->type) {
174     case VM_TYPE_C3600:
175     return(0xCC);
176    
177     case VM_TYPE_C7200:
178     return(0xCA);
179    
180     case VM_TYPE_C2691:
181     return(0xC0);
182    
183     case VM_TYPE_C3725:
184     return(0xC2);
185    
186     case VM_TYPE_C3745:
187     return(0xC4);
188    
189     default:
190     return(0xC6);
191     }
192     }
193    
194 dpavlin 1 /* Generate a filename for use by the instance */
195     char *vm_build_filename(vm_instance_t *vm,char *name)
196     {
197     char *filename,*machine;
198    
199     machine = vm_get_type(vm);
200    
201     switch(vm_file_naming_type) {
202     case 1:
203     filename = dyn_sprintf("%s_i%u_%s",machine,vm->instance_id,name);
204     break;
205     case 0:
206     default:
207     filename = dyn_sprintf("%s_%s_%s",machine,vm->name,name);
208     break;
209     }
210    
211     assert(filename != NULL);
212     return filename;
213     }
214    
215     /* Erase lock file */
216     void vm_release_lock(vm_instance_t *vm,int erase)
217     {
218     if (vm->lock_fd != NULL) {
219     fclose(vm->lock_fd);
220     vm->lock_fd = NULL;
221     }
222    
223     if (vm->lock_file != NULL) {
224     if (erase)
225     unlink(vm->lock_file);
226     free(vm->lock_file);
227     vm->lock_file = NULL;
228     }
229     }
230    
231     /* Check that an instance lock file doesn't already exist */
232     int vm_get_lock(vm_instance_t *vm)
233     {
234     char pid_str[32];
235     struct flock lock;
236    
237     vm->lock_file = vm_build_filename(vm,"lock");
238    
239     if (!(vm->lock_fd = fopen(vm->lock_file,"w"))) {
240     fprintf(stderr,"Unable to create lock file \"%s\".\n",vm->lock_file);
241     return(-1);
242     }
243    
244     memset(&lock,0,sizeof(lock));
245     lock.l_type = F_WRLCK;
246     lock.l_whence = SEEK_SET;
247     lock.l_start = 0;
248     lock.l_len = 0;
249    
250     if (fcntl(fileno(vm->lock_fd),F_SETLK,&lock) == -1) {
251     if (fcntl(fileno(vm->lock_fd),F_GETLK,&lock) == 0) {
252     snprintf(pid_str,sizeof(pid_str),"%ld",(long)lock.l_pid);
253     } else {
254     strcpy(pid_str,"unknown");
255     }
256    
257     fprintf(stderr,
258     "\nAn emulator instance (PID %s) is already running with "
259     "identifier %u.\n"
260     "If this is not the case, please erase file \"%s\".\n\n",
261     pid_str,vm->instance_id,vm->lock_file);
262     vm_release_lock(vm,FALSE);
263     return(-1);
264     }
265    
266     /* write the emulator PID */
267     fprintf(vm->lock_fd,"%ld\n",(u_long)getpid());
268     return(0);
269     }
270    
271     /* Log a message */
272     void vm_flog(vm_instance_t *vm,char *module,char *format,va_list ap)
273     {
274     if (vm->log_fd)
275     m_flog(vm->log_fd,module,format,ap);
276     }
277    
278     /* Log a message */
279     void vm_log(vm_instance_t *vm,char *module,char *format,...)
280     {
281     va_list ap;
282    
283     va_start(ap,format);
284     vm_flog(vm,module,format,ap);
285     va_end(ap);
286     }
287    
288     /* Close the log file */
289     int vm_close_log(vm_instance_t *vm)
290     {
291     if (vm->log_fd)
292     fclose(vm->log_fd);
293    
294     free(vm->log_file);
295    
296     vm->log_file = NULL;
297     vm->log_fd = NULL;
298     return(0);
299     }
300    
301     /* Create the log file */
302     int vm_create_log(vm_instance_t *vm)
303     {
304     vm_close_log(vm);
305    
306     if (!(vm->log_file = vm_build_filename(vm,"log.txt")))
307     return(-1);
308    
309     if (!(vm->log_fd = fopen(vm->log_file,"w"))) {
310     fprintf(stderr,"VM %s: unable to create log file '%s'\n",
311     vm->name,vm->log_file);
312     free(vm->log_file);
313     vm->log_file = NULL;
314     return(-1);
315     }
316    
317     return(0);
318     }
319    
320     /* Error message */
321     void vm_error(vm_instance_t *vm,char *format,...)
322     {
323     char buffer[2048];
324     va_list ap;
325    
326     va_start(ap,format);
327     vsnprintf(buffer,sizeof(buffer),format,ap);
328     va_end(ap);
329    
330     fprintf(stderr,"%s '%s': %s",vm_get_platform_type(vm),vm->name,buffer);
331     }
332    
333     /* Create a new VM instance */
334     vm_instance_t *vm_create(char *name,int instance_id,int machine_type)
335     {
336     vm_instance_t *vm;
337    
338     if (!(vm = malloc(sizeof(*vm)))) {
339     fprintf(stderr,"VM %s: unable to create new instance!\n",name);
340     return NULL;
341     }
342    
343     memset(vm,0,sizeof(*vm));
344     vm->instance_id = instance_id;
345     vm->type = machine_type;
346     vm->status = VM_STATUS_HALTED;
347     vm->jit_use = JIT_SUPPORT;
348     vm->vtty_con_type = VTTY_TYPE_TERM;
349     vm->vtty_aux_type = VTTY_TYPE_NONE;
350     vm->timer_irq_check_itv = VM_TIMER_IRQ_CHECK_ITV;
351    
352     if (!(vm->name = strdup(name))) {
353     fprintf(stderr,"VM %s: unable to store instance name!\n",name);
354     goto err_name;
355     }
356    
357     /* create lock file */
358     if (vm_get_lock(vm) == -1)
359     goto err_lock;
360    
361     /* create log file */
362     if (vm_create_log(vm) == -1)
363     goto err_log;
364    
365     if (registry_add(vm->name,OBJ_TYPE_VM,vm) == -1) {
366     fprintf(stderr,"VM: Unable to store instance '%s' in registry!\n",
367     vm->name);
368     goto err_reg_add;
369     }
370    
371     return vm;
372    
373     err_reg_add:
374     vm_close_log(vm);
375     err_log:
376     free(vm->lock_file);
377     err_lock:
378     free(vm->name);
379     err_name:
380     free(vm);
381     return NULL;
382     }
383    
384     /*
385     * Shutdown hardware resources used by a VM.
386     * The CPU must have been stopped.
387     */
388     int vm_hardware_shutdown(vm_instance_t *vm)
389     {
390     int i;
391    
392     if ((vm->status == VM_STATUS_HALTED) || !vm->cpu_group) {
393     vm_log(vm,"VM","trying to shutdown an inactive VM.\n");
394     return(-1);
395     }
396    
397     vm_log(vm,"VM","shutdown procedure engaged.\n");
398    
399     /* Mark the VM as halted */
400     vm->status = VM_STATUS_HALTED;
401    
402     /* Disable NVRAM operations */
403     vm->nvram_extract_config = NULL;
404     vm->nvram_push_config = NULL;
405    
406     /* Free the object list */
407     vm_object_free_list(vm);
408    
409     /* Free resources used by PCI busses */
410     vm_log(vm,"VM","removing PCI busses.\n");
411     pci_io_data_remove(vm,vm->pci_io_space);
412     pci_bus_remove(vm->pci_bus[0]);
413     pci_bus_remove(vm->pci_bus[1]);
414     vm->pci_bus[0] = vm->pci_bus[1] = NULL;
415    
416     /* Free the PCI bus pool */
417     for(i=0;i<VM_PCI_POOL_SIZE;i++) {
418     if (vm->pci_bus_pool[i] != NULL) {
419     pci_bus_remove(vm->pci_bus_pool[i]);
420     vm->pci_bus_pool[i] = NULL;
421     }
422     }
423    
424     /* Delete the VTTY for Console and AUX ports */
425     vm_log(vm,"VM","deleting VTTY.\n");
426     vm_delete_vtty(vm);
427    
428     /* Delete system CPU group */
429     vm_log(vm,"VM","deleting system CPUs.\n");
430     cpu_group_delete(vm->cpu_group);
431     vm->cpu_group = NULL;
432     vm->boot_cpu = NULL;
433    
434     vm_log(vm,"VM","shutdown procedure completed.\n");
435     return(0);
436     }
437    
438     /* Free resources used by a VM */
439     void vm_free(vm_instance_t *vm)
440     {
441     if (vm != NULL) {
442     /* Free hardware resources */
443     vm_hardware_shutdown(vm);
444    
445     /* Close log file */
446     vm_close_log(vm);
447    
448     /* Remove the lock file */
449     vm_release_lock(vm,TRUE);
450    
451     /* Free various elements */
452 dpavlin 4 free(vm->ghost_ram_filename);
453 dpavlin 1 free(vm->sym_filename);
454     free(vm->ios_image);
455     free(vm->ios_config);
456     free(vm->rom_filename);
457     free(vm->name);
458     free(vm);
459     }
460     }
461    
462     /* Get an instance given a name */
463     vm_instance_t *vm_acquire(char *name)
464     {
465     return(registry_find(name,OBJ_TYPE_VM));
466     }
467    
468     /* Release a VM (decrement reference count) */
469     int vm_release(vm_instance_t *vm)
470     {
471     return(registry_unref(vm->name,OBJ_TYPE_VM));
472     }
473    
474 dpavlin 4 /* Initialize RAM */
475     int vm_ram_init(vm_instance_t *vm,m_uint64_t paddr)
476     {
477     m_uint32_t len;
478    
479     len = vm->ram_size * 1048576;
480    
481     if (vm->ghost_status == VM_GHOST_RAM_USE)
482     return(dev_ram_ghost_init(vm,"ram",vm->ghost_ram_filename,paddr,len));
483    
484     return(dev_ram_init(vm,"ram",vm->ram_mmap,
485     (vm->ghost_status != VM_GHOST_RAM_GENERATE),
486     vm->ghost_ram_filename,paddr,len));
487     }
488    
489 dpavlin 1 /* Initialize VTTY */
490     int vm_init_vtty(vm_instance_t *vm)
491     {
492     /* Create Console and AUX ports */
493     vm->vtty_con = vtty_create(vm,"Console port",
494     vm->vtty_con_type,vm->vtty_con_tcp_port,
495     &vm->vtty_con_serial_option);
496    
497     vm->vtty_aux = vtty_create(vm,"AUX port",
498     vm->vtty_aux_type,vm->vtty_aux_tcp_port,
499     &vm->vtty_aux_serial_option);
500     return(0);
501     }
502    
503     /* Delete VTTY */
504     void vm_delete_vtty(vm_instance_t *vm)
505     {
506     vtty_delete(vm->vtty_con);
507     vtty_delete(vm->vtty_aux);
508     vm->vtty_con = vm->vtty_aux = NULL;
509     }
510    
511     /* Bind a device to a virtual machine */
512     int vm_bind_device(vm_instance_t *vm,struct vdevice *dev)
513     {
514     struct vdevice **cur;
515     u_int i;
516    
517     /*
518     * Add this device to the device array. The index in the device array
519     * is used by the MTS subsystem.
520     */
521     for(i=0;i<MIPS64_DEVICE_MAX;i++)
522     if (!vm->dev_array[i])
523     break;
524    
525     if (i == MIPS64_DEVICE_MAX) {
526     fprintf(stderr,"VM%u: vm_bind_device: device table full.\n",
527     vm->instance_id);
528     return(-1);
529     }
530    
531     vm->dev_array[i] = dev;
532     dev->id = i;
533    
534     /*
535     * Add it to the linked-list (devices are ordered by physical addresses).
536     */
537     for(cur=&vm->dev_list;*cur;cur=&(*cur)->next)
538     if ((*cur)->phys_addr > dev->phys_addr)
539     break;
540    
541     dev->next = *cur;
542     if (*cur) (*cur)->pprev = &dev->next;
543     dev->pprev = cur;
544     *cur = dev;
545     return(0);
546     }
547    
548     /* Unbind a device from a virtual machine */
549     int vm_unbind_device(vm_instance_t *vm,struct vdevice *dev)
550     {
551     u_int i;
552    
553     if (!dev->pprev)
554     return(-1);
555    
556     /* Remove the device from the linked list */
557     if (dev->next)
558     dev->next->pprev = dev->pprev;
559    
560     *(dev->pprev) = dev->next;
561    
562     /* Remove the device from the device array */
563     for(i=0;i<MIPS64_DEVICE_MAX;i++)
564     if (vm->dev_array[i] == dev) {
565     vm->dev_array[i] = NULL;
566     break;
567     }
568    
569     /* Clear device list info */
570     dev->next = NULL;
571     dev->pprev = NULL;
572     return(0);
573     }
574    
575     /* Map a device at the specified physical address */
576     int vm_map_device(vm_instance_t *vm,struct vdevice *dev,m_uint64_t base_addr)
577     {
578     #if 0
579     /* Suspend VM activity */
580     vm_suspend(vm);
581    
582     if (cpu_group_sync_state(vm->cpu_group) == -1) {
583     fprintf(stderr,"VM%u: unable to sync with system CPUs.\n",
584     vm->instance_id);
585     return(-1);
586     }
587     #endif
588    
589     /* Unbind the device if it was already active */
590     vm_unbind_device(vm,dev);
591    
592     /* Map the device at the new base address and rebuild MTS */
593     dev->phys_addr = base_addr;
594     vm_bind_device(vm,dev);
595     cpu_group_rebuild_mts(vm->cpu_group);
596    
597     #if 0
598     vm_resume(vm);
599     #endif
600     return(0);
601     }
602    
603     /* Set an IRQ for a VM */
604     void vm_set_irq(vm_instance_t *vm,u_int irq)
605     {
606     if (vm->boot_cpu->irq_disable) {
607     vm->boot_cpu->irq_pending = 0;
608     return;
609     }
610    
611     /* TODO: IRQ routing */
612     mips64_set_irq(vm->boot_cpu,irq);
613    
614     if (vm->boot_cpu->irq_idle_preempt[irq])
615     mips64_idle_break_wait(vm->boot_cpu);
616     }
617    
618     /* Clear an IRQ for a VM */
619     void vm_clear_irq(vm_instance_t *vm,u_int irq)
620     {
621     /* TODO: IRQ routing */
622     mips64_clear_irq(vm->boot_cpu,irq);
623     }
624    
625     /* Suspend a VM instance */
626     int vm_suspend(vm_instance_t *vm)
627     {
628     if (vm->status == VM_STATUS_RUNNING) {
629     cpu_group_save_state(vm->cpu_group);
630     cpu_group_set_state(vm->cpu_group,MIPS_CPU_SUSPENDED);
631     vm->status = VM_STATUS_SUSPENDED;
632     }
633     return(0);
634     }
635    
636     /* Resume a VM instance */
637     int vm_resume(vm_instance_t *vm)
638     {
639     if (vm->status == VM_STATUS_SUSPENDED) {
640     cpu_group_restore_state(vm->cpu_group);
641     vm->status = VM_STATUS_RUNNING;
642     }
643     return(0);
644     }
645    
646     /* Stop an instance */
647     int vm_stop(vm_instance_t *vm)
648     {
649     cpu_group_stop_all_cpu(vm->cpu_group);
650     vm->status = VM_STATUS_SHUTDOWN;
651     return(0);
652     }
653    
654     /* Monitor an instance periodically */
655     void vm_monitor(vm_instance_t *vm)
656     {
657     while(vm->status != VM_STATUS_SHUTDOWN)
658     usleep(200000);
659     }
660    
661 dpavlin 4 /* Open a VM file and map it in memory */
662     int vm_mmap_open_file(vm_instance_t *vm,char *name,
663     u_char **ptr,off_t *fsize)
664     {
665     char *filename;
666     int fd;
667    
668     if (!(filename = vm_build_filename(vm,name))) {
669     fprintf(stderr,"vm_mmap_open_file: unable to create filename (%s)\n",
670     name);
671     return(-1);
672     }
673    
674     if ((fd = memzone_open_file(filename,ptr,fsize)) == -1)
675     fprintf(stderr,"vm_mmap_open_file: unable to open file '%s' (%s)\n",
676     filename,strerror(errno));
677    
678     free(filename);
679     return(fd);
680     }
681    
682     /* Open/Create a VM file and map it in memory */
683     int vm_mmap_create_file(vm_instance_t *vm,char *name,size_t len,u_char **ptr)
684     {
685     char *filename;
686     int fd;
687    
688     if (!(filename = vm_build_filename(vm,name))) {
689     fprintf(stderr,"vm_mmap_create_file: unable to create filename (%s)\n",
690     name);
691     return(-1);
692     }
693    
694     if ((fd = memzone_create_file(filename,len,ptr)) == -1)
695     fprintf(stderr,"vm_mmap_create_file: unable to open file '%s' (%s)\n",
696     filename,strerror(errno));
697    
698     free(filename);
699     return(fd);
700     }
701    
702     /* Close a memory mapped file */
703     int vm_mmap_close_file(int fd,u_char *ptr,size_t len)
704     {
705     if (ptr != NULL)
706     munmap(ptr,len);
707    
708     if (fd != -1)
709     close(fd);
710    
711     return(0);
712     }
713    
714 dpavlin 1 /* Save the Cisco IOS configuration from NVRAM */
715     int vm_ios_save_config(vm_instance_t *vm)
716     {
717     char *output;
718     int res;
719    
720     if (!(output = vm_build_filename(vm,"ios_cfg.txt")))
721     return(-1);
722    
723     res = vm_nvram_extract_config(vm,output);
724     free(output);
725     return(res);
726     }
727    
728     /* Set Cisco IOS image to use */
729     int vm_ios_set_image(vm_instance_t *vm,char *ios_image)
730     {
731     char *str;
732    
733     if (!(str = strdup(ios_image)))
734     return(-1);
735    
736     if (vm->ios_image != NULL) {
737     free(vm->ios_image);
738     vm->ios_image = NULL;
739     }
740    
741     vm->ios_image = str;
742     return(0);
743     }
744    
745     /* Unset a Cisco IOS configuration file */
746     void vm_ios_unset_config(vm_instance_t *vm)
747     {
748     if (vm->ios_config != NULL) {
749     free(vm->ios_config);
750     vm->ios_config = NULL;
751     }
752     }
753    
754     /* Set Cisco IOS configuration file to use */
755     int vm_ios_set_config(vm_instance_t *vm,char *ios_config)
756     {
757     char *str;
758    
759     if (!(str = strdup(ios_config)))
760     return(-1);
761    
762     vm_ios_unset_config(vm);
763     vm->ios_config = str;
764     return(0);
765     }
766    
767     /* Extract IOS configuration from NVRAM and write it to a file */
768     int vm_nvram_extract_config(vm_instance_t *vm,char *filename)
769     {
770     char *cfg_buffer;
771     ssize_t cfg_len;
772     FILE *fd;
773    
774     if (!vm->nvram_extract_config)
775     return(-1);
776    
777     /* Extract the IOS configuration */
778     if (((cfg_len = vm->nvram_extract_config(vm,&cfg_buffer)) < 0) ||
779     (cfg_buffer == NULL))
780     return(-1);
781    
782     /* Write configuration to the specified filename */
783     if (!(fd = fopen(filename,"w"))) {
784     vm_error(vm,"unable to create file '%s'\n",filename);
785     free(cfg_buffer);
786     return(-1);
787     }
788    
789     fwrite(cfg_buffer,cfg_len,1,fd);
790    
791     fclose(fd);
792     free(cfg_buffer);
793     return(0);
794     }
795    
796     /* Read an IOS configuraton from a file and push it to NVRAM */
797     int vm_nvram_push_config(vm_instance_t *vm,char *filename)
798     {
799     char *cfg_buffer;
800     ssize_t len;
801     int res;
802    
803     if (!vm->nvram_push_config)
804     return(-1);
805    
806     /* Read configuration */
807     if (((len = m_read_file(filename,&cfg_buffer)) <= 0) || !cfg_buffer)
808     return(-1);
809    
810     /* Push it! */
811     res = vm->nvram_push_config(vm,cfg_buffer,len);
812     free(cfg_buffer);
813     return(res);
814     }
815    
816     /* Save general VM configuration into the specified file */
817     void vm_save_config(vm_instance_t *vm,FILE *fd)
818     {
819     if (vm->ios_image)
820     fprintf(fd,"vm set_ios %s %s\n",vm->name,vm->ios_image);
821    
822     fprintf(fd,"vm set_ram %s %u\n",vm->name,vm->ram_size);
823     fprintf(fd,"vm set_nvram %s %u\n",vm->name,vm->nvram_size);
824     fprintf(fd,"vm set_ram_mmap %s %u\n",vm->name,vm->ram_mmap);
825     fprintf(fd,"vm set_clock_divisor %s %u\n",vm->name,vm->clock_divisor);
826     fprintf(fd,"vm set_conf_reg %s 0x%4.4x\n",vm->name,vm->conf_reg_setup);
827    
828     if (vm->vtty_con_type == VTTY_TYPE_TCP)
829     fprintf(fd,"vm set_con_tcp_port %s %d\n",vm->name,vm->vtty_con_tcp_port);
830    
831     if (vm->vtty_aux_type == VTTY_TYPE_TCP)
832     fprintf(fd,"vm set_aux_tcp_port %s %d\n",vm->name,vm->vtty_aux_tcp_port);
833     }

  ViewVC Help
Powered by ViewVC 1.1.26