// Berkeley Open Infrastructure for Network Computing // http://boinc.berkeley.edu // Copyright (C) 2005 University of California // // This is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; // either version 2.1 of the License, or (at your option) any later version. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // To view the GNU Lesser General Public License visit // http://www.gnu.org/copyleft/lesser.html // or write to the Free Software Foundation, Inc., // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // Logic related to general (also known as global) preferences: // when to compute, how much disk to use, etc. // #ifdef _WIN32 #include "boinc_win.h" #endif #ifndef _WIN32 #if HAVE_SYS_STAT_H #include #endif #if HAVE_SYS_TYPES_H #include #endif #endif #include "util.h" #include "filesys.h" #include "parse.h" #include "file_names.h" #include "cpu_benchmark.h" #include "client_msgs.h" #include "client_state.h" using std::min; using std::string; void CLIENT_STATE::install_global_prefs() { net_xfers->max_bytes_sec_up = global_prefs.max_bytes_sec_up; net_xfers->max_bytes_sec_down = global_prefs.max_bytes_sec_down; net_xfers->bytes_left_up = global_prefs.max_bytes_sec_up; net_xfers->bytes_left_down = global_prefs.max_bytes_sec_down; // max_cpus may have changed, so update ncpus // set_ncpus(); } // Return the maximum allowed disk usage as determined by user preferences. // There are three different settings in the prefs; // return the least of the three. // int CLIENT_STATE::allowed_disk_usage(double& size) { double percent_space, min_val; percent_space = host_info.d_total*global_prefs.disk_max_used_pct/100.0; min_val = host_info.d_free - global_prefs.disk_min_free_gb*(1024.*1024.*1024.); size = min(min(global_prefs.disk_max_used_gb*(1024.*1024.*1024.), percent_space), min_val); if (size < 0) size = 0; return 0; } int CLIENT_STATE::project_disk_usage(PROJECT* p, double& size) { char buf[256]; unsigned int i; double s; get_project_dir(p, buf); dir_size(buf, size); for (i=0; iwup->project != p) continue; get_slot_dir(atp->slot, buf); dir_size(buf, s); size += s; } return 0; } int CLIENT_STATE::total_disk_usage(double& size) { return dir_size(".", size); } int CLIENT_STATE::allowed_project_disk_usage(double& size) { double other_disk_used; double total_disk_available; double project_disk_used; total_disk_usage(other_disk_used); allowed_disk_usage(total_disk_available); for(unsigned int i=0; itm_hour; if (start_hour < end_hour) { return (hour >= start_hour && hour < end_hour); } else { return !(hour >= end_hour && hour < start_hour); } } // See if (on the basis of user run request and prefs) // we should suspend activities. // void CLIENT_STATE::check_suspend_activities(int& reason) { reason = 0; // Don't work while we're running CPU benchmarks // if (are_cpu_benchmarks_running()) { reason |= SUSPEND_REASON_BENCHMARKS; } if (user_run_request == USER_RUN_REQUEST_ALWAYS) return; if (user_run_request == USER_RUN_REQUEST_NEVER) { reason |= SUSPEND_REASON_USER_REQ; return; } if (!global_prefs.run_on_batteries && host_info.host_is_running_on_batteries() ) { reason |= SUSPEND_REASON_BATTERIES; } if (!global_prefs.run_if_user_active && !host_info.users_idle( check_all_logins, global_prefs.idle_time_to_run ) ) { reason |= SUSPEND_REASON_USER_ACTIVE; } if (!now_between_two_hours(global_prefs.start_hour, global_prefs.end_hour)) { reason |= SUSPEND_REASON_TIME_OF_DAY; } } int CLIENT_STATE::suspend_activities(int reason) { string s_reason; s_reason = "Suspending computation and network activity"; if (reason & SUSPEND_REASON_BATTERIES) { s_reason += " - on batteries"; } if (reason & SUSPEND_REASON_USER_ACTIVE) { s_reason += " - user is active"; } if (reason & SUSPEND_REASON_USER_REQ) { s_reason += " - user request"; } if (reason & SUSPEND_REASON_TIME_OF_DAY) { s_reason += " - time of day"; } if (reason & SUSPEND_REASON_BENCHMARKS) { s_reason += " - running CPU benchmarks"; } if (reason & SUSPEND_REASON_DISK_SIZE) { s_reason += " - out of disk space - change global prefs"; } msg_printf(NULL, MSG_INFO, const_cast(s_reason.c_str())); if (reason & SUSPEND_REASON_BENCHMARKS) { active_tasks.suspend_all(false); } else { active_tasks.suspend_all(global_prefs.leave_apps_in_memory); } pers_file_xfers->suspend(); return 0; } // persistent file xfers will resume of their own accord // since activities_suspended is now true // int CLIENT_STATE::resume_activities() { msg_printf(NULL, MSG_INFO, "Resuming computation and network activity"); active_tasks.unsuspend_all(); gstate.request_schedule_cpus("Resuming activities"); return 0; } void CLIENT_STATE::check_suspend_network(int& reason) { reason = 0; //if (user_network_request == USER_RUN_REQUEST_ALWAYS) return; if (user_network_request == USER_RUN_REQUEST_NEVER) { reason |= SUSPEND_REASON_USER_REQ; return; } if (!now_between_two_hours(global_prefs.net_start_hour, global_prefs.net_end_hour)) { reason |= SUSPEND_REASON_TIME_OF_DAY; } return; } int CLIENT_STATE::suspend_network(int reason) { string s_reason; s_reason = "Suspending network activity"; if (reason & SUSPEND_REASON_USER_REQ) { s_reason += " - user request"; } if (reason & SUSPEND_REASON_TIME_OF_DAY) { s_reason += " - time of day"; } msg_printf(NULL, MSG_INFO, const_cast(s_reason.c_str())); pers_file_xfers->suspend(); return 0; } int CLIENT_STATE::resume_network() { msg_printf(NULL, MSG_INFO, "Resuming network activity"); return 0; } // call this only after parsing global prefs // PROJECT* CLIENT_STATE::global_prefs_source_project() { return lookup_project(global_prefs.source_project); } void CLIENT_STATE::show_global_prefs_source(bool found_venue) { PROJECT* pp = global_prefs_source_project(); if (pp) { msg_printf(NULL, MSG_INFO, "General prefs: from %s (last modified %s)\n", pp->get_project_name(), time_to_string(global_prefs.mod_time) ); } else { msg_printf(NULL, MSG_INFO, "General prefs: from unknown project %s (last modified %s)\n", global_prefs.source_project, time_to_string(global_prefs.mod_time) ); } if (strlen(main_host_venue)) { if (found_venue) { msg_printf(NULL, MSG_INFO, "General prefs: using separate prefs for %s\n", main_host_venue ); } else { msg_printf(NULL, MSG_INFO, "General prefs: no separate prefs for %s; using your defaults\n", main_host_venue ); } } else { msg_printf(NULL, MSG_INFO, "General prefs: using your defaults\n"); } } // parse user's project preferences, // generating FILE_REF and FILE_INFO objects for each element. // int PROJECT::parse_preferences_for_user_files() { char* p, *q, *q2; char buf[1024]; string timestamp, open_name, url, filename; FILE_INFO* fip; FILE_REF fr; char prefs_buf[MAX_BLOB_LEN]; strcpy(prefs_buf, project_specific_prefs.c_str()); p = prefs_buf; user_files.clear(); while (1) { q = strstr(p, ""); if (!q) break; q2 = strstr(q, ""); if (!q2) break; *q2 = 0; strcpy(buf, q); if (!parse_str(buf, "", timestamp)) break; if (!parse_str(buf, "", open_name)) break; if (!parse_str(buf, "", url)) break; filename = open_name + "_" + timestamp; fip = gstate.lookup_file_info(this, filename.c_str()); if (!fip) { fip = new FILE_INFO; fip->project = this; fip->urls.push_back(url); strcpy(fip->name, filename.c_str()); fip->is_user_file = true; gstate.file_infos.push_back(fip); } fr.file_info = fip; strcpy(fr.open_name, open_name.c_str()); user_files.push_back(fr); p = q2+strlen(""); } return 0; } const char *BOINC_RCSID_92ad99cddf = "$Id$";