netsolveclient.c

Go to the documentation of this file.
00001 
00007 /* $Id: netsolveclient.c,v 1.37 2008/05/01 15:03:30 yarkhan Exp $ */
00008 /* $UTK_Copyright: $ */
00009 
00010 #ifdef HAVE_CONFIG_H
00011 #include "config.h"
00012 #endif /* HAVE_CONFIG_H */
00013 
00014 #include "grpc.h"
00015 #include "netsolveclient.h"
00016 #include "utility.h"
00017 
00018 /* va_copy is not portable.  GNU suggests the following work-around
00019  * -JL 10/13/2004
00020  */
00021 #if ! defined va_copy
00022 #if defined __va_copy
00023 #define va_copy __va_copy
00024 #else
00025 #define va_copy(dst, src) memcpy (&dst, &src, sizeof(va_list))
00026 #endif
00027 #endif
00028 
00029 int ns_errno = NetSolveOK;
00030 
00031 static int ns_initialized = FALSE;
00032 static char *ns_criteria = NULL;
00033 NS_profile *ns_profile = NULL;
00034 
00035 extern grpc_error_t grpc_errno;
00036 
00037 int netslX(char *, va_list, int, int, int);
00038 
00042 int grpc_error_mapping[] = {
00043   NetSolveOK,
00044   NetSolveInternalError,
00045   NetSolveFileError,
00046   NetSolveFileError,
00047   NetSolveNoServer,
00048   NetSolveUnknownProblem,
00049   NetSolveUnknownProblem,
00050   NetSolveInvalidRequestID,
00051   NetSolveConnectionRefused,
00052   NetSolveNetworkError,
00053   NetSolveServerError,
00054   NetSolveNotReady,
00055   NetSolveNotReady,
00056   NetSolveInternalError,
00057   NetSolveInternalError,
00058   NetSolveInternalError
00059 };
00060 
00071 int
00072 netslset_criteria_file(char *criteria_file)
00073 {
00074   gs_info_t *ca_list, *tmp;
00075 
00076   if(!criteria_file) {
00077     ns_errno = NetSolveSystemError;
00078     return ns_errno;
00079   }
00080 
00081   /* free previous criteria */
00082   if(ns_criteria) free(ns_criteria);
00083 
00084   gs_parse_config_file(criteria_file, &ca_list);
00085   for(tmp = ca_list; tmp != NULL; tmp = tmp->next) {
00086     if(!strcasecmp(tmp->type, "criteria")) {
00087 
00088       ns_criteria = strdup(tmp->value);
00089 
00090       if(!ns_criteria) {
00091         gs_free_infolist(ca_list);
00092         ns_errno = NetSolveSystemError;
00093         return ns_errno;
00094       }
00095 
00096       gs_free_infolist(ca_list);
00097       return NetSolveOK;
00098     }
00099   }
00100 
00101   gs_free_infolist(ca_list);
00102   return NetSolveOK;
00103 }
00104 
00113 int 
00114 netsl_profile(NS_profile *prof)
00115 {
00116 #ifdef NS_PROFILING
00117   ns_profile = prof;
00118   return 0;
00119 #else
00120 
00121 #ifdef DEBUG
00122   fprintf(STDERR"Warning: netsl_profile() -- profiling not enabled.\n");
00123 #endif
00124 
00125   return -1;
00126 #endif
00127 }
00128 
00139 int
00140 netslset_criteria(char *criteria)
00141 {
00142   /* free previous criteria */
00143   if(ns_criteria) free(ns_criteria);
00144 
00145   if(!criteria) {
00146     ns_criteria = NULL;
00147     return NetSolveOK;
00148   }
00149     
00150   ns_criteria = strdup(criteria);
00151 
00152   if(!ns_criteria) {
00153     ns_errno = NetSolveSystemError;
00154     return ns_errno;
00155   }
00156 
00157   return NetSolveOK;
00158 }
00159 
00174 int
00175 netslinit(char *agent)
00176 {
00177   grpc_error_t rv;
00178 
00179   /* Get the agent name */
00180   if(agent == NULL) {           
00181     /* Get it from the environment.  Use GRIDSOLVE_AGENT first
00182      * if specified.  Otherwise, fall back on NETSOLVE_AGENT.
00183      */
00184 
00185     agent = getenv("GRIDSOLVE_AGENT");
00186     if(!agent) {
00187       agent = getenv("NETSOLVE_AGENT");
00188       if(!agent) {
00189         ns_errno = NetSolveSetNetSolveAgent;
00190         return ns_errno;
00191       }
00192     }
00193   }
00194 
00195   if(!getenv("GRIDSOLVE_AGENT")) {
00196     char *agent_env;
00197 
00198     /* store the user supplied agent name in the environment so that it'll be 
00199        available to the gridrpc client. */
00200 
00201     agent_env = dstring_sprintf("GRIDSOLVE_AGENT=%s", agent);
00202 
00203     if(!agent_env) {
00204       ns_errno = NetSolveSystemError;
00205       return ns_errno;
00206     }
00207 
00208     if(putenv(agent_env)) {
00209       ns_errno = NetSolveSystemError;
00210       return ns_errno;
00211     }
00212   }
00213 
00214   rv = grpc_initialize(NULL);
00215 
00216   if((rv != GRPC_NO_ERROR) && (rv != GRPC_ALREADY_INITIALIZED)) {
00217     ns_errno = grpc_error_mapping[grpc_errno];
00218     return ns_errno;
00219   }
00220 
00221   ns_initialized = TRUE;
00222 
00223   return NetSolveOK;
00224 }
00225 
00238 int
00239 netsl(char *nickname, ...)
00240 {
00241   va_list argptr;
00242 
00243   va_start(argptr, nickname);
00244 
00245   grpc_set_default_major("ROW");
00246 
00247   return netslX(nickname, argptr, GS_CALL_FROM_C, NS_BLOCK, NS_NOASSIGNMENT);
00248 }
00249 
00263 int
00264 netslnb(char *nickname, ...)
00265 {
00266   va_list argptr;
00267 
00268   va_start(argptr, nickname);
00269 
00270   grpc_set_default_major("ROW");
00271 
00272   return netslX(nickname, argptr, GS_CALL_FROM_C, NS_NOBLOCK,
00273                 NS_NOASSIGNMENT);
00274 }
00275 
00297 int
00298 netslX(char *nickname, va_list argptr, int lang, int blocking, int assign)
00299 {
00300   grpc_function_handle_t *handle;
00301   gs_va_list argstruct;
00302   char *grpc_name;
00303   grpc_error_t rv;
00304   int namelen;
00305 
00306   if(!nickname) {
00307     ns_errno = NetSolveBadProblemName;
00308     return ns_errno;
00309   }
00310 
00311   handle = (grpc_function_handle_t *) malloc(sizeof(grpc_function_handle_t));
00312   if(!handle) {
00313     ns_errno = NetSolveSystemError;
00314     return ns_errno;
00315   }
00316 
00317   if(!ns_initialized)
00318     if(netslinit(NULL) != NetSolveOK) {
00319       free(handle);
00320       return ns_errno;
00321     }
00322 
00323   if(grpc_set_client_language(lang) != GRPC_NO_ERROR) {
00324     ns_errno = NetSolveSystemError;
00325     free(handle);
00326     return ns_errno;
00327   }
00328 
00329   /* since name must end with "()" it cannot be less than 3 chars long */
00330   namelen = strlen(nickname);
00331   if(namelen < 3) {
00332     ns_errno = NetSolveBadProblemName;
00333     free(handle);
00334     return ns_errno;
00335   }
00336 
00337   /* now check that the "()" is actually there */
00338   if((nickname[namelen - 2] != '(') || (nickname[namelen - 1] != ')')) {
00339     ns_errno = NetSolveBadProblemName;
00340     free(handle);
00341     return ns_errno;
00342   }
00343 
00344   grpc_name = strdup(nickname);
00345   if(!grpc_name) {
00346     ns_errno = NetSolveSystemError;
00347     free(handle);
00348     return ns_errno;
00349   }
00350   grpc_name[namelen - 2] = '\0';
00351 
00352   if(assign == NS_ASSIGNMENT) {
00353     char *assigned_name, *host_part, *func_part;
00354 
00355     assigned_name = strdup(grpc_name);
00356     if(!assigned_name) {
00357       free(grpc_name);
00358       free(handle);
00359       ns_errno = NetSolveSystemError;
00360       return ns_errno;
00361     }
00362 
00363     host_part = strtok(assigned_name, ":");
00364     func_part = strtok(NULL, ":");
00365 
00366     if(!host_part || !func_part) {
00367       free(handle);
00368       free(grpc_name);
00369       free(assigned_name);
00370       ns_errno = NetSolveBadProblemName;
00371       return ns_errno;
00372     }
00373 
00374     if(grpc_function_handle_init(handle, host_part, func_part) != GRPC_NO_ERROR) {
00375       free(handle);
00376       free(grpc_name);
00377       free(assigned_name);
00378       ns_errno = NetSolveUnknownProblem;
00379       return ns_errno;
00380     }
00381 
00382     free(assigned_name);
00383   }
00384   else {
00385     /* Using the ns extension of grpc_function_handle_default_ns, we delay
00386      * the actual communication to the agent till the grpc_call. This allows
00387      * the scheduling (assignment of servers) to be delayed till the client
00388      * call parameters (N=1000 etc) are known, so these parameters can be
00389      * used in the scheduling.
00390      */
00391     if(grpc_function_handle_default_ns(handle, grpc_name) != GRPC_NO_ERROR) {
00392       free(handle);
00393       free(grpc_name);
00394       ns_errno = NetSolveUnknownProblem;
00395       return ns_errno;
00396     }
00397   }
00398 
00399   free(grpc_name);
00400 
00401   grpc_set_criteria(handle, ns_criteria);
00402 
00403 #ifdef NS_PROFILING
00404   if(ns_profile)
00405     grpc_profile(ns_profile);
00406 #endif
00407 
00408   va_copy(argstruct.args, argptr);
00409 
00410   if(blocking == NS_BLOCK) {
00411     rv = grpc_call_valist_ft(handle, &argstruct);
00412     grpc_function_handle_destruct(handle);
00413     free(handle);
00414 
00415     ns_errno = (rv == GRPC_NO_ERROR) ? NetSolveOK : grpc_error_mapping[rv];
00416   }
00417   else {
00418     grpc_sessionid_t reqid;
00419 
00420     rv = grpc_call_valist_async_ft(handle, &reqid, &argstruct);
00421 
00422     if(rv != GRPC_NO_ERROR) {
00423       grpc_function_handle_destruct(handle);
00424       free(handle);
00425     }
00426 
00427     ns_errno = (rv != GRPC_NO_ERROR) ? grpc_error_mapping[rv] : reqid;
00428   }
00429 
00430   return ns_errno;
00431 }
00432 
00443 int
00444 netslmajor(char *maj)
00445 {
00446   if(!ns_initialized)
00447     if(netslinit(NULL) != NetSolveOK)
00448       return ns_errno;
00449 
00450   if(grpc_set_client_major(maj) != GRPC_NO_ERROR) {
00451     ns_errno = NetSolveInvalidMajor;
00452     return -1;
00453   }
00454   ns_errno = NetSolveOK;
00455   return 1;
00456 }
00457 
00468 int
00469 netslwt(int request_id)
00470 {
00471   grpc_function_handle_t *handle;
00472 
00473   if(grpc_get_handle(&handle, request_id) != GRPC_NO_ERROR) {
00474     ns_errno = NetSolveInvalidRequestID;
00475     return ns_errno;
00476   }
00477 
00478   if(grpc_wait_ft(request_id) != GRPC_NO_ERROR) {
00479     if(grpc_errno == GRPC_NOT_INITIALIZED)
00480       ns_errno = NetSolveInvalidRequestID;
00481     else
00482       ns_errno = grpc_error_mapping[grpc_errno];
00483   }
00484   else
00485     ns_errno = NetSolveOK;
00486 
00487   if(handle) {
00488     grpc_function_handle_destruct(handle);
00489     free(handle);
00490   }
00491 
00492   return ns_errno;
00493 }
00494 
00506 int
00507 netslpr(int request_id)
00508 {
00509   if(grpc_probe_ft(request_id) == GRPC_NO_ERROR)
00510     ns_errno = NetSolveOK;
00511   else
00512     ns_errno = NetSolveNotReady;
00513 
00514   return ns_errno;
00515 }
00516 
00528 int
00529 netslkill(int request_id)
00530 {
00531   grpc_function_handle_t *handle;
00532 
00533   if(grpc_get_handle(&handle, request_id) != GRPC_NO_ERROR) {
00534     ns_errno = NetSolveInvalidRequestID;
00535     return ns_errno;
00536   }
00537 
00538   if(grpc_cancel(request_id) != GRPC_NO_ERROR) {
00539     if(grpc_errno == GRPC_NOT_INITIALIZED)
00540       ns_errno = NetSolveInvalidRequestID;
00541     else
00542       ns_errno = grpc_error_mapping[grpc_errno];
00543   }
00544   else
00545     ns_errno = NetSolveOK;
00546 
00547   if(handle) {
00548     grpc_function_handle_destruct(handle);
00549     free(handle);
00550   }
00551 
00552   return ns_errno;
00553 }
00554 
00562 void
00563 netslerr(int status)
00564 {
00565   fprintf(stderr, "NS:%s\n", netsolveErrorMessage(status));
00566 }
00567 
00582 int
00583 netsl_assignment(char *nickname, ...)
00584 {
00585   va_list argptr;
00586 
00587   va_start(argptr, nickname);
00588 
00589   grpc_set_default_major("ROW");
00590 
00591   return netslX(nickname, argptr, GS_CALL_FROM_C, NS_BLOCK, NS_ASSIGNMENT);
00592 }
00593 
00608 int
00609 netslnb_assignment(char *nickname, ...)
00610 {
00611   va_list argptr;
00612 
00613   va_start(argptr, nickname);
00614 
00615   grpc_set_default_major("ROW");
00616 
00617   return netslX(nickname, argptr, GS_CALL_FROM_C, NS_NOBLOCK, NS_ASSIGNMENT);
00618 }
00619 
00629 char *
00630 netsolveErrorMessage(int e)
00631 {
00632   switch (e) {
00633     case NetSolveBadIterationRange:
00634       return (" Invalid iteration range");
00635       break;
00636     case NetSolveCannotContactAgent:
00637       return (" Cannot contact agent");
00638       break;
00639     case NetSolveProxyError:
00640       return (" Error while talking to proxy");
00641       break;
00642     case NetSolveUnknownServer:
00643       return (" Unknown server");
00644       break;
00645     case NetSolveCannotStartProxy:
00646       return (" Cannot start proxy");
00647       break;
00648     case NetSolveFarmingError:
00649       return (" One or more requests failed");
00650       break;
00651     case NetSolveOK:
00652       return (" no error");
00653       break;
00654     case NetSolveCondorError:
00655       return (" Condor error");
00656       break;
00657     case NetSolveConnectionRefused:
00658       return (" connection refused");
00659       break;
00660     case NetSolveUPFUnsafe:
00661       return (" UPF security violation");
00662       break;
00663     case NetSolveServerError:
00664       return (" server error");
00665       break;
00666     case NetSolveUPFError:
00667       return (" impossible to compile UPF");
00668       break;
00669     case NetSolveCannotBind:
00670       return (" impossible to bind to port");
00671       break;
00672     case NetSolveSystemError:
00673       return (" system error");
00674       break;
00675     case NetSolveUnknownError:
00676       return (" unknown error");
00677       break;
00678     case NetSolveSetNetSolveArch:
00679       return (" GRIDSOLVE_ARCH not set");
00680       break;
00681     case NetSolveSetNetSolveAgent:
00682       return (" GRIDSOLVE_AGENT not set");
00683       break;
00684     case NetSolveSetNetSolveRoot:
00685       return (" GRIDSOLVE_ROOT not set");
00686     case NetSolveInternalError:
00687       return (" internal error");
00688       break;
00689     case NetSolveMismatch:
00690       return (" inconsistent object transfers");
00691       break;
00692     case NetSolveUnknownHost:
00693       return (" Unknown host");
00694       break;
00695     case NetSolveInvalidUPFFilename:
00696       return (" invalid upf filename");
00697       break;
00698     case NetSolveNetworkError:
00699       return (" network error");
00700       break;
00701     case NetSolveUnknownProblem:
00702       return (" unknown problem (Is GRIDSOLVE_AGENT set?)");
00703       break;
00704     case NetSolveProtocolError:
00705       return (" protocol error");
00706       break;
00707     case NetSolveNoServer:
00708       return (" no available server");
00709       break;
00710     case NetSolveBadProblemSpecification:
00711       return (" bad problem input/output");
00712       break;
00713     case NetSolveNotAllowed:
00714       return (" not allowed");
00715       break;
00716     case NetSolveBadValues:
00717       return (" bad input values");
00718       break;
00719     case NetSolveDimensionMismatch:
00720       return (" dimension mismatch");
00721       break;
00722     case NetSolveNoSolution:
00723       return (" no solution");
00724       break;
00725     case NetSolveNotReady:
00726       return (" not ready");
00727       break;
00728     case NetSolveInvalidRequestID:
00729       return (" invalid request ID");
00730       break;
00731     case NetSolveBadProblemName:
00732       return (" invalid problem name");
00733       break;
00734     case NetSolveInvalidMajor:
00735       return (" invalid major specification");
00736       break;
00737     case NetSolveTooManyPendingRequests:
00738       return (" too many pending requests");
00739       break;
00740     case NetSolveFileError:
00741       return (" file I/O error");
00742       break;
00743     case NetSolveUnknownDataFormat:
00744       return (" unknown machine type");
00745       break;
00746     case NetSolveTimedOut:
00747       return (" operation timed out");
00748       break;
00749     case NetSolveUnknownDsiFile:
00750       return (" DSI file not found");
00751       break;
00752     case NetSolveIBPAllocateError:
00753       return (" error in IBP_Allocate");
00754       break;
00755     case NetSolveIBPManageError:
00756       return (" error in IBP_Manage");
00757       break;
00758     case NetSolveIBPLoadError:
00759       return (" error in IBP_Load");
00760       break;
00761     case NetSolveIBPStoreError:
00762       return (" error in IBP_Store");
00763       break;
00764     case NetSolveDsiEACCESS:
00765       return (" permission denied to DSI file");
00766       break;
00767     case NetSolveDsiDisabled:
00768       return (" NetSolve not configured with DSI");
00769       break;
00770     case NetSolveAuthenticationError:
00771       return (" Authentication to server failed");
00772       break;
00773     case NetSolveUnknownHandle:
00774       return (" Handle not found ");
00775       break;
00776     default:
00777       return (" unknown error");
00778       break;
00779   }
00780 }
00781 
00782 
00783 /*
00784  * netsl_farm() : vararg C Farming interface
00785  *
00786  * netsl_farm("i=1,200","problem_name",....)
00787  *
00788  *  We assume : start < end and step=+1
00789  */
00790 
00791 int* netsl_farm(char *iteration,...)
00792 {
00793   va_list argptr;
00794   int start,end;
00795   char *buf;
00796   int i, len; 
00797   int *returned_value; 
00798   grpc_error_t rv;
00799 
00800   buf = strdup(iteration); 
00801 
00802   /* get the <start> end the <end> */
00803   if (sscanf(buf,"i=%d,%d",&start,&end) != 2)
00804   {
00805     free(buf);
00806     returned_value = (int *)calloc(1,sizeof(int));
00807     returned_value[0] =  -1;
00808     return returned_value;
00809   }
00810   free(buf); 
00811   
00812   /* Getting the iteration */
00813   va_start(argptr,iteration); 
00814 
00815   /* Get the problem name */
00816   buf = strdup((char*)va_arg(argptr, void*));
00817 
00818   /* Stripping off the parenthesis */
00819   len = strlen(buf);
00820   if (buf[len-2] != '(')
00821   {
00822     free(buf);
00823     returned_value = (int *)calloc(1,sizeof(int));
00824     returned_value[0] = -1;
00825     return returned_value;
00826   }
00827 
00828   if (buf[len-1] != ')')
00829   {
00830     free(buf);
00831     returned_value = (int *)calloc(1,sizeof(int));
00832     returned_value[0] = -1;
00833     return returned_value;
00834   }
00835   buf[len-2] = '\0'; 
00836 
00837    /* Initializing grpc    */
00838   rv = grpc_initialize(NULL);
00839 
00840   if((rv != GRPC_NO_ERROR) && (rv != GRPC_ALREADY_INITIALIZED)) {
00841     returned_value = (int *)calloc(1,sizeof(int));
00842     returned_value[0] = -1;
00843     return returned_value;
00844   }
00845 
00846   /* Initializing the major    */
00847   if(grpc_set_client_major("Row") != GRPC_NO_ERROR){
00848     returned_value = (int *)calloc(1,sizeof(int));
00849     returned_value[0] = -1;
00850     return returned_value;
00851   }
00852 
00853   returned_value = grpc_farming(start,end,buf,argptr);
00854 
00855   if(returned_value[0] != GRPC_NO_ERROR) {
00856     returned_value[0] = -1;
00857     for(i=1; i < (end - start + 1); i++)
00858       returned_value[i] = grpc_error_mapping[returned_value[i]];
00859   }
00860 
00861   return returned_value;  
00862 }
00863 
00864 NS_Iterator*
00865 ns_int(char *s){
00866   return grpc_int(s);
00867 }
00868 
00869 
00870 NS_Iterator*
00871 ns_int_array(int *array,char *expression){
00872  return grpc_int_array(array,expression);
00873 }
00874 
00875 NS_Iterator*
00876 ns_ptr_array(void **array,char* expression) {
00877   return grpc_ptr_array(array,expression);
00878 }