// The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.mozilla.org/MPL/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations // under the License. // // The Original Code is the Berkeley Open Infrastructure for Network Computing. // // The Initial Developer of the Original Code is the SETI@home project. // Portions created by the SETI@home project are Copyright (C) 2002, 2003 // University of California at Berkeley. All Rights Reserved. // // Contributor(s): // #ifndef _BOINC_DB_ #define _BOINC_DB_ // Structures corresponding to database records. // Some of these types have counterparts in client/types.h, // but don't be deceived - client and server have different variants. // The parse and write functions are for use in scheduler RPC. // They don't necessarily serialize the entire records. #include // Maximum allowed size for SQL based blobs (Binary Large Object) // #define MAX_BLOB_SIZE 4096 // represents the project as a whole. // There is only of these per DB // struct PROJECT { int id; char short_name[256]; // used as directory name and part of DB name of server side, // so no spaces or special chars char long_name[256]; // shown on client side, e.g. in GUI // can contain spaces etc. void clear(); }; // A compilation target, i.e. a architecture/OS combination. // The core client will be given only applications with the same platform // struct PLATFORM { int id; unsigned int create_time; char name[256]; // i.e. "sparc-sun-solaris" char user_friendly_name[256]; // i.e. "SPARC Solaris 2.8" void clear(); }; // A version of the core client // struct CORE_VERSION { int id; unsigned int create_time; int version_num; int platformid; char xml_doc[MAX_BLOB_SIZE]; // a for the download file char message[256]; // if we get a request from this version, // send this message bool deprecated; // if we get a request from this version, // don't send it any work. void clear(); }; // An application. // struct APP { int id; unsigned int create_time; char name[256]; // application name, preferably short int min_version; // don't use app versions before this int write(FILE*); void clear(); }; // A version of an application. // struct APP_VERSION { int id; unsigned int create_time; int appid; int version_num; int platformid; char xml_doc[MAX_BLOB_SIZE]; // describes app files. format: // ... // ... // // ... // x // // ... // [] // // // // the following let you handle backwards-incompatible changes to // the core client / app interface // int min_core_version; // min core version this app will run with int max_core_version; // if <>0, max core version this will run with int write(FILE*, APP&); void clear(); }; struct USER { int id; unsigned int create_time; char email_addr[256]; char name[256]; char authenticator[256]; char country[256]; char postal_code[256]; double total_credit; double expavg_credit; // credit per second, recent average double expavg_time; // when the above was computed char global_prefs[MAX_BLOB_SIZE]; // global preferences, within tag char project_prefs[MAX_BLOB_SIZE]; // project preferences, within tag int teamid; // team ID if any char venue[256]; // home/work/school (default) char url[256]; // user's web page if any bool send_email; bool show_hosts; void clear(); }; #define TEAM_TYPE_CLUB 1 #define TEAM_TYPE_COMPANY 2 #define TEAM_TYPE_PRIMARY 3 #define TEAM_TYPE_SECONDARY 4 #define TEAM_TYPE_JUNIOR_COLLEGE 5 #define TEAM_TYPE_UNIVERSITY 6 #define TEAM_TYPE_GOVERNMENT 7 struct TEAM { int id; unsigned int create_time; int userid; // User ID of team founder char name[256]; char name_lc[256]; // Team name in lowercase (used for searching) char url[256]; int type; // Team type (see above) char name_html[256]; char description[MAX_BLOB_SIZE]; int nusers; // UNDEFINED BY DEFAULT char country[256]; double total_credit; // UNDEFINED BY DEFAULT double expavg_credit; // UNDEFINED BY DEFAULT void clear(); }; struct HOST { int id; unsigned int create_time; int userid; // ID of user running this host int rpc_seqno; // last seqno received from client unsigned int rpc_time; // time of last scheduler RPC double total_credit; double expavg_credit; // credit per second, recent average double expavg_time; // last time the above was updated // all remaining items are assigned by the client int timezone; char domain_name[256]; char serialnum[256]; char last_ip_addr[256]; int nsame_ip_addr; double on_frac; // Fraction of time (0-1) that BOINC is running double connected_frac; // Fraction of time that host is connected to net double active_frac; // Fraction of time that host is enabled to work int p_ncpus; // Number of CPUs on host char p_vendor[256]; // Vendor name of CPU char p_model[256]; // Model of CPU double p_fpops; // measured floating point ops/sec of CPU double p_iops; // measured integer ops/sec of CPU double p_membw; // measured memory bandwidth (bytes/sec) of CPU double p_calculated; // when the above were calculated char os_name[256]; // Name of operating system char os_version[256]; // Version of operating system double m_nbytes; // Size of memory in bytes double m_cache; // Size of CPU cache in bytes (L1 or L2?) double m_swap; // Size of swap space in bytes double d_total; // Total disk space on host // - may include all volumes, // even if BOINC can use only one of them // - may include network (shared) storage double d_free; // Of the total disk space, how much is free double d_boinc_used_total; // amount being used for all projects double d_boinc_used_project; // amount being used for this project double d_boinc_max; // max amount that BOINC is allowed to use // This reflects both user preferences // and the fact that BOINC can use only 1 volume double n_bwup; // Average upload bandwidth, bytes/sec double n_bwdown; // Average download bandwidth, bytes/sec // The above are derived from actual // file upload/download times, and may reflect // factors other than network bandwidth // The following is derived (by server) from other fields double credit_per_cpu_sec; char venue[256]; // home/work/school char projects[MAX_BLOB_SIZE]; // list of projects this host is attached to, // and the resource shares (XML) int parse(FILE*); int parse_time_stats(FILE*); int parse_net_stats(FILE*); void clear(); }; // values for file_delete state #define FILE_DELETE_INIT 0 #define FILE_DELETE_READY 1 #define FILE_DELETE_DONE 2 // values for assimilate_state #define ASSIMILATE_INIT 0 #define ASSIMILATE_READY 1 #define ASSIMILATE_DONE 2 // NOTE: there is no overall state for a WU (like done/not done) // There's just a bunch of independent substates // (file delete, assimilate, and states of results, error flags) // bit fields of error_mask #define WU_ERROR_COULDNT_SEND_RESULT 1 #define WU_ERROR_TOO_MANY_ERROR_RESULTS 2 #define WU_ERROR_TOO_MANY_RESULTS 4 struct WORKUNIT { int id; unsigned int create_time; int appid; // associated app char name[256]; char xml_doc[MAX_BLOB_SIZE]; int batch; double rsc_fpops; // estimated # of FP operations double rsc_iops; // estimated # of integer operations // The above two items are used for 2 purposes: // 1) to estimate how long a result will take on a host // for scheduling purposes; // 2) to calculate an upper bound on the CPU time for a result // before it is aborted. // Currently this is twice the estimated CPU time. // At some point we might want to have separate "max rsc" fields double rsc_memory; // estimated size of RAM working set (bytes) // currently used only by scheduler to screen hosts // At some point, could use as runtime limit double rsc_disk; // estimated amount of disk needed (bytes) // (including input, output and temp files, but NOT the app) // This is used for 2 purposes: // 1) for scheduling (don't send this WU to a host w/ insuff. disk) // 2) upper bound (abort task if it uses more than this disk) // At some point we might want to have separate "max" fields bool need_validate; // this WU has at least 1 result in // validate state = NEED_CHECK int canonical_resultid; // ID of canonical result, or zero double canonical_credit; // credit that all correct results get unsigned int timeout_check_time; // when to check for timeouts // zero if no need to check int delay_bound; // determines result deadline, // timeout check time int error_mask; // bitmask of errors (see above) int file_delete_state; int assimilate_state; int workseq_next; // if part of a sequence, the next WU int opaque; // project-specific; usually external ID // the following not used in the DB char app_name[256]; void clear(); }; // WARNING: be Very careful about changing any states, especially for a // project already running - these values are entered into the database and // must stay consistent. #define RESULT_SERVER_STATE_INACTIVE 1 #define RESULT_SERVER_STATE_UNSENT 2 #define RESULT_SERVER_STATE_UNSENT_SEQ 3 // unsent, part of a work sequence #define RESULT_SERVER_STATE_IN_PROGRESS 4 #define RESULT_SERVER_STATE_OVER 5 // we received a reply, timed out, or decided not to send. // Note: we could get a reply even after timing out. #define RESULT_OUTCOME_INIT 0 #define RESULT_OUTCOME_SUCCESS 1 #define RESULT_OUTCOME_COULDNT_SEND 2 #define RESULT_OUTCOME_CLIENT_ERROR 3 #define RESULT_OUTCOME_NO_REPLY 4 #define RESULT_OUTCOME_DIDNT_NEED 5 // we created the result but didn't need to send it because we already // got a quorum #define VALIDATE_STATE_INIT 0 #define VALIDATE_STATE_VALID 1 #define VALIDATE_STATE_INVALID 2 struct RESULT { int id; unsigned int create_time; int workunitid; int server_state; // see above int outcome; // see above; defined if server state OVER int client_state; // phase that client contacted us in. // iff it is UPLOADED then outcome is success. // error details are in stderr_out. // The values for this field are defined // in lib/result_state.h int hostid; // host processing this result unsigned int report_deadline; // deadline for receiving result unsigned int sent_time; // when result was sent to host unsigned int received_time; // when result was received from host char name[256]; double cpu_time; // CPU time used to complete result char xml_doc_in[MAX_BLOB_SIZE]; // descriptions of output files char xml_doc_out[MAX_BLOB_SIZE]; // MD5s of output files char stderr_out[MAX_BLOB_SIZE]; // stderr output, if any int batch; int file_delete_state; int validate_state; double claimed_credit; // CPU time times host credit/sec double granted_credit; // == canonical credit of WU int opaque; // project-specific; usually external ID int random; // determines send order // the following not used in the DB char wu_name[256]; int parse_from_client(FILE*); void clear(); }; #define WORKSEQ_STATE_UNASSIGNED 0 #define WORKSEQ_STATE_ASSIGNED 1 #define WORKSEQ_STATE_DONE 2 struct WORKSEQ { int id; unsigned int create_time; int state; int hostid; // host this seq is assigned to int wuid_last_done; // last validated WU or zero int wuid_last_sent; // last sent WU or zero int workseqid_master; // if part of a redundant group, master ID void clear(); }; extern int boinc_db_open(char* dbname, char* passwd); extern int boinc_db_close(); extern void boinc_db_print_error(char*); extern const char* boinc_db_error_string(); extern int boinc_db_insert_id(); #include "mysql.h" struct CURSOR { int active; MYSQL_RES *rp; }; // Base for derived classes that can access the DB // Defines various generic operations on DB tables // class DB_BASE { public: DB_BASE(char *table_name); int insert(); int update(); int lookup_id(int id); int lookup(char*); int enumerate(char* clause=""); int count(int&, char* clause=""); int sum(double&, char* field, char* clause=""); int get_double(char* query, double&); int get_integer(char* query, int&); const char *table_name; CURSOR cursor; virtual int get_id(); virtual void db_print(char*); virtual void db_parse(MYSQL_ROW&); }; extern MYSQL *mysql; class DB_PROJECT : public DB_BASE, public PROJECT { public: DB_PROJECT(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); }; class DB_PLATFORM : public DB_BASE, public PLATFORM { public: DB_PLATFORM(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); }; class DB_CORE_VERSION : public DB_BASE, public CORE_VERSION { public: DB_CORE_VERSION(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); }; class DB_APP : public DB_BASE, public APP { public: DB_APP(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); }; class DB_APP_VERSION : public DB_BASE, public APP_VERSION { public: DB_APP_VERSION(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); }; class DB_USER : public DB_BASE, public USER { public: DB_USER(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); void operator=(USER& r) {USER::operator=(r);} }; class DB_TEAM : public DB_BASE, public TEAM { public: DB_TEAM(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); }; class DB_HOST : public DB_BASE, public HOST { public: DB_HOST(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); void operator=(HOST& r) {HOST::operator=(r);} }; class DB_RESULT : public DB_BASE, public RESULT { public: DB_RESULT(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); void operator=(RESULT& r) {RESULT::operator=(r);} }; class DB_WORKUNIT : public DB_BASE, public WORKUNIT { public: DB_WORKUNIT(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); }; class DB_WORKSEQ : public DB_BASE, public WORKSEQ { public: DB_WORKSEQ(); int get_id(); void db_print(char*); void db_parse(MYSQL_ROW &row); }; extern int boinc_db_open(char*, char*); #endif