# HG changeset patch # User Binki # Date 2010-01-23 15:26:03 # Node ID f1fb3f3ed5587cfc404f16d8c9251ea2d3c6b10b # Parent 9f7b19e75f9b64c42ca2f9a20fd4449d4cf240ea kill createJobFromXML(), fix distrenjob_unserialize(), kill distrenjob.email diff --git a/src/server/distrend.c b/src/server/distrend.c --- a/src/server/distrend.c +++ b/src/server/distrend.c @@ -254,7 +254,7 @@ int restoreJobState(struct distrenjob *j Passed strings must be free()d by the caller. */ -int prepare_distrenjob(struct general_info *geninfo, int type, char *name, char *submitter, char *email, int priority, int start_frame, int end_frame, int width, int height) +int prepare_distrenjob(struct general_info *geninfo, int type, char *name, char *submitter, int priority, int start_frame, int end_frame, int width, int height) { int counter; int counter2; @@ -272,7 +272,6 @@ int prepare_distrenjob(struct general_in distrenjob->type = 1; distrenjob->name = strdup(name); distrenjob->submitter = strdup(submitter); - distrenjob->email = strdup(email); distrenjob->priority = priority; distrenjob->width = width; distrenjob->height = height; @@ -784,71 +783,23 @@ int import_general_info(struct general_i return 0; } - -// extracts data from the xml created by above function and creates a job from it -// it returns a pointer to the created job -struct distrenjob *createJobFromXML(struct general_info *geninfo, unsigned int jobnum) +/** + determines path to the distenjob XML file and + calls distrenjob_unserialize() + */ +int restore_distrenjob(struct general_info *geninfo, struct distrenjob **distrenjob, jobnum_t jobnum) { - xmlDocPtr doc; - xmlNodePtr cur; + int tmp; char *file_name; - struct distrenjob *distrenjob; - int start_frame; - int counter; - int counter2; - - job_getserialfilename(&file_name, geninfo, jobnum, 0); - - doc = xmlParseFile(file_name); - if(!doc) - return NULL; - - distrenjob_new(&distrenjob); - - cur = xmlDocGetRootElement(doc); - - distrenjob->name = (char*)xmlGetProp(cur, (xmlChar*)"name"); - distrenjob->submitter = (char*)xmlGetProp(cur, (xmlChar*)"submitter"); - distrenjob->priority = atoi((char*)xmlGetProp(cur, (xmlChar*)"priority")); - - cur = cur->xmlChildrenNode; - distrenjob->width = atoi((char*)xmlGetProp(cur, (xmlChar*)"width")); - distrenjob->height = atoi((char*)xmlGetProp(cur, (xmlChar*)"number")); - cur = cur->next; - start_frame = atoi((char*)xmlGetProp(cur, (xmlChar*)"start_frame")); - distrenjob->total_frames = atoi((char*)xmlGetProp(cur, (xmlChar*)"end_frame")) - start_frame + 1; - distrenjob->output_format = (char*)xmlGetProp(cur, (xmlChar*)"output_format"); - - cur = cur->next; - distrenjob->watchdog_forgiveness = atoi((char*)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)); - - xmlFreeDoc(doc); - - /** load up stats.xml file to retrieve data */ - _distren_asprintf(&file_name, "stor/job%d/stats.xml", jobnum); - - doc = xmlParseFile(file_name); - free(file_name); - cur = xmlDocGetRootElement(doc); + tmp = job_getserialfilename(&file_name, geninfo, jobnum, 0); + if(tmp) + return tmp; - distrenjob->total_render_time = (time_t)atol((char*)xmlGetProp(cur, (xmlChar*)"total_render_time")); - - xmlFreeDoc(doc); - - distrenjob->frameset = malloc(sizeof(struct frameset) * distrenjob->total_frames); - - // change the status of all frames to "unassigned" - counter2 = start_frame; - for(counter = 0; counter <= distrenjob->total_frames; counter++){ - distrenjob->frameset[counter].num = counter2; - distrenjob->frameset[counter].status = FRAMESETSTATUS_UNASSIGNED; - - counter2++; - } - - restoreJobState(distrenjob); - return distrenjob; + tmp = distrenjob_unserialize(distrenjob, file_name); + free(file_name); + + return tmp; } int updateJobStatsXML(struct distrenjob *job) @@ -1017,7 +968,7 @@ int reCreateQueueFromXML(struct general_ struct distrenjob *holder; // holds the job that "was" after head, so that the new struct can be inserted after head struct distrenjob *job; // job to be added xmlChar *tmp; - int job_num; + jobnum_t job_num; if(current == NULL) // base case, if element doesn't exist then don't do anything return 0; @@ -1040,8 +991,7 @@ int reCreateQueueFromXML(struct general_ job_num = atoi((char*)tmp); xmlFree(tmp); - job = createJobFromXML(geninfo, job_num); - if(job == NULL) + if(restore_distrenjob(geninfo, &job, job_num)) return 1; /** @@ -1096,9 +1046,8 @@ int printJob(struct distrenjob *job) int printJobInfo(struct distrenjob *job) { fprintf(stderr, "type: %d\n", job->type); - fprintf(stderr, "name: %s\n", job->email); + fprintf(stderr, "name: %s\n", job->name); fprintf(stderr, "submitter: %s\n", job->submitter); - fprintf(stderr, "e-mail: %s\n", job->email); fprintf(stderr, "priority: %d\n", job->priority); fprintf(stderr, "completed: %d\n", job->completed_frames); fprintf(stderr, "assigned: %d\n", job->assigned_frames); @@ -1198,8 +1147,8 @@ int main(int argc, char *argv[]) } /** pre-loaded jobs for testing */ - prepare_distrenjob(&general_info, 1, "awesome", "LordOfWar", "onlylordofwar@gmail.com", 8, 1, 100, 640, 480); - prepare_distrenjob(&general_info, 1, "hamburger", "ohnobinki", "ohnobinki@ohnopublishing.net", 3, 1, 50, 1280, 720); + prepare_distrenjob(&general_info, 1, "awesome", "LordOfWar", 8, 1, 100, 640, 480); + prepare_distrenjob(&general_info, 1, "hamburger", "ohnobinki", 3, 1, 50, 1280, 720); while(test == 1) { @@ -1251,7 +1200,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "\nEnd frame: "); scanf("%d", &end_frame); fprintf(stderr, "\nWidth: "); scanf("%d", &width); fprintf(stderr, "\nHeight: "); scanf("%d", &height); - prepare_distrenjob(&general_info, type, name, submitter, email, priority, start_frame, end_frame, width, height); + prepare_distrenjob(&general_info, type, name, submitter, priority, start_frame, end_frame, width, height); break; case 5: fprintf(stderr, "\nJob number: "); diff --git a/src/server/distrenjob.c b/src/server/distrenjob.c --- a/src/server/distrenjob.c +++ b/src/server/distrenjob.c @@ -32,7 +32,6 @@ void distrenjob_free(struct distrenjob * dj = *distrenjob; xmlFree(dj->name); xmlFree(dj->submitter); - xmlFree(dj->email); free(dj->frameset); @@ -57,7 +56,6 @@ int distrenjob_new(struct distrenjob **d dj->next = NULL; dj->name = (char *)NULL; dj->submitter = (char *)NULL; - dj->email = (char *)NULL; dj->jobnum = 0; /*< @todo there should be a central jobnum allocator and a way to save the maximum jobnumber allocated */ dj->priority = 0; dj->width = 0; @@ -75,11 +73,49 @@ int distrenjob_new(struct distrenjob **d } /** - writes struct from xml + read an unsigned integer property from an xmlNode + + convenience function for distrenjob_unserialize() + @param xmlnode may be NULL for convenience + @return 0 on success, other on error + */ +int _distrenjob_xml_readuint(xmlNodePtr xmlnode, xmlChar *propname, unsigned int *num) +{ + xmlChar *string; + + if(!xmlnode) + return 1; + + string = xmlGetProp(xmlnode, propname); + if(!string) + return 1; + + *num = (unsigned int)strtoul((char *)string, (char **)NULL, 10); +#ifndef NDEBUG + fprintf(stderr, "_distrenjob_xml_readuint(%zx, \"%s\", *(%zx)=%u): read %s=\"%d\"\n", + (size_t)xmlnode, propname, (size_t)num, *num, propname, *num); +#endif + + xmlFree(string); + return 0; +} + +/** + Loads a distrenjob that was serialized with distrenjob_serialize() + + @see distrenjob_serialize() + @param pathtoxml path to XML file + @param distrenjob will be set to a pointer */ int distrenjob_unserialize(struct distrenjob **distrenjob, char *pathtoxml) { struct distrenjob *dj; + struct frameset *fs; + unsigned int start_frame; + unsigned int end_frame; + unsigned int counter; + + struct tm tm; xmlDocPtr xmldoc; xmlNodePtr xmlnode; @@ -109,7 +145,7 @@ int distrenjob_unserialize(struct distre } xmlxpathcontext = xmlXPathNewContext(xmldoc); - xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/distren/job"); + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job"); if(!xmlnode) { distrenjob_free(distrenjob); @@ -131,28 +167,80 @@ int distrenjob_unserialize(struct distre distrenjob_free(distrenjob); return 5; } - - tmp = _distren_asprintf((char **)&xmlchar, "/distren/submitters/submitter[attribute::name=\"%s\"]", dj->submitter); - if(tmp <= 0 - || !xmlchar) + tmp = _distrenjob_xml_readuint(xmlnode, (xmlChar *)"priority", &dj->priority); + if(tmp) { - fprintf(stderr, "error using _distren_asprintf\n"); distrenjob_free(distrenjob); return 6; } - xmlnode = xml_quickxpath(xmlxpathcontext, xmlchar); - free(xmlchar); - dj->email = (char *)xmlGetProp(xmlnode, (xmlChar *)"email"); - if(!dj->email) + + dj->output_format = (char *)xmlGetProp(xmlnode, (xmlChar *)"output_format"); + if(!dj->output_format) { - fprintf(stderr, "error getting email for user ``%s'' from ``%s''\n", - dj->submitter, pathtoxml); + distrenjob_free(distrenjob); + + return 6; + } + + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/resolution"); + tmp = _distrenjob_xml_readuint(xmlnode, (xmlChar *)"width" , &dj->width ); + tmp += _distrenjob_xml_readuint(xmlnode, (xmlChar *)"height" , &dj->height ); + + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/video"); + tmp += _distrenjob_xml_readuint(xmlnode, (xmlChar *)"start_frame", &start_frame); + tmp += _distrenjob_xml_readuint(xmlnode, (xmlChar *)"end_frame", &end_frame); + + if(tmp) + { + fprintf(stderr, "distrenjob_unserialize(): error reading integer values from ``%s''\n", + pathtoxml); distrenjob_free(distrenjob); return 7; } + /** + total_render_time and watchdog stuff doesn't need error + checking, just good defaults + */ + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/stats"); + dj->total_render_time = 0; + xmlchar = xmlGetProp(xmlnode, (xmlChar *)"total_render_time"); + if(xmlchar) + { + if(strptime((char *)xmlchar, "%D %T", &tm)) + dj->total_render_time = mktime(&tm); + xmlFree(xmlchar); + } + + xmlnode = xml_quickxpath(xmlxpathcontext, (xmlChar *)"/job/watchdog"); + dj->watchdog_forgiveness = 3600; + tmp =_distrenjob_xml_readuint(xmlnode, (xmlChar *)"forgiveness", &dj->watchdog_forgiveness); + if(tmp) + fprintf(stderr, "distrenjob_unserialize(): warning: watchdog forgiveness is unspecified in ``%s'', defaulting to 3600\n", pathtoxml); + xmlXPathFreeContext(xmlxpathcontext); xmlFreeDoc(xmldoc); + + /** + reconstruct the frameset + */ + dj->total_frames = end_frame - start_frame + 1; + dj->frameset = malloc(sizeof(struct frameset) * dj->total_frames); + if(!dj->frameset) + { + fprintf(stderr, "OOM!\n"); + distrenjob_free(distrenjob); + return 8; + } + fs = dj->frameset; + for(counter = start_frame; counter <= end_frame; counter ++) + { + fs->num = counter; + fs->status = FRAMESETSTATUS_UNASSIGNED; /*< @todo job partial completion and resumption support */ + + fs ++; + } + return 0; } diff --git a/src/server/distrenjob.h b/src/server/distrenjob.h --- a/src/server/distrenjob.h +++ b/src/server/distrenjob.h @@ -38,16 +38,15 @@ struct distrenjob short int type; /*< 1:Blender, 2:something else */ char *name; char *submitter; - char *email; /*< This should be looked up based on the value of submitter, not stored in this struct */ jobnum_t jobnum; - int width; /*< width in pixels of the frames to be rendered */ - int height; /*< height in pixels of the frames to be rendered */ - int priority; /*< 1 is lowest, 10 is highest, 0 means the job is done */ - int completed_frames; /*< number of completed frames for stats/etc */ - int assigned_frames; /*< number of assigned frames (that are not yet completed) for stats/etc */ - int total_frames; /*< how many frames are in the animation for stats/etc (unassigned frames) */ - int watchdog_forgiveness; /*< how many seconds till the frame is re-assigned (if client computer crashes etc); */ - short int hibernate; + unsigned int width; /*< width in pixels of the frames to be rendered */ + unsigned int height; /*< height in pixels of the frames to be rendered */ + unsigned int priority; /*< 1 is lowest, 10 is highest, 0 means the job is done */ + unsigned int completed_frames; /*< number of completed frames for stats/etc */ + unsigned int assigned_frames; /*< number of assigned frames (that are not yet completed) for stats/etc */ + unsigned int total_frames; /*< how many frames are in the animation for stats/etc (unassigned frames) */ + unsigned int watchdog_forgiveness; /*< how many seconds 'til the frame is re-assigned (if client computer crashes etc); */ + short int hibernate; /*< @todo DOCUMENT THIS */ int prev_frame_index; /*< the position in the array of the last frame that was assigned */ time_t total_render_time; /*< total seconds of time spent on all the completed frames */ char *output_format; /*< currently is the file extension of the request output format. @todo make this mime-type based/not a string */ diff --git a/src/server/slavefuncs.c b/src/server/slavefuncs.c --- a/src/server/slavefuncs.c +++ b/src/server/slavefuncs.c @@ -91,7 +91,10 @@ int sendExtSignal(struct remoteio *rem, /** - utility function for XPath-ish stuff: + Grabs the xml DOM node reached by an XPath. + + @param path an XPath that lead to DOM node + @return the first node associated with the path or NULL if there is no match */ xmlNodePtr xml_quickxpath(xmlXPathContextPtr xpathctxt, xmlChar *path) {