/* Show info about potential timer drift */ static int cmd_show_timer_drift(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); switch(cpu->type) { case CPU_TYPE_MIPS64: hypervisor_send_reply(conn,HSC_INFO_MSG,0,"Timer Drift: %u", CPU_MIPS64(cpu)->timer_drift); hypervisor_send_reply(conn,HSC_INFO_MSG,0,"Pending Timer IRQ: %u", CPU_MIPS64(cpu)->timer_irq_pending); break; case CPU_TYPE_PPC32: hypervisor_send_reply(conn,HSC_INFO_MSG,0,"Timer Drift: %u", CPU_PPC32(cpu)->timer_drift); hypervisor_send_reply(conn,HSC_INFO_MSG,0,"Pending Timer IRQ: %u", CPU_PPC32(cpu)->timer_irq_pending); break; } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Show slot bindings */ static int cmd_slot_bindings(hypervisor_conn_t *conn,int argc,char *argv[]) { struct cisco_card *card,*sc; vm_instance_t *vm; int i,j; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); for(i=0;i<vm->nr_slots;i++) { if (!(card = vm_slot_get_card_ptr(vm,i))) continue; /* main module */ hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%u/%u: %s", card->slot_id,card->subslot_id,card->dev_type); /* sub-slots */ for(j=0;j<CISCO_CARD_MAX_SUBSLOTS;j++) { if (!(sc = card->sub_slots[j])) continue; hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%u/%u: %s", card->slot_id,card->subslot_id,card->dev_type); } } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Set IOS configuration filename to load at startup */ static int cmd_set_config(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; const char *startup_filename = argv[1]; const char *private_filename = ((argc > 2) ? argv[2] : ""); if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); if (0 == strlen(startup_filename)) startup_filename = NULL; // keep existing data if (0 == strlen(private_filename)) private_filename = NULL; // keep existing data if (vm_ios_set_config(vm,startup_filename,private_filename) == -1) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_CREATE,1, "unable to store IOS config for router '%s'", argv[0]); return(-1); } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"IOS config file set for '%s'", argv[0]); return(0); }
/* Set a CPU register */ static int cmd_set_cpu_reg(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; cpu_gen_t *cpu; int reg_index; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); cpu = cpu_group_find_id(vm->cpu_group,atoi(argv[1])); reg_index = atoi(argv[2]); if (!cpu || (reg_index < 1)) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_BAD_OBJ,1,"Bad CPU or register"); return(-1); } /* Set register value */ cpu->reg_set(cpu,reg_index,strtoull(argv[3],NULL,0)); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Start a VM instance */ static int cmd_start(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); if (vm->vtty_con_type == VTTY_TYPE_NONE) { hypervisor_send_reply(conn,HSC_INFO_MSG,0, "Warning: no console port defined for " "VM '%s'",argv[0]); } if (vm_init_instance(vm) == -1) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_START,1, "unable to start VM instance '%s'", argv[0]); return(-1); } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"VM '%s' started",argv[0]); return(0); }
/* Delete a VM instance and related files */ static int cmd_clean_delete(hypervisor_conn_t *conn,int argc,char *argv[]) { int res, i; glob_t globbuf; char *pattern; vm_instance_t *vm; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); pattern = vm_build_filename(vm, "*"); vm_release(vm); res = vm_delete_instance(argv[0]); if (res == 1) { /* delete related files (best effort) */ if (pattern != NULL && glob(pattern, GLOB_NOSORT, NULL, &globbuf) == 0) { for (i = 0; i < globbuf.gl_pathc; i++) { remove(globbuf.gl_pathv[i]); } globfree(&globbuf); } hypervisor_send_reply(conn,HSC_INFO_OK,1,"VM '%s' and related files deleted",argv[0]); } else { hypervisor_send_reply(conn,HSC_ERR_DELETE,1, "unable to delete VM '%s'",argv[0]); } free(pattern); return(res); }
/* Rename a VM instance */ static int cmd_rename(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); if (registry_exists(argv[1],OBJ_TYPE_VM)) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_RENAME,1, "unable to rename VM instance '%s', '%s' already exists", argv[0],argv[1]); return(-1); } if (vm_rename_instance(vm,argv[1])) { hypervisor_send_reply(conn,HSC_ERR_RENAME,1, "unable to rename VM instance '%s'", argv[0]); return(-1); } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"VM '%s' renamed to '%s'",argv[0],argv[1]); return(0); }
/* Set PCMCIA ATA disk1 size */ static int cmd_set_disk1(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->pcmcia_disk_size[1] = atoi(argv[1]); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Set the config register used at startup */ static int cmd_set_conf_reg(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->conf_reg_setup = strtol(argv[1],NULL,0); 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); }
/* Send a message on the AUX port */ static int cmd_send_aux_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_aux,argv[1]); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Read IOS configuration files from a given router */ static int cmd_extract_config(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; u_char *startup_config = NULL; u_char *private_config = NULL; size_t startup_len; size_t private_len; u_char *startup_base64 = NULL; u_char *private_base64 = NULL; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); if (!vm->platform->nvram_extract_config) goto err_no_extract_method; /* Extract the IOS configuration */ if ((vm->platform->nvram_extract_config(vm,&startup_config,&startup_len,&private_config,&private_len))) goto err_nvram_extract; /* * Convert config to base64. base64 generates 4 bytes for each group of 3 bytes. */ if (!(startup_base64 = malloc(1 + (startup_len + 2) / 3 * 4)) || !(private_base64 = malloc(1 + (private_len + 2) / 3 * 4))) goto err_alloc_base64; base64_encode(startup_base64,startup_config,startup_len); base64_encode(private_base64,private_config,private_len); vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"conf '%s' '%s' '%s'",argv[0],startup_base64,private_base64); free(private_base64); free(startup_base64); free(private_config); free(startup_config); return(0); err_alloc_base64: free(private_base64); free(startup_base64); free(private_config); free(startup_config); err_nvram_extract: err_no_extract_method: vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_CREATE,1, "unable to extract config of VM '%s'",argv[0]); return(-1); }
/* Set ghost RAM file */ static int cmd_set_ghost_file(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); free(vm->ghost_ram_filename); vm->ghost_ram_filename = strdup(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); }
/* 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); }
/* 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 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); }
/* 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); }
/* Show CPU usage - experimental */ static int cmd_show_cpu_usage(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; double usage; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); usage = get_cpu_time(); if (usage == -1) return(-1); hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%u", (unsigned long)usage); 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 translation sharing group */ static int cmd_set_tsg(hypervisor_conn_t *conn,int argc,char *argv[]) { vm_instance_t *vm; int res; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); res = vm_set_tsg(vm,atoi(argv[1])); vm_release(vm); if (res < 0) hypervisor_send_reply(conn,HSC_ERR_BAD_PARAM,1,"unable to set group"); else hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Stop a VM instance */ static int cmd_stop(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); if (vm_stop_instance(vm) == -1) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_STOP,1, "unable to stop VM instance '%s'", argv[0]); return(-1); } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"VM '%s' stopped",argv[0]); return(0); }
/* * Remove a NIO from a bridge * * Parameters: <bridge_name> <nio_name> */ static int cmd_remove_nio(hypervisor_conn_t *conn,int argc,char *argv[]) { netio_bridge_t *t; if (!(t = hypervisor_find_object(conn,argv[0],OBJ_TYPE_NIO_BRIDGE))) return(-1); if (netio_bridge_remove_netio(t,argv[1]) == -1) { netio_bridge_release(argv[0]); hypervisor_send_reply(conn,HSC_ERR_BINDING,1, "unable to bind NIO '%s' to bridge '%s'", argv[1],argv[0]); return(-1); } netio_bridge_release(argv[0]); hypervisor_send_reply(conn,HSC_INFO_OK,1,"NIO '%s' unbound.",argv[1]); return(0); }
/* Set IOS image filename */ static int cmd_set_ios(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); if (vm_ios_set_image(vm,argv[1]) == -1) { vm_release(vm); hypervisor_send_reply(conn,HSC_ERR_CREATE,1, "unable to store IOS image name for router '%s'", argv[0]); return(-1); } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"IOS image set for '%s'",argv[0]); return(0); }
/* 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); }
/* 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); }
/* 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); }
/* 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); }
/* 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); }