char *PBS_get_server( const char *server, /* I (NULL|'\0' for not set,modified) */ unsigned int *port) /* O */ { int i; char *pc; for (i = 0;i < PBS_MAXSERVERNAME + 1;i++) { /* clear global server_name */ server_name[i] = '\0'; } if (dflt_port == 0) { dflt_port = get_svrport( (char *)PBS_BATCH_SERVICE_NAME, (char *)"tcp", PBS_BATCH_SERVICE_PORT); } /* first, get the "net.address[:port]" into 'server_name' */ if ((server == (char *)NULL) || (*server == '\0')) { if (pbs_default() == NULL) { return(NULL); } } else { snprintf(server_name, sizeof(server_name), "%s", server); } /* now parse out the parts from 'server_name' */ if ((pc = strchr(server_name, (int)':'))) { /* got a port number */ *pc++ = '\0'; *port = atoi(pc); } else { *port = dflt_port; } return(server_name); } /* END PBS_get_server() */
/** * @brief * pbs_loadconf - Populate the pbs_conf structure * * @par * Load the pbs_conf structure. The variables can be filled in * from either the environment or the pbs.conf file. The * environment gets priority over the file. If any of the * primary variables are not filled in, the function fails. * Primary vars: pbs_home_path, pbs_exec_path, pbs_server_name * * @note * Clients can now be multithreaded. So dont call pbs_loadconf with * reload = TRUE. Currently, the code flow ensures that the configuration * is loaded only once (never used with reload true). Thus in the rest of * the code a direct read of the pbs_conf.variables is fine. There is no * race of access of pbs_conf vars against the loading of pbs_conf vars. * However, if pbs_loadconf is called with reload = TRUE, this assumption * will be void. In that case, access to every pbs_conf.variable has to be * synchronized against the reload of those variables. * * @param[in] reload Whether to attempt a reload * * @return int * @retval 1 Success * @retval 0 Failure */ int pbs_loadconf(int reload) { FILE *fp; char buf[256]; char *conf_name; /* the name of the conf parameter */ char *conf_value; /* the value from the conf file or env*/ char *gvalue; /* used with getenv() */ unsigned int uvalue; /* used with sscanf() */ #ifndef WIN32 struct servent *servent; /* for use with getservent */ char **servalias; /* service alias list */ unsigned int *pui; /* for use with identify_service_entry */ #endif /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return 0; /* this section of the code modified the procecss-wide * tcp array. Since multiple threads can get into this * simultaneously, we need to serialize it */ if (pbs_client_thread_lock_conf() != 0) return 0; if (pbs_conf.loaded && !reload) { (void)pbs_client_thread_unlock_conf(); return 1; } else if (pbs_conf.load_failed && !reload) { (void)pbs_client_thread_unlock_conf(); return 0; } /* * If there are service port definitions available, use them * as the defaults. They may be overridden later by the config * file or environment variables. If not available, retain * whatever we were using before. */ #ifdef WIN32 /* Windows does not have the getservent() call. */ pbs_conf.batch_service_port = get_svrport( PBS_BATCH_SERVICE_NAME, "tcp", pbs_conf.batch_service_port); pbs_conf.batch_service_port_dis = get_svrport( PBS_BATCH_SERVICE_NAME_DIS, "tcp", pbs_conf.batch_service_port_dis); pbs_conf.mom_service_port = get_svrport( PBS_MOM_SERVICE_NAME, "tcp", pbs_conf.mom_service_port); pbs_conf.manager_service_port = get_svrport( PBS_MANAGER_SERVICE_NAME, "tcp", pbs_conf.manager_service_port); pbs_conf.scheduler_service_port = get_svrport( PBS_SCHEDULER_SERVICE_NAME, "tcp", pbs_conf.scheduler_service_port); pbs_conf.pbs_data_service_port = get_svrport( PBS_DATA_SERVICE_NAME, "tcp", pbs_conf.pbs_data_service_port); #else /* Non-Windows uses getservent() for better performance. */ while ((servent = getservent()) != NULL) { if (strcmp(servent->s_proto, "tcp") != 0) continue; /* First, check the official service name. */ pui = identify_service_entry(servent->s_name); if (pui != NULL) { *pui = (unsigned int)ntohs(servent->s_port); continue; } /* Next, check any aliases that may be defined. */ for (servalias = servent->s_aliases; (servalias != NULL) && (*servalias != NULL); servalias++) { pui = identify_service_entry(*servalias); if (pui != NULL) { *pui = (unsigned int)ntohs(servent->s_port); break; } } } endservent(); #endif /* * Once we determine the location of the pbs.conf file, it never changes. * The fact that it is saved to the pbs_conf global structure means that * we can always see its location when debugging. */ if (pbs_conf.pbs_conf_file == NULL) pbs_conf.pbs_conf_file = pbs_get_conf_file(); /* * Parse through the configuration file and set variables based * on the contents of the file. */ if ((fp = fopen(pbs_conf.pbs_conf_file, "r")) != NULL) { while (parse_config_line(fp, &conf_name, &conf_value) != NULL) { if ((conf_name == NULL) || (*conf_name == '\0')) continue; if (!strcmp(conf_name, PBS_CONF_START_SERVER)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.start_server = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_START_MOM)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.start_mom = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_START_SCHED)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.start_sched = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_START_COMM)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.start_comm = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_LOCALLOG)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.locallog = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_SYSLOG)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.syslogfac = ((uvalue <= (23<<3)) ? uvalue : 0); } else if (!strcmp(conf_name, PBS_CONF_SYSLOGSEVR)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.syslogsvr = ((uvalue <= 7) ? uvalue : 0); } else if (!strcmp(conf_name, PBS_CONF_BATCH_SERVICE_PORT)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.batch_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port); } else if (!strcmp(conf_name, PBS_CONF_BATCH_SERVICE_PORT_DIS)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.batch_service_port_dis = ((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port_dis); } else if (!strcmp(conf_name, PBS_CONF_MOM_SERVICE_PORT)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.mom_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.mom_service_port); } else if (!strcmp(conf_name, PBS_CONF_MANAGER_SERVICE_PORT)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.manager_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.manager_service_port); } else if (!strcmp(conf_name, PBS_CONF_SCHEDULER_SERVICE_PORT)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.scheduler_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.scheduler_service_port); } else if (!strcmp(conf_name, PBS_CONF_DATA_SERVICE_PORT)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.pbs_data_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.pbs_data_service_port); } else if (!strcmp(conf_name, PBS_CONF_DATA_SERVICE_HOST)) { free(pbs_conf.pbs_data_service_host); pbs_conf.pbs_data_service_host = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_USE_TCP)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.pbs_use_tcp = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_USE_COMPRESSION)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.pbs_use_compression = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_USE_MCAST)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.pbs_use_mcast = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_FORCE_FT_COMM)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.pbs_use_ft = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_LEAF_NAME)) { if (pbs_conf.pbs_leaf_name) free(pbs_conf.pbs_leaf_name); pbs_conf.pbs_leaf_name = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_LEAF_ROUTERS)) { if (pbs_conf.pbs_leaf_routers) free(pbs_conf.pbs_leaf_routers); pbs_conf.pbs_leaf_routers = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_COMM_NAME)) { if (pbs_conf.pbs_comm_name) free(pbs_conf.pbs_comm_name); pbs_conf.pbs_comm_name = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_COMM_ROUTERS)) { if (pbs_conf.pbs_comm_routers) free(pbs_conf.pbs_comm_routers); pbs_conf.pbs_comm_routers = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_COMM_THREADS)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.pbs_comm_threads = uvalue; } else if (!strcmp(conf_name, PBS_CONF_COMM_LOG_EVENTS)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.pbs_comm_log_events = uvalue; } else if (!strcmp(conf_name, PBS_CONF_HOME)) { free(pbs_conf.pbs_home_path); pbs_conf.pbs_home_path = shorten_and_cleanup_path(conf_value); } else if (!strcmp(conf_name, PBS_CONF_EXEC)) { free(pbs_conf.pbs_exec_path); pbs_conf.pbs_exec_path = shorten_and_cleanup_path(conf_value); } /* Check for PBS_DEFAULT for backward compatibility */ else if (!strcmp(conf_name, PBS_CONF_DEFAULT_NAME)) { free(pbs_conf.pbs_server_name); pbs_conf.pbs_server_name = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_SERVER_NAME)) { free(pbs_conf.pbs_server_name); pbs_conf.pbs_server_name = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_RCP)) { free(pbs_conf.rcp_path); pbs_conf.rcp_path = shorten_and_cleanup_path(conf_value); } else if (!strcmp(conf_name, PBS_CONF_SCP)) { free(pbs_conf.scp_path); pbs_conf.scp_path = shorten_and_cleanup_path(conf_value); } else if (!strcmp(conf_name, PBS_CONF_K5DCELOGIN)) { free(pbs_conf.k5dcelogin_path); pbs_conf.k5dcelogin_path = shorten_and_cleanup_path(conf_value); } /* rcp_path can be inferred from pbs_conf.pbs_exec_path - see below */ /* pbs_demux_path is inferred from pbs_conf.pbs_exec_path - see below */ else if (!strcmp(conf_name, PBS_CONF_ENVIRONMENT)) { free(pbs_conf.pbs_environment); pbs_conf.pbs_environment = shorten_and_cleanup_path(conf_value); } else if (!strcmp(conf_name, PBS_CONF_PRIMARY)) { free(pbs_conf.pbs_primary); pbs_conf.pbs_primary = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_SECONDARY)) { free(pbs_conf.pbs_secondary); pbs_conf.pbs_secondary = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_MOM_HOME)) { free(pbs_conf.pbs_mom_home); pbs_conf.pbs_mom_home = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_CORE_LIMIT)) { free(pbs_conf.pbs_core_limit); pbs_conf.pbs_core_limit = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_LICENSE_STRING)) { free(pbs_conf.pbs_license_file_location); pbs_conf.pbs_license_file_location = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_SERVER_HOST_NAME)) { free(pbs_conf.pbs_server_host_name); pbs_conf.pbs_server_host_name = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_PUBLIC_HOST_NAME)) { free(pbs_conf.pbs_public_host_name); pbs_conf.pbs_public_host_name = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_MAIL_HOST_NAME)) { free(pbs_conf.pbs_mail_host_name); pbs_conf.pbs_mail_host_name = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_SMTP_SERVER_NAME)) { free(pbs_conf.pbs_smtp_server_name); pbs_conf.pbs_smtp_server_name = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_OUTPUT_HOST_NAME)) { free(pbs_conf.pbs_output_host_name); pbs_conf.pbs_output_host_name = strdup(conf_value); } else if (!strcmp(conf_name, PBS_CONF_SCHEDULER_MODIFY_EVENT)) { if (sscanf(conf_value, "%u", &uvalue) == 1) pbs_conf.sched_modify_event = ((uvalue > 0) ? 1 : 0); } else if (!strcmp(conf_name, PBS_CONF_MOM_NODE_NAME)) { free(pbs_conf.pbs_mom_node_name); pbs_conf.pbs_mom_node_name = strdup(conf_value); } #ifdef WIN32 else if (!strcmp(conf_name, PBS_CONF_REMOTE_VIEWER)) { free(pbs_conf.pbs_conf_remote_viewer); pbs_conf.pbs_conf_remote_viewer = strdup(conf_value); } #endif #ifndef WIN32 else if (!strcmp(conf_name, PBS_CONF_AUTH)) { if (!strcasecmp(conf_value, "MUNGE")) { pbs_conf.auth_method = AUTH_MUNGE; } else { fprintf(stderr, "pbsconf error: illegal value for %s\n",PBS_CONF_AUTH); goto err; } } #endif /* iff_path is inferred from pbs_conf.pbs_exec_path - see below */ } fclose(fp); free(pbs_loadconf_buf); pbs_loadconf_buf = NULL; pbs_loadconf_len = 0; } /* * Next, check the environment variables and set values accordingly * overriding those that were set in the configuration file. */ if ((gvalue = getenv(PBS_CONF_START_SERVER)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.start_server = ((uvalue > 0) ? 1 : 0); } if ((gvalue = getenv(PBS_CONF_START_MOM)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.start_mom = ((uvalue > 0) ? 1 : 0); } if ((gvalue = getenv(PBS_CONF_START_SCHED)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.start_sched = ((uvalue > 0) ? 1 : 0); } if ((gvalue = getenv(PBS_CONF_START_COMM)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.start_comm = ((uvalue > 0) ? 1 : 0); } if ((gvalue = getenv(PBS_CONF_LOCALLOG)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.locallog = ((uvalue > 0) ? 1 : 0); } if ((gvalue = getenv(PBS_CONF_SYSLOG)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.syslogfac = ((uvalue <= (23<<3)) ? uvalue : 0); } if ((gvalue = getenv(PBS_CONF_SYSLOGSEVR)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.syslogsvr = ((uvalue <= 7) ? uvalue : 0); } if ((gvalue = getenv(PBS_CONF_BATCH_SERVICE_PORT)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.batch_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port); } if ((gvalue = getenv(PBS_CONF_BATCH_SERVICE_PORT_DIS)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.batch_service_port_dis = ((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port_dis); } if ((gvalue = getenv(PBS_CONF_MOM_SERVICE_PORT)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.mom_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.mom_service_port); } if ((gvalue = getenv(PBS_CONF_MANAGER_SERVICE_PORT)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.manager_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.manager_service_port); } if ((gvalue = getenv(PBS_CONF_SCHEDULER_SERVICE_PORT)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.scheduler_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.scheduler_service_port); } if ((gvalue = getenv(PBS_CONF_HOME)) != NULL) { free(pbs_conf.pbs_home_path); pbs_conf.pbs_home_path = shorten_and_cleanup_path(gvalue); } if ((gvalue = getenv(PBS_CONF_EXEC)) != NULL) { free(pbs_conf.pbs_exec_path); pbs_conf.pbs_exec_path = shorten_and_cleanup_path(gvalue); } /* Check for PBS_DEFAULT for backward compatibility */ if ((gvalue = getenv(PBS_CONF_DEFAULT_NAME)) != NULL) { free(pbs_conf.pbs_server_name); if ((pbs_conf.pbs_server_name = strdup(gvalue)) == NULL) { goto err; } } if ((gvalue = getenv(PBS_CONF_SERVER_NAME)) != NULL) { free(pbs_conf.pbs_server_name); if ((pbs_conf.pbs_server_name = strdup(gvalue)) == NULL) { goto err; } } if ((gvalue = getenv(PBS_CONF_RCP)) != NULL) { free(pbs_conf.rcp_path); pbs_conf.rcp_path = shorten_and_cleanup_path(gvalue); } if ((gvalue = getenv(PBS_CONF_SCP)) != NULL) { free(pbs_conf.scp_path); pbs_conf.scp_path = shorten_and_cleanup_path(gvalue); } if ((gvalue = getenv(PBS_CONF_K5DCELOGIN)) != NULL) { free(pbs_conf.k5dcelogin_path); pbs_conf.k5dcelogin_path = shorten_and_cleanup_path(gvalue); } if ((gvalue = getenv(PBS_CONF_PRIMARY)) != NULL) { free(pbs_conf.pbs_primary); if ((pbs_conf.pbs_primary = strdup(gvalue)) == NULL) { goto err; } } if ((gvalue = getenv(PBS_CONF_SECONDARY)) != NULL) { free(pbs_conf.pbs_secondary); if ((pbs_conf.pbs_secondary = strdup(gvalue)) == NULL) { goto err; } } if ((gvalue = getenv(PBS_CONF_MOM_HOME)) != NULL) { free(pbs_conf.pbs_mom_home); if ((pbs_conf.pbs_mom_home = strdup(gvalue)) == NULL) { goto err; } } if ((gvalue = getenv(PBS_CONF_CORE_LIMIT)) != NULL) { free(pbs_conf.pbs_core_limit); if ((pbs_conf.pbs_core_limit = strdup(gvalue)) == NULL) { goto err; } } if ((gvalue = getenv(PBS_CONF_DATA_SERVICE_HOST)) != NULL) { free(pbs_conf.pbs_data_service_host); if ((pbs_conf.pbs_data_service_host = strdup(gvalue)) == NULL) { goto err; } } if ((gvalue = getenv(PBS_CONF_USE_TCP)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.pbs_use_tcp = ((uvalue > 0) ? 1 : 0); } if ((gvalue = getenv(PBS_CONF_USE_COMPRESSION)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.pbs_use_compression = ((uvalue > 0) ? 1 : 0); } if ((gvalue = getenv(PBS_CONF_USE_MCAST)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.pbs_use_mcast = ((uvalue > 0) ? 1 : 0); } if ((gvalue = getenv(PBS_CONF_FORCE_FT_COMM)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.pbs_use_ft = ((uvalue > 0) ? 1 : 0); } if ((gvalue = getenv(PBS_CONF_LEAF_NAME)) != NULL) { if (pbs_conf.pbs_leaf_name) free(pbs_conf.pbs_leaf_name); pbs_conf.pbs_leaf_name = strdup(gvalue); } if ((gvalue = getenv(PBS_CONF_LEAF_ROUTERS)) != NULL) { if (pbs_conf.pbs_leaf_routers) free(pbs_conf.pbs_leaf_routers); pbs_conf.pbs_leaf_routers = strdup(gvalue); } if ((gvalue = getenv(PBS_CONF_COMM_NAME)) != NULL) { if (pbs_conf.pbs_comm_name) free(pbs_conf.pbs_comm_name); pbs_conf.pbs_comm_name = strdup(gvalue); } if ((gvalue = getenv(PBS_CONF_COMM_ROUTERS)) != NULL) { if (pbs_conf.pbs_comm_routers) free(pbs_conf.pbs_comm_routers); pbs_conf.pbs_comm_routers = strdup(gvalue); } if ((gvalue = getenv(PBS_CONF_COMM_THREADS)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.pbs_comm_threads = uvalue; } if ((gvalue = getenv(PBS_CONF_COMM_LOG_EVENTS)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.pbs_comm_log_events = uvalue; } if ((gvalue = getenv(PBS_CONF_DATA_SERVICE_PORT)) != NULL) { if (sscanf(gvalue, "%u", &uvalue) == 1) pbs_conf.pbs_data_service_port = ((uvalue <= 65535) ? uvalue : pbs_conf.pbs_data_service_port); } if ((gvalue = getenv(PBS_CONF_SERVER_HOST_NAME)) != NULL) { free(pbs_conf.pbs_server_host_name); pbs_conf.pbs_server_host_name = strdup(gvalue); } if ((gvalue = getenv(PBS_CONF_PUBLIC_HOST_NAME)) != NULL) { free(pbs_conf.pbs_public_host_name); pbs_conf.pbs_public_host_name = strdup(gvalue); } if ((gvalue = getenv(PBS_CONF_MAIL_HOST_NAME)) != NULL) { free(pbs_conf.pbs_mail_host_name); pbs_conf.pbs_mail_host_name = strdup(gvalue); } if ((gvalue = getenv(PBS_CONF_SMTP_SERVER_NAME)) != NULL) { free(pbs_conf.pbs_smtp_server_name); pbs_conf.pbs_smtp_server_name = strdup(gvalue); } if ((gvalue = getenv(PBS_CONF_OUTPUT_HOST_NAME)) != NULL) { free(pbs_conf.pbs_output_host_name); pbs_conf.pbs_output_host_name = strdup(gvalue); } /* support PBS_MOM_NODE_NAME to tell MOM natural node name on server */ if ((gvalue = getenv(PBS_CONF_MOM_NODE_NAME)) != NULL) { free(pbs_conf.pbs_mom_node_name); pbs_conf.pbs_mom_node_name = strdup(gvalue); } /* rcp_path is inferred from pbs_conf.pbs_exec_path - see below */ /* pbs_demux_path is inferred from pbs_conf.pbs_exec_path - see below */ if ((gvalue = getenv(PBS_CONF_ENVIRONMENT)) != NULL) { free(pbs_conf.pbs_environment); pbs_conf.pbs_environment = shorten_and_cleanup_path(gvalue); } #ifdef WIN32 if ((gvalue = getenv(PBS_CONF_REMOTE_VIEWER)) != NULL) { free(pbs_conf.pbs_conf_remote_viewer); pbs_conf.pbs_conf_remote_viewer = strdup(gvalue); } #endif /* iff_path is inferred from pbs_conf.pbs_exec_path - see below */ /* * Now that we have parsed through the configuration file and the * environment variables, check to make sure that all the critical * items are set. */ buf[0] = '\0'; if (pbs_conf.pbs_home_path == NULL) sprintf(buf, "%s %s", buf, PBS_CONF_HOME); if (pbs_conf.pbs_exec_path == NULL) sprintf(buf, "%s %s", buf, PBS_CONF_EXEC); if (pbs_conf.pbs_server_name == NULL) sprintf(buf, "%s %s", buf, PBS_CONF_SERVER_NAME); if (buf[0] != '\0') { fprintf(stderr, "pbsconf error: pbs conf variables not found: %s\n", buf); goto err; } /* * Perform sanity checks on PBS_*_HOST_NAME values and PBS_CONF_SMTP_SERVER_NAME. * See IDD for SPID 4534. */ buf[0] = '\0'; if ((pbs_conf.pbs_server_host_name != NULL) && (strchr(pbs_conf.pbs_server_host_name, ':') != NULL)) strcpy(buf, PBS_CONF_SERVER_HOST_NAME); else if ((pbs_conf.pbs_public_host_name != NULL) && (strchr(pbs_conf.pbs_public_host_name, ':') != NULL)) strcpy(buf, PBS_CONF_PUBLIC_HOST_NAME); else if ((pbs_conf.pbs_mail_host_name != NULL) && (strchr(pbs_conf.pbs_mail_host_name, ':') != NULL)) strcpy(buf, PBS_CONF_MAIL_HOST_NAME); else if ((pbs_conf.pbs_smtp_server_name != NULL) && (strchr(pbs_conf.pbs_smtp_server_name, ':') != NULL)) strcpy(buf, PBS_CONF_SMTP_SERVER_NAME); else if ((pbs_conf.pbs_output_host_name != NULL) && (strchr(pbs_conf.pbs_output_host_name, ':') != NULL)) strcpy(buf, PBS_CONF_OUTPUT_HOST_NAME); else if ((pbs_conf.pbs_mom_node_name != NULL) && (strchr(pbs_conf.pbs_mom_node_name, ':') != NULL)) strcpy(buf, PBS_CONF_MOM_NODE_NAME); if (buf[0] != '\0') { fprintf(stderr, "pbsconf error: illegal value for: %s\n", buf); goto err; } /* * Finally, fill in the blanks for variables with inferred values. */ if (pbs_conf.pbs_environment == NULL) { /* a reasonable default for the pbs_environment file is in pbs_home */ /* strlen("/pbs_environment") + '\0' == 16 + 1 == 17 */ if ((pbs_conf.pbs_environment = malloc(strlen(pbs_conf.pbs_home_path) + 17)) != NULL) { sprintf(pbs_conf.pbs_environment, "%s/pbs_environment", pbs_conf.pbs_home_path); #ifdef WIN32 back2forward_slash(pbs_conf.pbs_environment); #endif } else { goto err; } } free(pbs_conf.iff_path); /* strlen("/sbin/pbs_iff") + '\0' == 13 + 1 == 14 */ if ((pbs_conf.iff_path = malloc(strlen(pbs_conf.pbs_exec_path) + 14)) != NULL) { sprintf(pbs_conf.iff_path, "%s/sbin/pbs_iff", pbs_conf.pbs_exec_path); #ifdef WIN32 back2forward_slash(pbs_conf.iff_path); #endif } else { goto err; } if (pbs_conf.rcp_path == NULL) { if ((pbs_conf.rcp_path = malloc(strlen(pbs_conf.pbs_exec_path) + 14)) != NULL) { sprintf(pbs_conf.rcp_path, "%s/sbin/pbs_rcp", pbs_conf.pbs_exec_path); #ifdef WIN32 back2forward_slash(pbs_conf.rcp_path); #endif } else { goto err; } } free(pbs_conf.pbs_demux_path); /* strlen("/sbin/pbs_demux") + '\0' == 15 + 1 == 16 */ if ((pbs_conf.pbs_demux_path = malloc(strlen(pbs_conf.pbs_exec_path) + 16)) != NULL) { sprintf(pbs_conf.pbs_demux_path, "%s/sbin/pbs_demux", pbs_conf.pbs_exec_path); #ifdef WIN32 back2forward_slash(pbs_conf.pbs_demux_path); #endif } else { goto err; } if ((gvalue = getenv(PBS_CONF_LICENSE_STRING)) != NULL) { free(pbs_conf.pbs_license_file_location); if ((pbs_conf.pbs_license_file_location = strdup(gvalue)) == NULL) { goto err; } } #ifndef WIN32 if ((gvalue = getenv(PBS_CONF_AUTH)) != NULL) { if (!strcasecmp(gvalue, "MUNGE")) { pbs_conf.auth_method = AUTH_MUNGE; } else { fprintf(stderr, "pbsconf error: illegal value for %s\n",PBS_CONF_AUTH); goto err; } } #endif pbs_conf.pbs_tmpdir = pbs_get_tmpdir(); /* if routers has null value populate with server name as the default */ if (pbs_conf.pbs_leaf_routers == NULL) { if (pbs_conf.pbs_primary && pbs_conf.pbs_secondary) { pbs_conf.pbs_leaf_routers = malloc(strlen(pbs_conf.pbs_primary) + strlen(pbs_conf.pbs_secondary) + 2); if (pbs_conf.pbs_leaf_routers == NULL) { fprintf(stderr, "Out of memory\n"); goto err; } sprintf(pbs_conf.pbs_leaf_routers, "%s,%s", pbs_conf.pbs_primary, pbs_conf.pbs_secondary); } else { if (pbs_conf.pbs_server_host_name) { pbs_conf.pbs_leaf_routers = strdup(pbs_conf.pbs_server_host_name); } else if (pbs_conf.pbs_server_name) { pbs_conf.pbs_leaf_routers = strdup(pbs_conf.pbs_server_name); } else { fprintf(stderr, "PBS server undefined\n"); goto err; } if (pbs_conf.pbs_leaf_routers == NULL) { fprintf(stderr, "Out of memory\n"); goto err; } } } if (pbs_conf.pbs_use_tcp == 0) { pbs_conf.pbs_use_compression = 0; pbs_conf.pbs_use_mcast = 0; pbs_conf.pbs_use_ft = 0; } pbs_conf.loaded = 1; if (pbs_client_thread_unlock_conf() != 0) return 0; return 1; /* success */ err: if (pbs_conf.pbs_conf_file) { free(pbs_conf.pbs_conf_file); pbs_conf.pbs_conf_file = NULL; } if (pbs_conf.pbs_data_service_host) { free(pbs_conf.pbs_data_service_host); pbs_conf.pbs_data_service_host = NULL; } if (pbs_conf.pbs_home_path) { free(pbs_conf.pbs_home_path); pbs_conf.pbs_home_path = NULL; } if (pbs_conf.pbs_exec_path) { free(pbs_conf.pbs_exec_path); pbs_conf.pbs_exec_path = NULL; } if (pbs_conf.pbs_server_name) { free(pbs_conf.pbs_server_name); pbs_conf.pbs_server_name = NULL; } if (pbs_conf.rcp_path) { free(pbs_conf.rcp_path); pbs_conf.rcp_path = NULL; } if (pbs_conf.scp_path) { free(pbs_conf.scp_path); pbs_conf.scp_path = NULL; } if (pbs_conf.k5dcelogin_path) { free(pbs_conf.k5dcelogin_path); pbs_conf.k5dcelogin_path = NULL; } if (pbs_conf.pbs_environment) { free(pbs_conf.pbs_environment); pbs_conf.pbs_environment = NULL; } if (pbs_conf.pbs_primary) { free(pbs_conf.pbs_primary); pbs_conf.pbs_primary = NULL; } if (pbs_conf.pbs_secondary) { free(pbs_conf.pbs_secondary); pbs_conf.pbs_secondary = NULL; } if (pbs_conf.pbs_mom_home) { free(pbs_conf.pbs_mom_home); pbs_conf.pbs_mom_home = NULL; } if (pbs_conf.pbs_core_limit) { free(pbs_conf.pbs_core_limit); pbs_conf.pbs_core_limit = NULL; } if (pbs_conf.pbs_license_file_location) { free(pbs_conf.pbs_license_file_location); pbs_conf.pbs_license_file_location = NULL; } pbs_conf.load_failed = 1; (void)pbs_client_thread_unlock_conf(); return 0; }
void start_tcl(void) { char *id = "start_tcl"; char buf[BUFSIZ]; int fd; int tot, len; interp = Tcl_CreateInterp(); if (Tcl_Init(interp) == TCL_ERROR) { sprintf(log_buffer, "Tcl_Init error: %s", Tcl_GetStringResult(interp)); log_err(-1, id, log_buffer); die(0); } #if TCLX #if TCL_MINOR_VERSION < 5 && TCL_MAJOR_VERSION < 8 if (TclX_Init(interp) == TCL_ERROR) { #else if (Tclx_Init(interp) == TCL_ERROR) { #endif sprintf(log_buffer, "Tclx_Init error: %s", Tcl_GetStringResult(interp)); log_err(-1, id, log_buffer); die(0); } #endif add_cmds(interp); if (initfil) { int code; code = Tcl_EvalFile(interp, initfil); if (code != TCL_OK) { char *trace; trace = (char *)Tcl_GetVar(interp, "errorInfo", 0); if (trace == NULL) trace = (char *)Tcl_GetStringResult(interp); fprintf(stderr, "%s: TCL error @ line %d: %s\n", initfil, interp->errorLine, trace); sprintf(log_buffer, "%s: TCL error @ line %d: %s", initfil, interp->errorLine, Tcl_GetStringResult(interp)); log_err(-1, id, log_buffer); die(0); } sprintf(log_buffer, "init file %s", initfil); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); } if ((fd = open(bodyfil, O_RDONLY)) == -1) { log_err(errno, id, bodyfil); die(0); } sprintf(log_buffer, "body file: %s", bodyfil); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); if (body) free(body); if ((body = malloc(BUFSIZ)) == NULL) { log_err(errno, id, "malloc"); die(0); } for (tot = 0; (len = read(fd, buf, sizeof(buf))) > 0; tot += len) { if ((body = realloc(body, tot + len + 1)) == NULL) { log_err(errno, id, "realloc"); die(0); } memcpy(&body[tot], buf, len); } if (len == -1) { log_err(errno, id, bodyfil); die(0); } body[tot] = '\0'; close(fd); #if TCL_MAJOR_VERSION >= 8 if (body_obj == NULL) { body_obj = Tcl_NewStringObj(body, tot); Tcl_IncrRefCount(body_obj); } else { Tcl_SetStringObj(body_obj, body, tot); } #endif } int addclient(name) char *name; { static char id[] = "addclient"; struct hostent *host, *gethostbyname(); struct in_addr saddr; if ((host = gethostbyname(name)) == NULL) { sprintf(log_buffer, "host %s not found", name); log_err(-1, id, log_buffer); return -1; } if (numclients >= START_CLIENTS) { pbs_net_t *newclients; newclients = realloc(okclients, sizeof(pbs_net_t) * (numclients + 1)); if (newclients == NULL) return -1; okclients = newclients; } memcpy((char *)&saddr, host->h_addr, host->h_length); okclients[numclients++] = saddr.s_addr; return 0; } /* * read_config - read and process the configuration file (see -c option) * * Currently, the only statement is $clienthost to specify which systems * can contact the scheduler. */ #define CONF_LINE_LEN 120 static int read_config(file) char *file; { static char *id = "read_config"; FILE *conf; int i; char line[CONF_LINE_LEN]; char *token; struct specialconfig { char *name; int (*handler)(); } special[] = { {"clienthost", addclient }, { NULL, NULL } }; #if !defined(DEBUG) && !defined(NO_SECURITY_CHECK) if (chk_file_sec(file, 0, 0, S_IWGRP | S_IWOTH, 1, 0)) return (-1); #endif if ((conf = fopen(file, "r")) == NULL) { log_err(errno, id, "cannot open config file"); return (-1); } while (fgets(line, CONF_LINE_LEN, conf)) { if ((line[0] == '#') || (line[0] == '\n')) continue; /* ignore comment & null line */ else if (line[0] == '$') /* special */ { if ((token = strtok(line, " \t")) == NULL) token = ""; for (i = 0; special[i].name; i++) { if (strcmp(token + 1, special[i].name) == 0) break; } if (special[i].name == NULL) { sprintf(log_buffer, "config name %s not known", token); log_record(PBSEVENT_ERROR, PBS_EVENTCLASS_SERVER, msg_daemonname, log_buffer); return (-1); } token = strtok(NULL, " \t"); if (*(token + strlen(token) - 1) == '\n') *(token + strlen(token) - 1) = '\0'; if (special[i].handler(token)) { fclose(conf); return (-1); } } else { log_record(PBSEVENT_ERROR, PBS_EVENTCLASS_SERVER, msg_daemonname, "invalid line in config file"); fclose(conf); return (-1); } } fclose(conf); return (0); } void restart(sig) int sig; { char *id = "restart"; if (sig) { sprintf(log_buffer, "restart on signal %d", sig); log_close(1); log_open(logfile, path_log); } else { sprintf(log_buffer, "restart command"); } log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); Tcl_DeleteInterp(interp); if (configfile) { if (read_config(configfile) != 0) die(0); } start_tcl(); } void badconn(msg) char *msg; { static char id[] = "badconn"; struct in_addr addr; char buf[5*sizeof(addr) + 100]; struct hostent *phe; addr = saddr.sin_addr; phe = gethostbyaddr((void *) & addr, sizeof(addr), AF_INET); if (phe == NULL) { char hold[6]; int i; union { struct in_addr aa; u_char bb[sizeof(addr)]; } uu; uu.aa = addr; sprintf(buf, "%u", uu.bb[0]); for (i = 1; i < (int)sizeof(addr); i++) { sprintf(hold, ".%u", uu.bb[i]); strcat(buf, hold); } } else { strncpy(buf, phe->h_name, sizeof(buf)); buf[sizeof(buf)-1] = '\0'; } sprintf(log_buffer, "%s on port %u %s", buf, ntohs(saddr.sin_port), msg); log_err(-1, id, log_buffer); return; } unsigned int server_command() { static char id[] = "server_command"; int new_socket; int i; torque_socklen_t slen; unsigned int cmd; pbs_net_t addr; slen = sizeof(saddr); new_socket = accept(server_sock, (struct sockaddr *) & saddr, &slen); if (new_socket == -1) { log_err(errno, id, "accept"); return SCH_ERROR; } if (ntohs(saddr.sin_port) >= IPPORT_RESERVED) { badconn("non-reserved port"); close(new_socket); return SCH_ERROR; } addr = (pbs_net_t)saddr.sin_addr.s_addr; for (i = 0; i < numclients; i++) { if (addr == okclients[i]) break; } if (i == numclients) { badconn("unauthorized host"); close(new_socket); return SCH_ERROR; } if ((connector = socket_to_conn(new_socket)) < 0) { log_err(errno, id, "socket_to_conn"); return SCH_ERROR; } if (get_4byte(new_socket, &cmd) != 1) { log_err(errno, id, "get4bytes"); return SCH_ERROR; } return cmd; } /* * lock_out - lock out other daemons from this directory. */ static void lock_out(fds, op) int fds; int op; /* F_WRLCK or F_UNLCK */ { struct flock flock; flock.l_type = op; flock.l_whence = SEEK_SET; flock.l_start = 0; flock.l_len = 0; /* whole file */ if (fcntl(fds, F_SETLK, &flock) < 0) { (void)strcpy(log_buffer, "pbs_sched: another scheduler running\n"); log_err(errno, msg_daemonname, log_buffer); fprintf(stderr, log_buffer); exit(1); } } int main(argc, argv) int argc; char *argv[]; { char *id = "main"; int code; struct hostent *hp; int go, c, errflg = 0; int lockfds; int t = 1; char *ptr; pid_t pid; char *cp, host[100]; char *homedir = PBS_SERVER_HOME; unsigned int port; char path_priv[_POSIX_PATH_MAX]; char *dbfile = "sched_out"; int alarm_time = 180; struct sigaction act; caddr_t curr_brk = 0, next_brk; extern char *optarg; extern int optind, opterr; fd_set fdset; #ifndef DEBUG if (IamRoot() == 0) { return (1); } #endif /* DEBUG */ glob_argv = argv; if ((cp = strrchr(argv[0], '/')) == NULL) cp = argv[0]; else cp++; msg_daemonname = strdup(cp); port = get_svrport(PBS_SCHEDULER_SERVICE_NAME, "tcp", PBS_SCHEDULER_SERVICE_PORT); while ((c = getopt(argc, argv, "L:S:d:i:b:t:p:a:vc:")) != EOF) { switch (c) { case 'L': logfile = optarg; break; case 'S': port = (unsigned int)atoi(optarg); if (port == 0) { fprintf(stderr, "%s: illegal port\n", optarg); errflg = 1; } break; case 'd': homedir = optarg; break; case 'i': /* initialize */ initfil = optarg; break; case 'b': bodyfil = optarg; break; case 't': termfil = optarg; break; case 'p': dbfile = optarg; break; case 'a': alarm_time = strtol(optarg, &ptr, 10); if (alarm_time <= 0 || *ptr != '\0') { fprintf(stderr, "%s: bad alarm time\n", optarg); errflg = 1; } break; case 'c': configfile = optarg; break; case 'v': verbose = 1; break; case '?': errflg = 1; break; } } if (errflg || optind != argc) { static char *options[] = { "[-L logfile]", "[-S port]", "[-d home]", "[-i init]", "[-b body]", "[-t term]", "[-p output]", "[-a alarm]", "[-c configfile]", "[-v]", NULL }; int i; fprintf(stderr, "usage: %s\n", argv[0]); for (i = 0; options[i]; i++) fprintf(stderr, "\t%s\n", options[i]); exit(1); } /* Save the original working directory for "restart" */ if ((oldpath = getcwd((char *)NULL, MAXPATHLEN)) == NULL) { fprintf(stderr, "cannot get current working directory\n"); exit(1); } (void)sprintf(path_priv, "%s/sched_priv", homedir); #if !defined(DEBUG) && !defined(NO_SECURITY_CHECK) c = chk_file_sec(path_priv, 1, 0, S_IWGRP | S_IWOTH, 1, 0); c |= chk_file_sec(PBS_ENVIRON, 0, 0, S_IWGRP | S_IWOTH, 0, 0); if (c != 0) exit(1); #endif /* not DEBUG and not NO_SECURITY_CHECK */ if (chdir(path_priv) == -1) { perror(path_priv); exit(1); } (void)sprintf(path_log, "%s/sched_logs", homedir); (void)strcpy(pbs_current_user, "Scheduler"); /* The following is code to reduce security risks */ /* start out with standard umask, system resource limit infinite */ umask(022); if (setup_env(PBS_ENVIRON) == -1) exit(1); c = getgid(); (void)setgroups(1, (gid_t *)&c); /* secure suppl. group ids */ c = sysconf(_SC_OPEN_MAX); while (--c > 2) (void)close(c); /* close any file desc left open by parent */ #ifndef DEBUG #ifdef _CRAY (void)limit(C_JOB, 0, L_CPROC, 0); (void)limit(C_JOB, 0, L_CPU, 0); (void)limit(C_JOBPROCS, 0, L_CPU, 0); (void)limit(C_PROC, 0, L_FD, 255); (void)limit(C_JOB, 0, L_FSBLK, 0); (void)limit(C_JOBPROCS, 0, L_FSBLK, 0); (void)limit(C_JOB, 0, L_MEM , 0); (void)limit(C_JOBPROCS, 0, L_MEM , 0); #else /* not _CRAY */ { struct rlimit rlimit; rlimit.rlim_cur = RLIM_INFINITY; rlimit.rlim_max = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &rlimit); (void)setrlimit(RLIMIT_FSIZE, &rlimit); (void)setrlimit(RLIMIT_DATA, &rlimit); (void)setrlimit(RLIMIT_STACK, &rlimit); #ifdef RLIMIT_RSS (void)setrlimit(RLIMIT_RSS , &rlimit); #endif /* RLIMIT_RSS */ #ifdef RLIMIT_VMEM (void)setrlimit(RLIMIT_VMEM , &rlimit); #endif /* RLIMIT_VMEM */ } #endif /* not _CRAY */ #if !defined(NO_SECURITY_CHECK) c = 0; if (initfil) { if (*initfil != '/') { (void)sprintf(log_buffer, "%s/%s", path_priv, initfil); c |= chk_file_sec(log_buffer, 0, 0, S_IWGRP | S_IWOTH, 1, 0); } else { c |= chk_file_sec(initfil, 0, 0, S_IWGRP | S_IWOTH, 1, 0); } } if (bodyfil) { if (*bodyfil != '/') { (void)sprintf(log_buffer, "%s/%s", path_priv, bodyfil); c |= chk_file_sec(log_buffer, 0, 0, S_IWGRP | S_IWOTH, 1, 0); } else { c |= chk_file_sec(bodyfil, 0, 0, S_IWGRP | S_IWOTH, 1, 0); } } if (termfil) { if (*termfil != '/') { (void)sprintf(log_buffer, "%s/%s", path_priv, termfil); c |= chk_file_sec(log_buffer, 0, 0, S_IWGRP | S_IWOTH, 1, 0); } else { c |= chk_file_sec(termfil, 0, 0, S_IWGRP | S_IWOTH, 1, 0); } } if (c) exit(1); #endif /* not NO_SECURITY_CHECK */ #endif /* not DEBUG */ if (log_open(logfile, path_log) == -1) { fprintf(stderr, "%s: logfile could not be opened\n", argv[0]); exit(1); } if (gethostname(host, sizeof(host)) == -1) { char *prob = "gethostname"; log_err(errno, id, prob); perror(prob); die(0); } if ((hp = gethostbyname(host)) == NULL) { char *prob = "gethostbyname"; log_err(errno, id, prob); perror(prob); die(0); } if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { char *prob = "socket"; log_err(errno, id, prob); perror(prob); die(0); } if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&t, sizeof(t)) == -1) { char *prob = "setsockopt"; log_err(errno, id, prob); perror(prob); die(0); } saddr.sin_family = AF_INET; saddr.sin_port = htons((unsigned short)port); memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length); if (bind(server_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { char *prob = "bind"; log_err(errno, id, prob); perror(prob); die(0); } if (listen(server_sock, 5) < 0) { char *prob = "listen"; log_err(errno, id, prob); perror(prob); die(0); } okclients = (pbs_net_t *)calloc(START_CLIENTS, sizeof(pbs_net_t)); addclient("localhost"); /* who has permission to call MOM */ addclient(host); if (configfile) { if (read_config(configfile) != 0) die(0); } lockfds = open("sched.lock", O_CREAT | O_TRUNC | O_WRONLY, 0644); if (lockfds < 0) { char *prob = "lock file"; log_err(errno, id, prob); perror(prob); die(0); } lock_out(lockfds, F_WRLCK); #ifndef DEBUG lock_out(lockfds, F_UNLCK); if ((pid = fork()) == -1) /* error on fork */ { char *prob = "fork"; log_err(errno, id, prob); perror(prob); die(0); } else if (pid > 0) /* parent exits */ exit(0); if ((pid = setsid()) == -1) { log_err(errno, id, "setsid"); die(0); } lock_out(lockfds, F_WRLCK); freopen(dbfile, "a", stdout); setvbuf(stdout, NULL, _IOLBF, 0); dup2(fileno(stdout), fileno(stderr)); #else pid = getpid(); setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stderr, NULL, _IOLBF, 0); #endif freopen("/dev/null", "r", stdin); /* write schedulers pid into lockfile */ (void)sprintf(log_buffer, "%d\n", pid); (void)write(lockfds, log_buffer, strlen(log_buffer) + 1); #if (PLOCK_DAEMONS & 2) (void)plock(PROCLOCK); /* lock daemon into memory */ #endif sprintf(log_buffer, "%s startup pid %d", argv[0], pid); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); sprintf(log_buffer, "%s using TCL %s (%s)", argv[0], TCL_VERSION, TCL_PATCH_LEVEL); fprintf(stderr, "%s\n", log_buffer); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); fullresp(0); sigemptyset(&allsigs); act.sa_flags = 0; sigaddset(&allsigs, SIGHUP); /* remember to block these */ sigaddset(&allsigs, SIGINT); /* during critical sections */ sigaddset(&allsigs, SIGTERM); /* so we don't get confused */ act.sa_mask = allsigs; act.sa_handler = restart; /* do a restart on SIGHUP */ sigaction(SIGHUP, &act, NULL); act.sa_handler = toolong; /* handle an alarm call */ sigaction(SIGALRM, &act, NULL); act.sa_handler = die; /* bite the biscuit for all following */ sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); start_tcl(); FD_ZERO(&fdset); for (go = 1; go;) { unsigned int cmd; FD_SET(server_sock, &fdset); if (select(FD_SETSIZE, &fdset, NULL, NULL, NULL) == -1) { if (errno != EINTR) log_err(errno, id, "select"); continue; } if (!FD_ISSET(server_sock, &fdset)) continue; cmd = server_command(); if (cmd == (unsigned)SCH_ERROR || cmd == (unsigned)SCH_SCHEDULE_NULL) continue; if (sigprocmask(SIG_BLOCK, &allsigs, &oldsigs) == -1) log_err(errno, id, "sigprocmaskSIG_BLOCK)"); if (verbose) { sprintf(log_buffer, "command %d", cmd); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); } switch (cmd) { case SCH_SCHEDULE_NEW: case SCH_SCHEDULE_TERM: case SCH_SCHEDULE_TIME: case SCH_SCHEDULE_RECYC: case SCH_SCHEDULE_CMD: case SCH_SCHEDULE_FIRST: alarm(alarm_time); #if TCL_MAJOR_VERSION >= 8 /* execute compiled body code for TCL-8 */ code = Tcl_EvalObj(interp, body_obj); #else code = Tcl_Eval(interp, body); #endif alarm(0); switch (code) { case TCL_OK: case TCL_RETURN: break; default: { char *trace; char codename[20]; switch (code) { case TCL_BREAK: strcpy(codename, "break"); break; case TCL_CONTINUE: strcpy(codename, "continue"); break; default: strcpy(codename, "<unknown>"); break; } trace = (char *)Tcl_GetVar(interp, "errorInfo", 0); if (trace == NULL) trace = (char *)Tcl_GetStringResult(interp); fprintf(stderr, "%s: TCL interpreter return code %d (%s) @ line %d: %s\n", bodyfil, code, codename, interp->errorLine, trace); sprintf(log_buffer, "%s: TCL error @ line %d: %s", bodyfil, interp->errorLine, Tcl_GetStringResult(interp)); log_err(-1, id, log_buffer); die(0); } } break; case SCH_CONFIGURE: case SCH_RULESET: restart(0); break; case SCH_QUIT: go = 0; break; default: log_err(-1, id, "unknown command"); break; } if (connector >= 0 && server_disconnect(connector)) { log_err(errno, id, "server_disconnect"); die(0); } connector = -1; if (verbose) { next_brk = (caddr_t)sbrk(0); if (next_brk > curr_brk) { sprintf(log_buffer, "brk point %p", next_brk); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); curr_brk = next_brk; } } if (sigprocmask(SIG_SETMASK, &oldsigs, NULL) == -1) log_err(errno, id, "sigprocmask(SIG_SETMASK)"); } if (termfil) { code = Tcl_EvalFile(interp, termfil); if (code != TCL_OK) { char *trace; trace = (char *)Tcl_GetVar(interp, "errorInfo", 0); if (trace == NULL) trace = (char *)Tcl_GetStringResult(interp); fprintf(stderr, "%s: TCL error @ line %d: %s\n", termfil, interp->errorLine, trace); sprintf(log_buffer, "%s: TCL error @ line %d: %s", termfil, interp->errorLine, Tcl_GetStringResult(interp)); log_err(-1, id, log_buffer); die(0); } sprintf(log_buffer, "term file: %s", termfil); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); } sprintf(log_buffer, "%s normal finish pid %d", argv[0], pid); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); (void)close(server_sock); exit(0); }
int openrm( char *host, /* I */ unsigned int port) /* I (optional,0=DEFAULT) */ { int stream; int rc; int retries = 0; static unsigned int gotport = 0; if (port == 0) { if (gotport == 0) { gotport = get_svrport((char *)PBS_MANAGER_SERVICE_NAME, (char *)"tcp", PBS_MANAGER_SERVICE_PORT); } /* END if (gotport == 0) */ port = gotport; } if ((stream = socket(AF_INET, SOCK_STREAM, 0)) != -1) { struct sockaddr_in addr; struct addrinfo *addr_info; if (pbs_getaddrinfo(host, NULL, &addr_info) != 0) { DBPRT(("host %s not found\n", host)) close(stream); return(ENOENT * -1); } memset(&addr, '\0', sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); while (retries++ < MAX_RETRIES) { rc = bindresvport(stream, &addr); if (rc != 0) { if (retries >= MAX_RETRIES) { close(stream); return(-1*errno); } sleep(1); } else break; } memset(&addr, '\0', sizeof(addr)); addr.sin_addr = ((struct sockaddr_in *)addr_info->ai_addr)->sin_addr; addr.sin_family = AF_INET; addr.sin_port = htons((unsigned short)port); if (connect(stream, (struct sockaddr *)&addr, sizeof(addr)) == -1) { close(stream); return(-1 * errno); } } /* END if ((stream = socket(AF_INET,SOCK_STREAM,0)) != -1) */ if (stream < 0) { return(-1 * errno); } if (addrm(stream) == -1) { close(stream); return(-1 * errno); } return(stream); } /* END openrm() */
int main( int argc, char *argv[]) { char *id = "main"; struct hostent *hp; int go, c, errflg = 0; int lockfds; int t = 1; pid_t pid; char host[100]; char *homedir = PBS_SERVER_HOME; unsigned int port; char *dbfile = "sched_out"; struct sigaction act; sigset_t oldsigs; caddr_t curr_brk = 0; caddr_t next_brk; extern char *optarg; extern int optind, opterr; extern int rpp_fd; fd_set fdset; int schedinit(int argc, char **argv); int schedule(int com, int connector); glob_argv = argv; alarm_time = 180; /* The following is code to reduce security risks */ /* move this to a place where nss_ldap doesn't hold a socket yet */ c = sysconf(_SC_OPEN_MAX); while (--c > 2) (void)close(c); /* close any file desc left open by parent */ port = get_svrport(PBS_SCHEDULER_SERVICE_NAME, "tcp", PBS_SCHEDULER_SERVICE_PORT); pbs_rm_port = get_svrport(PBS_MANAGER_SERVICE_NAME, "tcp", PBS_MANAGER_SERVICE_PORT); strcpy(pbs_current_user, "Scheduler"); msg_daemonname = strdup("pbs_sched"); opterr = 0; while ((c = getopt(argc, argv, "L:S:R:d:p:c:a:-:")) != EOF) { switch (c) { case '-': if ((optarg == NULL) || (optarg[0] == '\0')) { errflg = 1; } if (!strcmp(optarg, "version")) { fprintf(stderr, "version: %s\n", PACKAGE_VERSION); exit(0); } else { errflg = 1; } break; case 'L': logfile = optarg; break; case 'S': port = atoi(optarg); if (port == 0) { fprintf(stderr, "%s: illegal port\n", optarg); errflg = 1; } break; case 'R': if ((pbs_rm_port = atoi(optarg)) == 0) { (void)fprintf(stderr, "%s: bad -R %s\n", argv[0], optarg); return 1; } break; case 'd': homedir = optarg; break; case 'p': dbfile = optarg; break; case 'c': configfile = optarg; break; case 'a': alarm_time = atoi(optarg); if (alarm_time == 0) { fprintf(stderr, "%s: bad alarm time\n", optarg); errflg = 1; } break; case '?': errflg = 1; break; } } if (errflg) { fprintf(stderr, "usage: %s %s\n", argv[0], usage); exit(1); } #ifndef DEBUG if (IamRoot() == 0) { return (1); } #endif /* DEBUG */ /* Save the original working directory for "restart" */ if ((oldpath = getcwd((char *)NULL, MAXPATHLEN)) == NULL) { fprintf(stderr, "cannot get current working directory\n"); exit(1); } (void)sprintf(log_buffer, "%s/sched_priv", homedir); #if !defined(DEBUG) && !defined(NO_SECURITY_CHECK) c = chk_file_sec(log_buffer, 1, 0, S_IWGRP | S_IWOTH, 1, NULL); c |= chk_file_sec(PBS_ENVIRON, 0, 0, S_IWGRP | S_IWOTH, 0, NULL); if (c != 0) exit(1); #endif /* not DEBUG and not NO_SECURITY_CHECK */ if (chdir(log_buffer) == -1) { perror("chdir"); exit(1); } (void)sprintf(path_log, "%s/sched_logs", homedir); (void)sprintf(path_acct, "%s/%s", log_buffer, PBS_ACCT); /* The following is code to reduce security risks */ /* start out with standard umask, system resource limit infinite */ umask(022); if (setup_env(PBS_ENVIRON) == -1) exit(1); c = getgid(); (void)setgroups(1, (gid_t *)&c); /* secure suppl. groups */ #ifndef DEBUG #ifdef _CRAY (void)limit(C_JOB, 0, L_CPROC, 0); (void)limit(C_JOB, 0, L_CPU, 0); (void)limit(C_JOBPROCS, 0, L_CPU, 0); (void)limit(C_PROC, 0, L_FD, 255); (void)limit(C_JOB, 0, L_FSBLK, 0); (void)limit(C_JOBPROCS, 0, L_FSBLK, 0); (void)limit(C_JOB, 0, L_MEM , 0); (void)limit(C_JOBPROCS, 0, L_MEM , 0); #else /* not _CRAY */ { struct rlimit rlimit; rlimit.rlim_cur = RLIM_INFINITY; rlimit.rlim_max = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &rlimit); (void)setrlimit(RLIMIT_FSIZE, &rlimit); (void)setrlimit(RLIMIT_DATA, &rlimit); (void)setrlimit(RLIMIT_STACK, &rlimit); #ifdef RLIMIT_RSS (void)setrlimit(RLIMIT_RSS , &rlimit); #endif /* RLIMIT_RSS */ #ifdef RLIMIT_VMEM (void)setrlimit(RLIMIT_VMEM , &rlimit); #endif /* RLIMIT_VMEM */ } #endif /* not _CRAY */ #endif /* DEBUG */ if (log_open(logfile, path_log) == -1) { fprintf(stderr, "%s: logfile could not be opened\n", argv[0]); exit(1); } if (gethostname(host, sizeof(host)) == -1) { log_err(errno, id, "gethostname"); die(0); } if ((hp = gethostbyname(host)) == NULL) { log_err(errno, id, "gethostbyname"); die(0); } if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { log_err(errno, id, "socket"); die(0); } if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&t, sizeof(t)) == -1) { log_err(errno, id, "setsockopt"); die(0); } saddr.sin_family = AF_INET; saddr.sin_port = htons(port); memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length); if (bind(server_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { log_err(errno, id, "bind"); die(0); } if (listen(server_sock, 5) < 0) { log_err(errno, id, "listen"); die(0); } okclients = (pbs_net_t *)calloc(START_CLIENTS, sizeof(pbs_net_t)); addclient("localhost"); /* who has permission to call MOM */ addclient(host); if (configfile) { if (read_config(configfile) != 0) die(0); } lockfds = open("sched.lock", O_CREAT | O_TRUNC | O_WRONLY, 0644); if (lockfds < 0) { log_err(errno, id, "open lock file"); exit(1); } lock_out(lockfds, F_WRLCK); fullresp(0); if (sigemptyset(&allsigs) == -1) { perror("sigemptyset"); exit(1); } if (sigprocmask(SIG_SETMASK, &allsigs, NULL) == -1) /* unblock */ { perror("sigprocmask"); exit(1); } act.sa_flags = 0; sigaddset(&allsigs, SIGHUP); /* remember to block these */ sigaddset(&allsigs, SIGINT); /* during critical sections */ sigaddset(&allsigs, SIGTERM); /* so we don't get confused */ act.sa_mask = allsigs; act.sa_handler = restart; /* do a restart on SIGHUP */ sigaction(SIGHUP, &act, NULL); act.sa_handler = toolong; /* handle an alarm call */ sigaction(SIGALRM, &act, NULL); act.sa_handler = die; /* bite the biscuit for all following */ sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); /* * Catch these signals to ensure we core dump even if * our rlimit for core dumps is set to 0 initially. * * Chris Samuel - VPAC * [email protected] - 29th July 2003 * * Now conditional on the PBSCOREDUMP environment variable */ if (getenv("PBSCOREDUMP")) { act.sa_handler = catch_abort; /* make sure we core dump */ sigaction(SIGSEGV, &act, NULL); sigaction(SIGBUS, &act, NULL); sigaction(SIGFPE, &act, NULL); sigaction(SIGILL, &act, NULL); sigaction(SIGTRAP, &act, NULL); sigaction(SIGSYS, &act, NULL); } /* * Local initialization stuff */ if (schedinit(argc, argv)) { (void) sprintf(log_buffer, "local initialization failed, terminating"); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); exit(1); } if (getenv("PBSDEBUG") == NULL) { lock_out(lockfds, F_UNLCK); #ifdef DISABLE_DAEMONS pid = getpid(); #else if ((pid = fork()) == -1) { /* error on fork */ perror("fork"); exit(1); } else if (pid > 0) /* parent exits */ { exit(0); } if ((pid = setsid()) == -1) { perror("setsid"); exit(1); } #endif /* DISABLE_DAEMONS */ lock_out(lockfds, F_WRLCK); if (freopen(dbfile, "a", stdout) == NULL) { perror("opening lockfile"); exit(1); } setvbuf(stdout, NULL, _IOLBF, 0); dup2(fileno(stdout), fileno(stderr)); } else { setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stderr, NULL, _IOLBF, 0); pid = getpid(); } if (freopen("/dev/null", "r", stdin) == NULL) { perror("opening /dev/null"); exit(1); } /* write scheduler's pid into lockfile */ (void)sprintf(log_buffer, "%ld\n", (long)pid); if (write(lockfds, log_buffer, strlen(log_buffer) + 1) != (ssize_t)(strlen(log_buffer) + 1)) { perror("writing to lockfile"); exit(1); } #if (PLOCK_DAEMONS & 2) (void)plock(PROCLOCK); /* lock daemon into memory */ #endif sprintf(log_buffer, "%s startup pid %ld", argv[0], (long)pid); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); FD_ZERO(&fdset); for (go = 1;go;) { int cmd; if (rpp_fd != -1) FD_SET(rpp_fd, &fdset); FD_SET(server_sock, &fdset); if (select(FD_SETSIZE, &fdset, NULL, NULL, NULL) == -1) { if (errno != EINTR) { log_err(errno, id, "select"); die(0); } continue; } if (rpp_fd != -1 && FD_ISSET(rpp_fd, &fdset)) { if (rpp_io() == -1) log_err(errno, id, "rpp_io"); } if (!FD_ISSET(server_sock, &fdset)) continue; cmd = server_command(); if (sigprocmask(SIG_BLOCK, &allsigs, &oldsigs) == -1) log_err(errno, id, "sigprocmaskSIG_BLOCK)"); alarm(alarm_time); if (schedule(cmd, connector)) /* magic happens here */ go = 0; alarm(0); if (connector >= 0 && server_disconnect(connector)) { log_err(errno, id, "server_disconnect"); die(0); } next_brk = (caddr_t)sbrk(0); if (next_brk > curr_brk) { sprintf(log_buffer, "brk point %ld", (long)next_brk); log_record(PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER, id, log_buffer); curr_brk = next_brk; } if (sigprocmask(SIG_SETMASK, &oldsigs, NULL) == -1) log_err(errno, id, "sigprocmask(SIG_SETMASK)"); } sprintf(log_buffer, "%s normal finish pid %ld", argv[0], (long)pid); log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer); close(server_sock); exit(0); } /* END main() */