VBOX: Introduce the notion of a temporary exit trigger file.

When the file is detected, the wrapper will call boinc_temporary_exit() and restart the VM at a later date.
This commit is contained in:
Rom Walton 2014-10-14 13:09:12 -04:00
parent 6eb9f2d298
commit 3919da9524
3 changed files with 74 additions and 1 deletions

View File

@ -1796,6 +1796,12 @@ void VBOX_VM::dump_vmguestlog_entries() {
}
}
void VBOX_VM::delete_temporary_exit_trigger_file() {
char path[MAXPATHLEN];
sprintf(path, "shared/%s", temporary_exit_trigger_file.c_str());
boinc_delete_file(path);
}
int VBOX_VM::is_registered() {
string command;
string output;
@ -1984,6 +1990,13 @@ bool VBOX_VM::is_logged_completion_file_exists() {
return false;
}
bool VBOX_VM::is_logged_temporary_exit_file_exists() {
char path[MAXPATHLEN];
sprintf(path, "shared/%s", temporary_exit_trigger_file.c_str());
if (boinc_file_exists(path)) return true;
return false;
}
bool VBOX_VM::is_virtualbox_version_newer(int maj, int min, int rel) {
int vbox_major = 0, vbox_minor = 0, vbox_release = 0;
if (3 == sscanf(virtualbox_version.c_str(), "%d.%d.%d", &vbox_major, &vbox_minor, &vbox_release)) {

View File

@ -186,6 +186,13 @@ public:
std::string completion_trigger_file;
// if find this file in shared/, task is over.
// File can optionally contain exit code (first line)
// File can optionally contain is_notice bool (second line)
// and stderr text (subsequent lines).
// Addresses a problem where VM doesn't shut down properly
std::string temporary_exit_trigger_file;
// if find this file in shared/, task is restarted at a later date.
// File can optionally contain restart delay (first line)
// File can optionally contain is_notice bool (second line)
// and stderr text (subsequent lines).
// Addresses a problem where VM doesn't shut down properly
@ -232,6 +239,7 @@ public:
void dump_hypervisor_logs(bool include_error_logs);
void dump_hypervisor_status_reports();
void dump_vmguestlog_entries();
void delete_temporary_exit_trigger_file();
int is_registered();
bool is_system_ready(std::string& message);
@ -244,6 +252,7 @@ public:
bool is_logged_failure_host_out_of_memory();
bool is_logged_failure_guest_job_out_of_memory();
bool is_logged_completion_file_exists();
bool is_logged_temporary_exit_file_exists();
bool is_virtualbox_version_newer(int maj, int min, int rel);
bool is_virtualbox_error_recoverable(int retval);

View File

@ -226,6 +226,10 @@ int parse_job_file(VBOX_VM& vm) {
vm.completion_trigger_file = str;
continue;
}
else if (xp.parse_string("temporary_exit_trigger_file", str)) {
vm.temporary_exit_trigger_file = str;
continue;
}
else if (xp.match_tag("port_forward")) {
vm.parse_port_forward(xp);
}
@ -317,6 +321,29 @@ void read_completion_file_info(unsigned long& exit_code, bool& is_notice, string
}
}
void read_temporary_exit_file_info(int& temp_delay, bool& is_notice, string& message, VBOX_VM& vm) {
char path[MAXPATHLEN];
char buf[1024];
temp_delay = 0;
message = "";
sprintf(path, "shared/%s", vm.temporary_exit_trigger_file.c_str());
FILE* f = fopen(path, "r");
if (f) {
if (fgets(buf, 1024, f) != NULL) {
temp_delay = atoi(buf);
}
if (fgets(buf, 1024, f) != NULL) {
is_notice = atoi(buf);
}
while (fgets(buf, 1024, f) != NULL) {
message += buf;
}
fclose(f);
}
}
// set CPU and network throttling if needed
//
void set_throttles(APP_INIT_DATA& aid, VBOX_VM& vm) {
@ -570,6 +597,7 @@ int main(int argc, char** argv) {
int vm_image = 0;
unsigned long vm_exit_code = 0;
bool is_notice = false;
int temp_delay = 86400;
string message;
char buf[256];
@ -917,7 +945,6 @@ int main(int argc, char** argv) {
bool do_dump_hypervisor_logs = false;
string error_reason;
const char* temp_reason = "";
int temp_delay = 86400;
if (VBOXWRAPPER_ERR_RECOVERABLE == retval) {
error_reason =
@ -1144,6 +1171,30 @@ int main(int argc, char** argv) {
boinc_finish(vm_exit_code);
}
}
if (vm.is_logged_temporary_exit_file_exists()) {
vm.reset_vm_process_priority();
vm.stop();
fprintf(
stderr,
"%s VM Temporary Exit File Detected.\n",
vboxwrapper_msg_prefix(buf, sizeof(buf))
);
read_temporary_exit_file_info(temp_delay, is_notice, message, vm);
if (message.size()) {
fprintf(
stderr,
"%s VM Temporary Exit Message: %s.\n",
vboxwrapper_msg_prefix(buf, sizeof(buf)),
message.c_str()
);
}
vm.delete_temporary_exit_trigger_file();
if (is_notice) {
boinc_temporary_exit(temp_delay, message.c_str(), is_notice);
} else {
boinc_temporary_exit(temp_delay);
}
}
if (!vm.online) {
// Is this a type of event we can recover from?
if (vm.is_logged_failure_host_out_of_memory()) {