mirror of https://github.com/BOINC/boinc.git
505 lines
16 KiB
C++
Executable File
505 lines
16 KiB
C++
Executable File
// 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 <stdio.h>
|
|
|
|
// 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 <file_info> 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:
|
|
// <file_info>...</file_info>
|
|
// ...
|
|
// <app_version>
|
|
// <app_name>...</app_name>
|
|
// <version_num>x</version_num>
|
|
// <file_ref>
|
|
// ...
|
|
// [<main_program/>]
|
|
// </file_ref>
|
|
// </app_version>
|
|
//
|
|
|
|
// 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 <global_preferences> tag
|
|
char project_prefs[MAX_BLOB_SIZE];
|
|
// project preferences, within <project_preferences> 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
|