diff --git a/samples/vboxwrapper/vbox.h b/samples/vboxwrapper/vbox.h index 67a1b255f476b1f924715f06b6c839c758101dec..db748b845da82391d2346789fe13eca96e54bb1a 100644 --- a/samples/vboxwrapper/vbox.h +++ b/samples/vboxwrapper/vbox.h @@ -140,8 +140,15 @@ public: double minimum_checkpoint_interval; // minimum time between checkpoints std::vector<std::string> copy_to_shared; + // list of files to copy from slot dir to shared/ std::vector<std::string> trickle_trigger_files; - std::vector<std::string> completion_trigger_files; + // if find file of this name in shared/, send trickle-up message + // with variety = filename, contents = file contents + std::string completion_trigger_file; + // if find this file in shared/, task is over. + // File can optionally contain exit code (first line) + // and stderr text (subsequent lines). + // Addresses a problem where VM doesn't shut down properly /////////// END VBOX_JOB.XML ITEMS ////////////// @@ -177,6 +184,7 @@ public: int pause(); int resume(); void check_trickle_triggers(); + void check_completion_trigger(); int createsnapshot(double elapsed_time); int cleanupsnapshots(bool delete_active); int restoresnapshot(); diff --git a/samples/vboxwrapper/vboxwrapper.cpp b/samples/vboxwrapper/vboxwrapper.cpp index 3183eb28c8935f043374a56511191d94c3b9ccc2..2e20b29c7409466c3d47eec335b0cabd6adceb53 100644 --- a/samples/vboxwrapper/vboxwrapper.cpp +++ b/samples/vboxwrapper/vboxwrapper.cpp @@ -176,7 +176,7 @@ int parse_job_file(VBOX_VM& vm) { continue; } else if (xp.parse_string("completion_trigger_file", str)) { - vm.completion_trigger_files.push_back(str); + vm.completion_trigger_file = str; continue; } fprintf(stderr, "%s parse_job_file(): unexpected tag %s\n", @@ -380,25 +380,28 @@ void set_remote_desktop_info(APP_INIT_DATA& /* aid */, VBOX_VM& vm) { } } -// check for trickle trigger files, and send trickles if find them. +// check for completion trigger file // -void VBOX_VM::check_trickle_triggers() { - char filename[256], path[MAXPATHLEN], buf[256]; - for (unsigned int i=0; i<trickle_trigger_files.size(); i++) { - strcpy(filename, trickle_trigger_files[i].c_str()); - sprintf(path, "shared/%s", filename); - if (!boinc_file_exists(path)) continue; - string text; - int retval = read_file_string(path, text); - if (retval) { - fprintf(stderr, - "%s can't read trickle trigger file %s\n", - vboxwrapper_msg_prefix(buf, sizeof(buf)), filename - ); +void VBOX_VM::check_completion_trigger() { + char path[MAXPATHLEN]; + + sprintf(path, "shared/%s", completion_trigger_file.c_str()); + if (!boinc_file_exists(path)) return; + int exit_code = 0; + FILE* f = fopen(path, "r"); + if (f) { + char buf[1024]; + if (fgets(buf, 1024, f) != NULL) { + exit_code = atoi(buf); } - boinc_send_trickle_up(filename, const_cast<char*>(text.c_str())); - boinc_delete_file(path); + while (fgets(buf, 1024, f) != NULL) { + fputs(buf, stderr); + } + fclose(f); } + cleanup(); + dumphypervisorlogs(true); + boinc_finish(exit_code); } // check for trickle trigger files, and send trickles if find them. @@ -1072,6 +1075,9 @@ int main(int argc, char** argv) { if ((loop_iteration % 10) == 0) { current_cpu_time = starting_cpu_time + vm.get_vm_cpu_time(); vm.check_trickle_triggers(); + if (!vm.completion_trigger_file.empty()) { + vm.check_completion_trigger(); + } } if (vm.job_duration) {