/* Show info about VM object */ static void cmd_show_vm_list(registry_entry_t *entry,void *opt,int *err) { hypervisor_conn_t *conn = opt; vm_instance_t *vm = entry->data; hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%s (%s)", entry->name,vm_get_type(vm)); }
/* Accept a TCP connection */ static int vtty_tcp_conn_accept(vtty_t *vtty, int nsock) { int fd,*fd_slot; u_int i; if (fd_pool_get_free_slot(&vtty->fd_pool,&fd_slot) < 0) { vm_error(vtty->vm,"unable to create a new VTTY TCP connection\n"); return(-1); } if ((fd = accept(vtty->fd_array[nsock],NULL,NULL)) < 0) { vm_error(vtty->vm,"vtty_tcp_conn_accept: accept on port %d failed %s\n", vtty->tcp_port,strerror(errno)); return(-1); } /* Register the new FD */ *fd_slot = fd; vm_log(vtty->vm,"VTTY","%s is now connected (accept_fd=%d,conn_fd=%d)\n", vtty->name,vtty->fd_array[nsock],fd); /* Adapt Telnet settings */ if (vtty->terminal_support) { vtty_telnet_do_ttype(fd); vtty_telnet_will_echo(fd); vtty_telnet_will_suppress_go_ahead(fd); vtty_telnet_dont_linemode(fd); vtty->input_state = VTTY_INPUT_TEXT; } if (telnet_message_ok == 1) { fd_printf(fd,0, "Connected to Dynamips VM \"%s\" (ID %u, type %s) - %s\r\n" "Press ENTER to get the prompt.\r\n", vtty->vm->name, vtty->vm->instance_id, vm_get_type(vtty->vm), vtty->name); /* replay old text */ for (i = vtty->replay_ptr; i < VTTY_BUFFER_SIZE; i++) { if (vtty->replay_buffer[i] != 0) { send(fd,&vtty->replay_buffer[i],VTTY_BUFFER_SIZE-i,0); break; } } for (i = 0; i < vtty->replay_ptr; i++) { if (vtty->replay_buffer[i] != 0) { send(fd,&vtty->replay_buffer[i],vtty->replay_ptr-i,0); break; } } /* warn if not running */ if (vtty->vm->status != VM_STATUS_RUNNING) fd_printf(fd,0,"\r\n!!! WARNING - VM is not running, will be unresponsive (status=%d) !!!\r\n",vtty->vm->status); vtty_flush(vtty); } return(0); }
/* Generate a filename for use by the instance */ char *vm_build_filename(vm_instance_t *vm,char *name) { char *filename,*machine; machine = vm_get_type(vm); switch(vm_file_naming_type) { case 1: filename = dyn_sprintf("%s_i%u_%s",machine,vm->instance_id,name); break; case 0: default: filename = dyn_sprintf("%s_%s_%s",machine,vm->name,name); break; } assert(filename != NULL); return filename; }
/* Rename a VM instance */ int vm_rename_instance(vm_instance_t *vm, char *name) { char *old_name; char *old_lock_file = NULL; FILE *old_lock_fd = NULL; glob_t globbuf; size_t i; char *pattern = NULL; char *filename; int do_rename = 0; if (name == NULL || vm == NULL) goto err_invalid; /* invalid argument */ if (vm->status != VM_STATUS_HALTED) goto err_not_stopped; /* VM is not stopped */ if (strcmp(vm->name, name) == 0) return(0); /* same name, done */ if (registry_exists(name,OBJ_TYPE_VM)) goto err_exists; /* name already exists */ old_name = vm->name; vm->name = NULL; if(!(vm->name = strdup(name))) goto err_strdup; /* out of memory */ /* get new lock */ do_rename = ( vm_file_naming_type != 1 ); if (do_rename) { old_lock_file = vm->lock_file; old_lock_fd = vm->lock_fd; vm->lock_file = NULL; vm->lock_fd = NULL; if (vm_get_lock(vm) == -1) goto err_lock; } if (registry_rename(old_name,name,OBJ_TYPE_VM)) goto err_registry; /* failed to rename */ vm_log(vm,"VM","renamed from '%s' to '%s'",old_name,vm->name); /* rename files (best effort) */ if (do_rename) { fclose(old_lock_fd); unlink(old_lock_file); free(old_lock_file); vm_close_log(vm); if ((pattern = dyn_sprintf("%s_%s_*",vm_get_type(vm),old_name)) == NULL) goto skip_rename; if (glob(pattern, GLOB_NOSORT, NULL, &globbuf) != 0) goto skip_rename; for (i = 0; i < globbuf.gl_pathc; i++) { if ((filename = dyn_sprintf("%s_%s_%s",vm_get_type(vm),vm->name,globbuf.gl_pathv[i] + strlen(pattern) - 1)) == NULL) break; /* out of memory */ rename(globbuf.gl_pathv[i], filename); free(filename); } globfree(&globbuf); skip_rename: free(pattern); vm_reopen_log(vm); } free(old_name); return(0); // done err_registry: err_lock: err_strdup: free(vm->name); vm->name = old_name; if (do_rename) { vm_release_lock(vm,TRUE); vm->lock_file = old_lock_file; vm->lock_fd = old_lock_fd; } err_exists: err_not_stopped: err_invalid: return(-1); }
/* Add a Network IO descriptor binding (command line) */ int vm_slot_cmd_add_nio(vm_instance_t *vm,char *str) { char *tokens[SLOT_DESC_MAX_TOKENS]; int i,count,nio_type,res=-1; u_int slot_id,port_id; netio_desc_t *nio; char nio_name[128]; /* A NIO binding description is like "1:3:tap:tap0" */ if ((count = m_strsplit(str,':',tokens,SLOT_DESC_MAX_TOKENS)) < 3) { vm_error(vm,"unable to parse NIO description '%s'.\n",str); return(-1); } /* Parse the slot id */ slot_id = atoi(tokens[0]); /* Parse the port id */ port_id = atoi(tokens[1]); /* Autogenerate a NIO name */ snprintf(nio_name,sizeof(nio_name),"%s-i%u/%u/%u", vm_get_type(vm),vm->instance_id,slot_id,port_id); /* Create the Network IO descriptor */ nio = NULL; nio_type = netio_get_type(tokens[2]); switch(nio_type) { case NETIO_TYPE_UNIX: if (count != 5) { vm_error(vm,"invalid number of arguments for UNIX NIO '%s'\n",str); goto done; } nio = netio_desc_create_unix(nio_name,tokens[3],tokens[4]); break; case NETIO_TYPE_VDE: if (count != 5) { vm_error(vm,"invalid number of arguments for VDE NIO '%s'\n",str); goto done; } nio = netio_desc_create_vde(nio_name,tokens[3],tokens[4]); break; case NETIO_TYPE_TAP: if (count != 4) { vm_error(vm,"invalid number of arguments for TAP NIO '%s'\n",str); goto done; } nio = netio_desc_create_tap(nio_name,tokens[3]); break; case NETIO_TYPE_UDP: if (count != 6) { vm_error(vm,"invalid number of arguments for UDP NIO '%s'\n",str); goto done; } nio = netio_desc_create_udp(nio_name,atoi(tokens[3]), tokens[4],atoi(tokens[5])); break; case NETIO_TYPE_TCP_CLI: if (count != 5) { vm_error(vm,"invalid number of arguments for TCP CLI NIO '%s'\n", str); goto done; } nio = netio_desc_create_tcp_cli(nio_name,tokens[3],tokens[4]); break; case NETIO_TYPE_TCP_SER: if (count != 4) { vm_error(vm,"invalid number of arguments for TCP SER NIO '%s'\n", str); goto done; } nio = netio_desc_create_tcp_ser(nio_name,tokens[3]); break; case NETIO_TYPE_NULL: nio = netio_desc_create_null(nio_name); break; #ifdef LINUX_ETH case NETIO_TYPE_LINUX_ETH: if (count != 4) { vm_error(vm,"invalid number of arguments for Linux Eth NIO '%s'\n", str); goto done; } nio = netio_desc_create_lnxeth(nio_name,tokens[3]); break; #endif #ifdef GEN_ETH case NETIO_TYPE_GEN_ETH: if (count != 4) { vm_error(vm, "invalid number of arguments for Generic Eth NIO '%s'\n", str); goto done; } nio = netio_desc_create_geneth(nio_name,tokens[3]); break; #endif default: vm_error(vm,"unknown NETIO type '%s'\n",tokens[2]); goto done; } if (!nio) { vm_error(vm,"unable to create NETIO descriptor for slot %u\n",slot_id); goto done; } if (vm_slot_add_nio_binding(vm,slot_id,port_id,nio_name) == -1) { vm_error(vm,"unable to add NETIO binding for slot %u\n",slot_id); netio_release(nio_name); netio_delete(nio_name); goto done; } netio_release(nio_name); res = 0; done: /* The complete array was cleaned by strsplit */ for(i=0;i<SLOT_DESC_MAX_TOKENS;i++) free(tokens[i]); return(res); }