// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2012 University of California // // BOINC 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 3 of the License, or (at your option) any later version. // // BOINC 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. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . // classes for volunteer data archival (VDA) // // Note: these classes are used by both the simulator (ssim.cpp) // and the VDA server software (vdad.cpp, sched_vda.cpp) #include #include #include #include #include "boinc_db.h" #include "stats.h" #include "vda_policy.h" extern bool debug_status; extern bool debug_ft; // a host with rpc_time < now-HOST_TIMEOUT is considered dead. // Make sure you set next_rpc_delay accordingly (e.g., to 86400) // #define VDA_HOST_TIMEOUT (86400*4) extern void show_msg(char*); extern char* time_str(double); extern const char* status_str(int status); inline bool outdated_client(HOST& h) { char* p = strstr(h.serialnum, "BOINC|"); if (!p) return true; int n = atoi(p + strlen("BOINC|")); return (n < 7); } struct META_CHUNK; struct VDA_FILE_AUX : VDA_FILE { POLICY policy; META_CHUNK* meta_chunk; // the following for the simulator // double accounting_start_time; STATS_ITEM disk_usage; STATS_ITEM upload_rate; STATS_ITEM download_rate; STATS_ITEM fault_tolerance; int pending_init_downloads; // # of initial downloads pending. // When this is zero, we start collecting stats for the file inline bool collecting_stats() { return (pending_init_downloads == 0); } VDA_FILE_AUX(){ meta_chunk = NULL; } // the following for vdad // DB_HOST enum_host; char enum_query[256]; int max_chunks; int last_id; bool enum_active; bool found_this_scan; bool found_any_this_scan; bool found_any_this_enum; int init(); int get_state(); int choose_host(); VDA_FILE_AUX(DB_VDA_FILE f) : VDA_FILE(f) { max_chunks = 0; enum_active = false; last_id = 0; } }; #define PRESENT 0 // this unit is present on the server // (in the case of meta-chunks, this means that enough chunks // to reconstruct the meta-chunk are present on the server) #define RECOVERABLE 1 // this unit is not present, but could be recovered from data on clients #define UNRECOVERABLE 2 // not present or recoverable // base class for chunks and meta-chunks // struct DATA_UNIT { virtual void recovery_plan(){}; virtual int recovery_action(double){return 0;}; virtual int compute_min_failures(){return 0;}; virtual int upload_all(){return 0;}; char name[256]; char dir[1024]; // the following are determined during recovery_plan() // and used during recovery_action() // int status; bool in_recovery_set; // if we need to reconstruct the parent, we'll use this unit bool data_now_present; // vdad: this unit was initially unrecoverable, // but the parent has become present so now this unit is present bool data_needed; // this unit is not currently present; // we need to take action (e.g. start uploads) // to make it present double cost; bool keep_present; // this unit is present and we need to keep it present bool need_present; // delete this?? int min_failures; // min # of host failures that would make this unrecoverable int delete_file(); // delete the file on server corresponding to this unit }; struct META_CHUNK : DATA_UNIT { std::vector children; META_CHUNK* parent; int n_children_present; bool have_unrecoverable_children; VDA_FILE_AUX* dfile; CODING coding; bool bottom_level; bool need_reconstruct; bool needed_by_parent; double child_size; // used by ssim META_CHUNK( VDA_FILE_AUX* d, META_CHUNK* par, double size, int coding_level, int index ); // used by vdad META_CHUNK(VDA_FILE_AUX* d, META_CHUNK* p, int index); int init(const char* dir, POLICY&, int level); int get_state(const char* dir, POLICY&, int level); virtual void recovery_plan(); virtual int recovery_action(double); virtual int compute_min_failures(); virtual int upload_all(); int decide_reconstruct(); int reconstruct_and_cleanup(); int expand(); bool some_child_is_unrecoverable() { for (unsigned int i=0; i hosts; META_CHUNK* parent; double size; bool present_on_server; CHUNK(META_CHUNK* mc, double s, int index); virtual ~CHUNK(){} int start_upload(); void host_failed(VDA_CHUNK_HOST* p); bool download_in_progress(); void upload_complete(); void download_complete(); int assign(); virtual void recovery_plan(); virtual int recovery_action(double); virtual int compute_min_failures(); virtual int upload_all(); bool need_more_replicas() { return ((int)hosts.size() < parent->dfile->policy.replication); } // used by vda void print_status(int indent_level); // used by vdad int start_upload_from_host(VDA_CHUNK_HOST&); }; // names // // chunk name: c1.c2.cn // (in VDA_CHUNK_HOST) // // chunk/file name: c1.c2.cn_filename.ext // // physical file name: vda_hostid_c1.c2.cn_filename.ext inline void physical_file_name( int hostid, char* chunk_name, char* file_name, char* buf ) { sprintf(buf, "vda_%d_%s_%s", hostid, chunk_name, file_name); } inline void physical_file_name( int hostid, char* chunk_file_name, char* buf ) { sprintf(buf, "vda_%d_%s", hostid, chunk_file_name); } // // download WU/result name: download_vda_c1.c2.cn_filename.ext // // upload WU/result name: upload_vda_c1.c2.cn_filename.ext