/** * @brief * -migrate users info on the current server to a destination server. * * @param[in] c - socket descriptor * @param[in] tohost - the destination host to migrate users cred to * * @return int * @retval 0 success * @retval error code error * */ int PBSD_user_migrate(int c, char *tohost) { int rc; struct batch_reply *reply = NULL; int sock; /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return pbs_errno; /* lock pthread mutex here for this connection */ /* blocking call, waits for mutex release */ if (pbs_client_thread_lock_connection(c) != 0) return pbs_errno; sock = connection[c].ch_socket; DIS_tcp_setup(sock); if ((rc =encode_DIS_ReqHdr(sock, PBS_BATCH_UserMigrate, pbs_current_user)) || (rc = encode_DIS_UserMigrate(sock, tohost)) || (rc = encode_DIS_ReqExtend(sock, NULL))) { connection[c].ch_errtxt = strdup(dis_emsg[rc]); if (connection[c].ch_errtxt == NULL) { pbs_errno = PBSE_SYSTEM; } else { pbs_errno = PBSE_PROTOCOL; } (void)pbs_client_thread_unlock_connection(c); return pbs_errno; } if (DIS_tcp_wflush(sock)) { pbs_errno = PBSE_PROTOCOL; (void)pbs_client_thread_unlock_connection(c); return pbs_errno; } reply = PBSD_rdrpy(c); PBSD_FreeReply(reply); rc = connection[c].ch_errno; /* unlock the thread lock and update the thread context data */ if (pbs_client_thread_unlock_connection(c) != 0) return pbs_errno; return rc; }
int totpool(int con, int update) { struct pbs_client_thread_context *ptr; struct node_pool *np; /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return -1; ptr = (struct pbs_client_thread_context *) pbs_client_thread_get_context_data(); if (!ptr) { pbs_errno = PBSE_INTERNAL; return -1; } if (!ptr->th_node_pool) { np = (struct node_pool *) malloc(sizeof(struct node_pool)); if (!np) { pbs_errno = PBSE_INTERNAL; return -1; } ptr->th_node_pool = (void *) np; if ((np->resc_nodes = strdup("nodes")) == NULL) { free(np); np = NULL; pbs_errno = PBSE_SYSTEM; return -1; } } else np = (struct node_pool *) ptr->th_node_pool; if (update) { if (pbs_rescquery(con, &np->resc_nodes, 1, &np->nodes_avail, &np->nodes_alloc, &np->nodes_resrv, &np->nodes_down) != 0) { return (-1); } } return (np->nodes_avail + np->nodes_alloc + np->nodes_resrv + np->nodes_down); }
/** * @brief * -send manager request and read reply. * * @param[in] c - communication handle * @param[in] function - req type * @param[in] command - command * @param[in] objtype - object type * @param[in] objname - object name * @param[in] aoplp - attribute list * @param[in] extend - extend string for req * * @return int * @retval 0 success * @retval !0 error * */ int PBSD_manager(int c, int function, int command, int objtype, char *objname, struct attropl *aoplp, char *extend) { int i; struct batch_reply *reply; int rc; /* initialize the thread context data, if not initialized */ if (pbs_client_thread_init_thread_context() != 0) return pbs_errno; /* verify the object name if creating a new one */ if (command == MGR_CMD_CREATE) if (pbs_verify_object_name(objtype, objname) != 0) return pbs_errno; /* now verify the attributes, if verification is enabled */ if ((pbs_verify_attributes(c, function, objtype, command, aoplp)) != 0) return pbs_errno; /* lock pthread mutex here for this connection */ /* blocking call, waits for mutex release */ if (pbs_client_thread_lock_connection(c) != 0) return pbs_errno; /* send the manage request */ i = PBSD_mgr_put(c, function, command, objtype, objname, aoplp, extend, 0, NULL); if (i) { (void)pbs_client_thread_unlock_connection(c); return i; } /* read reply from stream into presentation element */ reply = PBSD_rdrpy(c); PBSD_FreeReply(reply); rc = connection[c].ch_errno; /* unlock the thread lock and update the thread context data */ if (pbs_client_thread_unlock_connection(c) != 0) return pbs_errno; return rc; }
/** * @brief * Return the status of a hook. * * @param[in] c - communication handle * @param[in] id - object name * @param[in] attrib - pointer to attrl structure(list) * @param[in] extend - extend string for req * * @return structure handle * @retval pointer to attr list success * @retval NULL error * */ struct batch_status * __pbs_stathook(int c, char *id, struct attrl *attrib, char *extend) { struct batch_status *ret = NULL; int rc; int hook_obj; if (extend != NULL) { if (strcmp(extend, PBS_HOOK) == 0) { hook_obj = MGR_OBJ_PBS_HOOK; } else if (strcmp(extend, SITE_HOOK) == 0) { hook_obj = MGR_OBJ_SITE_HOOK; } else { return NULL; /* bad extend value */ } } else { hook_obj = MGR_OBJ_SITE_HOOK; } /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return NULL; /* first verify the attributes, if verification is enabled */ rc = pbs_verify_attributes(c, PBS_BATCH_StatusHook, hook_obj, MGR_CMD_NONE, (struct attropl *) attrib); if (rc) return NULL; if (pbs_client_thread_lock_connection(c) != 0) return NULL; ret = PBSD_status(c, PBS_BATCH_StatusHook, id, attrib, extend); /* unlock the thread lock and update the thread context data */ if (pbs_client_thread_unlock_connection(c) != 0) return NULL; return ret; }
/** * @brief * Passes submit reservation request to PBSD_submit_resv( ) * * @param[in] c - socket on which connected * @param[in] attrib - the list of attributes for batch request * @parma[in] extend - extension of batch request * * @return char* * @retval SUCCESS returns the reservation ID * @retval ERROR NULL */ char * __pbs_submit_resv(int c, struct attropl *attrib, char *extend) { struct attropl *pal; int rc; char *ret; for (pal = attrib; pal; pal = pal->next) pal->op = SET; /* force operator to SET */ /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return (char *)NULL; /* first verify the attributes, if verification is enabled */ rc = pbs_verify_attributes(c, PBS_BATCH_SubmitResv, MGR_OBJ_RESV, MGR_CMD_NONE, attrib); if (rc) return (char *)NULL; /* lock pthread mutex here for this connection */ /* blocking call, waits for mutex release */ if (pbs_client_thread_lock_connection(c) != 0) return (char *)NULL; /* initiate the queueing of the reservation */ /* Queue job with null string for job id */ ret = PBSD_submit_resv(c, "", attrib, extend); /* unlock the thread lock and update the thread context data */ if (pbs_client_thread_unlock_connection(c) != 0) return (char *) NULL; return ret; }
/** * @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; }
/** * @brief * main - the initialization and main loop of pbs_daemon */ int main(int argc, char *argv[]) { char buf[4096]; char *param_name, *param_val; int rc; execution_mode(argc, argv); if(set_msgdaemonname("PBS_send_hooks")) { fprintf(stderr, "Out of memory\n"); return 1; } pbs_loadconf(0); /* If we are not run with real and effective uid of 0, forget it */ if (!isAdminPrivilege(getlogin())) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); exit(-1); } pbs_client_thread_set_single_threaded_mode(); /* disable attribute verification */ set_no_attribute_verification(); /* initialize the thread context */ if (pbs_client_thread_init_thread_context() != 0) { fprintf(stderr, "%s: Unable to initialize thread context\n", argv[0]); exit(-1); } winsock_init(); connection_init(); while (fgets(buf, sizeof(buf), stdin) != NULL) { buf[strlen(buf)-1] = '\0'; /* gets rid of newline */ param_name = buf; param_val = strchr(buf, '='); if (param_val) { *param_val = '\0'; param_val++; } else { /* bad param_val -- skipping */ break; } if (strcmp(param_name, "path_log") == 0) { path_log[0] = '\0'; strncpy(path_log, param_val, MAXPATHLEN); } else if (strcmp(param_name, "path_hooks") == 0) { path_hooks = strdup(param_val); if (path_hooks == NULL) exit(-1); } else if (strcmp(param_name, "log_file") == 0) { log_file = strdup(param_val); if (log_file == NULL) exit(-1); } else if (strcmp(param_name, "path_hooks_tracking") == 0) { path_hooks_tracking = strdup(param_val); if (path_hooks_tracking == NULL) exit(-1); } else if (strcmp(param_name, "hook_action_tid") == 0) { #ifdef WIN32 hook_action_tid_set(_atoi64(param_val)); #else hook_action_tid_set(atoll(param_val)); #endif } else if (strcmp(param_name, "pbs_server_port_dis") == 0) { pbs_server_port_dis = atoi(param_val); } else if (strcmp(param_name, "pbs_server_addr") == 0) { pbs_server_addr = atol(param_val); } else break; } (void)log_open_main(log_file, path_log, 1); /* silent open */ hook_track_recov(); rc = sync_mom_hookfiles(NULL); log_close(0); /* silent close */ net_close(-1); if (log_file != NULL) free(log_file); if (path_hooks != NULL) free(path_hooks); if (path_hooks_tracking != NULL) free(path_hooks_tracking); exit(rc); }
/** * @brief * main - the initialization and main loop of pbs_daemon */ int main(int argc, char *argv[]) { char jobfile[MAXPATHLEN+1]; char jobfile_full[MAXPATHLEN+1]; pbs_net_t hostaddr = 0; int port = -1; int move_type = -1; pbs_list_head attrl; enum conn_type cntype = ToServerDIS; int con = -1; char *destin; int encode_type; int i; job *jobp; char job_id[PBS_MAXSVRJOBID+1]; attribute *pattr; struct attropl *pqjatr; /* list (single) of attropl for quejob */ char script_name[MAXPATHLEN+1]; int in_server = -1; char *param_name, *param_val; char buf[4096]; struct hostent *hp; struct in_addr addr; char *credbuf = NULL; size_t credlen = 0; int prot = PROT_TCP; /*the real deal or output version and exit?*/ execution_mode(argc, argv); /* If we are not run with real and effective uid of 0, forget it */ pbs_loadconf(0); if (!isAdminPrivilege(getlogin())) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); exit(SEND_JOB_FATAL); } /* initialize the pointers in the resource_def array */ for (i = 0; i < (svr_resc_size - 1); ++i) svr_resc_def[i].rs_next = &svr_resc_def[i+1]; /* last entry is left with null pointer */ /* set single threaded mode */ pbs_client_thread_set_single_threaded_mode(); /* disable attribute verification */ set_no_attribute_verification(); /* initialize the thread context */ if (pbs_client_thread_init_thread_context() != 0) { fprintf(stderr, "%s: Unable to initialize thread context\n", argv[0]); exit(SEND_JOB_FATAL); } if(set_msgdaemonname("PBS_send_job")) { fprintf(stderr, "Out of memory\n"); return 1; } winsock_init(); connection_init(); while (fgets(buf, sizeof(buf), stdin) != NULL) { buf[strlen(buf)-1] = '\0'; /* gets rid of newline */ param_name = buf; param_val = strchr(buf, '='); if (param_val) { *param_val = '\0'; param_val++; } else { /* bad param_val -- skipping */ break; } if (strcmp(param_name, "jobfile") == 0) { jobfile[0] = '\0'; strncpy(jobfile, param_val, MAXPATHLEN); } else if (strcmp(param_name, "destaddr") == 0) { hostaddr = atol(param_val); } else if (strcmp(param_name, "destport") == 0) { port = atoi(param_val); } else if (strcmp(param_name, "move_type") == 0) { move_type = atoi(param_val); } else if (strcmp(param_name, "in_server") == 0) { in_server = atoi(param_val); } else if (strcmp(param_name, "server_name") == 0) { server_name[0] = '\0'; strncpy(server_name, param_val, PBS_MAXSERVERNAME); } else if (strcmp(param_name, "server_host") == 0) { server_host[0] = '\0'; strncpy(server_host, param_val, (sizeof(server_host) - 1)); } else if (strcmp(param_name, "server_addr") == 0) { pbs_server_addr = atol(param_val); } else if (strcmp(param_name, "server_port") == 0) { pbs_server_port_dis = atoi(param_val); } else if (strcmp(param_name, "log_file") == 0) { log_file = strdup(param_val); } else if (strcmp(param_name, "path_log") == 0) { path_log[0] = '\0'; strncpy(path_log, param_val, MAXPATHLEN); } else if (strcmp(param_name, "path_jobs") == 0) { path_jobs = strdup(param_val); } else if (strcmp(param_name, "path_spool") == 0) { path_spool = strdup(param_val); } else if (strcmp(param_name, "path_rescdef") == 0) { path_rescdef = strdup(param_val); } else if (strcmp(param_name, "path_users") == 0) { path_users = strdup(param_val); } else if (strcmp(param_name, "path_hooks_workdir") == 0) { path_hooks_workdir = strdup(param_val); if (path_hooks_workdir == NULL) exit(SEND_JOB_FATAL); } else if (strcmp(param_name, "svr_history_enable") == 0) { svr_history_enable = atol(param_val); } else if (strcmp(param_name, "svr_history_duration") == 0) { svr_history_duration = atol(param_val); } else if (strcmp(param_name, "single_signon_password_enable") == 0) { if (decode_b(&server.sv_attr[(int)SRV_ATR_ssignon_enable], NULL, NULL, param_val) != 0) { fprintf(stderr, "%s: failed to set ssignon_password_enable\n", argv[0]); exit(SEND_JOB_FATAL); } } else if (strcmp(param_name, "script_name") == 0) { strncpy(script_name, param_val, MAXPATHLEN + 1); } else break; } time(&time_now); (void)log_open_main(log_file, path_log, 1); /* silent open */ if (setup_resc(1) == -1) { /* log_buffer set in setup_resc */ log_err(-1, "pbsd_send_job(setup_resc)", log_buffer); return (-1); } if( strlen(jobfile) == 0 || hostaddr == 0 || port == 0 || move_type == -1 || \ in_server == -1 || strlen(server_name) == 0 || strlen(server_host) == 0 || \ pbs_server_addr == 0 || pbs_server_port_dis == 0 || \ strlen(path_log) == 0 || path_jobs == NULL || \ path_spool == NULL || path_users == NULL ) { log_err(-1, "pbs_send_job", "error on one of the parameters"); log_close(0); /* silent close */ exit(SEND_JOB_FATAL); } CLEAR_HEAD(task_list_immed); CLEAR_HEAD(task_list_timed); CLEAR_HEAD(task_list_event); CLEAR_HEAD(svr_queues); CLEAR_HEAD(svr_alljobs); CLEAR_HEAD(svr_newjobs); CLEAR_HEAD(svr_allresvs); CLEAR_HEAD(svr_newresvs); CLEAR_HEAD(svr_deferred_req); CLEAR_HEAD(svr_unlicensedjobs); strcpy(jobfile_full, path_jobs); strcat(jobfile_full, jobfile); if (chk_save_file(jobfile_full) != 0) { sprintf(log_buffer, "Error opening jobfile=%s", jobfile); log_err(-1, __func__, log_buffer); goto fatal_exit; } if ((jobp=job_recov_fs(jobfile, RECOV_SUBJOB)) == NULL) { sprintf(log_buffer, "Failed to recreate job in jobfile=%s", jobfile); log_err(-1, __func__, log_buffer); goto fatal_exit; } /* now delete the temp job file that was created by job_save_fs in server code * jobs are in database now, no need to keep in filesystem */ unlink(jobfile_full); if (in_server) append_link(&svr_alljobs, &jobp->ji_alljobs, jobp); /* select attributes/resources to send based on move type */ if (move_type == MOVE_TYPE_Exec) { resc_access_perm = ATR_DFLAG_MOM; encode_type = ATR_ENCODE_MOM; cntype = ToServerDIS; } else { resc_access_perm = ATR_DFLAG_USWR | ATR_DFLAG_OPWR | ATR_DFLAG_MGWR | ATR_DFLAG_SvRD; encode_type = ATR_ENCODE_SVR; svr_dequejob(jobp); } CLEAR_HEAD(attrl); pattr = jobp->ji_wattr; for (i=0; i < (int)JOB_ATR_LAST; i++) { if ((job_attr_def+i)->at_flags & resc_access_perm) { (void)(job_attr_def+i)->at_encode(pattr+i, &attrl, (job_attr_def+i)->at_name, NULL, encode_type, NULL); } } attrl_fixlink(&attrl); /* script name is passed from parent */ /* get host name */ pbs_loadconf(0); addr.s_addr = htonl(hostaddr); hp = gethostbyaddr((void *)&addr, sizeof(struct in_addr), AF_INET); if (hp == NULL) { sprintf(log_buffer, "%s: h_errno=%d", inet_ntoa(addr), h_errno); log_err(-1, __func__, log_buffer); } else { /* read any credential file */ (void)get_credential(hp->h_name, jobp, PBS_GC_BATREQ, &credbuf, &credlen); } /* save the job id for when after we purge the job */ (void)strcpy(job_id, jobp->ji_qs.ji_jobid); con = -1; DIS_tcparray_init(); for (i=0; i<RETRY; i++) { pbs_errno = 0; /* connect to receiving server with retries */ if (i > 0) { /* recycle after an error */ if (con >= 0) svr_disconnect(con); if (should_retry_route(pbs_errno) == -1) { goto fatal_exit; /* fatal error, don't retry */ } sleep(1<<i); } if ((con = svr_connect(hostaddr, port, 0, cntype, prot)) == PBS_NET_RC_FATAL) { (void)sprintf(log_buffer, "send_job failed to %lx port %d", hostaddr, port); log_err(pbs_errno, __func__, log_buffer); goto fatal_exit; } else if (con == PBS_NET_RC_RETRY) { pbs_errno = WSAECONNREFUSED; /* should retry */ continue; } /* * if the job is substate JOB_SUBSTATE_TRNOUTCM which means * we are recovering after being down or a late failure, we * just want to send the "read-to-commit/commit" */ if (jobp->ji_qs.ji_substate != JOB_SUBSTATE_TRNOUTCM) { if (jobp->ji_qs.ji_substate != JOB_SUBSTATE_TRNOUT) { jobp->ji_qs.ji_substate = JOB_SUBSTATE_TRNOUT; } pqjatr = &((svrattrl *)GET_NEXT(attrl))->al_atopl; destin = jobp->ji_qs.ji_destin; if (PBSD_queuejob(con, jobp->ji_qs.ji_jobid, destin, pqjatr, NULL, prot, NULL)== 0) { if (pbs_errno == PBSE_JOBEXIST && move_type == MOVE_TYPE_Exec) { /* already running, mark it so */ log_event(PBSEVENT_ERROR, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, "Mom reports job already running"); goto ok_exit; } else if ((pbs_errno == PBSE_HOOKERROR) || (pbs_errno == PBSE_HOOK_REJECT) || (pbs_errno == PBSE_HOOK_REJECT_RERUNJOB) || (pbs_errno == PBSE_HOOK_REJECT_DELETEJOB)) { char name_buf[MAXPATHLEN+1]; int rfd; int len; char *reject_msg; int err; err = pbs_errno; reject_msg = pbs_geterrmsg(con); (void)snprintf(log_buffer, sizeof(log_buffer), "send of job to %s failed error = %d reject_msg=%s", destin, err, reject_msg?reject_msg:""); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer); (void)strcpy(name_buf, path_hooks_workdir); (void)strcat(name_buf, jobp->ji_qs.ji_jobid); (void)strcat(name_buf, HOOK_REJECT_SUFFIX); if ((reject_msg != NULL) && (reject_msg[0] != '\0')) { if ((rfd = open(name_buf, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) { snprintf(log_buffer, sizeof(log_buffer), "open of reject file %s failed: errno %d", name_buf, errno); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer); } else { secure_file(name_buf, "Administrators", READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED); setmode(rfd, O_BINARY); len = strlen(reject_msg)+1; /* write also trailing null char */ if (write(rfd, reject_msg, len) != len) { snprintf(log_buffer, sizeof(log_buffer), "write to file %s incomplete: errno %d", name_buf, errno); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer); } close(rfd); } } if (err == PBSE_HOOKERROR) exit(SEND_JOB_HOOKERR); if (err == PBSE_HOOK_REJECT) exit(SEND_JOB_HOOK_REJECT); if (err == PBSE_HOOK_REJECT_RERUNJOB) exit(SEND_JOB_HOOK_REJECT_RERUNJOB); if (err == PBSE_HOOK_REJECT_DELETEJOB) exit(SEND_JOB_HOOK_REJECT_DELETEJOB); } else { (void)sprintf(log_buffer, "send of job to %s failed error = %d", destin, pbs_errno); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer); continue; } } if (jobp->ji_qs.ji_svrflags & JOB_SVFLG_SCRIPT) { if (PBSD_jscript(con, script_name, prot, NULL) != 0) continue; } if (credlen > 0) { int ret; ret = PBSD_jcred(con, jobp->ji_extended.ji_ext.ji_credtype, credbuf, credlen, prot, NULL); if ((ret == 0) || (i == (RETRY - 1))) free(credbuf); /* free credbuf if credbuf is sent successfully OR */ /* at the end of all retry attempts */ if (ret != 0) continue; } if ((move_type == MOVE_TYPE_Exec) && (jobp->ji_qs.ji_svrflags & JOB_SVFLG_HASRUN) && (hostaddr != pbs_server_addr)) { /* send files created on prior run */ if ((move_job_file(con, jobp, StdOut, prot) != 0) || (move_job_file(con, jobp, StdErr, prot) != 0) || (move_job_file(con, jobp, Chkpt, prot) != 0)) continue; } jobp->ji_qs.ji_substate = JOB_SUBSTATE_TRNOUTCM; } if (PBSD_rdytocmt(con, job_id, prot, NULL) != 0) continue; if (PBSD_commit(con, job_id, prot, NULL) != 0) goto fatal_exit; goto ok_exit; /* This child process is all done */ } if (con >= 0) svr_disconnect(con); /* * If connection is actively refused by the execution node(or mother superior) OR * the execution node(or mother superior) is rejecting request with error * PBSE_BADHOST(failing to authorize server host), the node should be marked down. */ if ((move_type == MOVE_TYPE_Exec) && (pbs_errno == WSAECONNREFUSED || pbs_errno == PBSE_BADHOST)) { i = SEND_JOB_NODEDW; } else if (should_retry_route(pbs_errno) == -1) { i = SEND_JOB_FATAL; } else { i = SEND_JOB_RETRY; } (void)sprintf(log_buffer, "send_job failed with error %d", pbs_errno); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_NOTICE, jobp->ji_qs.ji_jobid, log_buffer); log_close(0); net_close(-1); unlink(script_name); exit(i); fatal_exit: if (con >= 0) svr_disconnect(con); log_close(0); net_close(-1); unlink(script_name); exit(SEND_JOB_FATAL); ok_exit: if (con >= 0) svr_disconnect(con); log_close(0); net_close(-1); unlink(script_name); exit(SEND_JOB_OK); }
int __pbs_rerunjob(int c, char *jobid, char *extend) { int rc; struct batch_reply *reply; int sock; time_t old_tcp_timeout; if ((jobid == NULL) || (*jobid == '\0')) return (pbs_errno = PBSE_IVALREQ); sock = connection[c].ch_socket; /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return pbs_errno; /* lock pthread mutex here for this connection */ /* blocking call, waits for mutex release */ if (pbs_client_thread_lock_connection(c) != 0) return pbs_errno; /* setup DIS support routines for following DIS calls */ DIS_tcp_setup(sock); if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_Rerun, pbs_current_user)) || (rc = encode_DIS_JobId(sock, jobid)) || (rc = encode_DIS_ReqExtend(sock, extend))) { connection[c].ch_errtxt = strdup(dis_emsg[rc]); if (connection[c].ch_errtxt == NULL) { pbs_errno = PBSE_SYSTEM; } else { pbs_errno = PBSE_PROTOCOL; } (void)pbs_client_thread_unlock_connection(c); return pbs_errno; } /* write data */ if (DIS_tcp_wflush(sock)) { pbs_errno = PBSE_PROTOCOL; (void)pbs_client_thread_unlock_connection(c); return pbs_errno; } /* Set timeout value to very long value as rerun request */ /* goes from Server to Mom and may take a long time */ old_tcp_timeout = pbs_tcp_timeout; pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG; /* read reply from stream into presentation element */ reply = PBSD_rdrpy(c); /* reset timeout */ pbs_tcp_timeout = old_tcp_timeout; PBSD_FreeReply(reply); rc = connection[c].ch_errno; /* unlock the thread lock and update the thread context data */ if (pbs_client_thread_unlock_connection(c) != 0) return pbs_errno; return rc; }
/** * @brief * -send async run job batch request. * * @param[in] c - connection handle * @param[in] jobid- job identifier * @param[in] location - string of vnodes/resources to be allocated to the job * @param[in] extend - extend string for encoding req * * @return int * @retval 0 success * @retval !0 error * */ int pbs_asyrunjob(int c, char *jobid, char *location, char *extend) { int rc; struct batch_reply *reply; unsigned long resch = 0; int sock; if ((jobid == (char *)0) || (*jobid == '\0')) return (pbs_errno = PBSE_IVALREQ); if (location == (char *)0) location = ""; sock = connection[c].ch_socket; /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return pbs_errno; /* lock pthread mutex here for this connection */ /* blocking call, waits for mutex release */ if (pbs_client_thread_lock_connection(c) != 0) return pbs_errno; /* setup DIS support routines for following DIS calls */ DIS_tcp_setup(sock); /* send run request */ if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_AsyrunJob, pbs_current_user)) || (rc = encode_DIS_Run(sock, jobid, location, resch)) || (rc = encode_DIS_ReqExtend(sock, extend))) { connection[c].ch_errtxt = strdup(dis_emsg[rc]); if (connection[c].ch_errtxt == NULL) { pbs_errno = PBSE_SYSTEM; } else { pbs_errno = PBSE_PROTOCOL; } (void)pbs_client_thread_unlock_connection(c); return pbs_errno; } if (DIS_tcp_wflush(sock)) { pbs_errno = PBSE_PROTOCOL; (void)pbs_client_thread_unlock_connection(c); return pbs_errno; } /* get reply */ reply = PBSD_rdrpy(c); rc = connection[c].ch_errno; PBSD_FreeReply(reply); /* unlock the thread lock and update the thread context data */ if (pbs_client_thread_unlock_connection(c) != 0) return pbs_errno; return rc; }
/** * @brief * establishes connection to host * * @param[in] momhost - The name of the MOM host to connect to. * * @return int * @retval connection slot success * @retval -1 error * */ static int pbs_connect2mom(char *momhost) { int conn, sd; #if defined(__hpux) struct sockaddr_in mom_addr; struct hostent *hp; #else struct addrinfo *aip, *pai; struct addrinfo hints; struct sockaddr_in *inp; #endif #if 0 struct passwd *pw; #endif /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return -1; if (pbs_loadconf(0) == 0) return -1; if (pbs_client_thread_lock_conntable() != 0) return -1; /* * Find an available connection slot. */ for (conn=1; conn<NCONNECTS; conn++) { if (connection[conn].ch_inuse) continue; break; } if (conn >= NCONNECTS) { pbs_errno = PBSE_NOCONNECTS; goto err; } /* * Ensure we have something valid to connect to. */ if (!momhost) momhost = "localhost"; if (strlen(momhost) <= 0) momhost = "localhost"; #if defined(__hpux) hp = gethostbyname(momhost); if (!hp) { pbs_errno = PBSE_BADHOST; goto err; } #else memset(&hints, 0, sizeof(struct addrinfo)); /* * Why do we use AF_UNSPEC rather than AF_INET? Some * implementations of getaddrinfo() will take an IPv6 * address and map it to an IPv4 one if we ask for AF_INET * only. We don't want that - we want only the addresses * that are genuinely, natively, IPv4 so we start with * AF_UNSPEC and filter ai_family below. */ hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; if (getaddrinfo(momhost, NULL, &hints, &pai) != 0) { pbs_errno = PBSE_BADHOST; goto err; } for (aip = pai; aip != NULL; aip = aip->ai_next) { /* skip non-IPv4 addresses */ if (aip->ai_family == AF_INET) { inp = (struct sockaddr_in *) aip->ai_addr; break; } } if (aip == NULL) { pbs_errno = PBSE_BADHOST; goto err; } else inp->sin_port = htons(pbs_conf.mom_service_port); #endif #if 0 /* * Prepare for authentication before we make the connection. */ pbs_current_uid = getuid(); if ((pw = getpwuid(pbs_current_uid)) == NULL) { pbs_errno = PBSE_SYSTEM; goto err; } strcpy(pbs_current_user, pw->pw_name); #endif /* * Establish a connection. */ sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0) { pbs_errno = PBSE_PROTOCOL; goto err; } #if defined(__hpux) mom_addr.sin_family = AF_INET; mom_addr.sin_port = htons(pbs_conf.mom_service_port); memcpy((char *)&mom_addr.sin_addr, hp->h_addr_list[0], hp->h_length); if (connect(sd, (struct sockaddr *)&mom_addr, sizeof(mom_addr)) < 0) { close(sd); pbs_errno = errno; goto err; } #else if (connect(sd, aip->ai_addr, aip->ai_addrlen) < 0) { close(sd); pbs_errno = errno; freeaddrinfo(pai); goto err; } freeaddrinfo(pai); #endif #if 0 /* * Have pbs_iff authenticate the connection. */ if (PBSD_authenticate(sd)) { close(sd); pbs_errno = PBSE_PERM; return -1; } #endif /* * Setup DIS support routines. */ DIS_tcp_setup(sd); pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG; /* * Register the connection slot as in use. */ connection[conn].ch_inuse = 1; connection[conn].ch_errno = 0; connection[conn].ch_socket= sd; connection[conn].ch_errtxt = (char *)NULL; /* setup connection level thread context */ if (pbs_client_thread_init_connect_context(conn) != 0) { close(connection[conn].ch_socket); connection[conn].ch_inuse = 0; /* pbs_errno would be set by the pbs_connect_init_context routine */ goto err; } if (pbs_client_thread_unlock_conntable() != 0) return -1; return conn; err: (void)pbs_client_thread_unlock_conntable(); return -1; }
/** * @brief * -submit job request * * @param[in] c - communication handle * @param[in] attrib - ponter to attr list * @param[in] script - job script * @param[in] destination - host where job submitted * @param[in] extend - buffer to hold cred info * * @return string * @retval jobid success * @retval NULL error * */ char * __pbs_submit(int c, struct attropl *attrib, char *script, char *destination, char *extend) { struct attropl *pal; char *return_jobid = NULL; int rc; struct pbs_client_thread_context *ptr; struct cred_info *cred_info = NULL; /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return return_jobid; ptr = (struct pbs_client_thread_context *) pbs_client_thread_get_context_data(); if (!ptr) { pbs_errno = PBSE_INTERNAL; return return_jobid; } /* first verify the attributes, if verification is enabled */ rc = pbs_verify_attributes(c, PBS_BATCH_QueueJob, MGR_OBJ_JOB, MGR_CMD_NONE, attrib); if (rc) return return_jobid; /* lock pthread mutex here for this connection */ /* blocking call, waits for mutex release */ if (pbs_client_thread_lock_connection(c) != 0) return return_jobid; /* first be sure that the script is readable if specified ... */ if ((script != NULL) && (*script != '\0')) { if (access(script, R_OK) != 0) { pbs_errno = PBSE_BADSCRIPT; if ((connection[c].ch_errtxt = strdup("cannot access script file")) == NULL) pbs_errno = PBSE_SYSTEM; goto error; } } /* initiate the queueing of the job */ for (pal = attrib; pal; pal = pal->next) pal->op = SET; /* force operator to SET */ /* Queue job with null string for job id */ return_jobid = PBSD_queuejob(c, "", destination, attrib, extend, 0, NULL); if (return_jobid == NULL) goto error; /* send script across */ if ((script != NULL) && (*script != '\0')) { if ((rc = PBSD_jscript(c, script, 0, NULL)) != 0) { if (rc == PBSE_JOBSCRIPTMAXSIZE) pbs_errno = rc; else pbs_errno = PBSE_BADSCRIPT; goto error; } } /* OK, the script got across, apparently, so we are */ /* ready to commit */ cred_info = (struct cred_info *) ptr->th_cred_info; /* opaque information */ if (cred_info && cred_info->cred_len > 0) { if (PBSD_jcred(c, cred_info->cred_type, cred_info->cred_buf, cred_info->cred_len, 0, NULL) != 0) { pbs_errno = PBSE_BADCRED; goto error; } } if (PBSD_commit(c, return_jobid, 0, NULL) != 0) goto error; /* unlock the thread lock and update the thread context data */ if (pbs_client_thread_unlock_connection(c) != 0) return NULL; return return_jobid; error: (void)pbs_client_thread_unlock_connection(c); return NULL; }
int pbs_rescquery(int c, char **resclist, int num_resc, int *available, int *allocated, int *reserved, int *down) { int i; struct batch_reply *reply; int rc = 0; /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return pbs_errno; /* lock pthread mutex here for this connection */ /* blocking call, waits for mutex release */ if (pbs_client_thread_lock_connection(c) != 0) return pbs_errno; if (resclist == 0) { pbs_errno = connection[c].ch_errno = PBSE_RMNOPARAM; (void)pbs_client_thread_unlock_connection(c); return pbs_errno; } /* send request */ if ((rc = PBS_resc(c, PBS_BATCH_Rescq, resclist, num_resc, (pbs_resource_t)0)) != 0) { (void)pbs_client_thread_unlock_connection(c); return rc; } /* read in reply */ reply = PBSD_rdrpy(c); if ((rc = connection[c].ch_errno) == PBSE_NONE && reply->brp_choice == BATCH_REPLY_CHOICE_RescQuery) { struct brp_rescq *resq = &reply->brp_un.brp_rescq; if (resq == NULL || num_resc != resq->brq_number) { rc = pbs_errno = connection[c].ch_errno = PBSE_IRESVE; goto done; } /* copy in available and allocated numbers */ for (i=0; i<num_resc; i++) { available[i] = resq->brq_avail[i]; allocated[i] = resq->brq_alloc[i]; reserved[i] = resq->brq_resvd[i]; down[i] = resq->brq_down[i]; } } done: PBSD_FreeReply(reply); /* unlock the thread lock and update the thread context data */ if (pbs_client_thread_unlock_connection(c) != 0) return pbs_errno; return (rc); }
/** * @brief * Open a connection with a pbs server. * Do not allow TCP to block us if Server host is down * At this point, this does not attempt to find a fail_over Server * * @param[in] server - specifies the server to which to connect * @param[in] tout - timeout value for select * * @return int * @retval >= 0 index to the internal connection table representing the * connection made. * @retval -1 error encountered in getting index */ int pbs_connect_noblk(char *server, int tout) { int out; int i; pbs_socklen_t l; int n; struct timeval tv; fd_set fdset; struct batch_reply *reply; char server_name[PBS_MAXSERVERNAME+1]; unsigned int server_port; struct addrinfo *aip, *pai; struct addrinfo hints; struct sockaddr_in *inp; short int connect_err = 0; struct sockaddr_in sockname; pbs_socklen_t socknamelen; #ifdef WIN32 int non_block = 1; struct sockaddr_in to_sock; struct sockaddr_in from_sock; #endif #ifndef WIN32 int nflg; int oflg; #endif /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return -1; if (pbs_loadconf(0) == 0) return -1; /* get server host and port */ server = PBS_get_server(server, server_name, &server_port); if (server == NULL) { pbs_errno = PBSE_NOSERVER; return -1; } /* Reserve a connection state record */ if (pbs_client_thread_lock_conntable() != 0) return -1; out = -1; for (i=1;i<NCONNECTS;i++) { if (connection[i].ch_inuse) continue; out = i; connection[out].ch_inuse = 1; connection[out].ch_errno = 0; connection[out].ch_socket= -1; connection[out].ch_errtxt = NULL; break; } if (pbs_client_thread_unlock_conntable() != 0) return -1; /* pbs_errno set by the function */ if (out < 0) { pbs_errno = PBSE_NOCONNECTS; return -1; } /* get socket */ #ifdef WIN32 /* the following lousy hack is needed since the socket call needs */ /* SYSTEMROOT env variable properly set! */ if (getenv("SYSTEMROOT") == NULL) { setenv("SYSTEMROOT", "C:\\WINNT", 1); setenv("SystemRoot", "C:\\WINNT", 1); } connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0); if (connection[out].ch_socket < 0) { setenv("SYSTEMROOT", "C:\\WINDOWS", 1); setenv("SystemRoot", "C:\\WINDOWS", 1); connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0); } #else connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0); #endif if (connection[out].ch_socket < 0) { connection[out].ch_inuse = 0; pbs_errno = ERRORNO; return -1; } /* set socket non-blocking */ #ifdef WIN32 if (ioctlsocket(connection[out].ch_socket, FIONBIO, &non_block) == SOCKET_ERROR) #else oflg = fcntl(connection[out].ch_socket, F_GETFL) & ~O_ACCMODE; nflg = oflg | O_NONBLOCK; if (fcntl(connection[out].ch_socket, F_SETFL, nflg) == -1) #endif goto err; /* and connect... */ strcpy(pbs_server, server); /* set for error messages from commands */ memset(&hints, 0, sizeof(struct addrinfo)); /* * Why do we use AF_UNSPEC rather than AF_INET? Some * implementations of getaddrinfo() will take an IPv6 * address and map it to an IPv4 one if we ask for AF_INET * only. We don't want that - we want only the addresses * that are genuinely, natively, IPv4 so we start with * AF_UNSPEC and filter ai_family below. */ hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; if (getaddrinfo(server, NULL, &hints, &pai) != 0) { CLOSESOCKET(connection[out].ch_socket); connection[out].ch_inuse = 0; pbs_errno = PBSE_BADHOST; return -1; } for (aip = pai; aip != NULL; aip = aip->ai_next) { /* skip non-IPv4 addresses */ if (aip->ai_family == AF_INET) { inp = (struct sockaddr_in *) aip->ai_addr; break; } } if (aip == NULL) { /* treat no IPv4 addresses as getaddrinfo() failure */ CLOSESOCKET(connection[out].ch_socket); connection[out].ch_inuse = 0; pbs_errno = PBSE_BADHOST; freeaddrinfo(pai); return -1; } else inp->sin_port = htons(server_port); if (connect(connection[out].ch_socket, aip->ai_addr, aip->ai_addrlen) < 0) { connect_err = 1; } if (connect_err == 1) { /* connect attempt failed */ pbs_errno = ERRORNO; switch (pbs_errno) { #ifdef WIN32 case WSAEWOULDBLOCK: #else case EINPROGRESS: case EWOULDBLOCK: #endif while (1) { FD_ZERO(&fdset); FD_SET(connection[out].ch_socket, &fdset); tv.tv_sec = tout; tv.tv_usec = 0; n = select(connection[out].ch_socket+1, NULL, &fdset, NULL, &tv); if (n > 0) { pbs_errno = 0; l = sizeof(pbs_errno); (void)getsockopt(connection[out].ch_socket, SOL_SOCKET, SO_ERROR, &pbs_errno, &l); if (pbs_errno == 0) break; else goto err; } if ((n < 0) && #ifdef WIN32 (ERRORNO == WSAEINTR) #else (ERRORNO == EINTR) #endif ) { continue; } else { goto err; } } break; default: err: CLOSESOCKET(connection[out].ch_socket); connection[out].ch_inuse = 0; freeaddrinfo(pai); return -1; /* cannot connect */ } } freeaddrinfo(pai); /* reset socket blocking */ #ifdef WIN32 non_block = 0; if (ioctlsocket(connection[out].ch_socket, FIONBIO, &non_block) == SOCKET_ERROR) #else if (fcntl(connection[out].ch_socket, F_SETFL, oflg) < 0) #endif goto err; /* * multiple threads cant get the same connection id above, * so no need to lock this piece of code */ /* setup connection level thread context */ if (pbs_client_thread_init_connect_context(out) != 0) { CLOSESOCKET(connection[out].ch_socket); connection[out].ch_inuse = 0; /* pbs_errno set by the pbs_connect_init_context routine */ return -1; } /* * even though the following is communication with server on * a connection handle, it does not need to be lock since * this connection handle has not be returned back yet to the client * so others threads cannot use it */ /* send "dummy" connect message */ DIS_tcp_setup(connection[out].ch_socket); if ((i = encode_DIS_ReqHdr(connection[out].ch_socket, PBS_BATCH_Connect, pbs_current_user)) || (i = encode_DIS_ReqExtend(connection[out].ch_socket, NULL))) { pbs_errno = PBSE_SYSTEM; return -1; } if (DIS_tcp_wflush(connection[out].ch_socket)) { pbs_errno = PBSE_SYSTEM; return -1; } reply = PBSD_rdrpy(out); PBSD_FreeReply(reply); /*do configured authentication (kerberos, pbs_iff, whatever)*/ /*Get the socket port for engage_authentication()*/ socknamelen = sizeof(sockname); if (getsockname(connection[out].ch_socket, (struct sockaddr *)&sockname, &socknamelen)) return -1; if (engage_authentication(connection[out].ch_socket, server, server_port, &sockname) == -1) { CLOSESOCKET(connection[out].ch_socket); connection[out].ch_inuse = 0; pbs_errno = PBSE_PERM; return -1; } /* setup DIS support routines for following pbs_* calls */ DIS_tcp_setup(connection[out].ch_socket); pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG; /* set for 3 hours */ return out; }
/** * @brief * -send close connection batch request * * @param[in] connect - socket descriptor * * @return int * @retval 0 success * @retval -1 error * */ int __pbs_disconnect(int connect) { int sock; char x; if (connect < 0 || NCONNECTS <= connect) return 0; if (!connection[connect].ch_inuse) return 0; /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return -1; /* * Use only connection handle level lock since this is * just communication with server */ if (pbs_client_thread_lock_connection(connect) != 0) return -1; /* * check again to ensure that another racing thread * had not already closed the connection */ if (!connection[connect].ch_inuse) { (void)pbs_client_thread_unlock_connection(connect); return 0; } /* send close-connection message */ sock = connection[connect].ch_socket; DIS_tcp_setup(sock); if ((encode_DIS_ReqHdr(sock, PBS_BATCH_Disconnect, pbs_current_user) == 0) && (DIS_tcp_wflush(sock) == 0)) { for (;;) { /* wait for server to close connection */ #ifdef WIN32 if (recv(sock, &x, 1, 0) < 1) #else if (read(sock, &x, 1) < 1) #endif break; } } CS_close_socket(sock); CLOSESOCKET(sock); if (connection[connect].ch_errtxt != NULL) { free(connection[connect].ch_errtxt); connection[connect].ch_errtxt = NULL; } connection[connect].ch_errno = 0; connection[connect].ch_inuse = 0; /* unlock the connection level lock */ if (pbs_client_thread_unlock_connection(connect) != 0) return -1; /* * this is only a per thread work, so outside lock and unlock * connection needs the thread level connect context so this should be * called after unlocking */ if (pbs_client_thread_destroy_connect_context(connect) != 0) return -1; return 0; }
/** * @brief * Makes a PBS_BATCH_Connect request to 'server'. * * @param[in] server - the hostname of the pbs server to connect to. * @param[in] extend_data - a string to send as "extend" data. * * @return int * @retval >= 0 index to the internal connection table representing the * connection made. * @retval -1 error encountered setting up the connection. */ int __pbs_connect_extend(char *server, char *extend_data) { struct sockaddr_in server_addr; struct sockaddr_in my_sockaddr; int out; int i; int f; char *altservers[2]; int have_alt = 0; struct batch_reply *reply; char server_name[PBS_MAXSERVERNAME+1]; unsigned int server_port; struct sockaddr_in sockname; pbs_socklen_t socknamelen; #ifdef WIN32 struct sockaddr_in to_sock; struct sockaddr_in from_sock; #endif #ifndef WIN32 char pbsrc[_POSIX_PATH_MAX]; struct stat sb; int using_secondary = 0; #endif /* not WIN32 */ /* initialize the thread context data, if not already initialized */ if (pbs_client_thread_init_thread_context() != 0) return -1; if (pbs_loadconf(0) == 0) return -1; /* get server host and port */ server = PBS_get_server(server, server_name, &server_port); if (server == NULL) { pbs_errno = PBSE_NOSERVER; return -1; } if (pbs_conf.pbs_primary && pbs_conf.pbs_secondary) { /* failover configuered ... */ if (hostnmcmp(server, pbs_conf.pbs_primary) == 0) { have_alt = 1; /* We want to try the one last seen as "up" first to not */ /* have connection delays. If the primary was up, there */ /* is no .pbsrc.NAME file. If the last command connected */ /* to the Secondary, then it created the .pbsrc.USER file. */ /* see if already seen Primary down */ #ifdef WIN32 /* due to windows quirks, all try both in same order */ altservers[0] = pbs_conf.pbs_primary; altservers[1] = pbs_conf.pbs_secondary; #else (void)snprintf(pbsrc, _POSIX_PATH_MAX, "%s/.pbsrc.%s", pbs_conf.pbs_tmpdir, pbs_current_user); if (stat(pbsrc, &sb) == -1) { /* try primary first */ altservers[0] = pbs_conf.pbs_primary; altservers[1] = pbs_conf.pbs_secondary; using_secondary = 0; } else { /* try secondary first */ altservers[0] = pbs_conf.pbs_secondary; altservers[1] = pbs_conf.pbs_primary; using_secondary = 1; } #endif } } /* if specific host name declared for the host on which */ /* this client is running, get its address */ if (pbs_conf.pbs_public_host_name) { if (get_hostsockaddr(pbs_conf.pbs_public_host_name, &my_sockaddr) != 0) return -1; /* pbs_errno was set */ } /* Reserve a connection state record */ if (pbs_client_thread_lock_conntable() != 0) return -1; out = -1; for (i=1;i<NCONNECTS;i++) { if (connection[i].ch_inuse) continue; out = i; connection[out].ch_errno = 0; connection[out].ch_socket= -1; connection[out].ch_errtxt = NULL; connection[out].ch_inuse = 1; /* reserve the socket */ break; } if (pbs_client_thread_unlock_conntable() != 0) return -1; /* pbs_errno set by the function */ if (out < 0) { pbs_errno = PBSE_NOCONNECTS; return -1; } /* * connect to server ... * If attempt to connect fails and if Failover configured and * if attempting to connect to Primary, try the Secondary * if attempting to connect to Secondary, try the Primary */ for (i=0; i<(have_alt+1); ++i) { /* get socket */ #ifdef WIN32 /* the following lousy hack is needed since the socket call needs */ /* SYSTEMROOT env variable properly set! */ if (getenv("SYSTEMROOT") == NULL) { setenv("SYSTEMROOT", "C:\\WINNT", 1); setenv("SystemRoot", "C:\\WINNT", 1); } connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0); if (connection[out].ch_socket < 0) { setenv("SYSTEMROOT", "C:\\WINDOWS", 1); setenv("SystemRoot", "C:\\WINDOWS", 1); connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0); } #else connection[out].ch_socket = socket(AF_INET, SOCK_STREAM, 0); #endif if (connection[out].ch_socket < 0) { connection[out].ch_inuse = 0; pbs_errno = errno; return -1; } /* and connect... */ if (have_alt) { server = altservers[i]; } strcpy(pbs_server, server); /* set for error messages from commands */ /* If a specific host name is defined which the client should use */ if (pbs_conf.pbs_public_host_name) { /* my address will be in my_sockaddr, bind the socket to it */ my_sockaddr.sin_port = 0; if (bind(connection[out].ch_socket, (struct sockaddr *)&my_sockaddr, sizeof(my_sockaddr)) != 0) { return -1; } } if (get_hostsockaddr(server, &server_addr) != 0) return -1; server_addr.sin_port = htons(server_port); if (connect(connection[out].ch_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == 0) { break; } else { /* connect attempt failed */ CLOSESOCKET(connection[out].ch_socket); pbs_errno = errno; } } if (i >= (have_alt+1)) { connection[out].ch_inuse = 0; return -1; /* cannot connect */ } #ifndef WIN32 if (have_alt && (i == 1)) { /* had to use the second listed server ... */ if (using_secondary == 1) { /* remove file that causes trying the Secondary first */ unlink(pbsrc); } else { /* create file that causes trying the Primary first */ f = open(pbsrc, O_WRONLY|O_CREAT, 0200); if (f != -1) (void)close(f); } } #endif /* setup connection level thread context */ if (pbs_client_thread_init_connect_context(out) != 0) { CLOSESOCKET(connection[out].ch_socket); connection[out].ch_inuse = 0; /* pbs_errno set by the pbs_connect_init_context routine */ return -1; } /* * No need for global lock now on, since rest of the code * is only communication on a connection handle. * But we dont need to lock the connection handle, since this * connection handle is not yet been returned to the client */ /* The following code was originally put in for HPUX systems to deal * with the issue where returning from the connect() call doesn't * mean the connection is complete. However, this has also been * experienced in some Linux ppc64 systems like js-2. Decision was * made to enable this harmless code for all architectures. * FIX: Need to use the socket to send * a message to complete the process. For IFF authentication there is * no leading authentication message needing to be sent on the client * socket, so will send a "dummy" message and discard the replyback. */ #if !defined(PBS_SECURITY ) || (PBS_SECURITY == STD ) DIS_tcp_setup(connection[out].ch_socket); if ((i = encode_DIS_ReqHdr(connection[out].ch_socket, PBS_BATCH_Connect, pbs_current_user)) || (i = encode_DIS_ReqExtend(connection[out].ch_socket, extend_data))) { pbs_errno = PBSE_SYSTEM; return -1; } if (DIS_tcp_wflush(connection[out].ch_socket)) { pbs_errno = PBSE_SYSTEM; return -1; } reply = PBSD_rdrpy(out); PBSD_FreeReply(reply); #endif /* PBS_SECURITY ... */ /*do configured authentication (kerberos, pbs_iff, whatever)*/ /*Get the socket port for engage_authentication() */ socknamelen = sizeof(sockname); if (getsockname(connection[out].ch_socket, (struct sockaddr *)&sockname, &socknamelen)) return -1; if (engage_authentication(connection[out].ch_socket, server, server_port, &sockname) == -1) { CLOSESOCKET(connection[out].ch_socket); connection[out].ch_inuse = 0; pbs_errno = PBSE_PERM; return -1; } /* setup DIS support routines for following pbs_* calls */ DIS_tcp_setup(connection[out].ch_socket); pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_VLONG; /* set for 3 hours */ /* * Disable Nagle's algorithm on the TCP connection to server. * Nagle's algorithm is hurting cmd-server communication. */ if (pbs_connection_set_nodelay(out) == -1) { CLOSESOCKET(connection[out].ch_socket); connection[out].ch_inuse = 0; pbs_errno = PBSE_SYSTEM; return -1; } return out; }