mirror of https://github.com/BOINC/boinc.git
- VBOX: Checkpoint, Re-implement the registering and un-registering of the
vm using the vboxmanage app. samples/vboxwrapper/ vbox.cpp, .h vm.cpp, .h svn path=/trunk/boinc/; revision=23485
This commit is contained in:
parent
4a5c418b43
commit
602f972292
|
@ -2705,3 +2705,11 @@ David 29 Apr 2011
|
|||
|
||||
lib/
|
||||
gui_rpc_client.cpp
|
||||
|
||||
Rom 29 Apr 2011
|
||||
- VBOX: Checkpoint, Re-implement the registering and un-registering of the
|
||||
vm using the vboxmanage app.
|
||||
|
||||
samples/vboxwrapper/
|
||||
vbox.cpp, .h
|
||||
vm.cpp, .h
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "procinfo.h"
|
||||
#include "boinc_api.h"
|
||||
#include "vbox.h"
|
||||
#include "vm.h"
|
||||
|
||||
|
||||
// Execute the vbox manage application and copy the output to the
|
||||
|
@ -61,9 +62,8 @@ int virtualbox_vbm_popen(std::string& arguments, std::string& output) {
|
|||
if (fp == NULL){
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s vbm_popen popen failed! cmd = '%s', errno = %d\n",
|
||||
"%s vbm_popen popen failed! errno = %d\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
command.c_str(),
|
||||
errno
|
||||
);
|
||||
return VBOX_POPEN_ERROR;
|
||||
|
@ -84,7 +84,7 @@ int virtualbox_vbm_popen(std::string& arguments, std::string& output) {
|
|||
// Returns the current directory in which the executable resides.
|
||||
//
|
||||
int virtualbox_generate_vm_root_dir( std::string& dir ) {
|
||||
TCHAR root_dir[256];
|
||||
char root_dir[256];
|
||||
|
||||
#ifdef _WIN32
|
||||
_getcwd(root_dir, (sizeof(root_dir)*sizeof(TCHAR)));
|
||||
|
@ -127,6 +127,48 @@ int virtualbox_generate_vm_name( std::string& name ) {
|
|||
}
|
||||
|
||||
|
||||
// Generate a deterministic yet unique UUID for a given medium (hard drive,
|
||||
// cd drive, hard drive image)
|
||||
// Rules:
|
||||
// 1. Must be unique
|
||||
// 2. Must identifity itself as being part of BOINC
|
||||
// 3. Must be based on the slot directory id
|
||||
// 4. Must be in the form of a GUID
|
||||
// 00000000-0000-0000-0000-000000000000
|
||||
//
|
||||
// Form/Meaning
|
||||
// A B C D E
|
||||
// 00000000-0000-0000-0000-000000000000
|
||||
//
|
||||
// A = Drive ID
|
||||
// B = Slot ID
|
||||
// C = Standalone Flag
|
||||
// D = Reserved
|
||||
// E = 'BOINC' ASCII converted to Hex
|
||||
//
|
||||
int virtualbox_generate_medium_uuid( int drive_id, std::string& uuid ) {
|
||||
APP_INIT_DATA aid;
|
||||
char medium_uuid[256];
|
||||
|
||||
boinc_get_init_data_p( &aid );
|
||||
|
||||
sprintf(
|
||||
medium_uuid,
|
||||
_T("%08d-%04d-%04d-0000-00424F494E43"),
|
||||
drive_id,
|
||||
aid.slot,
|
||||
boinc_is_standalone()
|
||||
);
|
||||
|
||||
uuid = medium_uuid;
|
||||
|
||||
if (!uuid.empty()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool virtualbox_vm_is_registered() {
|
||||
std::string command;
|
||||
std::string output;
|
||||
|
@ -140,7 +182,23 @@ bool virtualbox_vm_is_registered() {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool virtualbox_vm_is_hdd_uuid_registered() {
|
||||
std::string command;
|
||||
std::string output;
|
||||
std::string virtual_hdd_uuid;
|
||||
|
||||
virtualbox_generate_medium_uuid(0, virtual_hdd_uuid);
|
||||
command = "showhdinfo " + virtual_hdd_uuid;
|
||||
|
||||
if (VBOX_SUCCESS == virtualbox_vbm_popen(command, output)) {
|
||||
if (output.find("VBOX_E_FILE_ERROR") != std::string::npos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -173,9 +231,13 @@ int virtualbox_register_vm() {
|
|||
std::string output;
|
||||
std::string virtual_machine_name;
|
||||
std::string virtual_machine_root_dir;
|
||||
std::string virtual_hdd_uuid;
|
||||
char buf[256];
|
||||
int retval;
|
||||
|
||||
virtualbox_generate_vm_name(virtual_machine_name);
|
||||
virtualbox_generate_vm_root_dir(virtual_machine_root_dir);
|
||||
virtualbox_generate_medium_uuid(0, virtual_hdd_uuid);
|
||||
|
||||
fprintf(
|
||||
stderr,
|
||||
|
@ -183,14 +245,247 @@ int virtualbox_register_vm() {
|
|||
boinc_msg_prefix(buf, sizeof(buf))
|
||||
);
|
||||
|
||||
//command = "startvm " + virtual_machine_name + " --type headless";
|
||||
//virtualbox_vbm_popen(command, output);
|
||||
|
||||
// Create and register the VM
|
||||
//
|
||||
command = "createvm ";
|
||||
command += "--name \"" + virtual_machine_name + "\" ";
|
||||
command += "--basefolder \"" + virtual_machine_root_dir + "\" ";
|
||||
command += "--settingsfile \"" + virtual_machine_root_dir + "/" + virtual_machine_name + "\" ";
|
||||
command += "--ostype \"" + vm.vm_os_name + "\" ";
|
||||
command += "--register";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error registering virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// Tweak the VM from it's default configuration
|
||||
//
|
||||
command = "modifyvm \"" + virtual_machine_name + "\" ";
|
||||
command += "--memory " + vm.vm_memory_size + " ";
|
||||
command += "--acpi on ";
|
||||
command += "--ioapic on ";
|
||||
command += "--boot1 disk ";
|
||||
command += "--boot2 none ";
|
||||
command += "--boot3 none ";
|
||||
command += "--boot4 none ";
|
||||
command += "--nic1 nat ";
|
||||
command += "--natdnsproxy1 on ";
|
||||
command += "--cableconnected1 off ";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error modifing virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// Add storage controller to VM
|
||||
//
|
||||
command = "storagectl \"" + virtual_machine_name + "\" ";
|
||||
command += "--name \"IDE Controller\" ";
|
||||
command += "--add ide ";
|
||||
command += "--controller PIIX4 ";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error adding storage controller to virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// Adding virtual hard drive to Virtual Box Media Registry
|
||||
//
|
||||
command = "openmedium ";
|
||||
command += "disk \"" + virtual_machine_root_dir + "/" + vm.vm_disk_image_name + "\" ";
|
||||
command += "--uuid " + virtual_hdd_uuid + " ";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error adding virtual disk drive to virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// Adding virtual hard drive to VM
|
||||
//
|
||||
command = "storageattach \"" + virtual_machine_name + "\" ";
|
||||
command += "--storagectl \"IDE Controller\" ";
|
||||
command += "--port 0 ";
|
||||
command += "--device 0 ";
|
||||
command += "--type hdd ";
|
||||
command += "--medium " + virtual_hdd_uuid + " ";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error adding virtual disk drive to virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// Enable the network adapter if a network connection is required.
|
||||
// NOTE: Network access should never be allowed if the code running in a
|
||||
// shared directory or the VM itself is NOT signed. Doing so opens up
|
||||
// the network behind the firewall to attack.
|
||||
//
|
||||
if (vm.enable_network) {
|
||||
command = "modifyvm \"" + virtual_machine_name + "\" ";
|
||||
command += "--cableconnected1 on ";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error enabling network access for virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Enable the shared folder if a shared folder is specified.
|
||||
//
|
||||
if (vm.enable_shared_directory) {
|
||||
command = "sharedfolder add \"" + virtual_machine_name + "\" ";
|
||||
command += "--name \"" + vm.vm_shared_folder_name + "\" ";
|
||||
command += "--hostpath \"" + virtual_machine_root_dir + "/" + vm.vm_shared_folder_dir_name + "\" ";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error enabling shared directory for virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
return VBOX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int virtualbox_deregister_vm() {
|
||||
std::string command;
|
||||
std::string output;
|
||||
std::string virtual_machine_name;
|
||||
std::string virtual_machine_root_dir;
|
||||
std::string virtual_hdd_uuid;
|
||||
char buf[256];
|
||||
int retval;
|
||||
|
||||
virtualbox_generate_vm_name(virtual_machine_name);
|
||||
virtualbox_generate_vm_root_dir(virtual_machine_root_dir);
|
||||
virtualbox_generate_medium_uuid(0, virtual_hdd_uuid);
|
||||
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Deregistering virtual machine.\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf))
|
||||
);
|
||||
|
||||
|
||||
// First step in deregistering a VM is to delete its storage controller
|
||||
//
|
||||
command = "storagectl \"" + virtual_machine_name + "\" ";
|
||||
command += "--name \"IDE Controller\" ";
|
||||
command += "--remove ";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error removing storage controller from virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// Next delete VM
|
||||
//
|
||||
command = "unregistervm \"" + virtual_machine_name + "\" ";
|
||||
command += "--delete ";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error removing virtual machine from virtual box! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// Lastly delete medium from Virtual Box Media Registry
|
||||
//
|
||||
command = "closemedium \"" + virtual_hdd_uuid + "\" ";
|
||||
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error removing virtual hdd from virtual box! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return VBOX_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -204,10 +499,24 @@ int virtualbox_startvm() {
|
|||
std::string command;
|
||||
std::string output;
|
||||
std::string virtual_machine_name;
|
||||
char buf[256];
|
||||
int retval;
|
||||
|
||||
virtualbox_generate_vm_name(virtual_machine_name);
|
||||
command = "startvm " + virtual_machine_name + " --type headless";
|
||||
return virtualbox_vbm_popen(command, output);
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error starting virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
return VBOX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,10 +524,24 @@ int virtualbox_stopvm() {
|
|||
std::string command;
|
||||
std::string output;
|
||||
std::string virtual_machine_name;
|
||||
char buf[256];
|
||||
int retval;
|
||||
|
||||
virtualbox_generate_vm_name(virtual_machine_name);
|
||||
command = "controlvm " + virtual_machine_name + " savestate";
|
||||
return virtualbox_vbm_popen(command, output);
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error stopping virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
return VBOX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -226,10 +549,24 @@ int virtualbox_pausevm() {
|
|||
std::string command;
|
||||
std::string output;
|
||||
std::string virtual_machine_name;
|
||||
char buf[256];
|
||||
int retval;
|
||||
|
||||
virtualbox_generate_vm_name(virtual_machine_name);
|
||||
command = "controlvm " + virtual_machine_name + " pause";
|
||||
return virtualbox_vbm_popen(command, output);
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error pausing virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
return VBOX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -237,10 +574,24 @@ int virtualbox_resumevm() {
|
|||
std::string command;
|
||||
std::string output;
|
||||
std::string virtual_machine_name;
|
||||
char buf[256];
|
||||
int retval;
|
||||
|
||||
virtualbox_generate_vm_name(virtual_machine_name);
|
||||
command = "controlvm " + virtual_machine_name + " resume";
|
||||
return virtualbox_vbm_popen(command, output);
|
||||
retval = virtualbox_vbm_popen(command, output);
|
||||
if (retval) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s Error resuming virtual machine! rc = 0x%x\nCommand:\n%s\nOutput:\n%s\n",
|
||||
boinc_msg_prefix(buf, sizeof(buf)),
|
||||
retval,
|
||||
command.c_str(),
|
||||
output.c_str()
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
return VBOX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,8 +28,10 @@
|
|||
// Functions
|
||||
extern int virtualbox_generate_vm_root_dir( std::string& dir );
|
||||
extern int virtualbox_generate_vm_name( std::string& name );
|
||||
extern int virtualbox_generate_medium_uuid( int drive_id, std::string& uuid );
|
||||
|
||||
extern bool virtualbox_vm_is_registered();
|
||||
extern bool virtualbox_vm_is_hdd_uuid_registered();
|
||||
extern bool virtualbox_vm_is_running();
|
||||
|
||||
extern int virtualbox_initialize();
|
||||
|
|
|
@ -47,10 +47,8 @@ VM::VM() {
|
|||
stdout_filename.clear();
|
||||
stderr_filename.clear();
|
||||
vm_os_name.clear();
|
||||
vm_os_version.clear();
|
||||
vm_memory_size = 0;
|
||||
vm_memory_size.clear();
|
||||
vm_disk_image_name.clear();
|
||||
vm_disk_image_type.clear();
|
||||
vm_shared_folder_name.clear();
|
||||
vm_shared_folder_dir_name.clear();
|
||||
suspended = false;
|
||||
|
@ -79,10 +77,8 @@ int VM::parse(XML_PARSER& xp) {
|
|||
else if (xp.parse_string(tag, "stdout_filename", stdout_filename)) continue;
|
||||
else if (xp.parse_string(tag, "stderr_filename", stderr_filename)) continue;
|
||||
else if (xp.parse_string(tag, "vm_os_name", vm_os_name)) continue;
|
||||
else if (xp.parse_string(tag, "vm_os_version", vm_os_version)) continue;
|
||||
else if (xp.parse_int(tag, "vm_memory_size", vm_memory_size)) continue;
|
||||
else if (xp.parse_string(tag, "vm_memory_size", vm_memory_size)) continue;
|
||||
else if (xp.parse_string(tag, "vm_disk_image_name", vm_disk_image_name)) continue;
|
||||
else if (xp.parse_string(tag, "vm_disk_image_type", vm_disk_image_type)) continue;
|
||||
else if (xp.parse_string(tag, "vm_shared_folder_name", vm_shared_folder_name)) continue;
|
||||
else if (xp.parse_string(tag, "vm_shared_folder_dir_name", vm_shared_folder_dir_name)) continue;
|
||||
else if (xp.parse_bool(tag, "enable_network", enable_network)) continue;
|
||||
|
|
|
@ -31,14 +31,10 @@ public:
|
|||
std::string stderr_filename;
|
||||
// name of the OS the VM runs
|
||||
std::string vm_os_name;
|
||||
// name of the version of the VM the OS runs
|
||||
std::string vm_os_version;
|
||||
// size of the memory allocation for the VM
|
||||
int vm_memory_size;
|
||||
std::string vm_memory_size;
|
||||
// name of the virtual machine disk image file
|
||||
std::string vm_disk_image_name;
|
||||
// name of the virtual machine disk image type
|
||||
std::string vm_disk_image_type;
|
||||
// name of shared folder
|
||||
std::string vm_shared_folder_name;
|
||||
// shared folder directory name
|
||||
|
|
Loading…
Reference in New Issue