gs_storage_sqlite.c

Go to the documentation of this file.
00001 /* 
00002  * @file
00003  *
00004  * This implements the interface defined in gs_storage.h for
00005  * the sqlite library.  Rather than communicating to SQLite 
00006  * directly, these functions use a unix domain socket to talk
00007  * to the database manager process.
00008  */
00009 /* $Id: gs_storage_sqlite.c,v 1.105 2008/12/15 21:00:59 seymour Exp $ */
00010 /* $UTK_Copyright: $ */
00011 
00012 #include <ctype.h>
00013 #include <stdlib.h>
00014 #include <stdio.h>
00015 #include <string.h>
00016 #include <time.h>
00017 #include <sys/types.h>
00018 #include <sys/socket.h>
00019 #include <sys/un.h>
00020 #include <unistd.h>
00021 
00022 #include "gs_storage.h"
00023 #include "utility.h"
00024 #include "server.h"
00025 #include "problem.h"
00026 #include "agent.h"
00027 #include "comm_basics.h"
00028 #include "comm_encode.h"
00029 #include "gs_storage_sql_tables.h"
00030 #include "sqlite3.h"
00031 
00032 
00033 #define GS_QUERY_RETRIES 120
00034 
00035 #define FREE_TABLE(x) do { \
00036     if(x) { \
00037       sqlite3_free_table(x); \
00038       x = NULL; \
00039     } \
00040   } while(0);
00041 
00042 extern int sqliteIsNumber(char *);
00043 int gs_create_criteria_table(char *name, char *description, char *firstValue);
00044 
00045 static int
00046   gs_insert_task(char *, char *, int, double, double, double, double, int, int,
00047     char *, int);
00048 
00049 int
00050   gs_add_single_problem(gs_agent_t * gs_agent, gs_problem_t * gs_problem,
00051       char *cid_string);
00052 
00053 struct sockaddr_un GS_SQL_SOCKADDR;
00054 
00055 extern sqlite3 *global_db;
00056 
00057 int
00058 gs_init_tables(sqlite3 *db)
00059 {
00060   char **table, *dbErrMsg;
00061   int i, err, nr, nc;
00062   char *cmds[] = {
00063     GS_SQL_SERVER_TABLE,
00064     GS_SQL_PROBLEM_TABLE,
00065     GS_SQL_PROBLEM_SERVER_MAPPING_TABLE,
00066     GS_SQL_CRITERIA_TABLE,
00067     GS_SQL_TASKS_TABLE,
00068     GS_SQL_INIT_TASKS_TABLE,
00069     GS_SQL_COMPLETED_TASKS_TABLE,
00070     GS_SQL_INIT_COMPLETED_TASKS_TABLE,
00071     GS_SQL_EXTRA_OPTIONS,
00072     NULL};
00073 
00074   for(i=0; cmds[i]; i++) {
00075     /*
00076      * Initialize the database.  Ingnore failure that could result
00077      * from attempting to re-initialize the database
00078      */
00079     err = sqlite3_get_table(db, cmds[i], &table, &nr, &nc, &dbErrMsg);
00080     if(err != SQLITE_OK && err != SQLITE_CONSTRAINT && err != SQLITE_ERROR) {
00081       ERRPRINTF("Error initializing database: %d: %s\n", err, dbErrMsg);
00082       return -1;
00083     }
00084 
00085     FREE_TABLE(table);
00086   }
00087 
00088   return 0;
00089 }
00090 
00091 int 
00092 gs_init_db(sqlite3 **db)
00093 {
00094   int err;
00095 
00096   unlink(GRIDSOLVE_SQLITE_DB);
00097 
00098   /*
00099    * open database
00100    */
00101   err = sqlite3_open(GRIDSOLVE_SQLITE_DB, db);
00102   if( err != SQLITE_OK ) {
00103     ERRPRINTF("Error connecting to database: %s\n", sqlite3_errmsg(*db));
00104     return -1;
00105   }
00106 
00107   if(gs_init_tables(*db) < 0) {
00108     ERRPRINTF("Error initializing database tables\n");
00109     return -1;
00110   }
00111   
00112   return 0;
00113 }
00114 
00115 int
00116 gs_random_sleep(long lo_usec, long hi_usec)
00117 {
00118   struct timeval tv;
00119 
00120   gettimeofday(&tv, NULL);
00121 
00122   srand48(tv.tv_usec);
00123 
00124   tv.tv_sec = 0;
00125   tv.tv_usec = lo_usec + (lrand48() % hi_usec);
00126 
00127   return select(0, NULL, NULL, NULL, &tv);
00128 }
00129 
00130 int
00131 gs_db_mgr_run_query(sqlite3 *db, char *query, int sz[3], char ***tbl,
00132   char **dbErrMsg)
00133 {
00134   int err, nrows, ncols, retval, continueTrying;
00135   char **table, *errMsg;
00136   double wait_time;
00137 
00138   retval = 0;
00139   *dbErrMsg = NULL;
00140 
00141   DBGPRINTF("About to run query: %s\n", query);
00142 
00143   continueTrying = GS_QUERY_RETRIES;
00144 
00145   wait_time = walltime();
00146 
00147   while(continueTrying) {
00148     err = sqlite3_get_table(db, query, &table, &nrows, &ncols, &errMsg);
00149 
00150     switch (err) {
00151       case SQLITE_BUSY:
00152         DBGPRINTF("[%d] SQLITE_BUSY: sleeping for a while...\n",
00153           (int)getpid());
00154         continueTrying--;
00155         gs_random_sleep(40000, 200000);
00156         break;
00157       case SQLITE_OK:
00158         continueTrying = 0;
00159         break;
00160       default:
00161         continueTrying = 0;
00162         break;
00163     }
00164   }
00165 
00166   wait_time = walltime() - wait_time;
00167 
00168   if(err == SQLITE_BUSY)
00169     ERRPRINTF("Number of retries exceeded (%d).. total time spent = %g\n",
00170         GS_QUERY_RETRIES, wait_time);
00171 
00172   if(err != SQLITE_OK) {
00173     if(errMsg != NULL) {
00174       ERRPRINTF("SQL Error %d: %s.\n", err, errMsg);
00175       *dbErrMsg = errMsg;
00176     }
00177 
00178     sz[0] = err * -1;
00179     sz[1] = strlen(errMsg);;
00180     sz[2] = sz[0];
00181 
00182     *tbl = NULL;
00183 
00184     retval = -1;
00185   }
00186   else {
00187     sz[0] = nrows;
00188     sz[1] = ncols;
00189     sz[2] = sqlite3_changes(db);
00190 
00191     *tbl = table;
00192   }
00193 
00194   return retval;
00195 }
00196 
00212 int
00213 gs_sqlite_submit_query(char *sql, char ***table, int *nrows, int *ncols,
00214                        char **dbErrMsg)
00215 {
00216   int sz[3];
00217 
00218   *nrows = 0;
00219   *ncols = 0;
00220   *table = NULL;
00221 
00222   if(!sql)
00223     return -1;
00224 
00225   if(gs_db_mgr_run_query(global_db, sql, sz, table, dbErrMsg) < 0) {
00226     ERRPRINTF("Query failed\n");
00227     return -1;
00228   }
00229 
00230   *nrows = sz[0];
00231   *ncols = sz[1];
00232 
00233   return sz[2];
00234 }
00235 
00240 int
00241 gs_storage_init(gs_agent_t * gs_agent)
00242 {
00243   int err;
00244 
00245   err = sqlite3_open(GRIDSOLVE_SQLITE_DB, &global_db);
00246   if( err != SQLITE_OK ) {
00247     ERRPRINTF("Error opening to database: %s\n",
00248         sqlite3_errmsg(global_db));
00249     return -1;
00250   }
00251 
00252   return 0;
00253 }
00254 
00255 int
00256 gs_sqlite_begin_transaction()
00257 {
00258   char *dbErrMsg = NULL, **table = NULL;
00259   int err, nrows, ncols;
00260 
00261   err = gs_sqlite_submit_query("begin transaction;", &table, 
00262     &nrows, &ncols, &dbErrMsg);
00263   if(err < 0) {
00264     ERRPRINTF("Error beginning transaction\n");
00265     return -1;
00266   }
00267 
00268   FREE_TABLE(table);
00269 
00270   return 0;
00271 }
00272 
00273 int
00274 gs_sqlite_commit_transaction()
00275 {
00276   char *dbErrMsg = NULL, **table = NULL;
00277   int err, nrows, ncols;
00278 
00279   err = gs_sqlite_submit_query("commit transaction;", &table,
00280     &nrows, &ncols, &dbErrMsg);
00281   if(err < 0) {
00282     ERRPRINTF("Error beginning transaction\n");
00283     return -1;
00284   }
00285 
00286   FREE_TABLE(table);
00287 
00288   return 0;
00289 }
00290 
00298 void
00299 gs_storage_finalize(gs_agent_t * gs_agent)
00300 {
00301   sqlite3_close(global_db);
00302 
00303   return;
00304 }
00305 
00316 int
00317 gs_add_server(gs_agent_t * gs_agent, gs_server_t * gs_server)
00318 {
00319   int err, now, nrows, ncols, i;
00320   char *sql, *dbErrMsg = NULL, cid_string[2 * CID_LEN + 1],
00321       server_dottedIP[20], proxy_dottedIP[20], **table, *sa_str, *sp_str;
00322   gs_info_t *attrs;
00323 
00324   DBGPRINTF("Adding Server.\n");
00325 
00326   proxy_cid_to_str(cid_string, gs_server->componentid);
00327   proxy_ip_to_str(gs_server->ipaddress, server_dottedIP);
00328   proxy_ip_to_str(gs_server->proxyip, proxy_dottedIP);
00329   sa_str = strdup("");
00330   sp_str = strdup(GS_NO_SERVER_PING_UPDATE);
00331   gs_encode_infolist(&sa_str, gs_server->sa_list);
00332 
00333   now = time(0);
00334   sql =
00335       sqlite3_mprintf
00336       ("INSERT INTO servers (hostname,ipaddress,port,proxyip,proxyport,componentid,arch,data_format,kflops,workload,ncpu,status,availcpu,availmem,nproblems,agenthost,agentport,smart,lastupdate,addedat,infolist,server_pings) VALUES (%Q,%Q,\"%d\",%Q,\"%d\",%Q,%Q,\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%lf\",\"%lf\",\"%d\",%Q,\"%d\",\"%d\",\"%d\",\"%d\",%Q,%Q);",
00337        gs_server->hostname, server_dottedIP, gs_server->port, proxy_dottedIP,
00338        gs_server->proxyport, cid_string, gs_server->arch,
00339        gs_server->data_format, gs_server->kflops, gs_server->workload,
00340        gs_server->ncpu, gs_server->status, gs_server->availcpu,
00341        gs_server->availmem, gs_server->nproblems, gs_server->agenthost,
00342        gs_server->agentport, gs_server->smart, now, now, sa_str, sp_str);
00343 
00344   free(sa_str);
00345 
00346   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00347 
00348   if(err < 0) {
00349     if ( dbErrMsg != NULL )
00350     {
00351       ERRPRINTF("SQL ERROR: %s\n", dbErrMsg);
00352       sqlite3_free(dbErrMsg);
00353     }  
00354     sqlite3_free(sql);
00355     return -1;
00356   }
00357   sqlite3_free(sql);
00358 
00359   SENSORPRINTF("SRV_UP %s %s\n", gs_server->hostname, cid_string);
00360   DBGPRINTF("Added Server, now adding attributes.\n");
00361 
00362   /* 
00363    * Add attributes
00364    */
00365   attrs = gs_server->sa_list;
00366   while(attrs != NULL) {
00367     i=0;
00368     while ( !isspace((int)attrs->type[i]) && attrs->type[i] != '\0') i++;
00369     attrs->type[i] = '\0';
00370     i=0;
00371     while ( !isspace((int)attrs->value[i]) && attrs->value[i] != '\0') i++;
00372     attrs->value[i] = '\0';
00373     err = gs_create_criteria_table(attrs->type, "", attrs->value);
00374     if(err < 0) {
00375       ERRPRINTF("Error adding criteria table.\n");
00376       return -1;
00377     }
00378     if ( sqliteIsNumber(attrs->value) )
00379       sql =
00380         sqlite3_mprintf
00381         ("INSERT INTO %s (value,componentid) values (%s,%Q);",
00382          attrs->type, attrs->value, cid_string);
00383     else
00384       sql =
00385         sqlite3_mprintf
00386         ("INSERT INTO %s (value,componentid) values (%Q,%Q);",
00387          attrs->type, attrs->value, cid_string);
00388     DBGPRINTF("Submitting Attribute Query.\n");
00389     err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00390     sqlite3_free(sql);
00391     if(err < 0) {
00392       ERRPRINTF("SQL Error: %s\n", dbErrMsg);
00393       if(dbErrMsg) sqlite3_free(dbErrMsg);
00394       return -1;
00395     }
00396     DBGPRINTF("Attribute added: %s.\n", attrs->type);
00397     attrs = attrs->next;
00398   }
00399 
00400   return 0;
00401 }
00402 
00411 int
00412 gs_delete_problem_if_last_mapping(gs_agent_t *gs_agent, char *problemname)
00413 {
00414   char *sql, *dbErrMsg = NULL, **table = NULL;
00415   int err, ncols, nrows;
00416 
00417   if(gs_sqlite_begin_transaction() < 0)
00418     ERRPRINTF("Warning: table lock failed\n");
00419 
00420   sql = sqlite3_mprintf("SELECT 1 FROM problem_server WHERE problemname=%Q;",
00421                        problemname);
00422   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00423 
00424   sqlite3_free(sql);
00425 
00426   FREE_TABLE(table);
00427 
00428   if(err < 0) {
00429     if ( dbErrMsg != NULL ) {
00430       ERRPRINTF("%s\n", dbErrMsg);
00431       sqlite3_free(dbErrMsg);
00432     }
00433 
00434     gs_sqlite_commit_transaction();
00435 
00436     return -1;
00437   }
00438 
00439   if(nrows == 1) {
00440     sql = sqlite3_mprintf("DELETE FROM problems WHERE problemname=%Q;",
00441                        problemname);
00442     err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00443 
00444     sqlite3_free(sql);
00445 
00446     FREE_TABLE(table);
00447 
00448     if(err < 0) {
00449       if ( dbErrMsg != NULL ) {
00450         ERRPRINTF("%s\n", dbErrMsg);
00451         sqlite3_free(dbErrMsg);
00452       }
00453 
00454       gs_sqlite_commit_transaction();
00455 
00456       return -1;
00457     }
00458   }
00459 
00460   gs_sqlite_commit_transaction();
00461 
00462   return 0;
00463 }
00464 
00472 int
00473 gs_delete_server_problems(gs_agent_t *gs_agent, char *cid_string)
00474 {
00475   int err, i, nrows, ncols, els;
00476   char *sql, *dbErrMsg = NULL, **table = NULL;
00477 
00478   sql = sqlite3_mprintf("SELECT problemname FROM problem_server WHERE componentid=%Q;",
00479                        cid_string);
00480   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00481   sqlite3_free(sql);
00482   if(err < 0) {
00483     if ( dbErrMsg != NULL )
00484     {
00485       ERRPRINTF("%s\n", dbErrMsg);
00486       sqlite3_free(dbErrMsg);
00487     }
00488     return -1;
00489   }
00490 
00491   /* save number of table elements before nrows gets clobbered */
00492   els = (nrows+1)*ncols;
00493 
00494   for(; nrows > 0; nrows--) {
00495     i = nrows * ncols;
00496 
00497     if(gs_delete_problem_if_last_mapping(gs_agent, table[i]) < 0)
00498       ERRPRINTF("Warning: could not delete unreferenced problems (if needed)\n");
00499   }
00500 
00501   FREE_TABLE(table);
00502 
00503   sql = sqlite3_mprintf("DELETE FROM problem_server WHERE componentid=%Q;",
00504                        cid_string);
00505   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00506   sqlite3_free(sql);
00507   if(err < 0) {
00508     if ( dbErrMsg != NULL )
00509     {
00510       ERRPRINTF("%s\n", dbErrMsg);
00511       sqlite3_free(dbErrMsg);
00512     }
00513     return -1;
00514   }
00515 
00516   FREE_TABLE(table);
00517 
00518   return 0;
00519 }
00520 
00532 int
00533 gs_delete_server(gs_agent_t * gs_agent, gs_server_t * gs_server)
00534 {
00535   int err, ncols, nrows;
00536   char *sql, *dbErrMsg = NULL, cid_string[2 * CID_LEN + 1], **table = NULL;
00537   gs_info_t *attrs, *tmp;
00538 
00539   proxy_cid_to_str(cid_string, gs_server->componentid);
00540 
00541   /* 
00542    * remove server attributes from their tables.
00543    */
00544 
00545   sql = sqlite3_mprintf("SELECT infolist FROM servers WHERE componentid=%Q;",
00546                        cid_string);
00547   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00548   sqlite3_free(sql);
00549   if(err < 0) {
00550     if ( dbErrMsg != NULL )
00551     {
00552       ERRPRINTF("%s\n", dbErrMsg);
00553       sqlite3_free(dbErrMsg);
00554     }
00555 
00556     FREE_TABLE(table);
00557 
00558     return -1;
00559   }
00560 
00561   attrs = NULL;
00562   err = gs_decode_infolist(table[1], &attrs);
00563 
00564   FREE_TABLE(table);
00565 
00566   while(attrs != NULL) {
00567     sql = sqlite3_mprintf("DELETE FROM %Q WHERE componentid=%Q;",
00568                          attrs->type, cid_string);
00569     err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00570     sqlite3_free(sql);
00571     if(err < 0) {
00572       if ( dbErrMsg != NULL )
00573     sqlite3_free(dbErrMsg);
00574     }
00575     tmp = attrs;
00576     attrs = attrs->next;
00577 
00578     FREE_TABLE(table);
00579 
00580     if(tmp) {
00581       if(tmp->type) free(tmp->type);
00582       if(tmp->value) free(tmp->value);
00583       free(tmp);
00584     }
00585   }
00586 
00587   /* DELETE SERVER */
00588   sql = sqlite3_mprintf("DELETE FROM servers WHERE componentid=%Q;",
00589                        cid_string);
00590   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00591 
00592   sqlite3_free(sql);
00593 
00594   FREE_TABLE(table);
00595 
00596   if(err < 0) {
00597     if ( dbErrMsg != NULL )
00598     {
00599       ERRPRINTF("%s\n", dbErrMsg);
00600       sqlite3_free(dbErrMsg);
00601     }
00602     return -1;
00603   }
00604 
00605   if(gs_delete_server_problems(gs_agent, cid_string) < 0) {
00606     ERRPRINTF("Failed to delete server-problem mappings\n");
00607     return -1;
00608   }
00609 
00610   SENSORPRINTF("SRV_RM %s unknown\n", cid_string);
00611 
00612   return 0;
00613 }
00614 
00638 int
00639 gs_insert_submitted_task(char *cid_string, char *taskid, int agent_taskid, 
00640   double start, double duration, double remaining, double end, int active, 
00641   int finished)
00642 {
00643   return gs_insert_task(cid_string, taskid, agent_taskid, start,
00644     duration, remaining, end, active, finished, "tasks", 1);
00645 }
00646 
00668 int
00669 gs_insert_submitted_task_guess(char *cid_string, char *taskid, int agent_taskid,
00670   double start, double duration, double remaining, double end, int active,
00671   int finished)
00672 {
00673   return gs_insert_task(cid_string, taskid, agent_taskid, start,
00674     duration, remaining, end, active, finished, "tasks", 0);
00675 }
00676 
00694 int
00695 gs_insert_completed_task(char *cid_string, char *taskid, int agent_taskid, 
00696   double start, double duration, double remaining, double end, int active, 
00697   int finished)
00698 {
00699   return gs_insert_task(cid_string, taskid, agent_taskid, start,
00700     duration, remaining, end, active, finished, "completed_tasks", 1);
00701 }
00702 
00724 static int
00725 gs_insert_task(char *cid_string, char *taskid, int agent_taskid, double start,
00726   double duration, double remaining, double end, int active, int finished,
00727   char *tname, int clobber)
00728 {
00729   int err = 0, nrows = 0, ncols = 0;
00730   char *sql = 0, *dbErrMsg = 0, **table = 0, *conflict_res;
00731 
00732   switch(clobber) {
00733     case 0:
00734       conflict_res = "IGNORE";
00735       break;
00736     case 1:
00737       conflict_res = "REPLACE";
00738       break;
00739     default:
00740       ERRPRINTF("Bad arg value for clobber: %d\n", clobber);
00741       return -1;
00742       break;
00743   }
00744 
00745   sql = sqlite3_mprintf("INSERT OR %s INTO %s VALUES (%Q,%Q,\"%d\",\"%lf\",\"%lf\",\"%lf\",\"%lf\",\"%d\",\"%d\");",
00746            conflict_res, tname, cid_string, taskid, agent_taskid, start, duration, remaining, end, active, finished);
00747 
00748   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00749   sqlite3_free(sql);
00750   if(err < 0) {
00751     if ( dbErrMsg != NULL )
00752     {
00753       ERRPRINTF("%s\n", dbErrMsg);
00754       sqlite3_free(dbErrMsg);
00755     }
00756     return -1;
00757   }
00758 
00759   return 0;
00760 }
00761 
00781 int
00782 gs_update_task(char *cid_string, char *old_taskid, char *new_taskid,
00783   int agent_taskid, double start, double duration, double remaining, 
00784   double end, int active, int finished)
00785 {
00786   int err, ncols, nrows;
00787   char *sql, *dbErrMsg = NULL, **table = NULL;
00788 
00789   sql = sqlite3_mprintf("UPDATE tasks SET t_componentid=%Q, t_taskid=%Q, t_agent_taskid=\"%d\", t_start=\"%lf\", t_duration=\"%lf\", t_remaining=\"%lf\", t_end=\"%lf\", t_active=\"%d\", t_finished=\"%d\" WHERE t_taskid=%Q;",
00790            cid_string, new_taskid, agent_taskid, start, duration, remaining, end, active, finished, old_taskid);
00791 
00792   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00793   if(err < 0) {
00794     if ( dbErrMsg != NULL )
00795     {
00796       ERRPRINTF("%s\n", dbErrMsg);
00797       sqlite3_free(dbErrMsg);
00798     }
00799     return -1;
00800   }
00801   sqlite3_free(sql);
00802 
00803   if(err == 0) {
00804     return -1;
00805   }
00806 
00807   return 0;
00808 }
00809 
00818 int
00819 gs_insert_problem(gs_problem_t * gs_problem)
00820 {
00821   int err = 0, nrows = 0, ncols = 0;
00822   char *sql = 0, *dbErrMsg = 0, **table = 0, *penc = 0;
00823 
00824   if(gs_encode_problem(&penc, gs_problem) < 0)
00825     return -1;
00826 
00827   sql = sqlite3_mprintf("INSERT INTO problems (problemname,encoding) VALUES (%Q,%Q);",
00828          gs_problem->name, penc);
00829   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00830   if(err < 0) {
00831     if ( dbErrMsg != NULL )
00832     {
00833       ERRPRINTF("%s\n", dbErrMsg);
00834       sqlite3_free(dbErrMsg);
00835     }
00836     free(penc);
00837     gs_sqlite_commit_transaction();
00838     return -1;
00839   }
00840 
00841   sqlite3_free(sql);
00842   free(penc);
00843 
00844   return 0;
00845 }
00846 
00857 int
00858 gs_register_problem_changes(gs_agent_t * gs_agent, 
00859   gs_problem_t ** gs_problem, int num_services, char **models,
00860   char **rm_prob, int num_removed, char *cid_string)
00861 {
00862   int i;
00863 
00864   if(gs_sqlite_begin_transaction() < 0)
00865     ERRPRINTF("Warning: table lock failed\n");
00866 
00867   for(i=0;i<num_services;i++) {
00868     if(gs_add_single_problem(gs_agent, gs_problem[i], cid_string) < 0) {
00869       ERRPRINTF("Add problem failed.\n");
00870       gs_sqlite_commit_transaction();
00871       return -1;
00872     }
00873 
00874     if(gs_update_perf_expr(cid_string, gs_problem[i]->name, models[i]) < 0)
00875       ERRPRINTF("Warning: failed to update perf model expression\n");
00876   }
00877 
00878   gs_sqlite_commit_transaction();
00879 
00880   for(i=0;i<num_removed;i++) {
00881     if(gs_delete_problem(gs_agent, rm_prob[i], cid_string) < 0)
00882       ERRPRINTF("Failed to delete problem: %s\n", rm_prob[i]);
00883     else
00884       LOGPRINTF("Unregistered problem %s\n", rm_prob[i]);
00885   }
00886 
00887   return 0;
00888 }
00889 
00903 int
00904 gs_add_single_problem(gs_agent_t * gs_agent, gs_problem_t * gs_problem,
00905                char *cid_string)
00906 {
00907   int err = 0, pid = 0, nrows = 0, ncols = 0;
00908   char *sql = 0, *dbErrMsg = 0, **table = 0, *penc = 0;
00909 
00910   DBGPRINTF("ADDING %s to %s\n", gs_problem->name, cid_string);
00911   /* 
00912    * encode the problem
00913    */
00914   gs_encode_problem(&penc, gs_problem);
00915 
00916   /* 
00917    * Check if problem already exists
00918    */
00919   sql = sqlite3_mprintf("SELECT encoding FROM problems WHERE problemname=%Q;",
00920                        gs_problem->name);
00921   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
00922   if(err < 0) {
00923     if(dbErrMsg != NULL)
00924     {
00925       ERRPRINTF("%s\n", dbErrMsg);
00926       sqlite3_free(dbErrMsg);
00927     }
00928     ERRPRINTF("Failed to submit query '%s'\n", sql);
00929     free(penc);
00930     sqlite3_free(sql);
00931     return -1;
00932   }
00933   sqlite3_free(sql);
00934   if(nrows == 1) {
00935     pid = 1;
00936   }
00937   else {
00938     FREE_TABLE(table);
00939   }
00940 
00941   /* 
00942    * If problem is not in db, insert it
00943    */
00944   if(!pid) {
00945     if(gs_insert_problem(gs_problem) < 0) {
00946       free(penc);
00947       ERRPRINTF("Failed to insert new problem.\n");
00948       return -1;
00949     }
00950   }
00951   else {
00952     int comparison_result;
00953     char *new_prot, *db_prot;
00954 
00955     /* 
00956      * Check encoding for differences, looking only at the actual prototype
00957      */
00958     gs_problem_t *gs_problem_in_db  = (gs_problem_t *) CALLOC(1, sizeof(gs_problem_t));
00959     if(!gs_problem_in_db) {
00960       ERRPRINTF("couldn't malloc space for problem to compare\n");
00961       return -1;
00962     }
00963 
00964     if(gs_decode_problem(table[1], gs_problem_in_db) < 0) {
00965       ERRPRINTF("decoding problem from database failed\n");
00966       return -1;
00967     }
00968 
00969     new_prot = gs_problem_prototype(gs_problem);
00970     db_prot = gs_problem_prototype(gs_problem_in_db);
00971 
00972     comparison_result = strcmp(new_prot, db_prot);
00973 
00974     gs_free_problem(gs_problem_in_db);
00975     free(new_prot);
00976     free(db_prot);
00977 
00978     if(comparison_result != 0) {
00979       gs_server_t **server_list = NULL;
00980       int server_match, count, i;
00981 
00982       /* this problem exists, but is different than the problem being
00983        * registered.  if this is the only server that has the problem
00984        * then allow the new version to be registered.
00985        */
00986       count = gs_get_server_list(gs_agent, gs_problem, NULL, &server_list,
00987                  &count);
00988 
00989       server_match = 0;
00990 
00991       if(server_list) {
00992         char srv_cid[CID_LEN];
00993 
00994         proxy_str_to_cid(srv_cid, cid_string);
00995 
00996         for(i = 0; i < count; i++) {
00997           if(!memcmp(srv_cid, server_list[i]->componentid, CID_LEN))
00998             server_match = 1;
00999 
01000           gs_server_free(server_list[i]);
01001         }
01002         free(server_list);
01003       }
01004 
01005       /* if only one server has the problem and it matches the
01006        * current server name, then delete the old problem and
01007        * allow registration of the new version of the problem.
01008        */
01009       if((count == 1) && server_match &&
01010           (gs_delete_problem(gs_agent, gs_problem->name, cid_string) >= 0) &&
01011           (gs_insert_problem(gs_problem) >= 0))
01012       {
01013         LOGPRINTF("Successfully replaced old version of problem %s\n",
01014            gs_problem->name);
01015       }
01016       else {
01017         FREE_TABLE(table);
01018         ERRPRINTF("Failed to replace old version of problem '%s'.\n",
01019           gs_problem->name);
01020         gs_delete_problem(gs_agent, gs_problem->name, cid_string);
01021         free(penc);
01022         return -1;
01023       }
01024     }
01025   }
01026 
01027   free(penc);
01028   FREE_TABLE(table);
01029 
01030   /* 
01031    * Associate the problem with the server.
01032    */
01033   sql =
01034       sqlite3_mprintf
01035       ("INSERT INTO problem_server (problemname,componentid,perf_model_expr) VALUES (%Q,%Q,%Q);",
01036        gs_problem->name, cid_string, "-1");
01037   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01038   if(err < 0) {
01039     /* 
01040      * If we violated a contraint, then the problem must already
01041      * be registered to this server.  Return success.
01042      */
01043     if((err * -1) == SQLITE_CONSTRAINT) {
01044       return 0;
01045     }
01046     if ( dbErrMsg != NULL )
01047     {
01048       ERRPRINTF("%s\n", dbErrMsg);
01049       sqlite3_free(dbErrMsg);
01050     }
01051     ERRPRINTF("failed to associate problem.. query = '%s'\n", sql);
01052     sqlite3_free(sql);
01053     return -1;
01054   }
01055   sqlite3_free(sql);
01056 
01057   return 0;
01058 }
01059 
01070 int
01071 gs_delete_problem(gs_agent_t * gs_agent, char * probname,
01072                   char *cid_string)
01073 {
01074   int err, nrows, ncols;
01075   char *sql, *dbErrMsg = NULL, **table = NULL;
01076 
01077   if(gs_delete_problem_if_last_mapping(gs_agent, probname) < 0)
01078     ERRPRINTF("Warning: failed to delete last problem mapping (if needed)\n");
01079 
01080   /* 
01081    * delete association
01082    */
01083   sql =
01084       sqlite3_mprintf
01085       ("DELETE FROM problem_server WHERE componentid=%Q AND problemname=%Q;",
01086        cid_string, probname);
01087   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01088   sqlite3_free(sql);
01089   if(err < 0) {
01090     if ( dbErrMsg != NULL )
01091     {
01092       ERRPRINTF("%s\n", dbErrMsg);
01093       sqlite3_free(dbErrMsg);
01094     }
01095     return -1;
01096   }
01097   return 0;
01098 }
01099 
01112 int
01113 gs_update_perf_expr(char *srv_cid, char *probname, char *expr)
01114 {
01115   char *sql, *dbErrMsg = NULL, **table = NULL;
01116   int err, ncols, nrows;
01117 
01118   sql = sqlite3_mprintf("UPDATE problem_server SET perf_model_expr=%Q WHERE componentid=%Q AND problemname=%Q;",
01119        expr, srv_cid, probname);
01120   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01121   if(err < 0) {
01122     if ( dbErrMsg != NULL )
01123     {
01124       ERRPRINTF("%s\n", dbErrMsg);
01125       sqlite3_free(dbErrMsg);
01126     }
01127     return -1;
01128   }
01129   sqlite3_free(sql);
01130 
01131   if(err == 0) {
01132     return -1;
01133   }
01134 
01135   return 0;
01136 }
01137 
01145 int
01146 gs_update_ping_list(gs_agent_t * gs_agent, char *cid, char *pings)
01147 {
01148   int now, err, ncols, nrows;
01149   char *sql, *dbErrMsg = NULL, **table = NULL;
01150 
01151   now = time(0);
01152   sql =
01153       sqlite3_mprintf("UPDATE servers SET server_pings=%Q WHERE componentid=%Q;",
01154         pings, cid);
01155   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01156   if(err < 0) {
01157     if ( dbErrMsg != NULL )
01158     {
01159       ERRPRINTF("%s\n", dbErrMsg);
01160       sqlite3_free(dbErrMsg);
01161     }
01162     return -1;
01163   }
01164   sqlite3_free(sql);
01165 
01166   if(err == 0) {
01167     return -1;
01168   }
01169 
01170   return 0;
01171 }
01172 
01180 int
01181 gs_update_workload(gs_agent_t * gs_agent, gs_server_t * gs_server)
01182 {
01183   int now, err, ncols, nrows;
01184   char *sql, *dbErrMsg = NULL, cid_string[2 * CID_LEN + 1], **table = NULL;
01185 
01186   proxy_cid_to_str(cid_string, gs_server->componentid);
01187 
01188   now = time(0);
01189   sql =
01190       sqlite3_mprintf
01191       ("UPDATE servers SET workload=\"%d\", nproblems=\"%d\", lastupdate=\"%ld\" WHERE componentid=%Q;",
01192        gs_server->workload, gs_server->nproblems, now, cid_string);
01193   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01194   if(err < 0) {
01195     if ( dbErrMsg != NULL )
01196     {
01197       ERRPRINTF("%s\n", dbErrMsg);
01198       sqlite3_free(dbErrMsg);
01199     }
01200     return -1;
01201   }
01202   sqlite3_free(sql);
01203 
01204   SENSORPRINTF("WORK %s %d\n", cid_string, gs_server->workload);
01205 
01206   if(err == 0) {
01207     return -1;
01208   }
01209 
01210   return 0;
01211 }
01212 
01220 int
01221 gs_server_exists(gs_agent_t * gs_agent, gs_server_t * gs_server)
01222 {
01223   int err, nrows, ncols;
01224   char *sql, *dbErrMsg = NULL, **table = NULL, cid_string[2 * CID_LEN + 1];
01225 
01226   proxy_cid_to_str(cid_string, gs_server->componentid);
01227 
01228   sql = sqlite3_mprintf("SELECT 1 FROM servers WHERE componentid=%Q;",
01229                        cid_string);
01230   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01231   if(err < 0) {
01232     if ( dbErrMsg != NULL )
01233     {
01234       ERRPRINTF("%s\n", dbErrMsg);
01235       sqlite3_free(dbErrMsg);
01236     }
01237     return -1;
01238   }
01239 
01240   if(nrows > 0) {
01241     FREE_TABLE(table);
01242     return 1;
01243   }
01244   else {
01245     return 0;
01246   }
01247 }
01248 
01260 void
01261 gs_server_expiration(void **args)
01262 {
01263   gs_agent_t *agent;
01264   int timeout;
01265 
01266   agent = (gs_agent_t *) args[0];
01267   timeout = *((int *) args[1]);
01268 
01269   gs_server_expire(agent, timeout);
01270 }
01271 
01278 void
01279 gs_server_expiration_pre(void **args)
01280 {
01281   gs_agent_t *agent;
01282   int timeout;
01283 
01284   agent = (gs_agent_t *) args[0];
01285   timeout = *((int *) args[1]);
01286   if ( gs_storage_init(agent) < 0 )
01287   {
01288     ERRPRINTF("Error connecting to database manager.\n");
01289     return;
01290   }
01291   DBGPRINTF("Connected to db manager.\n");
01292   gs_server_expire(agent, timeout);
01293 }
01294 
01302 void
01303 gs_server_expiration_post(void **args)
01304 {
01305   gs_agent_t *agent;
01306   agent = (gs_agent_t *) args[0];
01307   DBGPRINTF("Closing connection to db manager.\n");
01308   gs_storage_finalize(agent);
01309 }
01310 
01320 int
01321 gs_server_expire(gs_agent_t * gs_agent, int timeout)
01322 {
01323   int i, err, now, nrows, ncols;
01324   char *sql, *dbErrMsg = NULL, **table = NULL;
01325 
01326   now = time(0);
01327   sql = sqlite3_mprintf("SELECT componentid FROM servers WHERE lastupdate < \"%ld\";",
01328                         now - timeout);
01329   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01330   if(err < 0) {
01331     if ( dbErrMsg != NULL )
01332     {
01333       ERRPRINTF("%s\n", dbErrMsg);
01334       sqlite3_free(dbErrMsg);
01335     }
01336     return -1;
01337   }
01338   sqlite3_free(sql);
01339 
01340   if(table != NULL) {
01341     gs_server_t tmpsrv;
01342 
01343     /* just in case */
01344     memset(&tmpsrv, 0, sizeof(tmpsrv));
01345 
01346     for(i = 1; i < (nrows + 1) * ncols; i++)
01347     {
01348       ERRPRINTF("expiring %s\n", table[i]);
01349 
01350       proxy_str_to_cid(tmpsrv.componentid, table[i]);
01351       if(gs_delete_server(gs_agent, &tmpsrv) < 0)
01352         ERRPRINTF("Failed to delete server '%s'\n", table[i]);
01353     }
01354 
01355     FREE_TABLE(table);
01356   }
01357 
01358   return 0;
01359 }
01360 
01375 int
01376 gs_get_server_list(gs_agent_t * gs_agent, gs_problem_t * gs_problem,
01377                    char *client_criteria, gs_server_t *** servers, int *count)
01378 {
01379   int err, i, nrows, ncols, table_els;
01380   char *sql, *dbErrMsg = NULL, **table = NULL;
01381   gs_server_t **server_list;
01382 
01383   /* 
01384    * fill in remaining problem information.
01385    */
01386   sql = sqlite3_mprintf("SELECT encoding FROM problems WHERE problemname=%Q;",
01387                        gs_problem->name);
01388   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01389   if(err < 0) {
01390     if ( dbErrMsg != NULL )
01391     {
01392       ERRPRINTF("%s\n", dbErrMsg);
01393       sqlite3_free(dbErrMsg);
01394     }
01395     return -1;
01396   }
01397   sqlite3_free(sql);
01398   if(nrows > 0) {
01399     free(gs_problem->name);
01400     gs_problem->name = NULL;
01401     err = gs_decode_problem(table[1], gs_problem);
01402   }
01403   FREE_TABLE(table);
01404 
01405   if(client_criteria == NULL) {
01406     /* 
01407      * get servers associated with this problem.
01408      */
01409     sql =
01410         sqlite3_mprintf
01411         ("SELECT servers.*,problem_server.perf_model_expr FROM problem_server JOIN servers ON problem_server.componentid = servers.componentid WHERE problemname=%Q;",
01412          gs_problem->name);
01413   }
01414   else {                        /* we need to consider server attributes */
01415     char *critq, *gs_parse_client_criteria(char *, int);
01416 
01417     critq = gs_parse_client_criteria(client_criteria, GS_CRIT_PARSE_SQLITE);
01418     sql = sqlite3_mprintf(critq, gs_problem->name);
01419     FREE(critq);
01420   }
01421   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01422   sqlite3_free(sql);
01423   if(err < 0) {
01424     if ( dbErrMsg != NULL )
01425     {
01426       ERRPRINTF("%s %d\n", dbErrMsg, nrows);
01427       sqlite3_free(dbErrMsg);
01428     }
01429     (*servers) = NULL;
01430     return -1;
01431   }
01432   *count = nrows;
01433   server_list = (gs_server_t **) CALLOC(nrows, sizeof(gs_server_t *));
01434   if(server_list == NULL) {
01435     ERRPRINTF("malloc error\n");
01436     FREE_TABLE(table);
01437     return -1;
01438   }
01439 
01440   /* save number of table elements before nrows gets clobbered */
01441   table_els = (nrows + 1) * ncols - 1;
01442 
01443   for(; nrows > 0; nrows--) {
01444     /* fill in servers array */
01445     i = nrows * ncols;
01446     server_list[nrows-1] = (gs_server_t *) CALLOC(1, sizeof(gs_server_t));
01447     server_list[nrows - 1]->hostname = strdup(table[i]);
01448     proxy_str_to_ip(&(server_list[nrows - 1]->ipaddress), table[i + 1]);
01449     server_list[nrows - 1]->port = atoi(table[i + 2]);
01450     proxy_str_to_ip(&(server_list[nrows - 1]->proxyip), table[i + 3]);
01451     server_list[nrows - 1]->proxyport = atoi(table[i + 4]);
01452     proxy_str_to_cid(server_list[nrows - 1]->componentid, table[i + 5]);
01453     server_list[nrows - 1]->arch = strdup(table[i + 6]);
01454     server_list[nrows - 1]->data_format = atoi(table[i + 7]);
01455     server_list[nrows - 1]->kflops = atoi(table[i + 8]);
01456     server_list[nrows - 1]->workload = atoi(table[i + 9]);
01457     server_list[nrows - 1]->ncpu = atoi(table[i + 10]);
01458     server_list[nrows - 1]->status = atoi(table[i + 11]);
01459     server_list[nrows - 1]->availcpu = atof(table[i + 12]);
01460     server_list[nrows - 1]->availmem = atof(table[i + 13]);
01461     server_list[nrows - 1]->nproblems = atoi(table[i + 14]);
01462     server_list[nrows - 1]->agenthost = strdup(table[i + 15]);
01463     server_list[nrows - 1]->agentport = atoi(table[i + 16]);
01464     server_list[nrows - 1]->smart = atoi(table[i + 17]);
01465     server_list[nrows - 1]->last_update = atoi(table[i + 18]);
01466 
01467     /* skip 19 for addedat */
01468 
01469     /* 
01470      * fill in server attribuites
01471      */
01472     server_list[nrows - 1]->sa_list = NULL;
01473 
01474     gs_decode_infolist(table[i + 20], &(server_list[nrows - 1]->sa_list));
01475 
01476     server_list[nrows - 1]->my_ping_str = strdup(table[i+21]);
01477  
01478     server_list[nrows - 1]->perf_expr = strdup(table[i+22]);
01479   }
01480 
01481   FREE_TABLE(table);
01482 
01483   *servers = server_list;
01484   return *count;
01485 }
01486 
01487 int
01488 task_start_compare_function(const void *p1, const void *p2)
01489 {
01490   gs_htm_task *s1, *s2;
01491 
01492   if(!p1 || !p2) return 0;
01493 
01494   s1 = *((gs_htm_task **) p1);
01495   s2 = *((gs_htm_task **) p2);
01496 
01497   if(s1->start > s2->start)
01498     return 1;
01499   if(s1->start < s2->start)
01500     return -1;
01501 
01502   return 0;
01503 }
01504 
01520 int
01521 gs_get_tasks_for_server(char *cid_string, gs_htm_task ***tasks, 
01522   int *count, int sync)
01523 {
01524   int err, i, nrows, ncols, els;
01525   char *sql, *dbErrMsg = NULL, **table = NULL;
01526   gs_htm_task **task_list;
01527 
01528   *count = -1;
01529 
01530   sql = sqlite3_mprintf("select * from (select * from tasks,completed_tasks where tasks.t_taskid=completed_tasks.c_taskid and tasks.t_componentid=completed_tasks.c_componentid union select * from tasks,completed_tasks where completed_tasks.c_taskid='-1' and tasks.t_taskid not in (select tasks.t_taskid from tasks,completed_tasks where tasks.t_taskid=completed_tasks.c_taskid and tasks.t_componentid=completed_tasks.c_componentid) union select * from tasks,completed_tasks where tasks.t_taskid='-1' and completed_tasks.c_taskid not in (select tasks.t_taskid from tasks,completed_tasks where tasks.t_taskid=completed_tasks.c_taskid and tasks.t_componentid=completed_tasks.c_componentid)) as foo where t_componentid=%Q or c_componentid=%Q;", cid_string, cid_string);
01531   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01532   if(err < 0) {
01533     if ( dbErrMsg != NULL )
01534     {
01535       ERRPRINTF("%s\n", dbErrMsg);
01536       sqlite3_free(dbErrMsg);
01537     }
01538     return -1;
01539   } 
01540 
01541   sqlite3_free(sql);
01542   *count = nrows;
01543   task_list = (gs_htm_task **) CALLOC(nrows, sizeof(gs_htm_task *));
01544 
01545   if(task_list == NULL) {
01546     ERRPRINTF("malloc error\n");
01547     FREE_TABLE(table);
01548     return -1;
01549   }
01550 
01551   /* save number of table elements before nrows gets clobbered */
01552   els = (nrows+1)*ncols;
01553 
01554   for(; nrows > 0; nrows--) {
01555     i = nrows * ncols;
01556 
01557     task_list[nrows - 1] = (gs_htm_task *) CALLOC(1, sizeof(gs_htm_task));
01558 
01559     if(!task_list[nrows-1]) {
01560       ERRPRINTF("malloc error\n");
01561       FREE_TABLE(table);
01562       return -1;
01563     }
01564 
01565     if(table[i+1] && table[i+10] && strcmp(table[i+1], "-1") && strcmp(table[i+10], "-1")) {
01566       /* entry exists in both tasks and completed_tasks */
01567 
01568       /* skip table[i] which is component_id */
01569       strcpy(task_list[nrows - 1]->id, table[i+1]);
01570       /* skip table[i+2] which is agent_taskid */
01571       if(sync) {
01572         task_list[nrows - 1]->start = MIN(atof(table[i+3]), atof(table[i+12]));
01573         task_list[nrows - 1]->end = MAX(atof(table[i+6]), atof(table[i+15]));
01574         task_list[nrows - 1]->duration = task_list[nrows - 1]->end - task_list[nrows - 1]->start;
01575       }
01576       else {
01577         task_list[nrows - 1]->start = atof(table[i+3]);
01578         task_list[nrows - 1]->end = atof(table[i+6]);
01579         task_list[nrows - 1]->duration = atof(table[i+4]);
01580       }
01581       task_list[nrows - 1]->remaining = atof(table[i+14]);
01582       task_list[nrows - 1]->active = atoi(table[i+7]);
01583       task_list[nrows - 1]->finished = atoi(table[i+17]);
01584       task_list[nrows - 1]->next = NULL;
01585     }
01586     else if(table[i+1] && strcmp(table[i+1], "-1")) {
01587       /* entry exists in only in tasks */
01588 
01589       /* skip table[i] which is component_id */
01590       strcpy(task_list[nrows - 1]->id, table[i+1]);
01591       /* skip table[i+2] which is agent_taskid */
01592       task_list[nrows - 1]->start = atof(table[i+3]);
01593       task_list[nrows - 1]->duration = atof(table[i+4]);
01594       task_list[nrows - 1]->remaining = atof(table[i+5]);
01595       task_list[nrows - 1]->end = atof(table[i+6]);
01596       task_list[nrows - 1]->active = atoi(table[i+7]);
01597       task_list[nrows - 1]->finished = atoi(table[i+8]);
01598       task_list[nrows - 1]->next = NULL;
01599     }
01600     else if(table[i+10] && strcmp(table[i+10], "-1")) {
01601       /* entry exists in only in completed_tasks */
01602 
01603       /* skip table[i+9] which is component_id */
01604       strcpy(task_list[nrows - 1]->id, table[i+10]);
01605       /* skip table[i+11] which is agent_taskid */
01606       task_list[nrows - 1]->start = atof(table[i+12]);
01607       task_list[nrows - 1]->duration = atof(table[i+13]);
01608       task_list[nrows - 1]->remaining = atof(table[i+14]);
01609       task_list[nrows - 1]->end = atof(table[i+15]);
01610       task_list[nrows - 1]->active = atoi(table[i+16]);
01611       task_list[nrows - 1]->finished = atoi(table[i+17]);
01612       task_list[nrows - 1]->next = NULL;
01613     }
01614     else {
01615       /* should not hit this case */
01616       ERRPRINTF("Unexpected result from query.\n");
01617       return -1;
01618     }
01619 
01620     /* make sure duration isn't some weird value */
01621     if(task_list[nrows - 1]->duration <= 0.0)
01622       task_list[nrows - 1]->duration = 0.001;
01623   }
01624 
01625   FREE_TABLE(table);
01626 
01627   qsort(task_list, nrows, sizeof(gs_htm_task *), task_start_compare_function);
01628 
01629   *tasks = task_list;
01630   return 0;
01631 }
01632 
01633 int
01634 OLD_gs_get_tasks_for_server(char *cid_string, gs_htm_task ***tasks, 
01635   int *count)
01636 {
01637   int err, i, nrows, ncols, els;
01638   char *sql, *dbErrMsg = NULL, **table = NULL;
01639   gs_htm_task **task_list;
01640 
01641   *count = -1;
01642 
01643   sql = sqlite3_mprintf("SELECT * FROM taskviewjoin WHERE componentid=%Q;",
01644     cid_string);
01645   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01646   if(err < 0) {
01647     if ( dbErrMsg != NULL )
01648     {
01649       ERRPRINTF("%s\n", dbErrMsg);
01650       sqlite3_free(dbErrMsg);
01651     }
01652     return -1;
01653   } 
01654 
01655   sqlite3_free(sql);
01656   *count = nrows;
01657   task_list = (gs_htm_task **) CALLOC(nrows, sizeof(gs_htm_task *));
01658 
01659   if(task_list == NULL) {
01660     ERRPRINTF("malloc error\n");
01661     FREE_TABLE(table);
01662     return -1;
01663   }
01664 
01665   /* save number of table elements before nrows gets clobbered */
01666   els = (nrows+1)*ncols;
01667 
01668   for(; nrows > 0; nrows--) {
01669     i = nrows * ncols;
01670 
01671     task_list[nrows - 1] = (gs_htm_task *) CALLOC(1, sizeof(gs_htm_task));
01672 
01673     if(!task_list[nrows-1]) {
01674       ERRPRINTF("malloc error\n");
01675       FREE_TABLE(table);
01676       return -1;
01677     }
01678 
01679     /* skip table[i] which is component_id */
01680     strcpy(task_list[nrows - 1]->id, table[i+1]);
01681     /* skip table[i+2] which is agent_taskid */
01682     task_list[nrows - 1]->start = atof(table[i+3]);
01683     task_list[nrows - 1]->duration = atof(table[i+4]);
01684     task_list[nrows - 1]->remaining = atof(table[i+5]);
01685     task_list[nrows - 1]->end = atof(table[i+6]);
01686     task_list[nrows - 1]->active = atoi(table[i+7]);
01687     task_list[nrows - 1]->finished = atoi(table[i+8]);
01688     task_list[nrows - 1]->next = NULL;
01689   }
01690 
01691   FREE_TABLE(table);
01692 
01693   *tasks = task_list;
01694   return 0;
01695 }
01696 
01708 int
01709 gs_get_server_ping_list(gs_agent_t * gs_agent, gs_server_t *** servers, char *cid, int *count)
01710 {
01711   int err, i, nrows, ncols, els;
01712   char *sql, *dbErrMsg = NULL, **table = NULL;
01713   gs_server_t **server_list;
01714 
01715   sql = sqlite3_mprintf("SELECT * FROM servers WHERE componentid<%Q AND smart=\"1\";", cid);
01716   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01717   if(err < 0) {
01718     if ( dbErrMsg != NULL )
01719     {
01720       ERRPRINTF("%s\n", dbErrMsg);
01721       sqlite3_free(dbErrMsg);
01722     }
01723     return -1;
01724   }
01725   sqlite3_free(sql);
01726   *count = nrows;
01727   server_list = (gs_server_t **) CALLOC(nrows, sizeof(gs_server_t *));
01728 
01729   if(server_list == NULL) {
01730     ERRPRINTF("malloc error\n");
01731     FREE_TABLE(table);
01732     return -1;
01733   }
01734 
01735   /* save number of table elements before nrows gets clobbered */
01736   els = (nrows+1)*ncols;
01737 
01738   for(; nrows > 0; nrows--) {
01739     i = nrows * ncols;
01740     server_list[nrows-1] = (gs_server_t *) CALLOC(1, sizeof(gs_server_t));
01741     if(!server_list[nrows-1]) {
01742       ERRPRINTF("malloc error\n");
01743       FREE_TABLE(table);
01744       return -1;
01745     }
01746 
01747     server_list[nrows - 1]->hostname = strdup(table[i]);
01748     proxy_str_to_ip(&(server_list[nrows - 1]->ipaddress), table[i + 1]);
01749     server_list[nrows - 1]->port = atoi(table[i + 2]);
01750     proxy_str_to_ip(&(server_list[nrows - 1]->proxyip), table[i + 3]);
01751     server_list[nrows - 1]->proxyport = atoi(table[i + 4]);
01752     proxy_str_to_cid(server_list[nrows - 1]->componentid, table[i + 5]);
01753     server_list[nrows - 1]->arch = strdup(table[i + 6]);
01754     server_list[nrows - 1]->data_format = atoi(table[i + 7]);
01755     server_list[nrows - 1]->kflops = atoi(table[i + 8]);
01756     server_list[nrows - 1]->workload = atoi(table[i + 9]);
01757     server_list[nrows - 1]->ncpu = atoi(table[i + 10]);
01758     server_list[nrows - 1]->status = atoi(table[i + 11]);
01759     server_list[nrows - 1]->availcpu = atof(table[i + 12]);
01760     server_list[nrows - 1]->availmem = atof(table[i + 13]);
01761     server_list[nrows - 1]->nproblems = atoi(table[i + 14]);
01762     server_list[nrows - 1]->agenthost = strdup(table[i + 15]);
01763     server_list[nrows - 1]->agentport = atoi(table[i + 16]);
01764     server_list[nrows - 1]->smart = atoi(table[i + 17]);
01765     server_list[nrows - 1]->last_update = atoi(table[i + 18]);
01766   }
01767 
01768   FREE_TABLE(table);
01769 
01770   *servers = server_list;
01771   return *count;
01772 }
01773 
01781 int
01782 gs_get_all_smart_servers(gs_agent_t * gs_agent, gs_server_t *** servers, int *count)
01783 {
01784   int err, i, nrows, ncols, els;
01785   char *sql, *dbErrMsg = NULL, **table = NULL;
01786   gs_server_t **server_list;
01787 
01788   sql = sqlite3_mprintf("SELECT * FROM servers WHERE smart=\"1\";");
01789   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01790   if(err < 0) {
01791     if ( dbErrMsg != NULL )
01792     {
01793       ERRPRINTF("%s\n", dbErrMsg);
01794       sqlite3_free(dbErrMsg);
01795     }
01796     return -1;
01797   }
01798   sqlite3_free(sql);
01799   *count = nrows;
01800   server_list = (gs_server_t **) CALLOC(nrows, sizeof(gs_server_t *));
01801 
01802   if(server_list == NULL) {
01803     ERRPRINTF("malloc error\n");
01804     FREE_TABLE(table);
01805     return -1;
01806   }
01807 
01808   /* save number of table elements before nrows gets clobbered */
01809   els = (nrows+1)*ncols;
01810 
01811   for(; nrows > 0; nrows--) {
01812     i = nrows * ncols;
01813     server_list[nrows-1] = (gs_server_t *) CALLOC(1, sizeof(gs_server_t));
01814     if(!server_list[nrows-1]) {
01815       ERRPRINTF("malloc error\n");
01816       FREE_TABLE(table);
01817       return -1;
01818     }
01819 
01820     server_list[nrows - 1]->hostname = strdup(table[i]);
01821     proxy_str_to_ip(&(server_list[nrows - 1]->ipaddress), table[i + 1]);
01822     server_list[nrows - 1]->port = atoi(table[i + 2]);
01823     proxy_str_to_ip(&(server_list[nrows - 1]->proxyip), table[i + 3]);
01824     server_list[nrows - 1]->proxyport = atoi(table[i + 4]);
01825     proxy_str_to_cid(server_list[nrows - 1]->componentid, table[i + 5]);
01826     server_list[nrows - 1]->arch = strdup(table[i + 6]);
01827     server_list[nrows - 1]->data_format = atoi(table[i + 7]);
01828     server_list[nrows - 1]->kflops = atoi(table[i + 8]);
01829     server_list[nrows - 1]->workload = atoi(table[i + 9]);
01830     server_list[nrows - 1]->ncpu = atoi(table[i + 10]);
01831     server_list[nrows - 1]->status = atoi(table[i + 11]);
01832     server_list[nrows - 1]->availcpu = atof(table[i + 12]);
01833     server_list[nrows - 1]->availmem = atof(table[i + 13]);
01834     server_list[nrows - 1]->nproblems = atoi(table[i + 14]);
01835     server_list[nrows - 1]->agenthost = strdup(table[i + 15]);
01836     server_list[nrows - 1]->agentport = atoi(table[i + 16]);
01837     server_list[nrows - 1]->smart = atoi(table[i + 17]);
01838     server_list[nrows - 1]->last_update = atoi(table[i + 18]);
01839     /* skip 19 - addedat */
01840     /* skip 20 - infolist */
01841     server_list[nrows - 1]->my_ping_str = strdup(table[i + 21]);
01842   }
01843 
01844   FREE_TABLE(table);
01845 
01846   *servers = server_list;
01847   return *count;
01848 }
01849 
01857 int
01858 gs_get_all_servers(gs_agent_t * gs_agent, gs_server_t *** servers, int *count)
01859 {
01860   int err, i, nrows, ncols, els;
01861   char *sql, *dbErrMsg = NULL, **table = NULL;
01862   gs_server_t **server_list;
01863 
01864   sql = sqlite3_mprintf("SELECT * FROM servers WHERE 1;");
01865   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01866   if(err < 0) {
01867     if ( dbErrMsg != NULL )
01868     {
01869       ERRPRINTF("%s\n", dbErrMsg);
01870       sqlite3_free(dbErrMsg);
01871     }
01872     return -1;
01873   }
01874   sqlite3_free(sql);
01875   *count = nrows;
01876   server_list = (gs_server_t **) CALLOC(nrows, sizeof(gs_server_t *));
01877 
01878   if(server_list == NULL) {
01879     ERRPRINTF("malloc error\n");
01880     FREE_TABLE(table);
01881     return -1;
01882   }
01883 
01884   /* save number of table elements before nrows gets clobbered */
01885   els = (nrows+1)*ncols;
01886 
01887   for(; nrows > 0; nrows--) {
01888     i = nrows * ncols;
01889     server_list[nrows-1] = (gs_server_t *) CALLOC(1, sizeof(gs_server_t));
01890     if(!server_list[nrows-1]) {
01891       ERRPRINTF("malloc error\n");
01892       FREE_TABLE(table);
01893       return -1;
01894     }
01895 
01896     server_list[nrows - 1]->hostname = strdup(table[i]);
01897     proxy_str_to_ip(&(server_list[nrows - 1]->ipaddress), table[i + 1]);
01898     server_list[nrows - 1]->port = atoi(table[i + 2]);
01899     proxy_str_to_ip(&(server_list[nrows - 1]->proxyip), table[i + 3]);
01900     server_list[nrows - 1]->proxyport = atoi(table[i + 4]);
01901     proxy_str_to_cid(server_list[nrows - 1]->componentid, table[i + 5]);
01902     server_list[nrows - 1]->arch = strdup(table[i + 6]);
01903     server_list[nrows - 1]->data_format = atoi(table[i + 7]);
01904     server_list[nrows - 1]->kflops = atoi(table[i + 8]);
01905     server_list[nrows - 1]->workload = atoi(table[i + 9]);
01906     server_list[nrows - 1]->ncpu = atoi(table[i + 10]);
01907     server_list[nrows - 1]->status = atoi(table[i + 11]);
01908     server_list[nrows - 1]->availcpu = atof(table[i + 12]);
01909     server_list[nrows - 1]->availmem = atof(table[i + 13]);
01910     server_list[nrows - 1]->nproblems = atoi(table[i + 14]);
01911     server_list[nrows - 1]->agenthost = strdup(table[i + 15]);
01912     server_list[nrows - 1]->agentport = atoi(table[i + 16]);
01913     server_list[nrows - 1]->smart = atoi(table[i + 17]);
01914     server_list[nrows - 1]->last_update = atoi(table[i + 18]);
01915 #ifdef GS_SMART_GRIDSOLVE
01916    if(server_list[nrows - 1]->smart==1){
01917      server_list[nrows - 1]->my_ping_str = strdup(table[i + 21]);
01918    }
01919 #endif
01920   }
01921 
01922   FREE_TABLE(table);
01923 
01924   *servers = server_list;
01925   return *count;
01926 }
01927 
01937 int
01938 gs_get_problem_list(gs_agent_t * gs_agent, gs_server_t * gs_server,
01939                     gs_problem_t *** problems, int *count)
01940 {
01941   int els, err, i, nrows, ncols;
01942   char *sql, *dbErrMsg = NULL, **table = NULL, cid_string[2 * CID_LEN + 1];
01943   gs_problem_t **problem_list;
01944 
01945   proxy_cid_to_str(cid_string, gs_server->componentid);
01946   sql =
01947       sqlite3_mprintf
01948       ("SELECT problems.encoding FROM problem_server JOIN problems ON problem_server.problemname = problems.problemname WHERE componentid=%Q;",
01949        cid_string);
01950   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
01951   if(err < 0) {
01952     if ( dbErrMsg != NULL )
01953     {
01954       ERRPRINTF("%s\n", dbErrMsg);
01955       sqlite3_free(dbErrMsg);
01956     }
01957     return -1;
01958   }
01959   sqlite3_free(sql);
01960   *count = nrows;
01961 
01962   problem_list = (gs_problem_t **) CALLOC(nrows, sizeof(gs_problem_t *));
01963   if(problem_list == NULL) {
01964     ERRPRINTF("malloc error in gs_get_problem_list\n");
01965     FREE_TABLE(table);
01966     return -1;
01967   }
01968 
01969   /* save number of table elements before nrows gets clobbered */
01970   els = (nrows+1)*ncols;
01971 
01972   for(; nrows > 0; nrows--) {
01973     i = nrows * ncols;
01974     problem_list[nrows - 1] = (gs_problem_t *) CALLOC(1, sizeof(gs_problem_t));
01975     gs_decode_problem(table[i], problem_list[nrows - 1]);
01976   }
01977 
01978   FREE_TABLE(table);
01979 
01980   *problems = problem_list;
01981 
01982   return *count;
01983 }
01984 
01993 int
01994 gs_get_all_problems(gs_agent_t * gs_agent, gs_problem_t *** problems, int *count)
01995 {
01996   return gs_get_problem_info(gs_agent, problems, count, NULL);
01997 }
01998 
02009 int
02010 gs_get_problem_info(gs_agent_t * gs_agent, gs_problem_t *** problems, int *count,
02011   char *name)
02012 {
02013   int err, i, nrows, ncols, els;
02014   char *sql, *dbErrMsg = NULL, **table = NULL;
02015   gs_problem_t **problem_list;
02016 
02017   if(name)
02018     sql = sqlite3_mprintf("SELECT encoding FROM problems WHERE problemname=%Q;", name);
02019   else
02020     sql = sqlite3_mprintf("SELECT encoding FROM problems WHERE 1;");
02021 
02022   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
02023   if(err < 0) {
02024     if ( dbErrMsg != NULL )
02025     {
02026       ERRPRINTF("%s\n", dbErrMsg);
02027       sqlite3_free(dbErrMsg);
02028     }
02029     return -1;
02030   }
02031   sqlite3_free(sql);
02032   *count = nrows;
02033   problem_list = (gs_problem_t **) CALLOC(nrows, sizeof(gs_problem_t *));
02034   if(problem_list == NULL) {
02035     ERRPRINTF("malloc error in gs_get_problem_list\n");
02036     FREE_TABLE(table);
02037     return -1;
02038   }
02039 
02040   /* save number of table elements before nrows gets clobbered */
02041   els = (nrows+1)*ncols;
02042 
02043   for(; nrows > 0; nrows--) {
02044     i = nrows * ncols;
02045     problem_list[nrows - 1] = (gs_problem_t *) CALLOC(1, sizeof(gs_problem_t));
02046     gs_decode_problem(table[i], problem_list[nrows - 1]);
02047   }
02048 
02049   FREE_TABLE(table);
02050 
02051   *problems = problem_list;
02052 
02053   return *count;
02054 }
02055 
02066 int
02067 gs_create_criteria_table(char *name, char *description, char *firstValue)
02068 {
02069   char *sql, *dbErrMsg = NULL, **table = NULL;
02070   int err, nrows, ncols;
02071 
02072   if(gs_sqlite_begin_transaction() < 0)
02073     ERRPRINTF("Warning: table lock failed\n");
02074 
02075   /* 
02076    * Check if criteria is already in db
02077    */
02078   sql = sqlite3_mprintf("SELECT 1 FROM criteria WHERE critname = %Q;", name);
02079   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
02080   sqlite3_free(sql);
02081   if(err < 0) {
02082     if ( dbErrMsg != NULL )
02083     {
02084       ERRPRINTF("%s\n", dbErrMsg);
02085       sqlite3_free(dbErrMsg);
02086     }
02087     gs_sqlite_commit_transaction();
02088     return -1;
02089   }
02090 
02091   FREE_TABLE(table);
02092 
02093   if(nrows > 0) {
02094     gs_sqlite_commit_transaction();
02095     return 0;
02096   }
02097 
02098   /* 
02099    * Create table, if it's not already there.
02100    */
02101   if ( sqliteIsNumber(firstValue) )
02102   {
02103     sql =
02104       sqlite3_mprintf
02105       ("CREATE TABLE %s (value NUMERIC NOT NULL, componentid VARCHAR(128) NOT NULL, UNIQUE('componentid'));",
02106        name);
02107   } else
02108   {
02109     sql =
02110       sqlite3_mprintf
02111       ("CREATE TABLE %s (value VARCHAR(128) NOT NULL, componentid VARCHAR(128) NOT NULL, UNIQUE('componentid'));",
02112        name);
02113   }
02114   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
02115   sqlite3_free(sql);
02116   if(err < 0) {
02117     if ( dbErrMsg != NULL )
02118     {
02119       ERRPRINTF("%s\n", dbErrMsg);
02120       sqlite3_free(dbErrMsg);
02121     }
02122     gs_sqlite_commit_transaction();
02123     return -1;
02124   }
02125 
02126   sql =
02127     sqlite3_mprintf
02128     ("INSERT INTO criteria (critname,description) VALUES (%Q,%Q);", 
02129      name, description);
02130   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
02131   sqlite3_free(sql);
02132   if(err < 0) {
02133     if ( dbErrMsg != NULL )
02134     {
02135       ERRPRINTF("%s\n", dbErrMsg);
02136       sqlite3_free(dbErrMsg);
02137     }
02138     gs_sqlite_commit_transaction();
02139     return -1;
02140   }
02141 
02142   gs_sqlite_commit_transaction();
02143 
02144   return 0;
02145 }
02146 
02157 int 
02158 gs_get_server(gs_agent_t *gs_agent, char *name, gs_server_t *server) 
02159 {
02160   char *sql, *dbErrMsg = NULL, **table = NULL;
02161   int err, nrows, ncols, i;
02162 
02163   sql = sqlite3_mprintf("SELECT * FROM servers WHERE hostname=%Q LIMIT 1;",
02164       name);
02165   if ( sql == NULL )
02166   {
02167     return -1;
02168   }
02169   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
02170   sqlite3_free(sql);
02171   if ( err < 0 )
02172   {
02173     if ( dbErrMsg != NULL )
02174     {
02175       ERRPRINTF("Error from database: %s\n", dbErrMsg);
02176       sqlite3_free(dbErrMsg);
02177     }
02178     return -1;
02179   }
02180   if ( nrows == 0 )
02181   {
02182     return -1;
02183   }
02184 
02185   /* fill in structure */
02186   i = nrows * ncols;
02187   server->hostname = strdup(table[i]);
02188   proxy_str_to_ip(&(server->ipaddress), table[i + 1]);
02189   server->port = atoi(table[i + 2]);
02190   proxy_str_to_ip(&(server->proxyip), table[i + 3]);
02191   server->proxyport = atoi(table[i + 4]);
02192   proxy_str_to_cid(server->componentid, table[i + 5]);
02193   server->arch = strdup(table[i + 6]);
02194   server->data_format = atoi(table[i + 7]);
02195   server->kflops = atoi(table[i + 8]);
02196   server->workload = atoi(table[i + 9]);
02197   server->ncpu = atoi(table[i + 10]);
02198   server->status = atoi(table[i + 11]);
02199   server->availcpu = atof(table[i + 12]);
02200   server->availmem = atof(table[i + 13]);
02201   server->nproblems = atoi(table[i + 14]);
02202   server->agenthost = strdup(table[i + 15]);
02203   server->agentport = atoi(table[i + 16]);
02204   server->smart = atoi(table[i + 17]);
02205   server->last_update = atoi(table[i + 18]);
02206 
02207   /* 
02208    * fill in server attribuites
02209    */
02210   server->sa_list = NULL;
02211   gs_decode_infolist(table[i + 20], &(server->sa_list));
02212 
02213   FREE_TABLE(table);
02214 
02215   return 0;
02216 }
02217 
02230 int
02231 gs_get_all_servers_by_hostname(gs_agent_t * gs_agent, char *hostname,
02232   gs_server_t *** servers, int *count)
02233 {
02234   int err, i, nrows, ncols, els;
02235   char *sql, *dbErrMsg = NULL, **table = NULL;
02236   gs_server_t **server_list;
02237 
02238   *count = -1;
02239 
02240   sql = sqlite3_mprintf("SELECT * FROM servers WHERE hostname=%Q;", 
02241     hostname);
02242   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
02243   if(err < 0) {
02244     if ( dbErrMsg != NULL )
02245     {
02246       ERRPRINTF("%s\n", dbErrMsg);
02247       sqlite3_free(dbErrMsg);
02248     }
02249     return -1;
02250   }
02251   sqlite3_free(sql);
02252   *count = nrows;
02253   server_list = (gs_server_t **) CALLOC(nrows, sizeof(gs_server_t *));
02254 
02255   if(server_list == NULL) {
02256     ERRPRINTF("malloc error\n");
02257     FREE_TABLE(table);
02258     return -1;
02259   }
02260 
02261   /* save number of table elements before nrows gets clobbered */
02262   els = (nrows+1)*ncols;
02263 
02264   for(; nrows > 0; nrows--) {
02265     i = nrows * ncols;
02266     server_list[nrows-1] = (gs_server_t *) CALLOC(1, sizeof(gs_server_t));
02267     if(!server_list[nrows-1]) {
02268       ERRPRINTF("malloc error\n");
02269       FREE_TABLE(table);
02270       return -1;
02271     }
02272 
02273     server_list[nrows - 1]->hostname = strdup(table[i]);
02274     proxy_str_to_ip(&(server_list[nrows - 1]->ipaddress), table[i + 1]);
02275     server_list[nrows - 1]->port = atoi(table[i + 2]);
02276     proxy_str_to_ip(&(server_list[nrows - 1]->proxyip), table[i + 3]);
02277     server_list[nrows - 1]->proxyport = atoi(table[i + 4]);
02278     proxy_str_to_cid(server_list[nrows - 1]->componentid, table[i + 5]);
02279     server_list[nrows - 1]->arch = strdup(table[i + 6]);
02280     server_list[nrows - 1]->data_format = atoi(table[i + 7]);
02281     server_list[nrows - 1]->kflops = atoi(table[i + 8]);
02282     server_list[nrows - 1]->workload = atoi(table[i + 9]);
02283     server_list[nrows - 1]->ncpu = atoi(table[i + 10]);
02284     server_list[nrows - 1]->status = atoi(table[i + 11]);
02285     server_list[nrows - 1]->availcpu = atof(table[i + 12]);
02286     server_list[nrows - 1]->availmem = atof(table[i + 13]);
02287     server_list[nrows - 1]->nproblems = atoi(table[i + 14]);
02288     server_list[nrows - 1]->agenthost = strdup(table[i + 15]);
02289     server_list[nrows - 1]->agentport = atoi(table[i + 16]);
02290     server_list[nrows - 1]->last_update = atol(table[i + 17]);
02291   }
02292 
02293   FREE_TABLE(table);
02294 
02295   *servers = server_list;
02296   return *count;
02297 }
02298 
02308 int
02309 gs_get_task_by_agent_taskid(int agent_taskid, gs_htm_task *task)
02310 {
02311   char *sql, *dbErrMsg = NULL, **table = NULL;
02312   int err, nrows, ncols, i;
02313 
02314   sql = sqlite3_mprintf("SELECT * FROM tasks WHERE t_agent_taskid=\"%d\" LIMIT 1;", 
02315     agent_taskid);
02316 
02317   if ( sql == NULL ) {
02318     return -1;
02319   }
02320 
02321   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
02322   sqlite3_free(sql);
02323   if ( err < 0 ) {
02324     if ( dbErrMsg != NULL ) {
02325       ERRPRINTF("Error from database: %s\n", dbErrMsg);
02326       sqlite3_free(dbErrMsg);
02327     }
02328     return -1;
02329   }
02330 
02331   if ( nrows == 0 ) {
02332     return -1;
02333   }
02334 
02335   /* fill in structure */
02336   i = nrows * ncols;
02337 
02338   strcpy(task->id, table[i+1]);
02339   task->agent_taskid = atof(table[i+2]);
02340   task->start = atof(table[i+3]);
02341   task->duration = atof(table[i+4]);
02342   task->remaining = atof(table[i+5]);
02343   task->end = atof(table[i+6]);
02344   task->active = atoi(table[i+7]);
02345   task->finished = atoi(table[i+8]);
02346   task->next = NULL;
02347 
02348   FREE_TABLE(table);
02349 
02350   return 0;
02351 }
02352 
02363 int 
02364 gs_get_server_by_cid(gs_agent_t * gs_agent, char *cid, gs_server_t *server) 
02365 {
02366   char *sql, *dbErrMsg = NULL, **table = NULL;
02367   int err, nrows, ncols, i;
02368 
02369   sql = sqlite3_mprintf("SELECT * FROM servers WHERE componentid=%Q LIMIT 1;",
02370       cid);
02371   if ( sql == NULL )
02372   {
02373     return -1;
02374   }
02375   err = gs_sqlite_submit_query(sql, &table, &nrows, &ncols, &dbErrMsg);
02376   sqlite3_free(sql);
02377   if ( err < 0 )
02378   {
02379     if ( dbErrMsg != NULL )
02380     {
02381       DBGPRINTF("Error from database: %s\n", dbErrMsg);
02382       sqlite3_free(dbErrMsg);
02383     }
02384     return -1;
02385   }
02386   if ( nrows == 0 )
02387   {
02388     return -1;
02389   }
02390   /* fill in structure */
02391   i = nrows * ncols;
02392   server->hostname = strdup(table[i]);
02393   proxy_str_to_ip(&(server->ipaddress), table[i + 1]);
02394   server->port = atoi(table[i + 2]);
02395   proxy_str_to_ip(&(server->proxyip), table[i + 3]);
02396   server->proxyport = atoi(table[i + 4]);
02397   proxy_str_to_cid(server->componentid, table[i + 5]);
02398   server->arch = strdup(table[i + 6]);
02399   server->data_format = atoi(table[i + 7]);
02400   server->kflops = atoi(table[i + 8]);
02401   server->workload = atoi(table[i + 9]);
02402   server->ncpu = atoi(table[i + 10]);
02403   server->status = atoi(table[i + 11]);
02404   server->availcpu = atof(table[i + 12]);
02405   server->availmem = atof(table[i + 13]);
02406   server->nproblems = atoi(table[i + 14]);
02407   server->agenthost = strdup(table[i + 15]);
02408   server->agentport = atoi(table[i + 16]);
02409   server->smart = atoi(table[i + 17]);
02410   server->last_update = atoi(table[i + 18]);
02411 
02412   /* 
02413    * fill in server attribuites
02414    */
02415   server->sa_list = NULL;
02416   gs_decode_infolist(table[i + 20], &(server->sa_list));
02417 
02418   FREE_TABLE(table);
02419 
02420   return 0;
02421 }