static batch_job_id_t batch_job_cluster_wait (struct batch_queue * q, struct batch_job_info * info_out, time_t stoptime)
{
	struct batch_job_info *info;
	batch_job_id_t jobid;
	int t, c;

	while(1) {
		UINT64_T ujobid;
		itable_firstkey(q->job_table);
		while(itable_nextkey(q->job_table, &ujobid, (void **) &info)) {
			jobid = ujobid;
			char *statusfile = string_format("%s.status.%" PRIbjid, cluster_name, jobid);
			FILE *file = fopen(statusfile, "r");
			if(file) {
				char line[BATCH_JOB_LINE_MAX];
				while(fgets(line, sizeof(line), file)) {
					if(sscanf(line, "start %d", &t)) {
						info->started = t;
					} else if(sscanf(line, "stop %d %d", &c, &t) == 2) {
						debug(D_BATCH, "job %" PRIbjid " complete", jobid);
						if(!info->started)
							info->started = t;
						info->finished = t;
						info->exited_normally = 1;
						info->exit_code = c;
					}
				}
				fclose(file);

				if(info->finished != 0) {
					unlink(statusfile);
					info = itable_remove(q->job_table, jobid);
					*info_out = *info;
					free(info);
					free(statusfile);
					return jobid;
				}
			} else {
				debug(D_BATCH, "could not open status file \"%s\"", statusfile);
			}

			free(statusfile);
		}

		if(itable_size(q->job_table) <= 0)
			return 0;

		if(stoptime != 0 && time(0) >= stoptime)
			return -1;

		if(process_pending())
			return -1;

		sleep(1);
	}

	return -1;
}
Exemple #2
0
struct pipes_res * pclose(struct pipes_close *pcmd, struct pipe *p, int task)
{
	CPOSITION it;

	// check pipe type
	if(p->type == PIPES_FILEPIPE)
	{
		fclose(p->pf);		
		return build_response_msg(PIPESERR_OK);
	}

	if(task == p->taskid)
	{
		p->task1_closed = 1;
	}
	else if(task == p->taskid2)
	{
		p->task2_closed = 1;
	}

	// if there was a pending read, send what's left on the buffer
	if(p->pending)
	{
		process_pending(p);
	}

	if((p->task1_closed && p->task2_closed) || task == p->creating_task)
	{
		it = get_head_position(&p->buffer->blocks);
		while(it != NULL)
		{
			struct pipe_buffer_block *b = (struct pipe_buffer_block*)get_next(&it);
			free_block(b);
		}
		lstclear(&p->buffer->blocks);	

		avl_remove(&pipes, p->id);

		free(p);
	}

	return build_response_msg(PIPESERR_OK);
}
Exemple #3
0
void process_pipes_cmd(struct pipes_cmd *pcmd, int task)
{
    struct pipes_res *res= NULL;
    struct pipe *p = NULL;

    // check for open
    if(pcmd->command == PIPES_OPENSHARED)
    {
        // create a new shared pipe
        struct pipe *p = (struct pipe*)malloc(sizeof(struct pipe));

        p->id = get_new_pipeid();
        p->type = PIPES_SHAREDPIPE;
        p->taskid = ((struct pipes_openshared*)pcmd)->task1;
        p->taskid2 = ((struct pipes_openshared*)pcmd)->task2;
        p->pf = NULL;
        p->creating_task = task;
        p->pending = 0;
        p->task1_closed = 0;
        p->task2_closed = 0;

        p->buffer = (struct pipe_buffer*)malloc(sizeof(struct pipe_buffer));
        p->buffer->rcursor = p->buffer->wcursor = p->buffer->size = 0;
        init(&p->buffer->blocks);

        avl_insert(&pipes, p, p->id);

        res = build_response_msg(PIPESERR_OK);
        ((struct pipes_open_res*)res)->pipeid = p->id;
    }
    else if(pcmd->command == PIPES_OPENFILE)
    {
        // create a new file pipe
        struct pipe *p = (struct pipe*)malloc(sizeof(struct pipe));

        char *filepath = get_string(((struct pipes_openfile*)pcmd)->path_smo);

        p->id = get_new_pipeid();
        p->type = PIPES_FILEPIPE;
        p->taskid = ((struct pipes_openshared*)pcmd)->task1;
        p->taskid2 = -1;
        p->pf = fopen(filepath, (char*)((struct pipes_openfile*)pcmd)->open_mode);
        p->creating_task = task;
        p->buffer = NULL;
        p->pending = 0;

        if(p->pf != NULL)
        {
            avl_insert(&pipes, p, p->id);
            res = build_response_msg(PIPESERR_OK);
            ((struct pipes_open_res*)res)->pipeid = p->id;
        }
        else
        {
            res = build_response_msg(PIPESERR_FSERROR);
            free(p);
        }

        free(filepath);
    }
    else
    {
        p = (struct pipe*)avl_getvalue(pipes, ((struct pipes_close*)pcmd)->pipeid);

        if(p != NULL)
        {
            /* Check permissions */
            switch(pcmd->command)
            {
            case PIPES_CLOSE:
                // a shared pipe must be closed on both ends or by the creating task
                if(p->type == PIPES_SHAREDPIPE)
                {
                    if(task != p->taskid && task != p->taskid2 && task != p->creating_task)
                    {
                        res = build_response_msg(PIPESERR_ERR);
                    }
                    else if((task == p->taskid && p->task1_closed) || (task == p->taskid2 && p->task2_closed))
                    {
                        res = build_response_msg(PIPESERR_PIPECLOSED);
                    }
                }
                else if(p->type == PIPES_FILEPIPE && task != p->taskid)
                {
                    res = build_response_msg(PIPESERR_ERR);
                }
                break;
            case PIPES_SEEK:
            case PIPES_TELL:
                break;
            case PIPES_WRITE:
            case PIPES_PUTS:
            case PIPES_PUTC:
                if(p->type == PIPES_SHAREDPIPE && task != p->taskid)
                {
                    res = build_response_msg(PIPESERR_ERR);
                }
                break;
            case PIPES_READ:
            case PIPES_GETS:
            case PIPES_GETC:
                if(p->type == PIPES_SHAREDPIPE && task != p->taskid2)
                {
                    res = build_response_msg(PIPESERR_ERR);
                }
                break;
            default:
                res = build_response_msg(PIPESERR_ERR);
            }

            if(res != NULL)
            {
                res->thr_id = pcmd->thr_id;
                res->command = pcmd->command;

                send_msg(task, pcmd->ret_port, res);
                return;
            }

            /* Process pipe command */
            switch(pcmd->command)
            {
            case PIPES_CLOSE:
                res = pclose((struct pipes_close *)pcmd, p, task);
                if(res->ret == PIPESERR_OK) p = NULL;
                break;
            case PIPES_READ:
                res = pread((struct pipes_read *)pcmd, p);
                break;
            case PIPES_WRITE:
                res = pwrite((struct pipes_write *)pcmd, p);
                break;
            case PIPES_SEEK:
                res = pseek((struct pipes_seek *)pcmd, p, task);
                break;
            case PIPES_TELL:
                res = ptell((struct pipes_tell *)pcmd, p, task);
                break;
            case PIPES_PUTS:
                res = pputs((struct pipes_puts *)pcmd, p);
                break;
            case PIPES_PUTC:
                res = pputc((struct pipes_putc *)pcmd, p);
                break;
            case PIPES_GETS:
                res = pgets((struct pipes_gets *)pcmd, p);
                break;
            case PIPES_GETC:
                res = pgetc((struct pipes_getc *)pcmd, p);
                break;
            default:
                res = build_response_msg(PIPESERR_ERR);
            }
        }
        else
        {
            res = build_response_msg(PIPESERR_PIPECLOSED);
        }
    }

    if(p == NULL || (p != NULL && !(p->pending && (pcmd->command == PIPES_READ
                                    || (pcmd->command == PIPES_SEEK && task == p->taskid2)
                                    || pcmd->command == PIPES_GETS
                                    || pcmd->command == PIPES_GETC))))
    {
        if(res == NULL)
        {
            res = build_response_msg(PIPESERR_ERR);
        }

        res->thr_id = pcmd->thr_id;
        res->command = pcmd->command;

        send_msg(task, pcmd->ret_port, res);

        if(res != NULL) free(res);
    }
    else
    {
        // check pending read
        if(p != NULL && p->pending && (pcmd->command == PIPES_WRITE
                                       || (pcmd->command == PIPES_SEEK && task == p->taskid2)
                                       || pcmd->command == PIPES_READ
                                       || pcmd->command == PIPES_PUTS
                                       || pcmd->command == PIPES_PUTC))
        {
            // process the pending message
            process_pending(p);
        }

        send_msg(task, pcmd->ret_port, res);
        if(res != NULL) free(res);
    }
}
Exemple #4
0
static batch_job_id_t batch_job_condor_wait (struct batch_queue * q, struct batch_job_info * info_out, time_t stoptime)
{
	static FILE *logfile = 0;

	if(!logfile) {
		logfile = fopen(q->logfile, "r");
		if(!logfile) {
			debug(D_NOTICE, "couldn't open logfile %s: %s\n", q->logfile, strerror(errno));
			return -1;
		}
	}

	while(1) {
		/*
		   Note: clearerr is necessary to clear any cached end-of-file condition,
		   otherwise some implementations of fgets (i.e. darwin) will read to end
		   of file once and then never look for any more data.
		 */

		clearerr(logfile);

		char line[BATCH_JOB_LINE_MAX];
		while(fgets(line, sizeof(line), logfile)) {
			int type, proc, subproc;
			batch_job_id_t jobid;
			time_t current;
			struct tm tm;

			struct batch_job_info *info;
			int logcode, exitcode;

			if(sscanf(line, "%d (%" SCNbjid ".%d.%d) %d/%d %d:%d:%d", &type, &jobid, &proc, &subproc, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 9) {
				tm.tm_year = 2008 - 1900;
				tm.tm_isdst = 0;

				current = mktime(&tm);

				info = itable_lookup(q->job_table, jobid);
				if(!info) {
					info = malloc(sizeof(*info));
					memset(info, 0, sizeof(*info));
					itable_insert(q->job_table, jobid, info);
				}

				debug(D_BATCH, "line: %s", line);

				if(type == 0) {
					info->submitted = current;
				} else if(type == 1) {
					info->started = current;
					debug(D_BATCH, "job %" PRIbjid " running now", jobid);
				} else if(type == 9) {
					itable_remove(q->job_table, jobid);

					info->finished = current;
					info->exited_normally = 0;
					info->exit_signal = SIGKILL;

					debug(D_BATCH, "job %" PRIbjid " was removed", jobid);

					memcpy(info_out, info, sizeof(*info));
					free(info);
					return jobid;
				} else if(type == 5) {
					itable_remove(q->job_table, jobid);

					info->finished = current;

					fgets(line, sizeof(line), logfile);
					if(sscanf(line, " (%d) Normal termination (return value %d)", &logcode, &exitcode) == 2) {
						debug(D_BATCH, "job %" PRIbjid " completed normally with status %d.", jobid, exitcode);
						info->exited_normally = 1;
						info->exit_code = exitcode;
					} else if(sscanf(line, " (%d) Abnormal termination (signal %d)", &logcode, &exitcode) == 2) {
						debug(D_BATCH, "job %" PRIbjid " completed abnormally with signal %d.", jobid, exitcode);
						info->exited_normally = 0;
						info->exit_signal = exitcode;
					} else {
						debug(D_BATCH, "job %" PRIbjid " completed with unknown status.", jobid);
						info->exited_normally = 0;
						info->exit_signal = 0;
					}

					memcpy(info_out, info, sizeof(*info));
					free(info);
					return jobid;
				}
			}
		}


		if(itable_size(q->job_table) <= 0)
			return 0;

		if(stoptime != 0 && time(0) >= stoptime)
			return -1;

		if(process_pending())
			return -1;

		sleep(1);
	}

	return -1;
}