diff --git a/src/server/distrend.c b/src/server/distrend.c --- a/src/server/distrend.c +++ b/src/server/distrend.c @@ -38,12 +38,12 @@ #include #include -#include +#include #include #include -#include +#include +#include #include -#include /* local defs */ #define NUMBER_ELEVEN 11 @@ -78,14 +78,14 @@ void distrenjob_remove(struct general_in struct distrenjob *distrenjob_get(struct distrenjob *head, jobnum_t jobnum); int distrenjob_enqueue(struct general_info *, struct distrenjob *job); int mortition(struct general_info *, struct distrenjob *job); -int distrenjob_serialize(struct general_info *geninfo, struct distrenjob *job); int update_xml_joblist(struct general_info *); -int createQueueFromXML(struct distrenjob *head); -int reCreateQueueFromXML(struct distrenjob *head, xmlDocPtr doc, xmlNodePtr current); +int createQueueFromXML(struct general_info*); +int reCreateQueueFromXML(struct general_info*, xmlDocPtr doc, xmlNodePtr current); void update_general_info(struct general_info*); int import_general_info(struct general_info*); int updateJobStatsXML(struct distrenjob *job); +char *job_getserialfilename(struct general_info *, unsigned int jobnum); /* ********************** Functions ************************* */ @@ -144,7 +144,7 @@ int start_data(struct general_info *gene fprintf(stderr, "FAILURE\n"); fprintf(stderr, "Restoring queue...\n"); - if(createQueueFromXML(&general_info->head)) + if(createQueueFromXML(general_info)) fprintf(stderr, "FAILURE\n"); fprintf(stderr, "done\n"); @@ -180,26 +180,35 @@ int mortition(struct general_info *genin isJobDone = 1; // set isJobDone to true for(counter = 0; counter < job->total_frames; counter++) { - _distren_asprintf(&path_and_number, "stor/job%d/out/%d.%s", job->jobnum, job->frameset[counter].num, job->output_format); + _distren_asprintf(&path_and_number, "%s/stor/job%d/out/%d.%s", + geninfo->config->datadir, + job->jobnum, + job->frameset[counter].num, + job->output_format); if(stat(path_and_number, &buffer) == -1) { job->frameset[counter].status = FRAMESETSTATUS_UNASSIGNED; job->completed_frames--; geninfo->total_frames_rendered--; - isJobDone = 0; // if a missing frame is found, set isJobDone to false + /** if a missing frame is found, set isJobDone to false */ + isJobDone = 0; } + free(path_and_number); } - if(isJobDone) // if all frames were accounted for + /** if all frames were accounted for */ + if(isJobDone) { distrenjob_remove(geninfo, job); distrenjob_free(&job); geninfo->jobs_in_queue --; update_xml_joblist(geninfo); } - else{ - job->prev_frame_index = -1; // if the job isn't done, have frame_finder() start from the first frame, allowing it to see the frames that are now unassigned - } + else + /** + if the job isn't done, have frame_finder() start from the first frame, allowing it to see the frames that are now unassigned + */ + job->prev_frame_index = -1; update_general_info(geninfo); @@ -219,7 +228,7 @@ int restoreJobState(struct distrenjob *j isJobDone = 1; for(counter = 0; counter < job->total_frames; counter++) { - _distren_asprintf(&path_and_number, "stor/job%d/out/%d.%s", job->jobnum, job->frameset[counter].num, job->output_format); + _distren_asprintf(&path_and_number, "stor/job%d/out/%d.%s", job->jobnum, job->frameset[counter].num, job->output_format); /*< @TODO this path is used in multiple places, construct/build/determine it in a central function */ if(stat(path_and_number, &buffer) == 0) { job->frameset[counter].status = FRAMESETSTATUS_ASSIGNED; @@ -227,6 +236,7 @@ int restoreJobState(struct distrenjob *j } else isJobDone = 0; + free(path_and_number); } return isJobDone; @@ -239,6 +249,7 @@ int prepare_distrenjob(struct general_in int counter; int tmp; char *path_with_num; + char *serialfile; struct distrenjob *distrenjob; tmp = distrenjob_new(&distrenjob); @@ -273,11 +284,16 @@ int prepare_distrenjob(struct general_in } _distren_asprintf(&path_with_num, "stor/job%d/out/", distrenjob->jobnum); - fprintf(stderr, "creating dir '%s'", path_with_num); + fprintf(stderr, ">>NOT<< creating dir ``%s''\n", path_with_num); /*< @TODO recursively create job directory */ + serialfile = job_getserialfilename(geninfo, distrenjob->jobnum); + + free(path_with_num); /* add job to queue */ fprintf(stderr, "\nprepare_distrenjob: attempting distrenjob_serialize()\n"); - distrenjob_serialize(geninfo, distrenjob); + distrenjob_serialize(distrenjob, serialfile); + free(serialfile); + fprintf(stderr, "\nprepare_distrenjob: attempting distrenjob_enqueue()\n"); distrenjob_enqueue(geninfo, distrenjob); @@ -327,10 +343,12 @@ int distrenjob_enqueue(struct general_in /** Changes the priority of an existing (and maybe running) job. @arg head I may end up changing the head if job == head */ int change_job_priority(struct general_info *geninfo, struct distrenjob *job, int new_priority){ + struct distrenjob *current_job; + struct distrenjob *prev_job; + char *serialname; + distrenjob_remove(geninfo, job); job->priority = new_priority; - struct distrenjob *current_job; - struct distrenjob *prev_job; prev_job = &geninfo->head; @@ -357,7 +375,10 @@ int change_job_priority(struct general_i update_xml_joblist(geninfo); - distrenjob_serialize(geninfo, job); // because priority is changed + /** reserialize after changes */ + serialname = job_getserialfilename(geninfo, job->jobnum); + distrenjob_serialize(job, serialname); + free(serialname); return 0; } @@ -634,11 +655,11 @@ int distrend_do_config(int argc, char *a int tmp; /* - * test xml2distrenjob() + * test distrenjob_unserialize() */ - tmp = xml2distrenjob(&distrenjob, "distrenjob.xml.example"); + tmp = distrenjob_unserialize(&distrenjob, "distrenjob.xml.example"); if(tmp) - fprintf(stderr, "xml2distrenjob() returned %d. Try to cd to distren/doc if you want to test out the xml2distrenjob() function. (This will only fix this error if the error is due to an inability of the xml library to access distrenjob.xml.example)\n\n", tmp); + fprintf(stderr, "distrenjob_unserialize() returned %d. Try to cd to distren/doc if you want to test out the distrenjob_unserialize() function. (This will only fix this error if the error is due to an inability of the xml library to access distrenjob.xml.example)\n\n", tmp); else fprintf(stderr, "using email ``%s'' for user ``%s'' -- reading in XML files and pulling data from them using libxml2+XPath works!!!\n", distrenjob->email, distrenjob->submitter); @@ -736,92 +757,10 @@ int import_general_info(struct general_i return 0; } -/** - serializes a distrenjob into XML -*/ -int distrenjob_serialize(struct general_info *geninfo, struct distrenjob *job) -{ - xmlTextWriterPtr writer; - char *tmp; - char *tmpfile; - char *outfile; - int tmprtn; - - _distren_asprintf(&tmpfile, "%s/stor/job%d/.job_info.xml", geninfo->config->datadir, job->jobnum); - - /* create xml document at the location tmp with no compression */ - writer = xmlNewTextWriterFilename(tmpfile, 0); - xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL); - - /** - write distrenjob element and add its attributes */ - xmlTextWriterStartElement(writer, (xmlChar*)"job"); - xmlTextWriterWriteAttribute(writer, (xmlChar*)"name", (xmlChar*)job->name); - xmlTextWriterWriteAttribute(writer, (xmlChar*)"submitter", (xmlChar*)job->submitter); - _distren_asprintf(&tmp, "%d", job->priority); - xmlTextWriterWriteAttribute(writer, (xmlChar*)"priority", (xmlChar*)tmp); - free(tmp); - - /** - write resolution element and add its attributes */ - xmlTextWriterStartElement(writer, (xmlChar*)"resolution"); - _distren_asprintf(&tmp, "%d", job->width); - xmlTextWriterWriteAttribute(writer, (xmlChar*)"width", (xmlChar*)tmp); - free(tmp); - - _distren_asprintf(&tmp, "%d", job->height); - xmlTextWriterWriteAttribute(writer, (xmlChar*)"height", (xmlChar*)tmp); - free(tmp); - - xmlTextWriterEndElement(writer); - - /** - write video element and its attributes */ - xmlTextWriterStartElement(writer, (xmlChar*)"video"); - _distren_asprintf(&tmp, "%d", job->frameset[0].num); - xmlTextWriterWriteAttribute(writer, (xmlChar*)"start_frame", (xmlChar*)tmp); - free(tmp); - - _distren_asprintf(&tmp, "%d", job->frameset[(job->total_frames - 1)].num); - xmlTextWriterWriteAttribute(writer, (xmlChar*)"end_fame", (xmlChar*)tmp); - free(tmp); - - xmlTextWriterWriteAttribute(writer, (xmlChar*)"output_format", (xmlChar*)job->output_format); - xmlTextWriterEndElement(writer); - - /** - write watchdog forgiveness element */ - _distren_asprintf(&tmp, "%d", job->watchdog_forgiveness); - xmlTextWriterWriteElement(writer, (xmlChar*)"wd_forgiveness", (xmlChar*)tmp); - free(tmp); - - /** - end document */ - xmlTextWriterEndDocument(writer); - - /** - free writer and save xml file to disk */ - xmlFreeTextWriter(writer); - - _distren_asprintf(&outfile, "%s/stor/job%d/job_info.xml", geninfo->config->datadir, job->jobnum); - tmprtn = rename(tmpfile, outfile); - if(tmprtn == -1) - { - fprintf(stderr, "%s:%d: Error renaming ``%s'' to ``%s''\n", - __FILE__, __LINE__, - tmpfile, outfile); - perror("rename"); - tmprtn = 1; - } - free(tmpfile); - free(outfile); - - return tmprtn; -} // 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(int job_number) +struct distrenjob *createJobFromXML(struct general_info *geninfo, unsigned int jobnum) { xmlDocPtr doc; xmlNodePtr cur; @@ -831,7 +770,7 @@ struct distrenjob *createJobFromXML(int int counter; int counter2; - _distren_asprintf(&file_name, "stor/job%d/job_info.xml", job_number); + file_name = job_getserialfilename(geninfo, jobnum); doc = xmlParseFile(file_name); if(!doc) @@ -859,8 +798,8 @@ struct distrenjob *createJobFromXML(int xmlFreeDoc(doc); - // load up stats.xml file to retrieve data - _distren_asprintf(&file_name, "stor/job%d/stats.xml", job_number); + /** load up stats.xml file to retrieve data */ + _distren_asprintf(&file_name, "stor/job%d/stats.xml", jobnum); doc = xmlParseFile(file_name); cur = xmlDocGetRootElement(doc); @@ -966,7 +905,7 @@ int update_xml_joblist(struct general_in this reads a list of jobs in the queue before DistRen was shut down and then adds the jobs to the queue, as if it were never shut down */ -int createQueueFromXML(struct distrenjob *head) +int createQueueFromXML(struct general_info *geninfo) { int tmp; @@ -997,16 +936,19 @@ int createQueueFromXML(struct distrenjob // moves into the children elements of job_list cur = cur->xmlChildrenNode; - tmp = reCreateQueueFromXML(head, doc, cur); + tmp = reCreateQueueFromXML(geninfo, doc, cur); xmlFreeDoc(doc); return tmp; } -// inserts jobs at front of queue, starting with the last job in the job_list xml file -// to preserve the order of the queue -int reCreateQueueFromXML(struct distrenjob *head, xmlDocPtr doc, xmlNodePtr current) +/** + inserts jobs at front of queue, starting + with the last job in the job_list xml file + to preserve the order of the queue +*/ +int reCreateQueueFromXML(struct general_info *geninfo, xmlDocPtr doc, xmlNodePtr current) { 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 @@ -1015,23 +957,33 @@ int reCreateQueueFromXML(struct distrenj if(current == NULL) // base case, if element doesn't exist then don't do anything return 0; - // recursively call itself so that the next job in the queue is added to the front before the current one - if(reCreateQueueFromXML(head, doc, current->next)) + /** + recursively call itself so that the next job in + the queue is added to the front before the current one + */ + if(reCreateQueueFromXML(geninfo, doc, current->next)) + /** + bail if failure recursevely + ^-- is this the best thing to do in this case? + @TODO bail-out cleanup + */ return 1; - // now actual work is done, adding the job to the front of the queue - holder = head->next; // initialize holder + /** actual work is done now: add the job to the front of the queue */ + holder = geninfo->head.next; tmp = xmlNodeListGetString(doc, current->xmlChildrenNode, 1); // get job number job_num = atoi((char*)tmp); xmlFree(tmp); - job = createJobFromXML(job_num); + job = createJobFromXML(geninfo, job_num); if(job == NULL) return 1; - // insert job at front of the queue - head->next = job; + /** + insert job at front of the queue + */ + geninfo->head.next = job; job->next = holder; return 0; @@ -1301,3 +1253,18 @@ int main(int argc, char *argv[]) return 0; } + +/** + constructs the filename for a distrenjob's serialized XML + to be stored/retrieved from/in. + */ +char *job_getserialfilename(struct general_info *geninfo, unsigned int jobnum) +{ + char *filename; + + _distren_asprintf(&filename, "%s/stor/job/%d/distrenjob.xml", + geninfo->config->datadir, + jobnum); + + return filename; +}