📄 toolkit.c
字号:
#ifdef DEBUG if (!schd_ENFORCE_PRIME_TIME) { fprintf(stderr,"WARNING!!! "); fprintf(stderr,"prime_time() called but ENFORCE_PRIME_TIME not set\n"); fprintf(stderr,"WARNING!!! "); fprintf(stderr,"This is almost certainly a bug!\n"); return (0); }#endif /* DEBUG */ /* If no time specified, use the scheduler's "TimeNow" time_t. */ if (when == 0) when = schd_TimeNow; tmptr = localtime(&when); cur_time = (tmptr->tm_hour * 3600) + (tmptr->tm_min * 60) + tmptr->tm_sec; /* * Check holidays array to determine if today is a holiday. Holidays * are not primetime. Note that days in struct timeval's are counted * starting at 0, not at the first like on the calendar. */ for (h_idx = 0; h_idx < Num_holidays; h_idx++) { if (tmptr->tm_yday + 1 == holidays[h_idx][0]) return (0); } /* Today isn't a holiday so is it SATURDAY, SUNDAY or WEEKDAY? */ switch (tmptr->tm_wday) { case 0: rcode = day_prime_time(SUNDAY, cur_time); break; case 6: rcode = day_prime_time(SATURDAY, cur_time); break; default: rcode = day_prime_time(WEEKDAY, cur_time); break; }#if 0 DBPRT(("schd_prime_time: it %s primetime at %s", rcode ? "is" : "is not", asctime(tmptr)));#endif /* 0 */ return (rcode);}/* Based on time of day and day of week, is it prime time now? */static int day_prime_time(int dow, int now){ int prime_time; int not_prime_time; prime_time = weekdays[dow][PRIME]; not_prime_time = weekdays[dow][NONPRIME]; switch (prime_time) { case ALL: return (1); /* Prime time all day */ case NONE: return (0); /* No prime time today */ default: /* XXX document this case */ if (not_prime_time > prime_time) { if ((now >= prime_time) && (now < not_prime_time)) return (1); else return (0); } else { if ((now >= not_prime_time) && (now < prime_time)) return (0); else return (1); } }}/* Initialize the holidays[] array from the contents of the holidays file */int schd_read_holidays(void){ char *id = "schd_read_holidays"; FILE *fd; char buf[255]; char *ptr, *err; int h_idx = 0; long day, line = 0; init_holidays(); if ((fd = fopen(HOLIDAYS_FILE, "r")) == NULL) { (void)sprintf(log_buffer, "Warning: holidays file (%s) is unreadable. Ignoring...", HOLIDAYS_FILE); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); return (-1); } /* Read lines from the holidays file one by one. */ while (fgets(buf, sizeof (buf), fd)) { line ++; if (strlen(buf) == (sizeof(buf) - 1)) { (void)sprintf(log_buffer, "Line %ld of %s is too long.", line, HOLIDAYS_FILE); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); return (-1); } /* Trim off comments before anything else is done. */ if ((ptr = strchr(buf, '*')) != NULL) *ptr = '\0'; /* Find first whitespace-separated token in the remaining string. */ ptr = strtok(buf, " \t"); /* Skip blank lines (may have been only a comment). */ if (ptr == NULL) continue; /* Skip 'YEAR ...' entries */ if (!strncmp(ptr, "YEAR", 4)) continue; /* * Line was not parsed otherwise -- must be a holiday. Holidays * are non prime, so set current holiday list to the day number * of the current year on which the holiday is celebrated. * Note a syntax error if the number doesn't parse nicely, or it * is nonsensical. */ day = strtol(ptr, &err, 10); if ((*err != '\0') || (day < 0) || (day > 365)) { (void)sprintf(log_buffer, "Syntax error in line %ld of %s", line, HOLIDAYS_FILE); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); return (-1); } /* SGI uses a day of 0 to indicate "ANY YEAR" - ignore these. */ if (day == 0) continue; /* No loss of precision, since 1 <= day <= 365 (see above). */ holidays[h_idx][0] = (int)day; holidays[h_idx][NONPRIME] = ALL; h_idx++; Num_holidays++; if (Num_holidays == MAX_HOLIDAYS) { (void)sprintf(log_buffer, "Only %d holidays allowed - skipping any remaining in %s", MAX_HOLIDAYS, HOLIDAYS_FILE); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); break; } } fclose(fd); return (Num_holidays);}/* * Initialize weekdays array. Default is "no primetime anytime", and no * holidays. * * Holidays are loaded from the file ''/usr/lib/acct/holidays'' */void init_holidays(void){ /* Default is no primetime anytime. */ weekdays[SATURDAY][PRIME] = NONE; weekdays[SATURDAY][NONPRIME] = ALL; weekdays[SUNDAY][PRIME] = NONE; weekdays[SUNDAY][NONPRIME] = ALL; weekdays[WEEKDAY][PRIME] = schd_PRIME_TIME_START; weekdays[WEEKDAY][NONPRIME] = schd_PRIME_TIME_END; Num_holidays = 0; /* No holidays to start out. */}#define MIDNIGHT 86400/* * Calculate the number of seconds until the next prime time begins. * If the 'when' argument is non-zero, determine how long from the * time given. Otherwise, determine how long it is from now. */int schd_secs_til_prime(time_t when){ struct tm *tmptr; time_t now; /* Number of seconds elapsed since midnight */ int next_prime; int prime_start; int days; int p; if (when == 0) { /* No time specified -- find out what time it is now. */ time(&when); } tmptr = localtime(&when); /* * Calculate number of seconds elapsed since last midnight (00:00:00). */ now = ((tmptr->tm_hour * 60 * 60) + (tmptr->tm_min * 60) + tmptr->tm_sec); /* * Is today a FRIDAY or SATURDAY? Assume there is no primetime on * weekends, and calculate number of days forward from that. */ switch (tmptr->tm_wday) { case 5: /* Friday */ /* * If it's before the start of prime time, then the next prime time * is in a matter of hours. Otherwise, prime time starts on the * following Monday (in 2 days). */ p = weekdays[WEEKDAY][PRIME]; if (now < p) days = 0; else days = 2; break; case 6: /* Saturday */ /* * Primetime won't start until Monday, so we know we have at least * one day to wait (all on Sunday). */ days = 1; break; default: /* Sunday through Thursday, expect primetime to start "soon" */ days = 0; break; } /* * 'days' tells us how many days we need to get to a weekday (either * this day, or the following Monday morning). This will be the first * prime time. This will need a special case if a specific weekday * does not have a prime time. */ prime_start = weekdays[WEEKDAY][PRIME]; /* * If we are already past the start of this prime time, than the *next* * prime time will begin tomorrow morning. To get the time until then, * take the number of seconds in a day, and subtract how far into today * you've gotten. XXX is this right in all cases? */ if (now >= prime_start) next_prime = MIDNIGHT - (now - prime_start); else next_prime = prime_start - now; /* Add in the time for any full days without primetime. */ next_prime += (days * MIDNIGHT); return (next_prime);}/* * Calculate the number of seconds until the next non-prime time begins. * If the 'when' argument is non-zero, determine how long from the * time given. Otherwise, determine how long it is from now. */int schd_secs_til_nonprime(time_t when){ struct tm *tmptr; time_t now; /* Number of seconds elapsed since midnight */ int prime_end; int non_prime_start; if (when == 0) { /* No time specified -- find out what time it is now. */ time(&when); } tmptr = localtime(&when); /* * Calculate number of seconds elapsed since last midnight (00:00:00). */ now = ((tmptr->tm_hour * 60 * 60) + (tmptr->tm_min * 60) + tmptr->tm_sec); /* Find how many seconds from midnight until the next nonprime time. */ non_prime_start = weekdays[WEEKDAY][NONPRIME]; prime_end = non_prime_start - now; return (prime_end);}int schd_reset_observed_pt (QueueList *qlist){ QueueList *qptr; int nqueues; nqueues = 0; for (qptr = qlist; qptr != NULL; qptr = qptr->next) { qptr->queue->observe_pt = (schd_ENFORCE_PRIME_TIME && schd_TimeNow >= schd_ENFORCE_PRIME_TIME); ++ nqueues; } return (nqueues);}/* * The size of the buffer to allocate to hold the message that will be * sent to the user. This is dynamically allocated (once) since it may * need to be a very large buffer, depending on the complexity of the * message. */#define MSG_BUFFER_SIZE 4000extern int connector;intschd_reject_job(Job *job, char *reason){ char *id = "schd_reject_job"; static char *message = NULL; int rc = 0; if (message == NULL) { if ((message = (char *)malloc(MSG_BUFFER_SIZE)) == NULL) { (void)sprintf(log_buffer, "cannot malloc %d bytes\n", MSG_BUFFER_SIZE); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); return (-1); } } (void)sprintf(message, "\n" "PBS job '%s' was rejected by all execution queues.\n" "\n" "The reason given for this action was :\n" "\n" " %s\n" "\n" "Please correct the problem and resubmit your job, or contact the PBS\n" "administrator for assistance.\n" "\n" "Thank you.\n" "\n", job->jobid, reason); /* * Ask PBS to delete the job from the queue, which should deliver the * message to the user. */ rc = pbs_deljob(connector, job->jobid, message); if (rc) { (void)sprintf(log_buffer, "pbs_deljob failed: error %d", rc); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); return 1; } /* * Delete this job from the queue's list (move to a NULL queue) */ DBPRT(("JOB %s DELETED!!!\n", job->jobid)); DBPRT(("Message: %s\n", reason)); schd_move_job_to(job, NULL); return 0;}void schd_check_primetime(){ char *id = "check_primetime"; /* * See if the holidays file has changed. If it's re-read successfully, * update the last changed timestamp. Otherwise, keep it around and * keep trying to re-read it until someone fixes the problem. "This * shouldn't happen." */ if (schd_file_has_changed(HOLIDAYS_FILE, 0) > 0) { (void)sprintf(log_buffer, "Attempting to update holidays/primetime from %s.", HOLIDAYS_FILE); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER,id,log_buffer); DBPRT(("%s\n", log_buffer)); if (schd_read_holidays() < 0) { (void)sprintf(log_buffer, "Failed to read holidays file."); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s\n", log_buffer)); } else { /* Reset the "last changed time", since it was re-read okay. */ (void)schd_file_has_changed(HOLIDAYS_FILE, 1); } } /* * If this is the first run during non-primetime, set all the execution * queues' observed primetime back to 'on'. If it's primetime now, set * the "last run in primetime" global. */ if (schd_prime_time(0)) { last_run_in_pt = 1; } else if (last_run_in_pt) { DBPRT(("%s: First non-pt run, reset queue observed times.\n",id)); if (schd_BatchQueues) schd_reset_observed_pt(schd_BatchQueues); /* Last run was not in prime time. */ last_run_in_pt = 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -