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

📄 dedicated.c

📁 openPBS的开放源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /*     * Walk the list of outages, looking for overlaps and resolving them.     * Once an overlap has been resolved, return 1 to indicate that there     * was an overlap found.  In this case, this function should be called     * again.  If no overlaps are found, return 0 to indicate that fact.     * Return -1 on error.     *     * Note that system outages should take priority over per-host outages.     *     * The outages list *must* be sorted into ascending order of start-time     * for the outages.     *     * The five possible overlap scenarios are ('*' indicates system outage     * time, '-' indicates host outages, blank space is non-outage time) :     *     * Time      ***     ***     -----    -----             -----     *  |       -***-    ***     -----     ***     *  |       -***-   -----     ***      ***               ***      *  |        ***    -----     ***     -----              ***      *  |     *  V   Case: 1       2        3        4                 5 (no overlap)     */    /*      * Discarded outages go on this list, so they can be easily reclaimed      * if another outage needs to be allocated.     */    discard = NULL;    /*      * Start with the original list head pointer.  This will be replaced     * with the new head at the end of the for loop.     */    new  = *outlistp;    for (this = new; this->next != NULL; this = next) {	next = this->next;	/* 	 * If this outage ends before the next one starts, then there is no 	 * overlap between these two elements.	 */	if (this->end_time < next->beg_time)	    continue;	/* Found an overlap. */	found = 1;	/* 	 * Check the types of the two outages.  If they are the same, extend	 * the first entry to stretch through the whole time, note the fact.	 * Otherwise, figure out which is the host outage, and which is the 	 * system outage, and assign pointers respectively.	 */	if ((this->flags & OUTAGE_FLAGS_SYSTEM) == 	    (next->flags & OUTAGE_FLAGS_SYSTEM))	{	    DBPRT(("%s: Two outages of same type (%s) overlap.\n", id,		(this->flags & OUTAGE_FLAGS_SYSTEM) ? "system" : "host"));	    DBPRT(("%s: Outages are (%s)\n", id, print_outage(this)));	    DBPRT(("%s:    (%s)\n", id, print_outage(next)));	    /*	     * Expand both outages to cover the same time.  This will	     * cause it to be dealt with by case 1 below.	     */	    this->beg_time = MIN(this->beg_time, next->beg_time);	    this->end_time = MAX(this->end_time, next->end_time);	    next->beg_time = this->beg_time;	    next->end_time = this->end_time;	    /* Create new time/date strings for the different time_t's. */	    make_time_strs(this);	    make_time_strs(next);	    DBPRT(("%s: Overlap extended to (%s)\n", id, print_outage(this)));	    /* And assign them "relative priorities". */	    sys  = this;	    host = next;	} else {	    /* Figure out which is the system and which is the host outage. */	    if (this->flags & OUTAGE_FLAGS_SYSTEM) {		sys  = this;		host = next;	    } else {		host = this;		sys  = next;	    }	}	DBPRT(("%s: system outage (%s) overlaps\n", id, print_outage(sys)));	DBPRT(("%s:   host outage (%s)\n", id, print_outage(host)));	sys_beg  = sys->beg_time;	sys_end  = sys->end_time;	host_beg = host->beg_time;	host_end = host->end_time;	/*	 * Quick sanity check for reasonable outage times.	 */	if ((sys_end - sys_beg) < 1) {	    (void)sprintf(log_buffer, 		"system outage (%s) less than 1 second!\n", print_outage(sys));	    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);	    DBPRT(("%s: %s\n", id, log_buffer));	    /* Note the problem and return an error. */	    found = -1;	    break;	}	if ((host_end - host_beg) < 1) {	    (void)sprintf(log_buffer, 		"host outage (%s) less than 1 second!\n", print_outage(host));	    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);	    DBPRT(("%s: %s\n", id, log_buffer));	    /* Note the problem and return an error. */	    found = -1;	    break;	}	/* Case 1: 'sys' starts before, and ends after, 'host'. 	 * This is a complete overlap (the easy case).  This is either a 	 * duplicated host outage, or a system outage overlaps the host	 * outage.  In either case, choose one to discard and it's done.	 */	if ((sys_beg <= host_beg) && (sys_end >= host_end)) {	    DBPRT(("%s: case 1: sys outage overlaps all of host outage.\n", 		id));	    DBPRT(("%s:     Discarding host outage (%s)\n", id, 		 print_outage(host)));	    /* 	     * Discard the per-host outage onto the discard pile.  It	     * may be re-used if a new element is required.  If not, it	     * will be freed at the end of the function.  If the host	     * outage is the first in the list, bump the new list pointer	     * forward, otherwise find the previous element and point over	     * the host element to the next one.	     */	    if (host != new) {		for (outp = new; outp != NULL; outp = outp->next)		    /* Walk list looking for previous pointer. */		    if (outp->next == host)			break;		if (outp == NULL) {		    DBPRT(("%s: host outage not found!\n", id));		    found = -1;		    break;		}		DBPRT(("%s: host outage not head of list.  Skipping from %s\n",		    id, print_outage(outp)));		outp->next = host->next;	    } else {		new = host->next;		DBPRT(("%s: host outage is head of list.  new head %s\n",		    id, print_outage(new)));	    }	    host->next = discard;	    discard = host;	    DBPRT(("%s: Place host on discard pile %s\n", id, 		print_outage(discard)));	    /* This conflict is now resolved.  Break out of loop. */	    break;	}	/* Case 2: 'system' starts before, and ends before, 'host' outage.	 * Adjust the host outage to start just after the system outage ends.	 * The conflict is then resolved.	 */	if ((sys_beg <= host_beg) && (sys_end < host_end)) {	    DBPRT(("%s: case 2: sys outage overlaps start of host outage.\n",		id));	    host->beg_time = sys_end + 1;	    /* Sanity check.  "This can't happen." */	    if (host->end_time <= host->beg_time) {		DBPRT(("%s: host outage %s < 1 second long!", id, 		     print_outage(host)));		found = -1;		break;	    }	    	    /* Create new time/date strings for the changed time_t's. */	    make_time_strs(host);	    DBPRT(("%s: host outage bumped to (%s)\n", id, print_outage(host)));		    /* That's all that's required to resolve the conflict. */	    break;	}	/* Case 3: 'system' outage starts after, and ends after, 'host' outage.	 * Adjust the host outage to end just before the system outage starts.	 * The conflict is then resolved.	 */	if ((sys_beg > host_beg) && (sys_end >= host_end)) {	    DBPRT(("%s: case 3: sys outage overlaps end of host outage.\n", 	        id));	    host->end_time = sys_beg - 1;	    /* Sanity check.  "This can't happen." */	    if (host->end_time <= host->beg_time) {		DBPRT(("%s: host outage %s < 1 second long!", id, 		     print_outage(host)));		found = -1;		break;	    }	    	    /* Create new time/date strings for the changed time_t's. */	    make_time_strs(host);	    DBPRT(("%s: host outage bumped to (%s)\n", id, print_outage(host)));		    /* That's all that's required to resolve the conflict. */	    break;	}	/* Case 4: 'system' outage starts after, and ends before 'host' outage.	 * System outage splits the host outage into two pieces.  Shorten the	 * first piece like case #3 above, and create a new Outage for the 	 * remaining chunk.	 */	if ((sys_beg > host_beg) && (sys_end < host_end)) {	    DBPRT(("%s: case 4: sys outage overlaps middle of host outage.\n",		id));	    /* Shorten the original host entry to first chunk of the outage. */	    host->end_time = sys_beg - 1;	    /* Create a new host chunk to follow the system one on the list. */	    if (discard) {		outp = discard;		discard = discard->next;	    } else {		if ((outp = (Outage *)malloc(sizeof (Outage))) == NULL) {		    (void)sprintf(log_buffer, "malloc(%d) failed!", 			(int)sizeof (Outage));		    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, 			 log_buffer);		    DBPRT(("%s: %s\n", id, log_buffer));		    found = -1;		    break;		}	    }	    /* Initialize the new element. */	    memset((void *)outp, 0, sizeof (Outage));	    /* Point to the host's exechost, and fill in the time fields. */	    outp->exechost = host->exechost;	    outp->beg_time = sys_end + 1;	    outp->end_time = host_end;	    /* Now recompute the date and time strings for each outage. */	    make_time_strs(host);	/* The original "first" chunk */	    make_time_strs(outp);	/* The newly-created 2nd chunk */	    DBPRT(("%s: Split host outage into :\n", id));	    DBPRT(("%s:       host outage (%s)\n", id, print_outage(host)));	    DBPRT(("%s:        sys outage (%s)\n", id, print_outage(sys)));	    DBPRT(("%s:   new host outage (%s)\n", id, print_outage(outp)));	    /* And link the new host outage in after the system outage. */	    outp->next = sys->next;	    sys->next  = outp;	    /* And this case is resolved. */	    break;	}		/* Unexpected case!  Return an error! */	(void)sprintf(log_buffer, "unexpected outage overlap!");	log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);	DBPRT(("%s: %s\n", id, log_buffer));	found = -1;	break;    }    /*      * Replace the pointer to the head of the list with the head of the new     * outage list.  The new list may not have the same head as the old one     * (if the original head was discarded).     */    *outlistp = new;    /* Clean up the discard list, if necessary. */    if (discard)	free_outages(discard);    discard = NULL;    return (found);}/* * Return a pointer to a static buffer containing a string describing the * times of the outage. */static char *print_outage(Outage *outp){    static char buffer[64];    sprintf(buffer, "%s %s:%02.2d - %s %s:%02.2d [%s]", 	outp->beg_datestr, outp->beg_timestr, (int)(outp->beg_time % 60),	outp->end_datestr, outp->end_timestr, (int)(outp->end_time % 60),	outp->exechost);    return (buffer);}static intcompare_outages_time(const void *e1, const void *e2){    Outage  *outage1 = *(Outage **)e1;    Outage  *outage2 = *(Outage **)e2;    time_t   diff;    /* Sort first based on starting time, from soonest to latest. */    diff = outage1->beg_time - outage2->beg_time;    if (diff)	return (diff);    /* Break ties by sorting by end time.  */    diff = outage1->end_time - outage2->end_time;    return (diff);}static int make_time_strs (Outage *outp){    struct tm *tm_ptr;    if ((tm_ptr = localtime(&(outp->beg_time))) == NULL)	return (1);    sprintf(outp->beg_datestr, "%2.2d/%2.2d/%4.4d",	tm_ptr->tm_mon + 1, tm_ptr->tm_mday, tm_ptr->tm_year + 1900);    sprintf(outp->beg_timestr, "%2.2d:%2.2d",	tm_ptr->tm_hour, tm_ptr->tm_min);    if ((tm_ptr = localtime(&(outp->end_time))) == NULL)	return (1);    sprintf(outp->end_datestr, "%2.2d/%2.2d/%4.4d",	tm_ptr->tm_mon + 1, tm_ptr->tm_mday, tm_ptr->tm_year + 1900);    sprintf(outp->end_timestr, "%2.2d:%2.2d",	tm_ptr->tm_hour, tm_ptr->tm_min);    return (0);}/* * Free each element of a list of outages.  Note that the 'exechost' field * for the outage points back to the OutageList->host, and isn't allocated * storage. */static int free_outages(Outage *outages){    int n;    Outage *ptr, *next;    for (n = 0, ptr = outages; ptr != NULL; ptr = next) {	next = ptr->next;	free(ptr);	n++;    }    return (n);}/* Parse "MM/DD/YYYY HH:MM" style dates into seconds since the Epoch. */static int MMDDYYYY_HHMM(char *MMDDYYYY, char *HHMM){    /* char   *id = "MMDDYYYY_HHMM"; */    struct tm junk;    char    copy[MAX_TXT + 1];        strcpy(copy, MMDDYYYY);	/* Copy it so we can modify the string. */    copy[2] = copy[5] = '\0';	/* 'MM/DD/YYYY\0' ==> 'MM\0DD\0YYYY\0' */    junk.tm_mon  = atoi(copy);    junk.tm_mday = atoi(copy + 3);    junk.tm_year = atoi(copy + 6);    junk.tm_mon  -= 1;		/* mktime() counts from 0, not 1 like us */    junk.tm_year -= 1900;	/* mktime() counts from 1900 */    strcpy(copy, HHMM);		/* Copy it so we can modify the string. */    copy[2] = '\0';		/* 'HH:MM\0' ==> 'HH\0MM\0' */    junk.tm_hour = atoi(copy);    junk.tm_min = atoi(copy + 3);    junk.tm_sec = 0;    junk.tm_isdst = -1;		/* Choose correct DST value from timezone */    return (int)mktime(&junk);}

⌨️ 快捷键说明

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