⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dedicated.c

📁 openPBS的开放源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* Is the time currently between the start and end of the dedicated time? */    if ((host_out->beg_time <= when) && (when <= host_out->end_time)) {	/*	 * If the job was not queued on the dedicated queue, it cannot be	 * run during dedicated time.  Note that and return "not okay."	 */	if (job->flags & JFLAGS_DEDICATED) {	    /* 	     * The job is on the dedicated queue.  It may not be runnable	     * if it runs over past the end of dedicated time.  Check that.	     */	    if (job_ends >= host_out->end_time) {		if (reason)		    (void)sprintf(reason, 			"Can't complete within this dedicated time (%s %s %s)",			shorthost ? shorthost : host_out->exechost, 			host_out->end_datestr, host_out->end_timestr);		return 0;	    }	} else {	    /* Job is a regular job.  It cannot run during dedicated time. */	    if (reason)		sprintf(reason, "Waiting for end of dedicated time (%s %s %s)",		    shorthost ? shorthost : host_out->exechost, 		    host_out->end_datestr, host_out->end_timestr);	    return 0;	}    } else {	/* 	 * It is not currently dedicated time.  However, the job may spill	 * over into dedtime.  Check this by calculating when the job will	 * finish execution and seeing if that falls within dedicated time.	 */	if (job_ends >= host_out->beg_time) {	    if (reason)		(void)sprintf(reason, 		    "Can't complete before next dedicated time (%s %s %s)",		    shorthost ? shorthost : host_out->exechost, 		    host_out->beg_datestr, host_out->beg_timestr);	    return 0;	}    }#ifdef DEBUG_DEDTIME    DBPRT(("%s: job %s is okay.\n", id, job->jobid));#endif /* DEBUG_DEDTIME */    return 1;	/* Job will not interfere with dedicated time if run now. */}/* * Get a linked list of outages for host exechost.  The caller is expected * to point the 'exechost' pointer for each element in this list to a piece * of storage containing the exechost's name.  This is crufty, but minimizes * the amount of extra allocation being done. */static intget_outages(char *exechost, Outage **outlistp){    char   *id = "get_outages";    char    buffer[BUFSIZ];    char    ded_ck_cmd[BUFSIZ];    char   *p, *shortexec;    char    Start_Date[DATE_LENGTH + 1];	/* + 1 for '\0' */    char    Start_Time[TIME_LENGTH + 1];	/* + 1 for '\0' */    char    End_Date[DATE_LENGTH + 1];		/* + 1 for '\0' */    char    End_Time[TIME_LENGTH + 1];		/* + 1 for '\0' */    char   *ded_system;    FILE   *schedule_pipe;    Outage *outs, *tail, *newout;    int     info_valid, ded_cancelled;    size_t  length;    outs = tail = NULL;    /*     * Assume we will not get valid dedtime information from the piped command.     */    info_valid    = 0;    Start_Date[0] = '\0';    Start_Time[0] = '\0';    End_Date[0]   = '\0';    End_Time[0]   = '\0';    /* Get the "short" version of the exechost. */    shortexec = schd_shorthost(exechost);    if (shortexec == NULL)	return (-1);    sprintf(ded_ck_cmd, "%s %s", schd_DEDTIME_COMMAND, shortexec);    DBPRT(("%s: Consult '%s'\n", id, ded_ck_cmd));    if ((schedule_pipe = popen(ded_ck_cmd, "r")) == NULL) {	(void)sprintf(log_buffer, "ERROR: \"%s\": %s", ded_ck_cmd, 	    strerror(errno));	log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);	DBPRT(("%s: %s\n", id, log_buffer));	free(shortexec);	return (1);    }    /* Read each entry from the schedule output. */    while (fgets(buffer, sizeof buffer, schedule_pipe) != NULL) {	ded_cancelled = 0;	/* Skip totally blank lines. */	if ((length = strlen(buffer)) == 0)	    continue;	/* Flag an error if this line was too long. */	if (length >= (sizeof (buffer) - 1)) {	    (void)sprintf(log_buffer, 		"%s: Input line from '%s' too long.", id, ded_ck_cmd);	    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);	    DBPRT(("%s: %s\n", id, log_buffer));	    info_valid = 0;	    break;	}		/* Remove trailing carriage return. */	if (buffer[length - 1] == '\n')	    buffer[length - 1] = '\0';	/* Check for error conditions returned by the program. */	if (!strncmp(buffer, "ERROR", 5)) {	    info_valid = 0;	    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, buffer);	    DBPRT(("%s: %s\n", id, buffer));	    break;	}	if (!strcmp(buffer, 	    "No scheduled downtime for the specified period."))	{	    info_valid ++;	    break;		/* None scheduled */	}	/* 	 * Output of 'schedule' "linewraps" with more than 8 spaces before 	 * the text.  I.e. more than 8 spaces means that this is a continued	 * line.  We are only interested in the "header" lines.	 */	if (!strncmp(buffer, "        ", 8)) {	    continue;	}	if (strstr(buffer, "CANCELLED"))	    ded_cancelled ++;	/* format: "SYSTEM MM/DD/YYYY HH:MM-HH:MM MM/DD/YYYY" */	p = strtok(buffer, " \t");		/* p -> '<system>' */	if (p == NULL) 	    continue;	/* Keep track of which system this line references. */	ded_system = p;	p = strtok(NULL, " \t");		/* p -> '<startdate>' */	if (p == NULL)	    continue;	strncpy(Start_Date, p, DATE_LENGTH);	p = strtok(NULL, "-");			/* p -> '<starttime>' */	if (p == NULL)	    continue;	strncpy(Start_Time, p, TIME_LENGTH);	p = strtok(NULL, " \t");		/* p -> '<endtime>' */	if (p == NULL)	    continue;	strncpy(End_Time, p, TIME_LENGTH);	p = strtok(NULL, " \t");		/* p -> '<enddate>' */	if (p == NULL)	    continue;	strncpy(End_Date, p, DATE_LENGTH);	/*	 * We have discovered a line that "looks okay".  Consider the output	 * being sent from the schedule command to be "acceptable".	 */	info_valid++;	/*	 * It may be a valid line, and still not be information about this 	 * machine.  Convert the string to all lowercase before comparing	 * it against the lowercase system name.	 */	schd_lowercase(ded_system);	if (strcmp(ded_system, shortexec) != 0)  {#if 0		DBPRT(("%s: wrong host '%s' != '%s'\n", id, ded_system, 		    shortexec));#endif /* 0 */	    continue;	}	if (MMDDYYYY_HHMM(Start_Date, Start_Time) >= 	    MMDDYYYY_HHMM(End_Date, End_Time))	{	    DBPRT(("%s: found dedtime shorter than 1 minute!\n", id));	    DBPRT(("%s: bad dedtime: (%s %s %s - %s %s)\n", id, shortexec, 	    Start_Date, Start_Time, End_Date, End_Time));	    continue;	}	if (ded_cancelled) {	    /*	     * A cancellation is a valid entry.  It also means we need to	     * update our cache, since it may be cancelling the cached	     * value.  However, we also need to see if there is any time	     * really scheduled later.	     */	    DBPRT(("%s: found cancelled dedtime for %s from %s:%s to %s:%s\n",		id, shortexec, Start_Date, Start_Time, End_Date, End_Time));	    info_valid ++;	    continue;	}	/* 	 * Dedicated time is scheduled for this machine.  Will it end at 	 * some _future_ time ??  If so, make a new entry in the list of	 * Outages for the shortexec.	 */	if (MMDDYYYY_HHMM(End_Date, End_Time) > schd_TimeNow) {	    info_valid ++;	    if ((newout = (Outage *)malloc(sizeof(Outage))) == NULL) {		(void)sprintf(log_buffer, "malloc(Outage) failed\n");		log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, 			log_buffer);		DBPRT(("%s: %s\n", id, log_buffer));		info_valid = 0;		break;	    }	    memset((void *)newout, 0, sizeof(Outage));	    /* Hook the new element on the end of the list. */	    if (tail)		tail->next = newout;	    else		outs = newout;	    tail = newout;	    newout->next = NULL;	    /* Load the outage information into the new struct. */	    newout->exechost = NULL;	/* Caller must set. */	    strncpy(newout->beg_datestr, Start_Date, DATE_LENGTH);	    strncpy(newout->beg_timestr, Start_Time, TIME_LENGTH);	    strncpy(newout->end_datestr, End_Date, DATE_LENGTH);	    strncpy(newout->end_timestr, End_Time, TIME_LENGTH);	    newout->beg_time = MMDDYYYY_HHMM(Start_Date, Start_Time);	    newout->end_time = MMDDYYYY_HHMM(End_Date, End_Time);#if 0	    DBPRT(("Got Outage for %s %s:%s %s:%s\n", shortexec,		newout->beg_datestr, newout->beg_timestr,		newout->end_datestr, newout->end_datestr));#endif /* 0 */	}    }    pclose(schedule_pipe);    free(shortexec);    if (info_valid) {	*outlistp = outs;	return 0;    } else {	DBPRT(("%s: no valid dedtime info found (%s)\n", id, ded_ck_cmd));	if (outs)	    free_outages(outs);	*outlistp = NULL;	return 1;    }}static Outage *merge_outages(Outage *system_outages, Outage *host_outages){    char     *id = "merge_outages";    Outage  **outp_array, *outp, *newlist;    int       num_outages, i, found;    /* If there are no system outages, just return the host list.  */    if (system_outages == NULL)	return (host_outages);    /* If there are no host outages, just return the system list.  */    if (host_outages == NULL)	return (system_outages);    /* Count the total number of outages in both lists. */    num_outages = 0;    for (outp = system_outages; outp != NULL; outp = outp->next)	++ num_outages;    for (outp = host_outages; outp != NULL; outp = outp->next)	++ num_outages;    /* Now allocate space for a bunch of pointers to the outages. */    outp_array = (Outage **)calloc(num_outages, sizeof(Outage *));    if (outp_array == NULL) {	(void)sprintf(log_buffer, "calloc() failed (%d * %d)\n", num_outages,	    (int)sizeof(Outage *));	log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);	DBPRT(("%s: %s\n", id, log_buffer));	/* Free the passed-in lists. */	free_outages(system_outages);	free_outages(host_outages);	/* And return an error condition. */	return (NULL);    }    /*      * Walk the outage lists again, assigning each element in the array to     * point to one outage.  Sort the resultant array in ascending order     * of the start time of the outage pointed to by each element in the     * array.     */    i = 0;    for (outp = system_outages; outp != NULL; outp = outp->next)	outp_array[i++] = outp;    for (outp = host_outages; outp != NULL; outp = outp->next)	outp_array[i++] = outp;    qsort(outp_array, num_outages, sizeof (Outage *), compare_outages_time);    /*      * The array is now a set of pointers to outages.  Re-link the outages in     * the order given in the array.     */    newlist = outp = outp_array[0];    for (i = 1; i < num_outages; i++) {	outp->next = outp_array[i];	outp = outp->next;    }    outp->next = NULL;    /* Free the array of pointers since it is no longer needed. */    free(outp_array);    /*      * Now the 'newlist' list contains the members of both lists, arranged in     * time from earliest to latest.  All that remains is to resolve any     * overlapping cases.  Do this one at a time, until no more can be found.     * This should significantly simplify the code, and since there should      * only be a handful of outages at any time, it won't be prohibitively     * expensive.     */    DBPRT(("%s: MERGED/SORTED OUTAGES LIST:\n", id));    for (outp = newlist; outp != NULL; outp = outp->next)	DBPRT(("%s:    %s\n", id, print_outage(outp)));    for (i = 0; i < MAX_OUTAGE_RESOLVE_ITERS; i++) {	found = resolve_outage_overlap(&newlist);		if (found < 0) {	    (void)sprintf(log_buffer, "couldn't resolve overlaps!");	    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);	    DBPRT(("%s: %s\n", id, log_buffer));	    /* Free the merged contents of the two lists. */	    free_outages(newlist);	    return (NULL);	}	if (found == 0) {	    /* No overlaps were found and resolved, so nothing left to do. */	    break;	}	/* At least one overlap was found and fixed.  Try to find more. */	continue;    }    if (i == MAX_OUTAGE_RESOLVE_ITERS) {	(void)sprintf(log_buffer, 	    "WARNING!!! Couldn't resolve all overlaps in %d passes!", i);	log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);	DBPRT(("%s: %s\n", id, log_buffer));    }    /*     * 'newlist' should now contain a list of outages, either for the system     * or for this individual host, ordered in time, and with no overlaps.     */    return (newlist);}static intresolve_outage_overlap(Outage **outlistp){    char    *id = "resolve_outage_overlap";    Outage  *new, *discard;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -