/* Dump the idle PC proposals */ static int cmd_show_idle_pc_prop(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; cpu_gen_t *cpu; int i; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); if (!(cpu = find_cpu(conn,vm,atoi(argv[1])))) return(-1); for(i=0;i<cpu->idle_pc_prop_count;i++) { hypervisor_send_reply(conn,HSC_INFO_MSG,0,"0x%llx [%d]", cpu->idle_pc_prop[i].pc, cpu->idle_pc_prop[i].count); } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Set ghost RAM status */ static int cmd_set_ghost_status(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); vm->ghost_status = atoi(argv[1]); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Set the idle PC */ static int cmd_set_idle_pc(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); vm->idle_pc = strtoull(argv[1],NULL,0); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Send a message on the console */ static int cmd_send_con_msg(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); vtty_store_str(vm->vtty_con,argv[1]); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Set the I/O mem size */ static int cmd_set_iomem(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; if (!(vm = hypervisor_find_vm(conn,argv[0]))) return(-1); vm->nm_iomem_size = 0x8000 | atoi(argv[1]); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Resume a VM instance */ static int cmd_resume(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); vm_resume(vm); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"VM '%s' resumed",argv[0]); return(0); }
/* Save the hypervisor configuration in the specified file */ static int cmd_save_config(hypervisor_conn_t *conn,int argc,char *argv[]) { FILE *fd; if (!(fd = fopen(argv[0],"w"))) { hypervisor_send_reply(conn,HSC_ERR_FILE,1,"fopen: %s",strerror(errno)); return(-1); } /* Save configuration for all objects */ netio_save_config_all(fd); frsw_save_config_all(fd); atmsw_save_config_all(fd); //atm_bridge_save_config_all(fd); netio_bridge_save_config_all(fd); vm_save_config_all(fd); fclose(fd); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Set TCP port for AUX port */ static int cmd_set_aux_tcp_port(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); vm->vtty_aux_type = VTTY_TYPE_TCP; vm->vtty_aux_tcp_port = atoi(argv[1]); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Get the status of a VM instance */ static int cmd_get_status(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; int status; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); status = vm->status; vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"%d",status); return(0); }
/* OIR to stop a slot/subslot */ static int cmd_slot_oir_stop(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; u_int slot,subslot; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); slot = atoi(argv[1]); subslot = atoi(argv[2]); if (vm_oir_stop(vm,slot,subslot) == -1) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_STOP,1, "VM %s: unable to engage OIR for slot %u/%u", argv[0],slot,subslot); return(-1); } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Add a breakpoint */ static int cmd_add_cpu_breakpoint(hypervisor_conn_t *conn, int argc,char *argv[]) { vm_instance_t *vm; cpu_gen_t *cpu; m_uint64_t addr; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); if (!(cpu = cpu_group_find_id(vm->cpu_group,atoi(argv[1])))) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_BAD_OBJ,1,"Bad CPU"); return(-1); } addr = strtoull(argv[2],NULL,0); cpu->add_breakpoint(cpu,addr); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Add a slot binding */ static int cmd_slot_add_binding(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; u_int slot,port; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); slot = atoi(argv[1]); port = atoi(argv[2]); if (vm_slot_add_binding(vm,argv[3],slot,port) == -1) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_BINDING,1, "VM %s: unable to add binding for slot %u/%u", argv[0],slot,port); return(-1); } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Show NIO bindings for the specified slot */ static int cmd_slot_nio_bindings(hypervisor_conn_t *conn,int argc,char *argv[]) { struct cisco_nio_binding *nb; struct cisco_card *card,*sc; vm_instance_t *vm; u_int i,slot; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); slot = atoi(argv[1]); if ((card = vm_slot_get_card_ptr(vm,slot))) { /* main module */ for(nb=card->nio_list;nb;nb=nb->next) { hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%u: %s", nb->port_id,nb->nio->name); } /* sub-slots */ for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) { if (!(sc = card->sub_slots[i])) continue; for(nb=sc->nio_list;nb;nb=nb->next) { hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%u: %s", nb->port_id,nb->nio->name); } } } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Show CPU MMU info */ static int cmd_show_cpu_mmu(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; cpu_gen_t *cpu; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); if ((cpu = cpu_group_find_id(vm->cpu_group,atoi(argv[1]))) != NULL) cpu->mmu_dump(cpu); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Find the specified CPU */ static cpu_gen_t *find_cpu(hypervisor_conn_t *conn,vm_instance_t *vm, u_int cpu_id) { cpu_gen_t *cpu; cpu = cpu_group_find_id(vm->cpu_group,cpu_id); if (!cpu) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_BAD_OBJ,1,"Bad CPU specified"); return NULL; } return cpu; }
/* Set the clock divisor */ static int cmd_set_clock_divisor(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; u_int clock_div; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); if ((clock_div = atoi(argv[1])) != 0) vm->clock_divisor = clock_div; vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Show C1700 hardware */ static int cmd_show_hardware(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; c1700_t *router; if (!(vm = hypervisor_find_vm(conn,argv[0]))) return(-1); router = VM_C1700(vm); c1700_show_hardware(router); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Read a 16-bit memory word */ static int cmd_pmem_r16(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; m_uint64_t addr; m_uint16_t value; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); /* Write word */ addr = strtoull(argv[2],NULL,0); value = physmem_copy_u16_from_vm(vm,addr); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"0x%4.4x",value); return(0); }
/* Set CPU idle max value */ static int cmd_set_idle_max(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; cpu_gen_t *cpu; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); if (!(cpu = find_cpu(conn,vm,atoi(argv[1])))) return(-1); cpu->idle_max = atoi(argv[2]); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Get the base MAC address for the chassis */ static int cmd_get_mac_addr(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; c3745_t *router; if (!(vm = hypervisor_find_vm(conn,argv[0]))) return(-1); router = VM_C3745(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1, "%2.2x%2.2x.%2.2x%2.2x.%2.2x%2.2x", router->mac_addr.eth_addr_byte[0], router->mac_addr.eth_addr_byte[1], router->mac_addr.eth_addr_byte[2], router->mac_addr.eth_addr_byte[3], router->mac_addr.eth_addr_byte[4], router->mac_addr.eth_addr_byte[5]); vm_release(vm); return(0); }
/* Stop hypervisor */ static int cmd_stop(hypervisor_conn_t *conn,int argc,char *argv[]) { hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); hypervisor_running = FALSE; return(0); }
/* Close connection */ static int cmd_close(hypervisor_conn_t *conn,int argc,char *argv[]) { hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); conn->active = FALSE; return(0); }
/* Reset hypervisor (delete all objects) */ static int cmd_reset(hypervisor_conn_t *conn,int argc,char *argv[]) { dynamips_reset(); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Statistics about JIT code sharing (dumped on console) */ static int cmd_tsg_stats(hypervisor_conn_t *conn,int argc,char *argv[]) { tsg_show_stats(); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Push IOS configuration to a given router */ static int cmd_push_config(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; u_char *startup_config = NULL; u_char *private_config = NULL; int startup_len = 0; int private_len = 0; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); if (!vm->platform->nvram_push_config) goto err_no_push_method; /* * Convert base64 input to standard text. base64 uses 4 bytes for each group of 3 bytes. */ if (strcmp(argv[1],"(keep)") != 0) { startup_len = (strlen(argv[1]) + 3) / 4 * 3; if (!(startup_config = malloc(1 + startup_len))) goto err_alloc_base64; if ((startup_len = base64_decode(startup_config,(u_char *)argv[1],startup_len)) < 0) goto err_decode_base64; startup_config[startup_len] = '\0'; } if (argc > 2 && strcmp(argv[2],"(keep)") != 0) { private_len = (strlen(argv[2]) + 3) / 4 * 3; if (!(private_config = malloc(1 + private_len))) goto err_alloc_base64; if ((private_len = base64_decode(private_config,(u_char *)argv[2],private_len)) < 0) goto err_decode_base64; private_config[private_len] = '\0'; } /* Push configuration */ if (vm->platform->nvram_push_config(vm,startup_config,(size_t)startup_len,private_config,(size_t)private_len) < 0) goto err_nvram_push; free(private_config); free(startup_config); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1, "IOS config file pushed tm VM '%s'", argv[0]); return(0); err_nvram_push: err_decode_base64: err_alloc_base64: free(private_config); free(startup_config); err_no_push_method: vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_CREATE,1, "unable to push IOS config for VM '%s'", argv[0]); return(-1); }
/* Thread for servicing connections */ static void *hypervisor_thread(void *arg) { hypervisor_conn_t *conn = arg; char buffer[512],**tokens; parser_context_t ctx; int res; tokens = NULL; parser_context_init(&ctx); while(conn->active) { if (!fgets(buffer,sizeof(buffer),conn->in)) break; if (!*buffer) continue; /* Tokenize command line */ res = parser_scan_buffer(&ctx,buffer,strlen(buffer)); if (res != 0) { tokens = NULL; if (ctx.error != 0) { hypervisor_send_reply(conn,HSC_ERR_PARSING,1,"Parse error: %s", parser_strerror(&ctx)); goto free_tokens; } if (ctx.tok_count < 2) { hypervisor_send_reply(conn,HSC_ERR_PARSING,1, "At least a module and a command " "must be specified"); goto free_tokens; } /* Map token list to an array */ tokens = parser_map_array(&ctx); if (!tokens) { hypervisor_send_reply(conn,HSC_ERR_PARSING,1,"No memory"); goto free_tokens; } /* Execute command */ m_log("HYPERVISOR","exec_cmd: "); m_flog_str_array(log_file,ctx.tok_count,tokens); hypervisor_exec_cmd(conn,tokens[0],tokens[1],ctx. tok_count-2,&tokens[2]); free_tokens: free(tokens); tokens = NULL; parser_context_free(&ctx); } } free(tokens); parser_context_free(&ctx); return NULL; }
/* Show hypervisor version */ static int cmd_version(hypervisor_conn_t *conn,int argc,char *argv[]) { hypervisor_send_reply(conn,HSC_INFO_OK,1,"%s",sw_version); return(0); }
/* Show info about a NIO bridge object */ static void cmd_show_list(registry_entry_t *entry,void *opt,int *err) { hypervisor_conn_t *conn = opt; hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%s",entry->name); }