diff --git a/samples/vboxwrapper/vbox.h b/samples/vboxwrapper/vbox.h index b856ab93cf..3028bb4330 100644 --- a/samples/vboxwrapper/vbox.h +++ b/samples/vboxwrapper/vbox.h @@ -83,27 +83,14 @@ public: std::string vm_name; // required CPU core count std::string vm_cpu_count; - // the type of disk controller to emulate - std::string vm_disk_controller_type; - // the disk controller model to emulate - std::string vm_disk_controller_model; - // name of the OS the VM runs - std::string os_name; - // size of the memory allocation for the VM, in megabytes std::string memory_size_mb; + // size of the memory allocation for the VM, in megabytes // name of the virtual machine disk image file std::string image_filename; // name of the virtual machine floppy disk image file std::string floppy_image_filename; - // maximum amount of wall-clock time this VM is allowed to run before - // considering itself done. - double job_duration; // amount of CPU time consumed by the VM (note: use get_vm_cpu_time()) double current_cpu_time; - // minimum amount of time between checkpoints - double minimum_checkpoint_interval; - // name of file where app will write its fraction done - std::string fraction_done_filename; // is the VM suspended? bool suspended; // is network access temporarily suspended? @@ -117,27 +104,46 @@ public: bool crashed; // whether to use CERN specific data structures bool enable_cern_dataformat; - // whether to use shared directory infrastructure at all - bool enable_shared_directory; - // whether to use floppy io infrastructure at all - bool enable_floppyio; - // whether to enable remote desktop functionality - bool enable_remotedesktop; - // whether to allow network access at all - bool enable_network; // whether we were instructed to only register the VM. // useful for debugging VMs. bool register_only; - // the following for optional port forwarding - int pf_host_port; - // specified in config file - int pf_guest_port; - // specified in config file // the following for optional remote desktop int rd_host_port; // dynamically assigned bool headless; + /////////// THE FOLLOWING SPECIFIED IN VBOX_JOB.XML ////////////// + // some of these don't really belong in this class + + std::string os_name; + // name of the OS the VM runs + std::string vm_disk_controller_type; + // the type of disk controller to emulate + std::string vm_disk_controller_model; + // the disk controller model to emulate + bool enable_network; + // whether to allow network access + bool enable_shared_directory; + // whether to use shared directory infrastructure + bool enable_floppyio; + // whether to use floppy io infrastructure + bool enable_remotedesktop; + // whether to enable remote desktop functionality + double job_duration; + // maximum amount of wall-clock time this VM is allowed to run before + // considering itself done. + std::string fraction_done_filename; + // name of file where app will write its fraction done + // the following for optional port forwarding + int pf_host_port; + int pf_guest_port; + double minimum_checkpoint_interval; + // minimum time between checkpoints + std::vector copy_to_shared; + std::vector trickle_trigger_files; + + /////////// END VBOX_JOB.XML ITEMS ////////////// + int vm_pid; int vboxsvc_pid; #ifdef _WIN32 @@ -230,6 +236,8 @@ public: void vbm_trace( std::string& command, std::string& ouput, int retval ); + + void check_trickle_triggers(); }; #endif diff --git a/samples/vboxwrapper/vboxwrapper.cpp b/samples/vboxwrapper/vboxwrapper.cpp index 224b7abc9d..6fbaa10afc 100644 --- a/samples/vboxwrapper/vboxwrapper.cpp +++ b/samples/vboxwrapper/vboxwrapper.cpp @@ -20,7 +20,7 @@ // // usage: vboxwrapper [options] // -// --trickle X send a trickle message reporting elapsed time every X secs +// --trickle X send a trickle-up message reporting elapsed time every X sec // (use this for credit granting if your app does its // own job management, like CernVM). // --nthreads N create a VM with N threads. @@ -124,7 +124,7 @@ char* vboxwrapper_msg_prefix(char* sbuf, int len) { } -int parse_job_file(VBOX_VM& vm, vector& copy_to_shared) { +int parse_job_file(VBOX_VM& vm) { MIOFILE mf; string str; char buf[1024], buf2[256]; @@ -168,7 +168,11 @@ int parse_job_file(VBOX_VM& vm, vector& copy_to_shared) { else if (xp.parse_int("pf_guest_port", vm.pf_guest_port)) continue; else if (xp.parse_int("pf_host_port", vm.pf_host_port)) continue; else if (xp.parse_string("copy_to_shared", str)) { - copy_to_shared.push_back(str); + vm.copy_to_shared.push_back(str); + continue; + } + else if (xp.parse_string("trickle_trigger_file", str)) { + vm.trickle_trigger_files.push_back(str); continue; } fprintf(stderr, "%s parse_job_file(): unexpected tag %s\n", @@ -372,9 +376,30 @@ void set_remote_desktop_info(APP_INIT_DATA& /* aid */, VBOX_VM& vm) { } } +// check for trickle trigger files, and send trickles if find them. +// +void VBOX_VM::check_trickle_triggers() { + char filename[256], path[MAXPATHLEN], buf[256]; + for (unsigned int i=0; i(text.c_str())); + boinc_delete_file(path); + } +} + int main(int argc, char** argv) { int retval; - int loop_iteraction = 0; + int loop_iteration = 0; BOINC_OPTIONS boinc_options; VBOX_VM vm; APP_INIT_DATA aid; @@ -400,7 +425,6 @@ int main(int argc, char** argv) { int vm_image = 0; unsigned long vm_exit_code = 0; string message; - vector copy_to_shared; char buf[256]; @@ -602,7 +626,7 @@ int main(int argc, char** argv) { // Parse Job File // - retval = parse_job_file(vm, copy_to_shared); + retval = parse_job_file(vm); if (retval) { fprintf( stderr, @@ -647,8 +671,8 @@ int main(int argc, char** argv) { // Copy files to the shared directory // - if (vm.enable_shared_directory && copy_to_shared.size()) { - for (vector::iterator iter = copy_to_shared.begin(); iter != copy_to_shared.end(); iter++) { + if (vm.enable_shared_directory && vm.copy_to_shared.size()) { + for (vector::iterator iter = vm.copy_to_shared.begin(); iter != vm.copy_to_shared.end(); iter++) { string source = *iter; string destination = string("shared/") + *iter; if (!boinc_file_exists(destination.c_str())) { @@ -921,7 +945,7 @@ int main(int argc, char** argv) { while (1) { // Begin stopwatch timer stopwatch_starttime = dtime(); - loop_iteraction += 1; + loop_iteration += 1; // Discover the VM's current state vm.poll(); @@ -1018,11 +1042,13 @@ int main(int argc, char** argv) { } } - // Basic bookkeeping + // stuff to do every 10 secs (everything else is 1/sec) // - if ((loop_iteraction % 10) == 0) { + if ((loop_iteration % 10) == 0) { current_cpu_time = starting_cpu_time + vm.get_vm_cpu_time(); + vm.check_trickle_triggers(); } + if (vm.job_duration) { fraction_done = elapsed_time / vm.job_duration; } else if (vm.fraction_done_filename.size() > 0) { @@ -1037,7 +1063,7 @@ int main(int argc, char** argv) { fraction_done ); - // Dump a status report at regular intervals + // write status report to stderr at regular intervals // if ((elapsed_time - last_status_report_time) >= 6000.0) { last_status_report_time = elapsed_time;