From 85e62bb5c344cd04325e9ec1791860a8887a5744 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Posp=C3=AD=C5=A1il?= Date: Sun, 3 Sep 2006 16:21:20 +0000 Subject: [PATCH] - bug#19533 - cleanup --- org.glite.lb.server/src/jobstat_supp.c | 28 +- org.glite.lb.server/src/lb_plugin.c | 469 +++++++++++++++++++-------------- 2 files changed, 297 insertions(+), 200 deletions(-) diff --git a/org.glite.lb.server/src/jobstat_supp.c b/org.glite.lb.server/src/jobstat_supp.c index 54351ac..2261dcf 100644 --- a/org.glite.lb.server/src/jobstat_supp.c +++ b/org.glite.lb.server/src/jobstat_supp.c @@ -17,8 +17,8 @@ #include "store.h" #include "index.h" -#include "jobstat.h" #include "lbs_db.h" +#include "jobstat.h" #include "get_events.h" @@ -760,8 +760,8 @@ int edg_wll_compare_seq(const char *a, const char *b) static int compare_events_by_seq(const void *a, const void *b) { - const edg_wll_Event *e = (edg_wll_Event *)a; - const edg_wll_Event *f = (edg_wll_Event *)b; + const edg_wll_Event *e = (edg_wll_Event *) a; + const edg_wll_Event *f = (edg_wll_Event *) b; int ret; ret = edg_wll_compare_seq(e->any.seqcode, f->any.seqcode); @@ -774,13 +774,33 @@ static int compare_events_by_seq(const void *a, const void *b) return 0; } +static int compare_pevents_by_seq(const void *a, const void *b) +{ + const edg_wll_Event **e = (edg_wll_Event **) a; + const edg_wll_Event **f = (edg_wll_Event **) b; + return compare_events_by_seq(*e,*f); +} + void edg_wll_SortEvents(edg_wll_Event *e) { int n; if (!e) return; for (n=0; e[n].type; n++); - qsort(e,n,sizeof *e,compare_events_by_seq); + qsort(e,n,sizeof(*e),compare_events_by_seq); +} + +void edg_wll_SortPEvents(edg_wll_Event **e) +{ + edg_wll_Event **p; + int n; + + if (!e) return; + p = e; + for (n=0; *p; n++) { + p++; + } + qsort(e,n,sizeof(*e),compare_pevents_by_seq); } diff --git a/org.glite.lb.server/src/lb_plugin.c b/org.glite.lb.server/src/lb_plugin.c index b98f706..106554e 100644 --- a/org.glite.lb.server/src/lb_plugin.c +++ b/org.glite.lb.server/src/lb_plugin.c @@ -11,13 +11,12 @@ #include "glite/lb/context.h" #include "glite/lb/jobstat.h" - #include "glite/lb/events.h" #include "glite/lb/events_parse.h" - #include "glite/lb/trio.h" #include "jobstat.h" +#include "get_events.h" #include "glite/jp/types.h" #include "glite/jp/context.h" @@ -29,29 +28,36 @@ #include "jp_job_attrs.h" #define INITIAL_NUMBER_EVENTS 100 +#define INITIAL_NUMBER_STATES EDG_WLL_NUMBER_OF_STATCODES #define LB_PLUGIN_NAMESPACE "urn:org.glite.lb" typedef struct _lb_buffer_t { - char *buf; - size_t pos, size; - off_t offset; + char *buf; + size_t pos, size; + off_t offset; } lb_buffer_t; +typedef struct _lb_historyStatus { + edg_wll_JobStatCode state; + struct timeval timestamp; + char *reason; +} lb_historyStatus; + typedef struct _lb_handle { - edg_wll_Event **events; - edg_wll_JobStat status; + edg_wll_Event **events; + edg_wll_JobStat status; + lb_historyStatus **fullStatusHistory, **lastStatusHistory; } lb_handle; #define check_strdup(s) ((s) ? strdup(s) : NULL) extern int processEvent(intJobStat *, edg_wll_Event *, int, int, char **); -static int lb_query(void *fpctx,void *handle,const char * attr,glite_jp_attrval_t **attrval); -static int lb_open(void *,void *, const char *uri, void **); -static int lb_close(void *,void *); -static int lb_status(edg_wll_Event **event, edg_wll_JobStat *status); -static int read_line(glite_jp_context_t ctx, void *handle, lb_buffer_t *buffer, char **line); - +static int lb_query(void *fpctx, void *handle, const char *attr, glite_jp_attrval_t **attrval); +static int lb_open(void *fpctx, void *bhandle, const char *uri, void **handle); +static int lb_close(void *fpctx, void *handle); +static int lb_status(void *handle); +static int read_line(glite_jp_context_t ctx, void *handle, lb_buffer_t *buffer, char **line); static int lb_dummy(void *fpctx, void *handle, int oper, ...) { puts("lb_dummy() - generic call not used; for testing purposes only..."); @@ -133,7 +139,7 @@ static int lb_open(void *fpctx, void *bhandle, const char *uri, void **handle) { h->events = realloc(h->events, maxnevents * sizeof(edg_wll_Event *)); } if ((retval = edg_wll_ParseEvent(context, line, &h->events[nevents])) != 0) { - char *ed; + char *ed; free(line); err.code = retval; edg_wll_Error(context,NULL,&ed); @@ -152,7 +158,6 @@ static int lb_open(void *fpctx, void *bhandle, const char *uri, void **handle) { err.desc = "reading LB logline"; err.source = "lb_plugin.c:read_line()"; glite_jp_stack_error(ctx,&err); - goto fail; } } @@ -171,8 +176,8 @@ static int lb_open(void *fpctx, void *bhandle, const char *uri, void **handle) { fprintf(stderr,"lb_plugin: opened %d events\n", nevents); #endif - /* count state of job given by loaded events */ - if ((retval = lb_status(h->events, &(h->status))) != 0) goto fail; + /* count state and status hiftory of the job given by the loaded events */ + if ((retval = lb_status(h)) != 0) goto fail; *handle = (void *)h; @@ -216,6 +221,15 @@ static int lb_close(void *fpctx,void *handle) { if (h->status.state != EDG_WLL_JOB_UNDEF) edg_wll_FreeStatus(&h->status); + if (h->fullStatusHistory) { + i = 0; + while (h->fullStatusHistory[i]) { + if (h->fullStatusHistory[i]->reason) free(h->fullStatusHistory[i]->reason); + free (h->fullStatusHistory[i]); + i++; + } + } + free(h); #ifdef PLUGIN_DEBUG @@ -238,151 +252,149 @@ static int lb_query(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t memset(&err,0,sizeof err); err.source = __FUNCTION__; + if ((h->events == NULL) || + (h->status.state == EDG_WLL_JOB_UNDEF) || + (h->fullStatusHistory == NULL) ) { + *attrval = NULL; + err.code = ENOENT; + trio_asprintf(&err.desc,"There is no job information to query."); + return glite_jp_stack_error(ctx,&err); + } + if (strcmp(attr, GLITE_JP_LB_user) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = check_strdup(h->status.owner); - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; + if (h->status.owner) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = strdup(h->status.owner); + av[0].size = -1; + av[0].timestamp = h->status.lastUpdateTime.tv_sec; + } } else if (strcmp(attr, GLITE_JP_LB_jobId) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = edg_wlc_JobIdUnparse(h->status.jobId); - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; - } else if (strcmp(attr, GLITE_JP_LB_parent) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = edg_wlc_JobIdUnparse(h->status.parent_job); - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; + if (h->status.jobId) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = edg_wlc_JobIdUnparse(h->status.jobId); + av[0].size = -1; + av[0].timestamp = h->status.lastUpdateTime.tv_sec; + } } else if (strcmp(attr, GLITE_JP_LB_VO) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - if (h->events) { - i = 0; - while (h->events[i]) { - if (h->events[i]->type == EDG_WLL_EVENT_REGJOB) { - struct cclassad *ad; - char *string_vo = NULL; - - ad = cclassad_create(h->events[i]->regJob.jdl); - if (ad) { - if (!cclassad_evaluate_to_string(ad, "VirtualOrganisation", &string_vo)) - string_vo = NULL; - + i = 0; + while (h->events[i]) { + if (h->events[i]->type == EDG_WLL_EVENT_REGJOB) { + struct cclassad *ad; + char *string_vo = NULL; + + ad = cclassad_create(h->events[i]->regJob.jdl); + if (ad) { + if (cclassad_evaluate_to_string(ad, "VirtualOrganisation", &string_vo)) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); av[0].value = check_strdup(string_vo); - cclassad_delete(ad); - if (string_vo) free(string_vo); + av[0].timestamp = h->events[i]->any.timestamp.tv_sec; } - av[0].timestamp = h->events[i]->any.timestamp.tv_sec; - break; - } - i++; - } - } + cclassad_delete(ad); + if (string_vo) free(string_vo); + } + break; + } + i++; + } } else if (strcmp(attr, GLITE_JP_LB_eNodes) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - if (h->events) { - i = 0; - while (h->events[i]) { - if (h->events[i]->type == EDG_WLL_EVENT_REGJOB) { - struct cclassad *ad; - char *string_nodes = NULL; - - ad = cclassad_create(h->events[i]->regJob.jdl); - if (ad) { - if (!cclassad_evaluate_to_string(ad, "max_nodes_running", &string_nodes)) - string_nodes = NULL; - + i = 0; + while (h->events[i]) { + if (h->events[i]->type == EDG_WLL_EVENT_REGJOB) { + struct cclassad *ad; + char *string_nodes = NULL; + + ad = cclassad_create(h->events[i]->regJob.jdl); + if (ad) { + if (cclassad_evaluate_to_string(ad, "max_nodes_running", &string_nodes)) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); av[0].value = check_strdup(string_nodes); - cclassad_delete(ad); - if (string_nodes) free(string_nodes); + av[0].timestamp = h->events[i]->any.timestamp.tv_sec; } - av[0].timestamp = h->events[i]->any.timestamp.tv_sec; - break; - } - i++; - } - } + cclassad_delete(ad); + if (string_nodes) free(string_nodes); + } + break; + } + i++; + } } else if (strcmp(attr, GLITE_JP_LB_eProc) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - if (h->events) { - i = 0; - while (h->events[i]) { - if (h->events[i]->type == EDG_WLL_EVENT_REGJOB) { - struct cclassad *ad; - char *string_nodes = NULL; - - ad = cclassad_create(h->events[i]->regJob.jdl); - if (ad) { - if (!cclassad_evaluate_to_string(ad, "NodeNumber", &string_nodes)) - string_nodes = NULL; - + i = 0; + while (h->events[i]) { + if (h->events[i]->type == EDG_WLL_EVENT_REGJOB) { + struct cclassad *ad; + char *string_nodes = NULL; + + ad = cclassad_create(h->events[i]->regJob.jdl); + if (ad) { + if (cclassad_evaluate_to_string(ad, "NodeNumber", &string_nodes)) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); av[0].value = check_strdup(string_nodes); - cclassad_delete(ad); - if (string_nodes) free(string_nodes); + av[0].timestamp = h->events[i]->any.timestamp.tv_sec; } - av[0].timestamp = h->events[i]->any.timestamp.tv_sec; - break; - } - i++; - } - } + cclassad_delete(ad); + if (string_nodes) free(string_nodes); + } + break; + } + i++; + } } else if (strcmp(attr, GLITE_JP_LB_aTag) == 0 || strcmp(attr, GLITE_JP_LB_rQType) == 0 || strcmp(attr, GLITE_JP_LB_eDuration) == 0) { - /* have to be retrieved from JDL */ -/* - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = "Not implemented yet."; - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; -*/ + /* have to be retrieved from JDL, but probably obsolete and not needed at all */ *attrval = NULL; err.code = ENOSYS; -// err.desc = "Not implemented yet."; trio_asprintf(&err.desc,"Attribute '%s' not implemented yet.",attr); return glite_jp_stack_error(ctx,&err); } else if (strcmp(attr, GLITE_JP_LB_RB) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = check_strdup(h->status.network_server); - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; + if (h->status.network_server) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = strdup(h->status.network_server); + av[0].size = -1; + av[0].timestamp = h->status.lastUpdateTime.tv_sec; + } } else if (strcmp(attr, GLITE_JP_LB_CE) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = check_strdup(h->status.destination); - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; + if (h->status.destination) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = strdup(h->status.destination); + av[0].size = -1; + av[0].timestamp = h->status.lastUpdateTime.tv_sec; + } } else if (strcmp(attr, GLITE_JP_LB_host) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = check_strdup(h->status.ce_node); - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; + if (h->status.ce_node) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = strdup(h->status.ce_node); + av[0].size = -1; + av[0].timestamp = h->status.lastUpdateTime.tv_sec; + } } else if (strcmp(attr, GLITE_JP_LB_UIHost) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = check_strdup(h->status.location); - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; + if (h->status.location) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = strdup(h->status.location); + av[0].size = -1; + av[0].timestamp = h->status.lastUpdateTime.tv_sec; + } } else if (strcmp(attr, GLITE_JP_LB_CPUTime) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - trio_asprintf(&av[0].value,"%d", - h->status.cpuTime); - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; + if (h->status.cpuTime) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + trio_asprintf(&av[0].value,"%d", h->status.cpuTime); + av[0].size = -1; + av[0].timestamp = h->status.lastUpdateTime.tv_sec; + } } else if (strcmp(attr, GLITE_JP_LB_NProc) == 0) { /* currently LB hasn't got the info */ *attrval = NULL; err.code = ENOSYS; -// err.desc = "Not implemented yet."; trio_asprintf(&err.desc,"Attribute '%s' not implemented yet.",attr); return glite_jp_stack_error(ctx,&err); } else if (strcmp(attr, GLITE_JP_LB_finalStatus) == 0) { @@ -400,11 +412,13 @@ static int lb_query(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t av[0].size = -1; av[0].timestamp = h->status.lastUpdateTime.tv_sec; } else if (strcmp(attr, GLITE_JP_LB_finalStatusReason) == 0) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = check_strdup(h->status.reason); - av[0].size = -1; - av[0].timestamp = h->status.lastUpdateTime.tv_sec; + if (h->status.reason) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = strdup(h->status.reason); + av[0].size = -1; + av[0].timestamp = h->status.lastUpdateTime.tv_sec; + } } else if (strcmp(attr, GLITE_JP_LB_LRMSDoneStatus) == 0) { av = calloc(2, sizeof(glite_jp_attrval_t)); av[0].name = strdup(attr); @@ -412,32 +426,30 @@ static int lb_query(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t av[0].size = -1; av[0].timestamp = h->status.lastUpdateTime.tv_sec; } else if (strcmp(attr, GLITE_JP_LB_LRMSStatusReason) == 0) { - if (h->events) { - i = 0; - while (h->events[i]) { - if (h->events[i]->type == EDG_WLL_EVENT_DONE) { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = check_strdup(h->events[i]->done.reason); - av[0].timestamp = - h->events[i]->any.timestamp.tv_sec; - break; - } - i++; - } - } + i = 0; + while (h->events[i]) { + if (h->events[i]->type == EDG_WLL_EVENT_DONE) { + if (h->events[i]->done.reason) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = strdup(h->events[i]->done.reason); + av[0].size = -1; + av[0].timestamp = h->events[i]->any.timestamp.tv_sec; + } + break; + } + i++; + } } else if (strcmp(attr, GLITE_JP_LB_retryCount) == 0) { av = calloc(2, sizeof(glite_jp_attrval_t)); av[0].name = strdup(attr); - trio_asprintf(&av[0].value,"%d", - h->status.resubmitted); + trio_asprintf(&av[0].value,"%d", h->status.resubmitted); av[0].size = -1; av[0].timestamp = h->status.lastUpdateTime.tv_sec; } else if (strcmp(attr, GLITE_JP_LB_additionalReason) == 0) { /* what is it? */ *attrval = NULL; err.code = ENOSYS; -// err.desc = "Not implemented yet."; trio_asprintf(&err.desc,"Attribute '%s' not implemented yet.",attr); return glite_jp_stack_error(ctx,&err); } else if (strcmp(attr, GLITE_JP_LB_jobType) == 0) { @@ -456,18 +468,58 @@ static int lb_query(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t } else if (strcmp(attr, GLITE_JP_LB_nsubjobs) == 0) { av = calloc(2, sizeof(glite_jp_attrval_t)); av[0].name = strdup(attr); - trio_asprintf(&av[0].value,"%d", - h->status.children_num); + trio_asprintf(&av[0].value,"%d", h->status.children_num); av[0].size = -1; av[0].timestamp = h->status.lastUpdateTime.tv_sec; - } else if (strcmp(attr, GLITE_JP_LB_lastStatusHistory) == 0 || - strcmp(attr, GLITE_JP_LB_fullStatusHistory) == 0) { - /* complex types */ - *attrval = NULL; - err.code = ENOSYS; -// err.desc = "Not implemented yet."; - trio_asprintf(&err.desc,"Attribute '%s' not implemented yet.",attr); - return glite_jp_stack_error(ctx,&err); + } else if (strcmp(attr, GLITE_JP_LB_lastStatusHistory) == 0) { +/* + av = calloc(1 + EDG_WLL_NUMBER_OF_STATCODES, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = check_strdup(h->status.reason); + av[0].timestamp = h->status.stateEnterTime.tv_sec; + av[0].size = -1; + for (i=1; istatus.state) av[i].value = check_strdup(h->status.reason); + av[i].timestamp = h->status.stateEnterTimes[i+1]; + av[i].size = -1; + } +*/ + i = 0; while (h->lastStatusHistory[i]) i++; + av = calloc(i+2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = check_strdup(h->status.reason); + av[0].timestamp = h->status.stateEnterTime.tv_sec; + av[0].size = -1; + if (h->fullStatusHistory[0]) { + av[1].name = edg_wll_StatToString(h->fullStatusHistory[0]->state); + av[1].value = check_strdup(h->fullStatusHistory[0]->reason); + av[1].timestamp = h->fullStatusHistory[0]->timestamp.tv_sec; + av[1].size = -1; + } + i = 0; + while (h->lastStatusHistory[i]) { + av[i+2].name = edg_wll_StatToString(h->lastStatusHistory[i]->state); + av[i+2].value = check_strdup(h->lastStatusHistory[i]->reason); + av[i+2].timestamp = h->lastStatusHistory[i]->timestamp.tv_sec; + av[i+2].size = -1; + i++; + } + } else if (strcmp(attr, GLITE_JP_LB_fullStatusHistory) == 0) { + i = 0; while (h->fullStatusHistory[i]) i++; + av = calloc(i+1, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = check_strdup(h->status.reason); + av[0].timestamp = h->status.stateEnterTime.tv_sec; + av[0].size = -1; + i = 0; + while (h->fullStatusHistory[i]) { + av[i+1].name = edg_wll_StatToString(h->fullStatusHistory[i]->state); + av[i+1].value = check_strdup(h->fullStatusHistory[i]->reason); + av[i+1].timestamp = h->fullStatusHistory[i]->timestamp.tv_sec; + av[i+1].size = -1; + i++; + } } else if (strncmp(attr, GLITE_JP_LBTAG_NS, sizeof(GLITE_JP_LBTAG_NS)-1) == 0) { tag = strrchr(attr, ':'); if (h->events && tag) { @@ -493,72 +545,97 @@ static int lb_query(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t } } } else if (strcmp(attr, GLITE_JP_LB_JDL) == 0) { - for (i=0; h->events[i]; i++) if (h->events[i]->type == EDG_WLL_EVENT_REGJOB - && h->events[i]->regJob.jdl) - { - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = check_strdup(h->events[i]->regJob.jdl); - av[0].timestamp = h->events[i]->any.timestamp.tv_sec; - av[0].size = -1; - break; + i = 0; + while (h->events[i]) { + if ((h->events[i]->type == EDG_WLL_EVENT_REGJOB) && + (h->events[i]->regJob.jdl) ) { + av = calloc(2, sizeof(glite_jp_attrval_t)); + av[0].name = strdup(attr); + av[0].value = strdup(h->events[i]->regJob.jdl); + av[0].timestamp = h->events[i]->any.timestamp.tv_sec; + av[0].size = -1; + break; + } + i++; } } else { *attrval = NULL; err.code = EINVAL; -// err.desc = "No such attribute."; trio_asprintf(&err.desc,"No such attribute '%s'.",attr); return glite_jp_stack_error(ctx,&err); } - if (av[0].value) { + if (av && av[0].value) { for (i=0; av[i].name; i++) av[i].origin = GLITE_JP_ATTR_ORIG_FILE; *attrval = av; return 0; - } - else { + } else { *attrval = NULL; err.code = ENOENT; -// err.desc = "Value unknown"; - trio_asprintf(&err.desc,"Value unknown for attribute '%s'.",av[0].name); - glite_jp_attrval_free(av,1); + trio_asprintf(&err.desc,"Value unknown for attribute '%s'.",attr); + if (av) glite_jp_attrval_free(av,1); // probably not needed return glite_jp_stack_error(ctx,&err); } } -static int lb_status(edg_wll_Event **events, edg_wll_JobStat *status) { +static int lb_status(void *handle) { + lb_handle *h = (lb_handle *) handle; intJobStat *js; - int i, be_strict = 0; + int maxnstates, nstates, i, be_strict = 0; char *errstring; + edg_wll_JobStatCode old_state = EDG_WLL_JOB_UNDEF; js = calloc(1, sizeof(intJobStat)); init_intJobStat(js); - /* TODO: - edg_wll_SortEvents(events); - */ + edg_wll_SortPEvents(h->events); + maxnstates = INITIAL_NUMBER_STATES; + nstates = 0; + h->fullStatusHistory = calloc(maxnstates, sizeof(lb_historyStatus *)); i = 0; - while (events[i]) + while (h->events[i]) { - /* XXX: job owner and jobId not filled from events normally */ - if (events[i]->any.type == EDG_WLL_EVENT_REGJOB) { - js->pub.owner = check_strdup(events[i]->any.user); - if (edg_wlc_JobIdDup(events[i]->any.jobId,&js->pub.jobId)) { + /* realloc the fullStatusHistory if needed */ + if (nstates >= maxnstates) { + maxnstates <<= 1; + h->fullStatusHistory = realloc(h->fullStatusHistory, maxnstates * sizeof(lb_historyStatus *)); + } + + /* job owner and jobId not filled from events normally */ + if (h->events[i]->any.type == EDG_WLL_EVENT_REGJOB) { + js->pub.owner = check_strdup(h->events[i]->any.user); + if (edg_wlc_JobIdDup(h->events[i]->any.jobId,&js->pub.jobId)) { goto err; } } - if (processEvent(js, events[i], 0, be_strict, &errstring) == RET_FATAL) { + /* Process Event and update the state */ + if (processEvent(js, h->events[i], 0, be_strict, &errstring) == RET_FATAL) { goto err; } + + /* if the state has changed, update the status history */ + if (js->pub.state != old_state) { + h->fullStatusHistory[nstates] = calloc(1,sizeof(lb_historyStatus)); + h->fullStatusHistory[nstates]->state = js->pub.state; + h->fullStatusHistory[nstates]->timestamp.tv_sec = js->pub.stateEnterTime.tv_sec; + h->fullStatusHistory[nstates]->timestamp.tv_usec = js->pub.stateEnterTime.tv_usec; + h->fullStatusHistory[nstates]->reason = check_strdup(js->pub.reason); + if (js->pub.state == EDG_WLL_JOB_WAITING) { + h->lastStatusHistory = &h->fullStatusHistory[nstates]; + } + old_state = js->pub.state; + nstates++; + } + i++; } - memcpy(status, &js->pub, sizeof(edg_wll_JobStat)); + memcpy(&h->status, &js->pub, sizeof(edg_wll_JobStat)); - // XXX: awful, hopefully working + // not very clean, but working memset(&js->pub, 0, sizeof(edg_wll_JobStat)); destroy_intJobStat(js); -- 1.8.2.3