mirror of https://github.com/BOINC/boinc.git
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:
parent
6eb9f2d298
commit
3919da9524
|
@ -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() {
|
int VBOX_VM::is_registered() {
|
||||||
string command;
|
string command;
|
||||||
string output;
|
string output;
|
||||||
|
@ -1984,6 +1990,13 @@ bool VBOX_VM::is_logged_completion_file_exists() {
|
||||||
return false;
|
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) {
|
bool VBOX_VM::is_virtualbox_version_newer(int maj, int min, int rel) {
|
||||||
int vbox_major = 0, vbox_minor = 0, vbox_release = 0;
|
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)) {
|
if (3 == sscanf(virtualbox_version.c_str(), "%d.%d.%d", &vbox_major, &vbox_minor, &vbox_release)) {
|
||||||
|
|
|
@ -186,6 +186,13 @@ public:
|
||||||
std::string completion_trigger_file;
|
std::string completion_trigger_file;
|
||||||
// if find this file in shared/, task is over.
|
// if find this file in shared/, task is over.
|
||||||
// File can optionally contain exit code (first line)
|
// 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).
|
// and stderr text (subsequent lines).
|
||||||
// Addresses a problem where VM doesn't shut down properly
|
// 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_logs(bool include_error_logs);
|
||||||
void dump_hypervisor_status_reports();
|
void dump_hypervisor_status_reports();
|
||||||
void dump_vmguestlog_entries();
|
void dump_vmguestlog_entries();
|
||||||
|
void delete_temporary_exit_trigger_file();
|
||||||
|
|
||||||
int is_registered();
|
int is_registered();
|
||||||
bool is_system_ready(std::string& message);
|
bool is_system_ready(std::string& message);
|
||||||
|
@ -244,6 +252,7 @@ public:
|
||||||
bool is_logged_failure_host_out_of_memory();
|
bool is_logged_failure_host_out_of_memory();
|
||||||
bool is_logged_failure_guest_job_out_of_memory();
|
bool is_logged_failure_guest_job_out_of_memory();
|
||||||
bool is_logged_completion_file_exists();
|
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_version_newer(int maj, int min, int rel);
|
||||||
bool is_virtualbox_error_recoverable(int retval);
|
bool is_virtualbox_error_recoverable(int retval);
|
||||||
|
|
||||||
|
|
|
@ -226,6 +226,10 @@ int parse_job_file(VBOX_VM& vm) {
|
||||||
vm.completion_trigger_file = str;
|
vm.completion_trigger_file = str;
|
||||||
continue;
|
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")) {
|
else if (xp.match_tag("port_forward")) {
|
||||||
vm.parse_port_forward(xp);
|
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
|
// set CPU and network throttling if needed
|
||||||
//
|
//
|
||||||
void set_throttles(APP_INIT_DATA& aid, VBOX_VM& vm) {
|
void set_throttles(APP_INIT_DATA& aid, VBOX_VM& vm) {
|
||||||
|
@ -570,6 +597,7 @@ int main(int argc, char** argv) {
|
||||||
int vm_image = 0;
|
int vm_image = 0;
|
||||||
unsigned long vm_exit_code = 0;
|
unsigned long vm_exit_code = 0;
|
||||||
bool is_notice = false;
|
bool is_notice = false;
|
||||||
|
int temp_delay = 86400;
|
||||||
string message;
|
string message;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
|
@ -917,7 +945,6 @@ int main(int argc, char** argv) {
|
||||||
bool do_dump_hypervisor_logs = false;
|
bool do_dump_hypervisor_logs = false;
|
||||||
string error_reason;
|
string error_reason;
|
||||||
const char* temp_reason = "";
|
const char* temp_reason = "";
|
||||||
int temp_delay = 86400;
|
|
||||||
|
|
||||||
if (VBOXWRAPPER_ERR_RECOVERABLE == retval) {
|
if (VBOXWRAPPER_ERR_RECOVERABLE == retval) {
|
||||||
error_reason =
|
error_reason =
|
||||||
|
@ -1144,6 +1171,30 @@ int main(int argc, char** argv) {
|
||||||
boinc_finish(vm_exit_code);
|
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) {
|
if (!vm.online) {
|
||||||
// Is this a type of event we can recover from?
|
// Is this a type of event we can recover from?
|
||||||
if (vm.is_logged_failure_host_out_of_memory()) {
|
if (vm.is_logged_failure_host_out_of_memory()) {
|
||||||
|
|
Loading…
Reference in New Issue