📄 vm.c
字号:
if (vm->pci_bus_pool[i] != NULL) { pci_bus_remove(vm->pci_bus_pool[i]); vm->pci_bus_pool[i] = NULL; } } /* Delete the VTTY for Console and AUX ports */ vm_log(vm,"VM","deleting VTTY.\n"); vm_delete_vtty(vm); /* Delete system CPU group */ vm_log(vm,"VM","deleting system CPUs.\n"); cpu_group_delete(vm->cpu_group); vm->cpu_group = NULL; vm->boot_cpu = NULL; vm_log(vm,"VM","shutdown procedure completed.\n"); return(0);}/* Free resources used by a VM */void vm_free(vm_instance_t *vm){ if (vm != NULL) { /* Free hardware resources */ vm_hardware_shutdown(vm); /* Close log file */ vm_close_log(vm); /* Remove the lock file */ vm_release_lock(vm,TRUE); /* Free various elements */ free(vm->ghost_ram_filename); free(vm->sym_filename); free(vm->ios_image); free(vm->ios_config); free(vm->rom_filename); free(vm->name); free(vm); }}/* Get an instance given a name */vm_instance_t *vm_acquire(char *name){ return(registry_find(name,OBJ_TYPE_VM));}/* Release a VM (decrement reference count) */int vm_release(vm_instance_t *vm){ return(registry_unref(vm->name,OBJ_TYPE_VM));}/* Initialize RAM */int vm_ram_init(vm_instance_t *vm,m_uint64_t paddr){ m_uint32_t len; len = vm->ram_size * 1048576; if (vm->ghost_status == VM_GHOST_RAM_USE) return(dev_ram_ghost_init(vm,"ram",vm->ghost_ram_filename,paddr,len)); return(dev_ram_init(vm,"ram",vm->ram_mmap, (vm->ghost_status != VM_GHOST_RAM_GENERATE), vm->ghost_ram_filename,paddr,len));}/* Initialize VTTY */int vm_init_vtty(vm_instance_t *vm){ /* Create Console and AUX ports */ vm->vtty_con = vtty_create(vm,"Console port", vm->vtty_con_type,vm->vtty_con_tcp_port, &vm->vtty_con_serial_option); vm->vtty_aux = vtty_create(vm,"AUX port", vm->vtty_aux_type,vm->vtty_aux_tcp_port, &vm->vtty_aux_serial_option); return(0);}/* Delete VTTY */void vm_delete_vtty(vm_instance_t *vm){ vtty_delete(vm->vtty_con); vtty_delete(vm->vtty_aux); vm->vtty_con = vm->vtty_aux = NULL;}/* Bind a device to a virtual machine */int vm_bind_device(vm_instance_t *vm,struct vdevice *dev){ struct vdevice **cur; u_int i; /* * Add this device to the device array. The index in the device array * is used by the MTS subsystem. */ for(i=0;i<MIPS64_DEVICE_MAX;i++) if (!vm->dev_array[i]) break; if (i == MIPS64_DEVICE_MAX) { fprintf(stderr,"VM%u: vm_bind_device: device table full.\n", vm->instance_id); return(-1); } vm->dev_array[i] = dev; dev->id = i; /* * Add it to the linked-list (devices are ordered by physical addresses). */ for(cur=&vm->dev_list;*cur;cur=&(*cur)->next) if ((*cur)->phys_addr > dev->phys_addr) break; dev->next = *cur; if (*cur) (*cur)->pprev = &dev->next; dev->pprev = cur; *cur = dev; return(0);}/* Unbind a device from a virtual machine */int vm_unbind_device(vm_instance_t *vm,struct vdevice *dev){ u_int i; if (!dev->pprev) return(-1); /* Remove the device from the linked list */ if (dev->next) dev->next->pprev = dev->pprev; *(dev->pprev) = dev->next; /* Remove the device from the device array */ for(i=0;i<MIPS64_DEVICE_MAX;i++) if (vm->dev_array[i] == dev) { vm->dev_array[i] = NULL; break; } /* Clear device list info */ dev->next = NULL; dev->pprev = NULL; return(0);}/* Map a device at the specified physical address */int vm_map_device(vm_instance_t *vm,struct vdevice *dev,m_uint64_t base_addr){#if 0 /* Suspend VM activity */ vm_suspend(vm); if (cpu_group_sync_state(vm->cpu_group) == -1) { fprintf(stderr,"VM%u: unable to sync with system CPUs.\n", vm->instance_id); return(-1); }#endif /* Unbind the device if it was already active */ vm_unbind_device(vm,dev); /* Map the device at the new base address and rebuild MTS */ dev->phys_addr = base_addr; vm_bind_device(vm,dev); cpu_group_rebuild_mts(vm->cpu_group);#if 0 vm_resume(vm);#endif return(0);}/* Set an IRQ for a VM */void vm_set_irq(vm_instance_t *vm,u_int irq){ if (vm->boot_cpu->irq_disable) { vm->boot_cpu->irq_pending = 0; return; } /* TODO: IRQ routing */ mips64_set_irq(vm->boot_cpu,irq); if (vm->boot_cpu->irq_idle_preempt[irq]) mips64_idle_break_wait(vm->boot_cpu);}/* Clear an IRQ for a VM */void vm_clear_irq(vm_instance_t *vm,u_int irq){ /* TODO: IRQ routing */ mips64_clear_irq(vm->boot_cpu,irq);}/* Suspend a VM instance */int vm_suspend(vm_instance_t *vm){ if (vm->status == VM_STATUS_RUNNING) { cpu_group_save_state(vm->cpu_group); cpu_group_set_state(vm->cpu_group,MIPS_CPU_SUSPENDED); vm->status = VM_STATUS_SUSPENDED; } return(0);}/* Resume a VM instance */int vm_resume(vm_instance_t *vm){ if (vm->status == VM_STATUS_SUSPENDED) { cpu_group_restore_state(vm->cpu_group); vm->status = VM_STATUS_RUNNING; } return(0);}/* Stop an instance */int vm_stop(vm_instance_t *vm){ cpu_group_stop_all_cpu(vm->cpu_group); vm->status = VM_STATUS_SHUTDOWN; return(0);}/* Monitor an instance periodically */void vm_monitor(vm_instance_t *vm){ while(vm->status != VM_STATUS_SHUTDOWN) usleep(200000);}/* Open a VM file and map it in memory */int vm_mmap_open_file(vm_instance_t *vm,char *name, u_char **ptr,off_t *fsize){ char *filename; int fd; if (!(filename = vm_build_filename(vm,name))) { fprintf(stderr,"vm_mmap_open_file: unable to create filename (%s)\n", name); return(-1); } if ((fd = memzone_open_file(filename,ptr,fsize)) == -1) fprintf(stderr,"vm_mmap_open_file: unable to open file '%s' (%s)\n", filename,strerror(errno)); free(filename); return(fd);}/* Open/Create a VM file and map it in memory */int vm_mmap_create_file(vm_instance_t *vm,char *name,size_t len,u_char **ptr){ char *filename; int fd; if (!(filename = vm_build_filename(vm,name))) { fprintf(stderr,"vm_mmap_create_file: unable to create filename (%s)\n", name); return(-1); } if ((fd = memzone_create_file(filename,len,ptr)) == -1) fprintf(stderr,"vm_mmap_create_file: unable to open file '%s' (%s)\n", filename,strerror(errno)); free(filename); return(fd);}/* Close a memory mapped file */int vm_mmap_close_file(int fd,u_char *ptr,size_t len){ if (ptr != NULL) munmap(ptr,len); if (fd != -1) close(fd); return(0);}/* Save the Cisco IOS configuration from NVRAM */int vm_ios_save_config(vm_instance_t *vm){ char *output; int res; if (!(output = vm_build_filename(vm,"ios_cfg.txt"))) return(-1); res = vm_nvram_extract_config(vm,output); free(output); return(res);}/* Set Cisco IOS image to use */int vm_ios_set_image(vm_instance_t *vm,char *ios_image){ char *str; if (!(str = strdup(ios_image))) return(-1); if (vm->ios_image != NULL) { free(vm->ios_image); vm->ios_image = NULL; } vm->ios_image = str; return(0);}/* Unset a Cisco IOS configuration file */void vm_ios_unset_config(vm_instance_t *vm){ if (vm->ios_config != NULL) { free(vm->ios_config); vm->ios_config = NULL; }}/* Set Cisco IOS configuration file to use */int vm_ios_set_config(vm_instance_t *vm,char *ios_config){ char *str; if (!(str = strdup(ios_config))) return(-1); vm_ios_unset_config(vm); vm->ios_config = str; return(0); }/* Extract IOS configuration from NVRAM and write it to a file */int vm_nvram_extract_config(vm_instance_t *vm,char *filename){ char *cfg_buffer; ssize_t cfg_len; FILE *fd; if (!vm->nvram_extract_config) return(-1); /* Extract the IOS configuration */ if (((cfg_len = vm->nvram_extract_config(vm,&cfg_buffer)) < 0) || (cfg_buffer == NULL)) return(-1); /* Write configuration to the specified filename */ if (!(fd = fopen(filename,"w"))) { vm_error(vm,"unable to create file '%s'\n",filename); free(cfg_buffer); return(-1); } fwrite(cfg_buffer,cfg_len,1,fd); fclose(fd); free(cfg_buffer); return(0);}/* Read an IOS configuraton from a file and push it to NVRAM */int vm_nvram_push_config(vm_instance_t *vm,char *filename){ char *cfg_buffer; ssize_t len; int res; if (!vm->nvram_push_config) return(-1); /* Read configuration */ if (((len = m_read_file(filename,&cfg_buffer)) <= 0) || !cfg_buffer) return(-1); /* Push it! */ res = vm->nvram_push_config(vm,cfg_buffer,len); free(cfg_buffer); return(res);}/* Save general VM configuration into the specified file */void vm_save_config(vm_instance_t *vm,FILE *fd){ if (vm->ios_image) fprintf(fd,"vm set_ios %s %s\n",vm->name,vm->ios_image); fprintf(fd,"vm set_ram %s %u\n",vm->name,vm->ram_size); fprintf(fd,"vm set_nvram %s %u\n",vm->name,vm->nvram_size); fprintf(fd,"vm set_ram_mmap %s %u\n",vm->name,vm->ram_mmap); fprintf(fd,"vm set_clock_divisor %s %u\n",vm->name,vm->clock_divisor); fprintf(fd,"vm set_conf_reg %s 0x%4.4x\n",vm->name,vm->conf_reg_setup); if (vm->vtty_con_type == VTTY_TYPE_TCP) fprintf(fd,"vm set_con_tcp_port %s %d\n",vm->name,vm->vtty_con_tcp_port); if (vm->vtty_aux_type == VTTY_TYPE_TCP) fprintf(fd,"vm set_aux_tcp_port %s %d\n",vm->name,vm->vtty_aux_tcp_port);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -