/** * @brief * are_we_primary - determines the failover role, are we the Primary * Server, the Secondary Server or the only Server (no failover) * * @return int: failover server role * @retval FAILOVER_NONE - failover not configured * @retval FAILOVER_PRIMARY - Primary Server * @retval FAILOVER_SECONDARY - Secondary Server * @retval FAILOVER_CONFIG_ERROR - error in pbs.conf configuration * @retval FAILOVER_NEITHER - failover configured, but I am neither primary/secondary */ enum failover_state are_we_primary(void) { char hn1[PBS_MAXHOSTNAME+1]; /* both secondary and primary should be set or neither set */ if ((pbs_conf.pbs_secondary == NULL) && (pbs_conf.pbs_primary == NULL)) return FAILOVER_NONE; if ((pbs_conf.pbs_secondary == NULL) || (pbs_conf.pbs_primary == NULL)) return FAILOVER_CONFIG_ERROR; if (get_fullhostname(pbs_conf.pbs_primary, primary_host, (sizeof(primary_host) - 1))==-1) { log_err(-1, "comm_main", "Unable to get full host name of primary"); return FAILOVER_CONFIG_ERROR; } if (strcmp(primary_host, server_host) == 0) return FAILOVER_PRIMARY; /* we are the listed primary */ if (get_fullhostname(pbs_conf.pbs_secondary, hn1, (sizeof(hn1) - 1))==-1) { log_err(-1, "comm_main", "Unable to get full host name of secondary"); return FAILOVER_CONFIG_ERROR; } if (strcmp(hn1, server_host) == 0) return FAILOVER_SECONDARY; /* we are the secondary */ return FAILOVER_NEITHER; /* failover configured, but I am neither primary nor secondary */ }
/** * @brief * validate if hname is local host * * @param[in] hname - host name * * @return int * @retval 0 success * @retval 1 error * */ int is_local_host(char *hname) { char hname_full[PBS_MAXSERVERNAME+1]; char cname_short[PBS_MAXSERVERNAME+1]; char cname_full[PBS_MAXSERVERNAME+1]; if (gethostname(cname_short, PBS_MAXSERVERNAME) != 0) return (0); /* * Compare with "locahost" and "localhost.localdomain". */ #ifdef WIN32 if (stricmp(hname, cname_short) == 0 || stricmp(hname, LOCALHOST_SHORTNAME) == 0 || stricmp(hname, LOCALHOST_FULLNAME)== 0) return (1); #else if (strcmp(hname, cname_short) == 0 || strcmp(hname, LOCALHOST_SHORTNAME) == 0 || strcmp(hname, LOCALHOST_FULLNAME)== 0) return (1); #endif if (get_fullhostname(cname_short, cname_full, PBS_MAXSERVERNAME) != 0) return (0); if (get_fullhostname(hname, hname_full, PBS_MAXSERVERNAME) != 0) return (0); if (strcmp(hname_full, cname_full) == 0) return (1); return (0); }
/** * @brief * Given the two hostnames, compare their short names and full names to make sure if those * point to same host. * * @param[in] host1 - first host * @param[in] host2 - second host * * @return int * @retval 0 - hostnames point to different hosts * @retval 1 - hostnames point to same host * */ int is_same_host(char *host1, char *host2) { char host1_full[PBS_MAXHOSTNAME + 1] = {'\0'}; char host2_full[PBS_MAXHOSTNAME + 1] = {'\0'}; if (host1 == NULL || host2 == NULL) return 0; if (strcasecmp(host1, host2) == 0) return 1; if ((get_fullhostname(host1, host1_full, (sizeof(host1_full) - 1)) != 0) || (get_fullhostname(host2, host2_full, (sizeof(host2_full) - 1)) != 0)) return 0; if (strcasecmp(host1_full, host2_full) == 0) return 1; return 0; }
int is_ms_on_server( const job *pjob) { char mom_fullhostname[PBS_MAXHOSTNAME + 1]; int ms_on_server = 0; char *exec_hosts = pjob->ji_wattr[JOB_ATR_exec_host].at_val.at_str; if (exec_hosts) { char *host_tok = threadsafe_tokenizer(&exec_hosts, "+"); if (host_tok) { char *slash; if ((slash = strchr(host_tok, '/')) != NULL) *slash = '\0'; snprintf(mom_fullhostname, sizeof(mom_fullhostname), "%s", host_tok); if (strstr(server_host, ".")) if (strstr(host_tok, ".") == NULL) get_fullhostname(host_tok, mom_fullhostname, sizeof(mom_fullhostname), NULL); ms_on_server = strcmp(server_host, mom_fullhostname) == 0; } } return(ms_on_server); } /* is_ms_on_server */
/** * @brief * parses path and prepares complete path name * * @param[in] path_in - the path name provided as input to be parsed * @param[out] path_out - contains final parsed and prepared path, must * be at least MAXPATHLEN+1 bytes. * * @return int * @retval 0 - success in parsing * @retval nonzero - error encountered in parsing */ int prepare_path(char *path_in, char *path_out) { char *c = NULL; int have_fqdn = 0; /* Initialization with {'\0'} populates entire array */ char host_name[PBS_MAXSERVERNAME + 1] = {'\0'}; /* short host name */ int h_pos = 0; char path_name[MAXPATHLEN + 1] = {'\0'}; size_t path_len; int p_pos = 0; char *host_given = NULL; struct stat statbuf = {0}; dev_t dev = 0; ino_t ino = 0; if (!path_out) return 1; *path_out = '\0'; if (!path_in) return 1; /* Begin the parse */ for (c = path_in; *c; c++) { if (isspace(*c) == 0) break; } if (*c == '\0') return 1; #ifdef WIN32 /* Check for drive letter in Windows */ if (!(isalpha(*c) && (*(c + 1) == ':'))) #endif { /* Looking for a hostname */ if ((host_given = strchr(c, ':')) != NULL) { /* Capture the hostname portion */ for (h_pos = 0; (h_pos < sizeof(host_name)); h_pos++, c++) { if (isalnum(*c) || (*c == '.') || (*c == '-') #ifdef WIN32 /* Underscores are legal in Windows */ || (*c == '_') #endif ) { host_name[h_pos] = *c; } else { break; } } if (*c != ':') return 1; /* Advance past the colon */ c++; } } /* Looking for a posix path */ for (p_pos = 0; p_pos < sizeof(path_name); p_pos++, c++) { if (!isprint(*c)) break; path_name[p_pos] = *c; } /* Should be at end of string */ if (*c != '\0') return 1; path_len = strlen(path_name); if (path_len == 0 && strlen(host_name) == 0) return 1; /* appending a slash in the end to indicate that it is a directory */ if ((path_name[path_len - 1] != '/') && (path_name[path_len - 1] != '\\') && (stat(path_name, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) { if ((path_len + 1) < sizeof(path_name)) { strcat(path_name, "/"); path_len++; } } #ifdef WIN32 if (IS_UNCPATH(path_name)) { /* * given path is UNC path * so just skip hostname * as UNC path dose not require it */ host_given = NULL; host_name[0] = '\0'; } else #endif { /* get full host name */ if (host_name[0] == '\0') { if (pbs_conf.pbs_output_host_name) { /* use the specified host for returning the file */ snprintf(host_name, sizeof(host_name), "%s", pbs_conf.pbs_output_host_name); have_fqdn = 1; } else { if (gethostname(host_name, sizeof(host_name)) != 0) return 2; host_name[sizeof(host_name) - 1] = '\0'; } } if (have_fqdn == 0) { char host_fqdn[PBS_MAXSERVERNAME + 1] = {'\0'}; /* need to fully qualify the host name */ if (get_fullhostname(host_name, host_fqdn, PBS_MAXSERVERNAME) != 0) return 2; strncpy(path_out, host_fqdn, MAXPATHLEN); /* FQ host name */ } else { strncpy(path_out, host_name, MAXPATHLEN); /* "localhost" or pbs_output_host_name */ } path_out[MAXPATHLEN - 1] = '\0'; /* finish preparing complete host name */ if (strlen(path_out) < MAXPATHLEN) strcat(path_out, ":"); } #ifdef WIN32 if (path_name[0] != '/' && path_name[0] != '\\' && host_given == NULL && strchr(path_name, ':') == NULL ) #else if (path_name[0] != '/' && host_given == NULL) #endif { char cwd[MAXPATHLEN + 1] = {'\0'}; c = getenv("PWD"); /* PWD carries a name that will cause */ if (c != NULL) { /* the NFS to mount */ if (stat(c, &statbuf) < 0) { /* can't stat PWD */ c = NULL; } else { dev = statbuf.st_dev; ino = statbuf.st_ino; if (stat(".", &statbuf) < 0) { perror("prepare_path: cannot stat current directory:"); *path_out = '\0'; return (1); } } if (dev == statbuf.st_dev && ino == statbuf.st_ino) { snprintf(cwd, sizeof(cwd), "%s", c); } else { c = NULL; } } if (c == NULL) { c = getcwd(cwd, MAXPATHLEN); if (c == NULL) { perror("prepare_path: getcwd failed : "); *path_out = '\0'; return (1); } } #ifdef WIN32 /* get UNC path (if available) if it is mapped drive */ get_uncpath(cwd); if (IS_UNCPATH(cwd)) { strcpy(path_out, cwd); if (cwd[strlen(cwd)-1] != '\\') strcat(path_out, "\\"); } else #endif { strncat(path_out, cwd, (MAXPATHLEN + 1) - strlen(path_out)); if (strlen(path_out) < MAXPATHLEN) strcat(path_out, "/"); } } #ifdef WIN32 /* get UNC path (if available) if it is mapped drive */ get_uncpath(path_name); if (IS_UNCPATH(path_name)) strcpy(path_out, path_name); else { /* * check whether given <path_name> is relative path * without drive on localhost and <cwd> is not UNC path? * if yes then do not append drive into <path_out> * otherwise append drive into <path_out> */ if (is_local_host(host_name) && (strchr(path_name, ':') == NULL) && (path_out[strlen(path_out) - 1] != '/') && (!IS_UNCPATH(path_out))) { char drivestr[3] = {'\0'}; char drivestr_unc[MAXPATHLEN + 1] = {'\0'}; drivestr[0] = _getdrive() + 'A' - 1; drivestr[1] = ':'; drivestr[2] = '\0'; /* * check whether <drivestr> is mapped drive? * by calling get_uncpath() * if yes then remove <hostname> part from <path_out> * * This is the case when user submit job * from mapped drive with relative path without drive * in path ex. localhost:err or localhost:out */ snprintf(drivestr_unc, sizeof(drivestr_unc), "%s\\", drivestr); get_uncpath(drivestr_unc); if (IS_UNCPATH(drivestr_unc)) { strncpy(path_out, drivestr_unc, MAXPATHLEN); } else { strncat(path_out, drivestr, MAXPATHLEN - strlen(path_out)); } } strncat(path_out, path_name, MAXPATHLEN - strlen(path_out)); } back2forward_slash(path_out); /* "\" translate to "/" for path */ strcpy(path_out, replace_space(path_out, "\\ ")); path_out[MAXPATHLEN - 1] = '\0'; #else strncat(path_out, path_name, (MAXPATHLEN + 1) - strlen(path_out)); #endif return (0); }
int main( int argc, /* I */ char **argv) /* I */ { char job_id1[PBS_MAXCLTJOBID+1]; /* from the command line */ char job_id2[PBS_MAXCLTJOBID+1]; /* from the command line */ char job_id1_out[PBS_MAXCLTJOBID+1]; char job_id2_out[PBS_MAXCLTJOBID+1]; char *pn; int port1 = 0; int port2 = 0; char server_out1[MAXSERVERNAME+1]; char server_out2[MAXSERVERNAME+1]; char svrtmp[MAXSERVERNAME+1] = ""; int connect; int stat = 0; int rc = 0; int local_errno = 0; if (argc != 3) { static char usage[] = "usage: qorder job_identifier job_identifier\n"; fprintf(stderr, "%s", usage); exit(2); } snprintf(job_id1, sizeof(job_id1), "%s", argv[1]); snprintf(job_id2, sizeof(job_id2), "%s", argv[2]); svrtmp[0] = '\0'; if (get_server(job_id1, job_id1_out, sizeof(job_id1_out), svrtmp, sizeof(svrtmp))) { fprintf(stderr, "qorder: illegally formed job identifier: %s\n", job_id1); exit(1); } if (*svrtmp == '\0') { if ((pn = pbs_default())) { strcpy(svrtmp, pn); } else { fprintf(stderr, "qorder: could not get default server: %s\n", job_id1); exit(1); } } if ((pn = strchr(svrtmp, (int)':')) != 0) { *pn = '\0'; port1 = atoi(pn + 1); } if (get_fullhostname(svrtmp, server_out1, MAXSERVERNAME, NULL) != 0) { fprintf(stderr, "qorder: invalid server name: %s\n", job_id1); exit(1); } svrtmp[0] = '\0'; if (get_server(job_id2, job_id2_out, sizeof(job_id2_out), svrtmp, sizeof(svrtmp))) { fprintf(stderr, "qorder: illegally formed job identifier: %s\n", job_id2); exit(1); } if (*svrtmp == '\0') { if ((pn = pbs_default())) { snprintf(svrtmp, sizeof(svrtmp), "%s", pn); } else { fprintf(stderr, "qorder: could not get default server: %s\n", job_id1); exit(1); } } if ((pn = strchr(svrtmp, (int)':')) != 0) { *pn = '\0'; port2 = atoi(pn + 1); } if (get_fullhostname(svrtmp, server_out2, MAXSERVERNAME, NULL) != 0) { fprintf(stderr, "qorder: invalid server name: %s\n", job_id2); exit(1); } if ((strcmp(server_out1, server_out2) != 0) || (port1 != port2)) { fprintf(stderr, "qorder: both jobs ids must specify the same server\n"); exit(1); } if (pn != NULL) *pn = ':'; /* restore : if it was present */ connect = cnt2server(svrtmp); if (connect <= 0) { local_errno = -1 * connect; if (svrtmp[0] != 0) fprintf(stderr, "qorder: cannot connect to server %s (errno=%d) %s\n", svrtmp, local_errno, pbs_strerror(local_errno)); else fprintf(stderr, "qorder: cannot connect to server %s (errno=%d) %s\n", pbs_server, local_errno, pbs_strerror(local_errno)); exit(1); } stat = pbs_orderjob_err(connect, job_id1_out, job_id2_out, NULL, &local_errno); if (stat != 0) { prt_job_err("qorder", connect, ""); rc = local_errno; } pbs_disconnect(connect); exit(rc); } /* END main() */
int main(int argc, char *argv[]) { int i; char mom_name[PBS_MAXHOSTNAME+1]; int mom_port = 0; int c, rc; int mom_sd; char *req; #ifdef WIN32 if (winsock_init()) { return 1; } #endif if (gethostname(mom_name, (sizeof(mom_name) - 1)) < 0 ) mom_name[0] = '\0'; while ((c = getopt(argc, argv, "m:p:")) != EOF) { switch (c) { case 'm': strcpy(mom_name, optarg); break; case 'p': mom_port = atoi(optarg); break; default: fprintf(stderr, "Bad option: %c\n", c); } } if (mom_name[0] == '\0' || optind == argc) { fprintf(stderr, "Error in usage: pbs_rmget [-m mom name] [-p mom port] <req1>...[reqN]\n"); return 1; } if(set_msgdaemonname("pbs_rmget")) { fprintf(stderr, "Out of memory\n"); return 1; } /* load the pbs conf file */ if (pbs_loadconf(0) == 0) { fprintf(stderr, "%s: Configuration error\n", argv[0]); return (1); } if (pbs_conf.pbs_use_tcp == 1) { struct tpp_config tpp_conf; fd_set selset; struct timeval tv; if (!pbs_conf.pbs_leaf_name) { char my_hostname[PBS_MAXHOSTNAME+1]; if (gethostname(my_hostname, (sizeof(my_hostname) - 1)) < 0) { fprintf(stderr, "Failed to get hostname\n"); return -1; } pbs_conf.pbs_leaf_name = get_all_ips(my_hostname, log_buffer, sizeof(log_buffer) - 1); if (!pbs_conf.pbs_leaf_name) { fprintf(stderr, "%s\n", log_buffer); fprintf(stderr, "%s\n", "Unable to determine TPP node name"); return -1; } } /* We don't want to show logs related to connecting pbs_comm on console * this set this flag to ignore it */ log_mask = SHOW_NONE; /* set tpp function pointers */ set_tpp_funcs(log_tppmsg); /* call tpp_init */ rc = 0; #ifndef WIN32 if (pbs_conf.auth_method == AUTH_MUNGE) rc = set_tpp_config(&pbs_conf, &tpp_conf, pbs_conf.pbs_leaf_name, -1, pbs_conf.pbs_leaf_routers, pbs_conf.pbs_use_compression, TPP_AUTH_EXTERNAL, get_ext_auth_data, validate_ext_auth_data); else #endif rc = set_tpp_config(&pbs_conf, &tpp_conf, pbs_conf.pbs_leaf_name, -1, pbs_conf.pbs_leaf_routers, pbs_conf.pbs_use_compression, TPP_AUTH_RESV_PORT, NULL, NULL); if (rc == -1) { fprintf(stderr, "Error setting TPP config\n"); return -1; } if ((rpp_fd = tpp_init(&tpp_conf)) == -1) { fprintf(stderr, "rpp_init failed\n"); return -1; } /* * Wait for net to get restored, ie, app to connect to routers */ FD_ZERO(&selset); FD_SET(rpp_fd, &selset); tv.tv_sec = 5; tv.tv_usec = 0; select(FD_SETSIZE, &selset, NULL, NULL, &tv); rpp_poll(); /* to clear off the read notification */ /* Once the connection is established we can unset log_mask */ log_mask &= ~SHOW_NONE; } else { /* set rpp function pointers */ set_rpp_funcs(log_rppfail); } /* get the FQDN of the mom */ c = get_fullhostname(mom_name, mom_name, (sizeof(mom_name) - 1)); if (c == -1) { fprintf(stderr, "Unable to get full hostname for mom %s\n", mom_name); return -1; } if ((mom_sd = openrm(mom_name, mom_port)) < 0) { fprintf(stderr, "Unable to open connection to mom: %s:%d\n", mom_name, mom_port); return 1; } for (i = optind; i < argc; i++) addreq(mom_sd, argv[i]); for (i = optind; i < argc; i++) { req = getreq(mom_sd); if (req == NULL) { fprintf(stderr, "Error getting response %d from mom.\n", i - optind); return 1; } printf("[%d] %s\n", i - optind, req); free(req); } closerm(mom_sd); return 0; }
/** * Take a job ID string and parse it into * job ID and server name parts. * * @param job_id_in Input string of the form <job number>[.<parent server name>][@<host server url>] * @param job_id_out Output string containing only the job ID part of the input specification. * @param server_out Output string containing nothing or a host url if specified. */ int get_server( char *job_id_in, /* read only */ char *job_id_out, /* write only */ int job_id_out_size, /* sizeof the out buffer */ char *server_out, /* write only */ int server_out_size) /* sizeof the out buffer */ { char *seq_number; char *parent_server; char *current_server; char def_server[PBS_MAXSERVERNAME + 1]; char host_server[PBS_MAXSERVERNAME + 1]; char *c; /* parse the job_id_in into components */ if (!strcasecmp("all",job_id_in)) { snprintf(job_id_out, job_id_out_size, "%s", job_id_in); server_out[0] = '\0'; } else { if (parse_jobid(job_id_in, &seq_number, &parent_server, ¤t_server)) { return(1); } /* Apply the above rules, in order, except for the locate job request. * That request is only sent if the job is not found on the local server. */ if (notNULL(current_server)) { /* @server found */ snprintf(server_out, server_out_size, "%s", current_server); } else if (notNULL(parent_server)) { /* .server found */ snprintf(server_out, server_out_size, "%s", parent_server); } else { /* can't locate a server, so return a NULL to tell pbs_connect to use default */ server_out[0] = '\0'; } /* Make a fully qualified name of the job id. */ if (notNULL(parent_server)) { if (notNULL(current_server)) { snprintf(job_id_out, job_id_out_size, "%s.%s", seq_number, parent_server); /* parent_server might not be resolvable if current_server specified */ } else { if (get_fullhostname(parent_server, host_server, PBS_MAXSERVERNAME, NULL) != 0) { /* FAILURE */ return(1); } snprintf(job_id_out, job_id_out_size, "%s.%s", seq_number, host_server); } if ((c = strchr(parent_server, ':')) != 0) { if (*(c - 1) == '\\') c--; snprintf(job_id_out + strlen(job_id_out), job_id_out_size - strlen(job_id_out), "%s", c); } } else { parent_server = pbs_default(); if ((parent_server == (char *)NULL) || (*parent_server == '\0')) { return(1); } snprintf(def_server, PBS_MAXSERVERNAME, "%s", parent_server); c = def_server; while ((*c != '\n') && (*c != '\0')) c++; *c = '\0'; if (get_fullhostname(def_server, host_server, PBS_MAXSERVERNAME, NULL) != 0) { /* FAILURE */ return(1); } if ((c = strchr(def_server, ':')) != 0) { if (*(c - 1) == '\\') c--; snprintf(job_id_out, job_id_out_size, "%s.%s%s", seq_number, host_server, c); } else snprintf(job_id_out, job_id_out_size, "%s.%s", seq_number, host_server); } /* END else */ } return(PBSE_NONE); } /* END get_server() */
/** * @brief * sets the environment for reservation * * @param[in] envp - pointer to pointer to the environment variable * * @return - Boolean value * @retval TRUE Success * @retval FALSE Failure * */ int set_resv_env(char **envp) { char *job_env; char *c, *env; char host[PBS_MAXHOSTNAME+1]; int len; int rc; /* Calculate how big to make the variable string. */ len = 0; env = getenv("HOME"); if (env != NULL) len += strlen(env); env = getenv("LANG"); if (env != NULL) len += strlen(env); env = getenv("LOGNAME"); if (env != NULL) len += strlen(env); env = getenv("PATH"); if (env != NULL) len += strlen(env); env = getenv("MAIL"); if (env != NULL) len += strlen(env); env = getenv("SHELL"); if (env != NULL) len += strlen(env); env = getenv("TZ"); if (env != NULL) len += strlen(env); len += PBS_MAXHOSTNAME; len += MAXPATHLEN; len += len; /* Double it for all the commas, etc. */ if ((job_env = (char *) malloc(len)) == NULL) { fprintf(stderr, "pbs_rsub: Out of memory\n"); return FALSE; } *job_env = '\0'; /* Send the required variables with the job. */ c = getenv("LOGNAME"); if (c != NULL) { strcat(job_env, "PBS_O_LOGNAME="); strcat(job_env, c); } if ((rc = gethostname(host, (sizeof(host) - 1))) == 0) { if ((rc = get_fullhostname(host, host, (sizeof(host) - 1))) == 0) { if (*job_env) strcat(job_env, ",PBS_O_HOST="); else strcat(job_env, "PBS_O_HOST="); strcat(job_env, host); } } c = getenv("MAIL"); if (c != NULL) { #ifdef WIN32 back2forward_slash(c); #endif strcat(job_env, ",PBS_O_MAIL="); strcat(job_env, c); } if (rc != 0) { fprintf(stderr, "pbs_rsub: cannot get full local host name\n"); exit(3); } c = getenv("PBS_TZID"); if (c != NULL) { strcat(job_env, ",PBS_TZID="); strcat(job_env, c); set_attr(&attrib, ATTR_resv_timezone, c); } else if (is_stdng_resv) { fprintf(stderr, "pbs_rsub error: a valid PBS_TZID timezone environment variable is required.\n"); exit(2); } set_attr(&attrib, ATTR_v, job_env); free(job_env); return TRUE; }
static int arg_to_qlist(char *arg, char *sep, QueueList **qlist_ptr) { char *id = "arg_to_qlist"; QueueList *qptr = NULL, *new_qlist; int num = 0; char *name, *exechost, canon[PBS_MAXHOSTNAME + 1]; /* * Multiple lines may be used to add queues to the queue list. Find * the tail of the passed-in list (if there is one), and assign the * qptr to the tail element. Later, the new element will be hung off * qptr's next field (or qptr will be set to it.) */ if (*qlist_ptr) { for (qptr = *qlist_ptr; qptr->next != NULL; qptr = qptr->next) /* Walk the list, looking for last element. */; } else { qptr = NULL; } for (name = strtok(arg, sep); name != NULL; name = strtok(NULL, sep)) { /* * If the list is NULL, create the first element and point qptr * at it. If not, take the qptr from the last iteration (which * will be the head the second time through) and place a new * element on its next pointer. Then replace qptr with the * address of the newly allocated struct. */ new_qlist = (QueueList *)malloc(sizeof(QueueList)); if (new_qlist == NULL) { log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, "malloc(newQueue)"); goto error_in_list; } memset(new_qlist, 0, sizeof(QueueList)); if (qptr == NULL) { *qlist_ptr = new_qlist; qptr = *qlist_ptr; } else { qptr->next = new_qlist; qptr = new_qlist; } new_qlist->queue = (Queue *)malloc(sizeof(Queue)); if (new_qlist->queue == NULL) { log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, "malloc(newQueue->queue)"); goto error_in_list; } memset(new_qlist->queue, 0, sizeof(Queue)); /* * Queue names may be either 'queue3' or 'queue3@exechost'. * If there is a '@', convert it to a '\0' and copy the two * halves of the string into the qname and exechost fields. * Otherwise, this queue is local to this host - paste in the * "local" hostname. */ if ((exechost = strchr(name, '@')) != NULL) { /* Parse queue@host into queue and hostname. */ *exechost = '\0'; /* '@' ==> '\0' to terminate qname */ exechost ++; /* Next character after the new '\0' */ if (get_fullhostname(exechost, canon, PBS_MAXHOSTNAME) == 0) { exechost = canon; /* Point at canonical name. */ } else { sprintf(log_buffer, "Warning: Cannot canonicalize queue %s@%s", name, exechost); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); } } else { exechost = schd_ThisHost; /* Queue lives on localhost. */ } new_qlist->queue->qname = schd_strdup(name); if (new_qlist->queue->qname == NULL) { log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, "schd_strdup(qname)"); goto error_in_list; } new_qlist->queue->exechost = schd_strdup(exechost); if (new_qlist->queue->exechost == NULL) { log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, "schd_strdup(exechost)"); goto error_in_list; } num++; } return (num); error_in_list: /* Something went wrong - delete the new list and return a fatal error. */ if (*qlist_ptr) { schd_destroy_qlist(*qlist_ptr); *qlist_ptr = NULL; } return (-1); }
/*ARGSUSED*/ int schedinit(int argc, char *argv[]) { char *id = "schedinit"; struct utsname name; struct sigaction act, oact; char *ptr, canon[PBS_MAXHOSTNAME + 1]; DBPRT(("\n%s\n", schd_VersionString)); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, schd_VersionString); /* * If this is the initial startup configuration, then schd_TimeNow will * be 0. Initialize it to the current time, so it can be tested against * various times when initializing. */ if (schd_TimeNow == 0) { schd_TimeNow = time(NULL); DBPRT(("%s: initialize/startup at %s", id, ctime(&schd_TimeNow))); } /* * Determine location of configuration file. Check for the presence of * the PBSSCHED_CONFIG environment variable. If not defined, fall back * to the compiled default CONFIGFILE. * * Since neither the environment variables nor the compiled-in default * can be changed (with the exception of someone wreaking havoc with * a debugger or something), this only needs to be done once. */ if (schd_CfgFilename == NULL) { ptr = getenv("PBSSCHED_CONFIG"); if (ptr == NULL) ptr = CONFIGFILE; schd_CfgFilename = schd_strdup(ptr); if (schd_CfgFilename == NULL) { (void)sprintf(log_buffer, "schd_strdup() failed for configfile"); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); return (-1); } } /* * From this point on, goto cleanup_and_error: to clean up any allocated * storage for filenames. */ DBPRT(("SCHEDINIT: Reading configuration from '%s'\n", schd_CfgFilename)); /* Reset the configuration to a "known" state. */ reset_config(); /* Determine on what host this scheduler running. */ uname(&name); if (get_fullhostname(name.nodename, canon, PBS_MAXHOSTNAME) == 0) { strncpy(schd_ThisHost, canon, PBS_MAXHOSTNAME); } else { (void)sprintf(log_buffer, "Failed to canonicalize uname %s (using it anyway)", name.nodename); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); strncpy(schd_ThisHost, name.nodename, PBS_MAXHOSTNAME); } schd_lowercase(schd_ThisHost); DBPRT(("%s: This host is '%s'\n", id, schd_ThisHost)); /* * Register the state of the config file. The call to reset_config() * above will have cleared all file watches. */ if (schd_register_file(schd_CfgFilename)) { (void)sprintf(log_buffer, "cannot watch %s", schd_CfgFilename); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); goto cleanup_and_error; } /* Read the configuration file. */ if (schd_get_config(schd_CfgFilename)) return (-1); /* if we are NOT making a distinction between Prime and Non-Prime Time, * then simply empty the holidays array; otherwise, try to read and load * the holidays file. */ if (!schd_ENFORCE_PRIME_TIME) init_holidays(); else { /* * Register the state of the holidays file. This allows schd_req() to * reload it if it is changed. */ if (schd_register_file(HOLIDAYS_FILE)) { (void)sprintf(log_buffer, "cannot watch %s", HOLIDAYS_FILE); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); goto cleanup_and_error; } /* Get a list of prime/non-prime times from the holidays file */ if (schd_read_holidays() < 0) return (-1); } /* * Set up a signal handler for SIGHUP. catch_HUP() will re-read the * configuration file. */ act.sa_flags = 0; act.sa_handler = catch_HUP; sigemptyset(&act.sa_mask); if (sigaction(SIGHUP, &act, &oact)) { (void)sprintf(log_buffer, "Failed to setup SIGHUP handler."); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); DBPRT(("%s: %s\n", id, log_buffer)); } DBPRT(("SCHEDINIT: configuration complete.\n")); return (0); cleanup_and_error: /* * Some error occurred. Remove watches and free the storage allocated * for the filenames. */ if (schd_CfgFilename) { schd_forget_file(schd_CfgFilename); free(schd_CfgFilename); } schd_CfgFilename = NULL; return (-1); }
int main(int argc, char **argv) #endif /* WIN32 */ { #ifdef WIN32 struct arg_param *p = (struct arg_param *)pv; int argc; char **argv; SERVICE_STATUS ss; #endif /* WIN32 */ char *name = NULL; struct tpp_config conf; int rpp_fd; char *pc; int numthreads; char lockfile[MAXPATHLEN + 1]; char path_log[MAXPATHLEN + 1]; char svr_home[MAXPATHLEN + 1]; char *log_file = 0; char *host; int port; char *routers = NULL; int c, i, rc; extern char *optarg; int are_primary; int num_var_env; #ifndef WIN32 struct sigaction act; struct sigaction oact; #endif #ifndef WIN32 /*the real deal or just pbs_version and exit*/ execution_mode(argc, argv); #endif /* As a security measure and to make sure all file descriptors */ /* are available to us, close all above stderr */ #ifdef WIN32 _fcloseall(); #else i = sysconf(_SC_OPEN_MAX); while (--i > 2) (void)close(i); /* close any file desc left open by parent */ #endif /* If we are not run with real and effective uid of 0, forget it */ #ifdef WIN32 argc = p->argc; argv = p->argv; ZeroMemory(&ss, sizeof(ss)); ss.dwCheckPoint = 0; ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ss.dwCurrentState = g_dwCurrentState; ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; ss.dwWaitHint = 6000; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); if (!isAdminPrivilege(getlogin())) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); return (2); } #else if ((getuid() != 0) || (geteuid() != 0)) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); return (2); } #endif /* WIN32 */ /* set standard umask */ #ifndef WIN32 umask(022); #endif /* load the pbs conf file */ if (pbs_loadconf(0) == 0) { fprintf(stderr, "%s: Configuration error\n", argv[0]); return (1); } umask(022); #ifdef WIN32 save_env(); #endif /* The following is code to reduce security risks */ /* start out with standard umask, system resource limit infinite */ if ((num_var_env = setup_env(pbs_conf.pbs_environment)) == -1) { #ifdef WIN32 g_dwCurrentState = SERVICE_STOPPED; ss.dwCurrentState = g_dwCurrentState; ss.dwWin32ExitCode = ERROR_INVALID_ENVIRONMENT; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); return (1); #else exit(1); #endif /* WIN32 */ } #ifndef WIN32 i = getgid(); (void)setgroups(1, (gid_t *)&i); /* secure suppl. groups */ #endif log_event_mask = &pbs_conf.pbs_comm_log_events; tpp_set_logmask(*log_event_mask); #ifdef WIN32 winsock_init(); #endif routers = pbs_conf.pbs_comm_routers; numthreads = pbs_conf.pbs_comm_threads; server_host[0] = '\0'; if (pbs_conf.pbs_comm_name) { name = pbs_conf.pbs_comm_name; host = tpp_parse_hostname(name, &port); if (host) snprintf(server_host, sizeof(server_host), "%s", host); free(host); host = NULL; } else if (pbs_conf.pbs_leaf_name) { char *endp; snprintf(server_host, sizeof(server_host), "%s", pbs_conf.pbs_leaf_name); endp = strchr(server_host, ','); /* find the first name */ if (endp) *endp = '\0'; endp = strchr(server_host, ':'); /* cut out the port */ if (endp) *endp = '\0'; name = server_host; } else { if (gethostname(server_host, (sizeof(server_host) - 1)) == -1) { #ifndef WIN32 sprintf(log_buffer, "Could not determine my hostname, errno=%d", errno); #else sprintf(log_buffer, "Could not determine my hostname, errno=%d", WSAGetLastError()); #endif fprintf(stderr, "%s\n", log_buffer); return (1); } if ((get_fullhostname(server_host, server_host, (sizeof(server_host) - 1)) == -1)) { sprintf(log_buffer, "Could not determine my hostname"); fprintf(stderr, "%s\n", log_buffer); return (1); } name = server_host; } if (server_host[0] == '\0') { sprintf(log_buffer, "Could not determine server host"); fprintf(stderr, "%s\n", log_buffer); return (1); } while ((c = getopt(argc, argv, "r:t:e:N")) != -1) { switch (c) { case 'e': *log_event_mask = strtol(optarg, NULL, 0); break; case 'r': routers = optarg; break; case 't': numthreads = atol(optarg); if (numthreads == -1) { usage(argv[0]); return (1); } break; case 'N': stalone = 1; break; default: usage(argv[0]); return (1); } } (void)strcpy(daemonname, "Comm@"); (void)strcat(daemonname, name); if ((pc = strchr(daemonname, (int)'.')) != NULL) *pc = '\0'; if(set_msgdaemonname(daemonname)) { fprintf(stderr, "Out of memory\n"); return 1; } (void) snprintf(path_log, sizeof(path_log), "%s/%s", pbs_conf.pbs_home_path, PBS_COMM_LOGDIR); #ifdef WIN32 /* * let SCM wait 10 seconds for log_open() to complete * as it does network interface query which can take time */ ss.dwCheckPoint++; ss.dwWaitHint = 60000; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); #endif (void) log_open(log_file, path_log); /* set pbs_comm's process limits */ set_limits(); /* set_limits can call log_record, so call only after opening log file */ /* set tcp function pointers */ set_tpp_funcs(log_tppmsg); (void) snprintf(svr_home, sizeof(svr_home), "%s/%s", pbs_conf.pbs_home_path, PBS_SVR_PRIVATE); if (chdir(svr_home) != 0) { (void) sprintf(log_buffer, msg_init_chdir, svr_home); log_err(-1, __func__, log_buffer); return (1); } (void) sprintf(lockfile, "%s/%s/comm.lock", pbs_conf.pbs_home_path, PBS_SVR_PRIVATE); if ((are_primary = are_we_primary()) == FAILOVER_SECONDARY) { strcat(lockfile, ".secondary"); } else if (are_primary == FAILOVER_CONFIG_ERROR) { sprintf(log_buffer, "Failover configuration error"); log_err(-1, __func__, log_buffer); #ifdef WIN32 g_dwCurrentState = SERVICE_STOPPED; ss.dwCurrentState = g_dwCurrentState; ss.dwWin32ExitCode = ERROR_SERVICE_NOT_ACTIVE; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); #endif return (3); } if ((lockfds = open(lockfile, O_CREAT | O_WRONLY, 0600)) < 0) { (void) sprintf(log_buffer, "pbs_comm: unable to open lock file"); log_err(errno, __func__, log_buffer); return (1); } if ((host = tpp_parse_hostname(name, &port)) == NULL) { sprintf(log_buffer, "Out of memory parsing leaf name"); log_err(errno, __func__, log_buffer); return (1); } rc = 0; if (pbs_conf.auth_method == AUTH_RESV_PORT) { rc = set_tpp_config(&pbs_conf, &conf, host, port, routers, pbs_conf.pbs_use_compression, TPP_AUTH_RESV_PORT, NULL, NULL); } else { /* for all non-resv-port based authentication use a callback from TPP */ rc = set_tpp_config(&pbs_conf, &conf, host, port, routers, pbs_conf.pbs_use_compression, TPP_AUTH_EXTERNAL, get_ext_auth_data, validate_ext_auth_data); } if (rc == -1) { (void) sprintf(log_buffer, "Error setting TPP config"); log_err(-1, __func__, log_buffer); return (1); } free(host); i = 0; if (conf.routers) { while (conf.routers[i]) { sprintf(log_buffer, "Router[%d]:%s", i, conf.routers[i]); fprintf(stdout, "%s\n", log_buffer); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_INFO, msg_daemonname, log_buffer); i++; } } #ifndef DEBUG #ifndef WIN32 if (stalone != 1) go_to_background(); #endif #endif #ifdef WIN32 ss.dwCheckPoint = 0; g_dwCurrentState = SERVICE_RUNNING; ss.dwCurrentState = g_dwCurrentState; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); #endif if (already_forked == 0) lock_out(lockfds, F_WRLCK); /* go_to_backgroud call creates a forked process, * thus print/log pid only after go_to_background() * has been called */ sprintf(log_buffer, "%s ready (pid=%d), Proxy Name:%s, Threads:%d", argv[0], getpid(), conf.node_name, numthreads); fprintf(stdout, "%s\n", log_buffer); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_INFO, msg_daemonname, log_buffer); #ifndef DEBUG pbs_close_stdfiles(); #endif #ifdef WIN32 signal(SIGINT, stop_me); signal(SIGTERM, stop_me); #else sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = hup_me; if (sigaction(SIGHUP, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for HUP"); return (2); } act.sa_handler = stop_me; if (sigaction(SIGINT, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for INT"); return (2); } if (sigaction(SIGTERM, &act, &oact) != 0) { log_err(errno, __func__, "sigactin for TERM"); return (2); } if (sigaction(SIGQUIT, &act, &oact) != 0) { log_err(errno, __func__, "sigactin for QUIT"); return (2); } #ifdef SIGSHUTDN if (sigaction(SIGSHUTDN, &act, &oact) != 0) { log_err(errno, __func__, "sigactin for SHUTDN"); return (2); } #endif /* SIGSHUTDN */ act.sa_handler = SIG_IGN; if (sigaction(SIGPIPE, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for PIPE"); return (2); } if (sigaction(SIGUSR1, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for USR1"); return (2); } if (sigaction(SIGUSR2, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for USR2"); return (2); } #endif /* WIN32 */ conf.node_type = TPP_ROUTER_NODE; conf.numthreads = numthreads; if ((rpp_fd = tpp_init_router(&conf)) == -1) { log_err(-1, __func__, "tpp init failed\n"); return 1; } /* Protect from being killed by kernel */ daemon_protect(0, PBS_DAEMON_PROTECT_ON); /* go in a while loop */ while (get_out == 0) { if (hupped == 1) { struct pbs_config pbs_conf_bak; int new_logevent; hupped = 0; /* reset back */ memcpy(&pbs_conf_bak, &pbs_conf, sizeof(struct pbs_config)); if (pbs_loadconf(1) == 0) { log_tppmsg(LOG_CRIT, NULL, "Configuration error, ignoring"); memcpy(&pbs_conf, &pbs_conf_bak, sizeof(struct pbs_config)); } else { /* restore old pbs.conf */ new_logevent = pbs_conf.pbs_comm_log_events; memcpy(&pbs_conf, &pbs_conf_bak, sizeof(struct pbs_config)); pbs_conf.pbs_comm_log_events = new_logevent; log_tppmsg(LOG_INFO, NULL, "Processed SIGHUP"); log_event_mask = &pbs_conf.pbs_comm_log_events; tpp_set_logmask(*log_event_mask); } } sleep(3); } tpp_router_shutdown(); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_NOTICE, msg_daemonname, "Exiting"); log_close(1); lock_out(lockfds, F_UNLCK); /* unlock */ (void)close(lockfds); (void)unlink(lockfile); return 0; }
/** * @brief * processes input jobid according to above mentioned rules * * @param[in] job_id_in - input job id * @param[out] job_id_out - processed job id * @param[out] server_out - server name * * @return int * @retval 0 success * @retval 1 error * */ int get_server(char *job_id_in, char *job_id_out, char *server_out) { char *seq_number = NULL; char *parent_server = NULL; char *current_server = NULL; char host_server[PBS_MAXSERVERNAME+1]; if (!job_id_in || !job_id_out || !server_out) return 1; if (pbs_loadconf(0) != 1) return 1; /* parse the job_id_in into components */ if (parse_jobid(job_id_in, &seq_number, &parent_server, ¤t_server)) { free(seq_number); free(parent_server); free(current_server); return 1; } /* Apply the above rules, in order, except for the locate job request. That request is only sent if the job is not found on the local server. */ server_out[0] = '\0'; if (notNULL(current_server)) /* @server found */ strcpy(server_out, current_server); free(current_server); strcpy(job_id_out, seq_number); free(seq_number); if (notNULL(parent_server)) { /* If parent_server matches PBS_SERVER then use it */ if (pbs_conf.pbs_server_name) { if (strcasecmp(parent_server, pbs_conf.pbs_server_name) == 0) { strcat(job_id_out, "."); strcat(job_id_out, pbs_conf.pbs_server_name); free(parent_server); return 0; } } if (get_fullhostname(parent_server, host_server, PBS_MAXSERVERNAME) != 0) { free(parent_server); return 1; } strcat(job_id_out, "."); #ifdef NAS_CANON_JOBID /* localmod 086 */ strcat(job_id_out, host_server); #else strcat(job_id_out, parent_server); #endif /* localmod 086 */ if (server_out[0] == '\0') strcpy(server_out, parent_server); free(parent_server); return 0; } free(parent_server); if (pbs_conf.pbs_server_name) { strcat(job_id_out, "."); strcat(job_id_out, pbs_conf.pbs_server_name); } else { return 1; } return 0; }
int main(int argc, char **argv, char **envp) { char job_id1[PBS_MAXCLTJOBID+1]; /* from the command line */ char job_id2[PBS_MAXCLTJOBID+1]; /* from the command line */ char job_id1_out[PBS_MAXCLTJOBID+1]; char job_id2_out[PBS_MAXCLTJOBID+1]; char *pn; int port1 = 0; int port2 = 0; char server_out1[MAXSERVERNAME+1]; char server_out2[MAXSERVERNAME+1]; char svrtmp[MAXSERVERNAME+1]; int connect; int stat=0; int rc = 0; extern char *PBS_get_server(); /*test for real deal or just version and exit*/ PRINT_VERSION_AND_EXIT(argc, argv); #ifdef WIN32 if (winsock_init()) { return 1; } #endif if (argc != 3) { static char usage[]="usage: qorder job_identifier job_identifier\n"; static char usag2[]=" qorder --version\n"; fprintf(stderr, "%s", usage); fprintf(stderr, "%s", usag2); exit(2); } strcpy(job_id1, argv[1]); strcpy(job_id2, argv[2]); svrtmp[0] = '\0'; if (get_server(job_id1, job_id1_out, svrtmp)) { fprintf(stderr, "qorder: illegally formed job identifier: %s\n", job_id1); exit(1); } if (*svrtmp == '\0') { if ((pn = pbs_default()) != NULL) { (void)strcpy(svrtmp, pn); } else { fprintf(stderr, "qorder: could not get default server: %s\n", job_id1); exit(1); } } if ((pn = strchr(svrtmp, (int)':')) != 0) { *pn = '\0'; port1 = atoi(pn+1); } if (get_fullhostname(svrtmp, server_out1, MAXSERVERNAME) != 0) { fprintf(stderr, "qorder: invalid server name: %s\n", job_id1); exit(1); } svrtmp[0] = '\0'; if (get_server(job_id2, job_id2_out, svrtmp)) { fprintf(stderr, "qorder: illegally formed job identifier: %s\n", job_id2); exit(1); } if (*svrtmp == '\0') { if ((pn = pbs_default()) != NULL) { (void)strcpy(svrtmp, pn); } else { fprintf(stderr, "qorder: could not get default server: %s\n", job_id1); exit(1); } } if ((pn = strchr(svrtmp, (int)':')) != 0) { *pn = '\0'; port2 = atoi(pn+1); } if (get_fullhostname(svrtmp, server_out2, MAXSERVERNAME) != 0) { fprintf(stderr, "qorder: invalid server name: %s\n", job_id2); exit(1); } if ((strcmp(server_out1, server_out2) != 0) || (port1 != port2)) { fprintf(stderr, "qorder: both jobs ids must specify the same server\n"); exit(1); } if (pn) *pn = ':'; /* restore : if it was present */ /*perform needed security library initializations (including none)*/ if (CS_client_init() != CS_SUCCESS) { fprintf(stderr, "qorder: unable to initialize security library.\n"); exit(1); } connect = cnt2server(svrtmp); if (connect <= 0) { fprintf(stderr, "qorder: cannot connect to server %s (errno=%d)\n", pbs_server, pbs_errno); exit(1);; } stat = pbs_orderjob(connect, job_id1_out, job_id2_out, NULL); if (stat) { char job_id_both[PBS_MAXCLTJOBID + PBS_MAXCLTJOBID + 3]; strcpy(job_id_both, job_id1_out); strcat(job_id_both, " or "); strcat(job_id_both, job_id2_out); prt_job_err("qorder", connect, job_id_both); rc = pbs_errno; } pbs_disconnect(connect); /*cleanup security library initializations before exiting*/ CS_close_app(); exit(rc); }