Skip to content
Snippets Groups Projects
Commit b8627bac authored by David Anderson's avatar David Anderson
Browse files

vboxwrapper: add "completion trigger file" mechanism.

When it's finished, the VM app can write a file of a given name
(specified in vbox_job.xml) in the shared dir.
This file can optionally contain an exit code and stderr text.
If vboxwrapper finds this file, it cleans up the VM and calls boinc_finish().
This works around a problem where the VM doesn't exit properly
and the task hangs forever.
parent b9907469
No related branches found
No related tags found
No related merge requests found
......@@ -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();
......
......@@ -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) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment