int decode_arst(struct attribute *patr, char *name, char *rescn, char *val) { int rc; attribute temp; if ((val == (char *)0) || (strlen(val) == 0)) { free_arst(patr); /* _SET cleared in free_arst */ patr->at_flags |= ATR_VFLAG_MODIFY | ATR_VFLAG_MODCACHE; return (0); } if ((patr->at_flags & ATR_VFLAG_SET) && (patr->at_val.at_arst)) { /* already have values, decode new into temp */ /* then use set(incr) to add new to existing */ temp.at_flags = 0; temp.at_type = ATR_TYPE_ARST; temp.at_user_encoded = NULL; temp.at_priv_encoded = NULL; temp.at_val.at_arst = 0; if ((rc = decode_arst_direct(&temp, val)) != 0) return (rc); rc = set_arst(patr, &temp, SET); free_arst(&temp); return (rc); } else { /* decode directly into real attribute */ return (decode_arst_direct(patr, val)); } }
END_TEST START_TEST(test_two) { pbs_attribute attr; server_host = (char *)"bdaw.ac"; memset(&attr,0,sizeof(attr)); decode_arst(&attr,NULL,NULL,"[email protected],[email protected],[email protected]",0); fail_unless(acl_check(&attr,(char *)"*****@*****.**",ACL_User)==1); free_arst(&attr); memset(&attr,0,sizeof(attr)); decode_arst(&attr,NULL,NULL,"[email protected],[email protected],[email protected]",0); fail_unless(acl_check(&attr,(char *)"*****@*****.**",ACL_User)==0); free_arst(&attr); memset(&attr,0,sizeof(attr)); decode_arst(&attr,NULL,NULL,"braddaw.com,gmail.com,farmer.org,host[0-7]",0); fail_unless(acl_check(&attr,(char *)"host0",ACL_Host)==1); fail_unless(acl_check(&attr,(char *)"host8",ACL_Host)==0); free_arst(&attr); memset(&attr,0,sizeof(attr)); decode_arst(&attr,NULL,NULL,"braddaw.com,gmail.com,farmer.org,host*",0); fail_unless(acl_check(&attr,(char *)"host0",ACL_Host)==1); fail_unless(acl_check(&attr,(char *)"heist8",ACL_Host)==0); free_arst(&attr); }
int decode_arst_merge( pbs_attribute *patr, /* O (modified) */ char *name, /* I pbs_attribute name (notused) */ char *rescn, /* I resource name (notused) */ char *val) /* I pbs_attribute value */ { int rc; pbs_attribute new_attr; pbs_attribute tmp; if ((val == NULL) || (strlen(val) == 0)) { free_arst(patr); patr->at_flags &= ~ATR_VFLAG_MODIFY; /* _SET cleared in free_arst */ return(0); } if (!(patr->at_flags & ATR_VFLAG_SET) || (patr->at_val.at_arst == NULL)) { /* decode directly into real pbs_attribute */ return(decode_arst_direct(patr,val)); } memset(&new_attr,0x0,sizeof(pbs_attribute)); memset(&tmp,0x0,sizeof(pbs_attribute)); /* already have values, decode new into temp */ /* then use set(incr) to add new to existing */ /* convert value string into pbs_attribute array */ if ((rc = decode_arst_direct(&new_attr,val)) != 0) { /* FAILURE */ return(rc); } /* copy patr to temp, and new to patr */ tmp.at_val.at_arst = patr->at_val.at_arst; patr->at_val.at_arst = new_attr.at_val.at_arst; /* incr original patr value onto new patr */ tmp.at_flags |= ATR_VFLAG_SET; rc = set_arst(patr,&tmp,MERGE); free_arst(&tmp); return(rc); } /* END decode_arst_merge() */
int decode_arst( pbs_attribute *patr, /* O (modified) */ char *name, /* I pbs_attribute name (notused) */ char *rescn, /* I resource name (notused) */ char *val, /* I pbs_attribute value */ int perm) /* only used for resources */ { int rc; pbs_attribute temp; if ((val == NULL) || (strlen(val) == 0)) { free_arst(patr); patr->at_flags &= ~ATR_VFLAG_MODIFY; /* _SET cleared in free_arst */ return(0); } memset(&temp, 0, sizeof(pbs_attribute)); if ((patr->at_flags & ATR_VFLAG_SET) && (patr->at_val.at_arst)) { /* already have values, decode new into temp */ /* then use set(incr) to add new to existing */ /* convert value string into pbs_attribute array */ if ((rc = decode_arst_direct(&temp,val)) != 0) { /* FAILURE */ return(rc); } rc = set_arst(patr,&temp,INCR); free_arst(&temp); return(rc); } /* decode directly into real pbs_attribute */ return(decode_arst_direct(patr,val)); } /* END decode_arst() */
int save_node_status( struct pbsnode *np, pbs_attribute *temp) { int rc = PBSE_NONE; char date_attrib[MAXLINE]; /* it's nice to know when the last update happened */ snprintf(date_attrib, sizeof(date_attrib), "rectime=%ld", (long)time(NULL)); if (decode_arst(temp, NULL, NULL, date_attrib, 0)) { DBPRT(("is_stat_get: cannot add date_attrib\n")); } /* insert the information from "temp" into np */ if ((rc = node_status_list(temp, np, ATR_ACTION_ALTER)) != PBSE_NONE) { DBPRT(("is_stat_get: cannot set node status list\n")); } free_arst(temp); return(rc); } /* END save_node_status() */
int process_gpu_status( struct pbsnode *pnode, unsigned int &i, std::vector<std::string> &status_info) { pbs_attribute temp; int gpu_count = 0; int rc = PBSE_NONE; char buf[MAXLINE * 2]; std::string gpu_info = ""; memset(&temp, 0, sizeof(temp)); if ((rc = decode_arst(&temp, NULL, NULL, NULL, 0)) != PBSE_NONE) { log_record(PBSEVENT_DEBUG, PBS_EVENTCLASS_NODE, __func__, "cannot initialize attribute"); finish_gpu_status(i, status_info); return(rc); } /* move past the initial gpu status */ i++; for (; i < status_info.size(); i++) { if (!strcmp(status_info[i].c_str(), CRAY_GPU_STATUS_END)) break; if (!strncmp(status_info[i].c_str(), "gpu_id=", strlen("gpu_id="))) { snprintf(buf, sizeof(buf), "gpu[%d]=%s;", gpu_count, status_info[i].c_str()); gpu_info += buf; gpu_count++; } else { gpu_info += status_info[i].c_str(); gpu_info += ';'; } } set_ngpus(pnode, gpu_count); decode_arst(&temp, NULL, NULL, gpu_info.c_str(), 0); node_gpustatus_list(&temp, pnode, ATR_ACTION_ALTER); free_arst(&temp); return(rc); } /* END process_gpu_status() */
int set_acl_arst( pbs_attribute *attr, /* I/O */ pbs_attribute *new_attr, /* I */ enum batch_op op) /* I */ { struct array_strings *newpas = NULL; assert(attr && new_attr && (new_attr->at_flags & ATR_VFLAG_SET)); newpas = new_attr->at_val.at_arst; //Empty input so empty the output. if (newpas == NULL) { if(op == SET) { free_arst(attr); attr->at_flags |= ATR_VFLAG_SET | ATR_VFLAG_MODIFY; } return(PBSE_NONE); } int rc = set_arst(attr,new_attr,op); if(rc != PBSE_NONE) { return(rc); } if(attr->at_val.at_arst->as_usedptr == 0) { free_arst(attr); attr->at_flags |= ATR_VFLAG_SET | ATR_VFLAG_MODIFY; } return(PBSE_NONE); }
int decode_acl_arst( pbs_attribute *patr, /* O (modified) */ const char *name, /* I pbs_attribute name (notused) */ const char *rescn, /* I resource name (notused) */ const char *val, /* I pbs_attribute value */ int perm) /* only used for resources */ { if ((val == NULL) || (strlen(val) == 0)) { free_arst(patr); patr->at_flags |= ATR_VFLAG_SET | ATR_VFLAG_MODIFY; return(0); } return decode_arst(patr,name,rescn,val,perm); }
int save_single_mic_status( std::string &single_mic_status, pbs_attribute *temp) { int rc = PBSE_NONE; if (single_mic_status.length() > 0) { if ((rc = decode_arst(temp, NULL, NULL, single_mic_status.c_str(), 0)) != PBSE_NONE) { log_err(ENOMEM, __func__, ""); free_arst(temp); } } return(rc); } /* END save_single_mic_status() */
int save_single_mic_status( dynamic_string *single_mic_status, pbs_attribute *temp) { int rc = PBSE_NONE; if (single_mic_status->used > 0) { if ((rc = decode_arst(temp, NULL, NULL, single_mic_status->str, 0)) != PBSE_NONE) { log_err(ENOMEM, __func__, ""); free_arst(temp); } clear_dynamic_string(single_mic_status); } return(rc); } /* END save_single_mic_status() */
int process_alps_status( char *nd_name, dynamic_string *status_info) { char *str; char node_index_buf[MAXLINE]; int node_index = 0; struct pbsnode *parent; struct pbsnode *current = NULL; int rc; pbs_attribute temp; memset(&temp, 0, sizeof(temp)); if ((rc = decode_arst(&temp, NULL, NULL, NULL, 0)) != PBSE_NONE) { log_record(PBSEVENT_DEBUG, PBS_EVENTCLASS_NODE, __func__, "cannot initialize attribute"); return(rc); } /* if we can't find the parent node, ignore the update */ if ((parent = find_nodebyname(nd_name)) == NULL) return(PBSE_NONE); /* loop over each string */ for (str = status_info->str; str != NULL && *str != '\0'; str += strlen(str) + 1) { if (!strncmp(str, "node=", strlen("node="))) { if (str != status_info->str) { snprintf(node_index_buf, sizeof(node_index_buf), "node_index=%d", node_index++); decode_arst(&temp, NULL, NULL, node_index_buf, 0); save_node_status(current, &temp); } if ((current = determine_node_from_str(str, parent, current)) == NULL) break; else continue; } /* process the gpu status information separately */ if (!strcmp(CRAY_GPU_STATUS_START, str)) { process_gpu_status(current, &str); continue; } else if (!strncmp(reservation_id, str, strlen(reservation_id))) { process_reservation_id(current, str); } /* save this as is to the status strings */ else if ((rc = decode_arst(&temp, NULL, NULL, str, 0)) != PBSE_NONE) { free_arst(&temp); return(rc); } /* perform any special processing */ if (!strncmp(str, cproc_eq, cproc_eq_len)) { set_ncpus(current, str); } else if (!strncmp(str, state, strlen(state))) { set_state(current, str); } } /* END processing the status update */ if (current != NULL) { snprintf(node_index_buf, sizeof(node_index_buf), "node_index=%d", node_index++); decode_arst(&temp, NULL, NULL, node_index_buf, 0); save_node_status(current, &temp); unlock_node(current, __func__, NULL, 0); } unlock_node(parent, __func__, NULL, 0); return(PBSE_NONE); } /* END process_alps_status() */
int process_gpu_status( struct pbsnode *pnode, char **str_ptr) { char *str = *str_ptr; pbs_attribute temp; int gpu_count = 0; int rc; char buf[MAXLINE * 2]; dynamic_string *gpu_info; memset(&temp, 0, sizeof(temp)); if ((gpu_info = get_dynamic_string(-1, NULL)) == NULL) { *str_ptr = finish_gpu_status(str); return(ENOMEM); } if ((rc = decode_arst(&temp, NULL, NULL, NULL, 0)) != PBSE_NONE) { log_record(PBSEVENT_DEBUG, PBS_EVENTCLASS_NODE, __func__, "cannot initialize attribute"); *str_ptr = finish_gpu_status(str); free_dynamic_string(gpu_info); return(rc); } /* move past the initial gpu status */ str += strlen(str) + 1; for (; str != NULL && *str != '\0'; str += strlen(str) + 1) { if (!strcmp(str, CRAY_GPU_STATUS_END)) break; if (!strncmp(str, "gpu_id=", strlen("gpu_id="))) { snprintf(buf, sizeof(buf), "gpu[%d]=%s;", gpu_count, str); rc = append_dynamic_string(gpu_info, buf); gpu_count++; } else { rc = append_dynamic_string(gpu_info, str); rc = append_char_to_dynamic_string(gpu_info, ';'); } if (rc != PBSE_NONE) { free_dynamic_string(gpu_info); *str_ptr = finish_gpu_status(str); return(rc); } } set_ngpus(pnode, gpu_count); decode_arst(&temp, NULL, NULL, gpu_info->str, 0); node_gpustatus_list(&temp, pnode, ATR_ACTION_ALTER); free_arst(&temp); free_dynamic_string(gpu_info); *str_ptr = str; return(PBSE_NONE); } /* END process_gpu_status() */
int is_gpustat_get( struct pbsnode *np, /* I (modified) */ unsigned int &i, std::vector<std::string> &status_info) { pbs_attribute temp; const char *gpuid = NULL; char log_buf[LOCAL_LOG_BUF_SIZE]; int gpuidx = -1; std::stringstream gpuinfo; int need_delimiter = FALSE; int reportedgpucnt = 0; int startgpucnt = 0; int drv_ver = 0; if (np == NULL) { sprintf(log_buf, "Invalid parameter for np passed to is_gpustat_get"); log_event(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, __func__, log_buf); return(PBSE_BAD_PARAMETER); } if (LOGLEVEL >= 7) { sprintf(log_buf, "received gpu status from node %s", np->nd_name); log_record(PBSEVENT_SCHED, PBS_EVENTCLASS_REQUEST, __func__, log_buf); } /* save current gpu count for node */ startgpucnt = np->nd_ngpus; /* * Before filling the "temp" pbs_attribute, initialize it. * The second and third parameter to decode_arst are never * used, so just leave them empty. (GBS) */ memset(&temp, 0, sizeof(temp)); if (decode_arst(&temp, NULL, NULL, NULL, 0)) { DBPRT(("is_gpustat_get: cannot initialize attribute\n")); return(DIS_NOCOMMIT); } i++; for (; i < status_info.size(); i++) { /* add the info to the "temp" attribute */ const char *str = status_info[i].c_str(); /* get timestamp */ if (!strncmp(str, "timestamp=", 10)) { if (decode_arst(&temp, NULL, NULL, str, 0)) { DBPRT(("is_gpustat_get: cannot add attributes\n")); free_arst(&temp); move_past_gpu_status(i, status_info); return(DIS_NOCOMMIT); } continue; } /* get driver version, if there is one */ if (!strncmp(str, "driver_ver=", 11)) { if (decode_arst(&temp, NULL, NULL, str, 0)) { DBPRT(("is_gpustat_get: cannot add attributes\n")); free_arst(&temp); move_past_gpu_status(i, status_info); return(DIS_NOCOMMIT); } drv_ver = atoi(str + 11); continue; } else if (!strcmp(str, END_GPU_STATUS)) { break; } /* gpuid must come before the rest or we will be in trouble */ if (!strncmp(str, "gpuid=", 6)) { if (gpuinfo.str().size() > 0) { if (decode_arst(&temp, NULL, NULL, gpuinfo.str().c_str(), 0)) { DBPRT(("is_gpustat_get: cannot add attributes\n")); free_arst(&temp); move_past_gpu_status(i, status_info); return(DIS_NOCOMMIT); } gpuinfo.str(""); } gpuid = &str[6]; /* * Get this gpus index, if it does not yet exist then find an empty entry. * We need to allow for the gpu status results being returned in * different orders since the nvidia order may change upon mom's reboot */ gpuidx = gpu_entry_by_id(np, gpuid, TRUE); if (gpuidx == -1) { /* * Failure - we could not get / create a nd_gpusn entry for this gpu, * log an error message. */ if (LOGLEVEL >= 3) { sprintf(log_buf, "Failed to get/create entry for gpu %s on node %s\n", gpuid, np->nd_name); log_ext(-1, __func__, log_buf, LOG_DEBUG); } free_arst(&temp); move_past_gpu_status(i, status_info); return(DIS_SUCCESS); } gpuinfo << "gpu[" << gpuidx << "]=gpu_id=" << gpuid << ";"; need_delimiter = FALSE; reportedgpucnt++; np->nd_gpusn[gpuidx].driver_ver = drv_ver; /* mark that this gpu node is not virtual */ np->nd_gpus_real = TRUE; /* * if we have not filled in the gpu_id returned by the mom node * then fill it in */ if ((gpuidx >= 0) && (np->nd_gpusn[gpuidx].gpuid == NULL)) { np->nd_gpusn[gpuidx].gpuid = strdup(gpuid); } } else { if (need_delimiter) { gpuinfo << ";"; } gpuinfo << str; need_delimiter = TRUE; } /* check current gpu mode and determine gpu state */ if (!memcmp(str, "gpu_mode=", 9)) { if ((!memcmp(str + 9, "Normal", 6)) || (!memcmp(str + 9, "Default", 7))) { np->nd_gpusn[gpuidx].mode = gpu_normal; if (gpu_has_job(np, gpuidx)) { np->nd_gpusn[gpuidx].state = gpu_shared; } else { np->nd_gpusn[gpuidx].inuse = 0; np->nd_gpusn[gpuidx].state = gpu_unallocated; } } else if ((!memcmp(str + 9, "Exclusive", 9)) || (!memcmp(str + 9, "Exclusive_Thread", 16))) { np->nd_gpusn[gpuidx].mode = gpu_exclusive_thread; if (gpu_has_job(np, gpuidx)) { np->nd_gpusn[gpuidx].state = gpu_exclusive; } else { np->nd_gpusn[gpuidx].inuse = 0; np->nd_gpusn[gpuidx].state = gpu_unallocated; } } else if (!memcmp(str + 9, "Exclusive_Process", 17)) { np->nd_gpusn[gpuidx].mode = gpu_exclusive_process; if (gpu_has_job(np, gpuidx)) { np->nd_gpusn[gpuidx].state = gpu_exclusive; } else { np->nd_gpusn[gpuidx].inuse = 0; np->nd_gpusn[gpuidx].state = gpu_unallocated; } } else if (!memcmp(str + 9, "Prohibited", 10)) { np->nd_gpusn[gpuidx].mode = gpu_prohibited; np->nd_gpusn[gpuidx].state = gpu_unavailable; } else { /* unknown mode, default to prohibited */ np->nd_gpusn[gpuidx].mode = gpu_prohibited; np->nd_gpusn[gpuidx].state = gpu_unavailable; if (LOGLEVEL >= 3) { sprintf(log_buf, "GPU %s has unknown mode on node %s", gpuid, np->nd_name); log_ext(-1, __func__, log_buf, LOG_DEBUG); } } /* add gpu_mode so it gets added to the pbs_attribute */ if (need_delimiter) { gpuinfo << ";"; } switch (np->nd_gpusn[gpuidx].state) { case gpu_unallocated: gpuinfo << "gpu_state=Unallocated"; break; case gpu_shared: gpuinfo << "gpu_state=Shared"; break; case gpu_exclusive: gpuinfo << "gpu_state=Exclusive"; break; case gpu_unavailable: gpuinfo << "gpu_state=Unavailable"; break; } } } /* end of while disrst */ if (gpuinfo.str().size() > 0) { if (decode_arst(&temp, NULL, NULL, gpuinfo.str().c_str(), 0)) { DBPRT(("is_gpustat_get: cannot add attributes\n")); free_arst(&temp); move_past_gpu_status(i, status_info); return(DIS_NOCOMMIT); } } /* maintain the gpu count, if it has changed we need to update the nodes file */ if (reportedgpucnt != startgpucnt) { np->nd_ngpus = reportedgpucnt; /* update the nodes file */ update_nodes_file(np); } node_gpustatus_list(&temp, np, ATR_ACTION_ALTER); move_past_gpu_status(i, status_info); return(DIS_SUCCESS); } /* END is_gpustat_get() */
int process_alps_status( const char *nd_name, std::vector<std::string> &status_info) { const char *ccu_p = NULL; char *current_node_id = NULL; char node_index_buf[MAXLINE]; int node_index = 0; struct pbsnode *parent; struct pbsnode *current = NULL; int rc; pbs_attribute temp; container::item_container<const char *> rsv_ht; char log_buf[LOCAL_LOG_BUF_SIZE]; memset(&temp, 0, sizeof(temp)); if ((rc = decode_arst(&temp, NULL, NULL, NULL, 0)) != PBSE_NONE) { log_record(PBSEVENT_DEBUG, PBS_EVENTCLASS_NODE, __func__, "cannot initialize attribute"); return(rc); } /* if we can't find the parent node, ignore the update */ if ((parent = find_nodebyname(nd_name)) == NULL) return(PBSE_NONE); /* loop over each string */ for(unsigned int i = 0; i < status_info.size(); i++) { const char *str = status_info[i].c_str(); if (!strncmp(str, "node=", strlen("node="))) { if (i != 0) { snprintf(node_index_buf, sizeof(node_index_buf), "node_index=%d", node_index++); decode_arst(&temp, NULL, NULL, node_index_buf, 0); if (current != NULL) save_node_status(current, &temp); } if ((current = determine_node_from_str(str, parent, current)) == NULL) break; else continue; } if (current == NULL) continue; /* process the gpu status information separately */ if (!strcmp(CRAY_GPU_STATUS_START, str)) { rc = process_gpu_status(current, i, status_info); continue; } else if (!strncmp(reservation_id, str, strlen(reservation_id))) { const char *just_rsv_id = str + strlen(reservation_id); rsv_ht.lock(); if (rsv_ht.find(just_rsv_id) == NULL) { rsv_ht.insert(just_rsv_id,just_rsv_id); rsv_ht.unlock(); /* sub-functions will attempt to lock a job, so we must unlock the * reporter node */ parent->unlock_node(__func__, NULL, LOGLEVEL); process_reservation_id(current, str); current_node_id = strdup(current->get_name()); current->unlock_node(__func__, NULL, LOGLEVEL); /* re-lock the parent */ if ((parent = find_nodebyname(nd_name)) == NULL) { /* reporter node disappeared - this shouldn't be possible */ log_err(PBSE_UNKNODE, __func__, "Alps reporter node disappeared while recording a reservation"); free_arst(&temp); free(current_node_id); return(PBSE_NONE); } if ((current = find_node_in_allnodes(parent->alps_subnodes, current_node_id)) == NULL) { /* current node disappeared, this shouldn't be possible either */ parent->unlock_node(__func__, NULL, LOGLEVEL); snprintf(log_buf, sizeof(log_buf), "Current node '%s' disappeared while recording a reservation", current_node_id); log_err(PBSE_UNKNODE, __func__, log_buf); free_arst(&temp); free(current_node_id); return(PBSE_NONE); } free(current_node_id); current_node_id = NULL; } else { rsv_ht.unlock(); } } /* save this as is to the status strings */ else if ((rc = decode_arst(&temp, NULL, NULL, str, 0)) != PBSE_NONE) { free_arst(&temp); return(rc); } /* perform any special processing */ if (!strncmp(str, ccu_eq, ac_ccu_eq_len)) { /* save compute unit count in case we need it */ /* note: this string (ccu_eq (CCU=)) needs to be found before cprocs_eq (CPROCS=) */ /* for the node */ ccu_p = str; } else if (!strncmp(str, cproc_eq, ac_cproc_eq_len)) { int ncpus; long svr_nppcu_value = 0; /* * Get the server nppcu value which determines how Hyper-Threaded * cores are reported. When server nppcu value is: * * 0 - Let ALPS choose whether or not to use Hyper-Threaded cores * (report all cores) * 1 - Do not use Hyper-Threaded cores * (report only physical core (compute unit count) * 2 - Use Hyper-Threaded cores * (report all cores) */ get_svr_attr_l(SRV_ATR_nppcu, &svr_nppcu_value); if (svr_nppcu_value == NPPCU_NO_USE_HT && ccu_p != NULL) { /* no HT (nppcu==1), so use compute unit count */ ncpus = atoi(ccu_p + ac_ccu_eq_len); /* use CPROC value if we are using APBASIL protocol < 1.3 */ if (ncpus == 0) ncpus = atoi(str + ac_cproc_eq_len); /* reset the pointer */ ccu_p = NULL; } else { /* let ALPS choose (nppcu==0) or use HT (nppcu==2), use actual processor count */ ncpus = atoi(str + ac_cproc_eq_len); } set_ncpus(current, parent, ncpus); } else if (!strncmp(str, state, strlen(state))) { set_state(current, str); } #ifdef PENABLE_LINUX_CGROUPS else if (!strncmp(str, "totmem", 6)) { set_total_memory(current, str); } #endif } /* END processing the status update */ if (current != NULL) { snprintf(node_index_buf, sizeof(node_index_buf), "node_index=%d", node_index++); decode_arst(&temp, NULL, NULL, node_index_buf, 0); save_node_status(current, &temp); current->unlock_node(__func__, NULL, LOGLEVEL); } parent->unlock_node(__func__, NULL, LOGLEVEL); return(PBSE_NONE); } /* END process_alps_status() */
int process_alps_status( char *nd_name, dynamic_string *status_info) { char *str; char *ccu_p = NULL; char *current_node_id = NULL; char node_index_buf[MAXLINE]; int node_index = 0; struct pbsnode *parent; struct pbsnode *current = NULL; int rc; pbs_attribute temp; hash_table_t *rsv_ht; char log_buf[LOCAL_LOG_BUF_SIZE]; memset(&temp, 0, sizeof(temp)); if ((rc = decode_arst(&temp, NULL, NULL, NULL, 0)) != PBSE_NONE) { log_record(PBSEVENT_DEBUG, PBS_EVENTCLASS_NODE, __func__, "cannot initialize attribute"); return(rc); } /* if we can't find the parent node, ignore the update */ if ((parent = find_nodebyname(nd_name)) == NULL) return(PBSE_NONE); /* keep track of reservations so that they're only processed once per update */ rsv_ht = create_hash(INITIAL_RESERVATION_HOLDER_SIZE); /* loop over each string */ for (str = status_info->str; str != NULL && *str != '\0'; str += strlen(str) + 1) { if (!strncmp(str, "node=", strlen("node="))) { if (str != status_info->str) { snprintf(node_index_buf, sizeof(node_index_buf), "node_index=%d", node_index++); decode_arst(&temp, NULL, NULL, node_index_buf, 0); if (current != NULL) save_node_status(current, &temp); } if ((current = determine_node_from_str(str, parent, current)) == NULL) break; else continue; } if (current == NULL) continue; /* process the gpu status information separately */ if (!strcmp(CRAY_GPU_STATUS_START, str)) { process_gpu_status(current, &str); continue; } else if (!strncmp(reservation_id, str, strlen(reservation_id))) { char *just_rsv_id = str + strlen(reservation_id); if (get_value_hash(rsv_ht, just_rsv_id) == -1) { add_hash(rsv_ht, 1, strdup(just_rsv_id)); /* sub-functions will attempt to lock a job, so we must unlock the * reporter node */ unlock_node(parent, __func__, NULL, LOGLEVEL); process_reservation_id(current, str); current_node_id = strdup(current->nd_name); unlock_node(current, __func__, NULL, LOGLEVEL); /* re-lock the parent */ if ((parent = find_nodebyname(nd_name)) == NULL) { /* reporter node disappeared - this shouldn't be possible */ log_err(PBSE_UNKNODE, __func__, "Alps reporter node disappeared while recording a reservation"); free_arst(&temp); free_all_keys(rsv_ht); free_hash(rsv_ht); free(current_node_id); return(PBSE_NONE); } if ((current = find_node_in_allnodes(&parent->alps_subnodes, current_node_id)) == NULL) { /* current node disappeared, this shouldn't be possible either */ unlock_node(parent, __func__, NULL, LOGLEVEL); snprintf(log_buf, sizeof(log_buf), "Current node '%s' disappeared while recording a reservation", current_node_id); log_err(PBSE_UNKNODE, __func__, log_buf); free_arst(&temp); free_all_keys(rsv_ht); free_hash(rsv_ht); free(current_node_id); return(PBSE_NONE); } free(current_node_id); current_node_id = NULL; } } /* save this as is to the status strings */ else if ((rc = decode_arst(&temp, NULL, NULL, str, 0)) != PBSE_NONE) { free_arst(&temp); free_all_keys(rsv_ht); free_hash(rsv_ht); return(rc); } /* perform any special processing */ if (!strncmp(str, ccu_eq, ac_ccu_eq_len)) { /* save compute unit count in case we need it */ /* note: this string (ccu_eq (CCU=)) needs to be found before cprocs_eq (CPROCS=) */ /* for the node */ ccu_p = str; } else if (!strncmp(str, cproc_eq, ac_cproc_eq_len)) { int ncpus; long svr_nppcu_value = 0; /* * Get the server nppcu value which determines how Hyper-Threaded * cores are reported. When server nppcu value is: * * 0 - Let ALPS choose whether or not to use Hyper-Threaded cores * (report all cores) * 1 - Do not use Hyper-Threaded cores * (report only physical core (compute unit count) * 2 - Use Hyper-Threaded cores * (report all cores) */ get_svr_attr_l(SRV_ATR_nppcu, &svr_nppcu_value); if (svr_nppcu_value == NPPCU_NO_USE_HT && ccu_p != NULL) { /* no HT (nppcu==1), so use compute unit count */ ncpus = atoi(ccu_p + ac_ccu_eq_len); /* use CPROC value if we are using APBASIL protocol < 1.3 */ if (ncpus == 0) ncpus = atoi(str + ac_cproc_eq_len); /* reset the pointer */ ccu_p = NULL; } else { /* let ALPS choose (nppcu==0) or use HT (nppcu==2), use actual processor count */ ncpus = atoi(str + ac_cproc_eq_len); } set_ncpus(current, parent, ncpus); } else if (!strncmp(str, state, strlen(state))) { set_state(current, str); } } /* END processing the status update */ if (current != NULL) { snprintf(node_index_buf, sizeof(node_index_buf), "node_index=%d", node_index++); decode_arst(&temp, NULL, NULL, node_index_buf, 0); save_node_status(current, &temp); unlock_node(current, __func__, NULL, LOGLEVEL); } unlock_node(parent, __func__, NULL, LOGLEVEL); free_all_keys(rsv_ht); free_hash(rsv_ht); return(PBSE_NONE); } /* END process_alps_status() */
int process_alps_status( char *nd_name, boost::ptr_vector<std::string>& status_info) { char *current_node_id = NULL; char node_index_buf[MAXLINE]; int node_index = 0; struct pbsnode *parent; struct pbsnode *current = NULL; int rc; pbs_attribute temp; hash_table_t *rsv_ht; char log_buf[LOCAL_LOG_BUF_SIZE]; memset(&temp, 0, sizeof(temp)); if ((rc = decode_arst(&temp, NULL, NULL, NULL, 0)) != PBSE_NONE) { log_record(PBSEVENT_DEBUG, PBS_EVENTCLASS_NODE, __func__, "cannot initialize attribute"); return(rc); } /* if we can't find the parent node, ignore the update */ if ((parent = find_nodebyname(nd_name)) == NULL) return(PBSE_NONE); /* keep track of reservations so that they're only processed once per update */ rsv_ht = create_hash(INITIAL_RESERVATION_HOLDER_SIZE); /* loop over each string */ for(boost::ptr_vector<std::string>::iterator i = status_info.begin();i != status_info.end();i++) { const char *str = i->c_str(); if (!strncmp(str, "node=", strlen("node="))) { if (i != status_info.begin()) { snprintf(node_index_buf, sizeof(node_index_buf), "node_index=%d", node_index++); decode_arst(&temp, NULL, NULL, node_index_buf, 0); save_node_status(current, &temp); } if ((current = determine_node_from_str(str, parent, current)) == NULL) break; else continue; } if(current == NULL) continue; /* process the gpu status information separately */ if (!strcmp(CRAY_GPU_STATUS_START, str)) { rc = process_gpu_status(current, i,status_info.end()); str = i->c_str(); continue; } else if (!strncmp(reservation_id, str, strlen(reservation_id))) { const char *just_rsv_id = str + strlen(reservation_id); if (get_value_hash(rsv_ht, just_rsv_id) == -1) { add_hash(rsv_ht, 1, strdup(just_rsv_id)); /* sub-functions will attempt to lock a job, so we must unlock the * reporter node */ unlock_node(parent, __func__, NULL, LOGLEVEL); process_reservation_id(current, str); current_node_id = strdup(current->nd_name); unlock_node(current, __func__, NULL, LOGLEVEL); /* re-lock the parent */ if ((parent = find_nodebyname(nd_name)) == NULL) { /* reporter node disappeared - this shouldn't be possible */ log_err(PBSE_UNKNODE, __func__, "Alps reporter node disappeared while recording a reservation"); free_arst(&temp); free_all_keys(rsv_ht); free_hash(rsv_ht); free(current_node_id); return(PBSE_NONE); } if ((current = find_node_in_allnodes(&parent->alps_subnodes, current_node_id)) == NULL) { /* current node disappeared, this shouldn't be possible either */ unlock_node(parent, __func__, NULL, LOGLEVEL); snprintf(log_buf, sizeof(log_buf), "Current node '%s' disappeared while recording a reservation", current_node_id); log_err(PBSE_UNKNODE, __func__, log_buf); free_arst(&temp); free_all_keys(rsv_ht); free_hash(rsv_ht); free(current_node_id); return(PBSE_NONE); } free(current_node_id); current_node_id = NULL; } } /* save this as is to the status strings */ else if ((rc = decode_arst(&temp, NULL, NULL, str, 0)) != PBSE_NONE) { free_arst(&temp); free_all_keys(rsv_ht); free_hash(rsv_ht); return(rc); } /* perform any special processing */ if (!strncmp(str, cproc_eq, ac_cproc_eq_len)) { set_ncpus(current, parent, str); } else if (!strncmp(str, state, strlen(state))) { set_state(current, str); } } /* END processing the status update */ if (current != NULL) { snprintf(node_index_buf, sizeof(node_index_buf), "node_index=%d", node_index++); decode_arst(&temp, NULL, NULL, node_index_buf, 0); save_node_status(current, &temp); unlock_node(current, __func__, NULL, LOGLEVEL); } unlock_node(parent, __func__, NULL, LOGLEVEL); free_all_keys(rsv_ht); free_hash(rsv_ht); return(PBSE_NONE); } /* END process_alps_status() */
int set_arst( pbs_attribute *attr, /* I/O */ pbs_attribute *new_attr, /* I */ enum batch_op op) /* I */ { int i; int j; int nsize; int need; long offset; char *pc = NULL; long used; struct array_strings *newpas = NULL; struct array_strings *pas = NULL; struct array_strings *tmp_arst = NULL; pas = attr->at_val.at_arst; newpas = new_attr->at_val.at_arst; if (newpas == NULL) { return(PBSE_INTERNAL); } if (pas == NULL) { /* not array_strings control structure, make one */ j = newpas->as_npointers; if (j < 1) { return(PBSE_INTERNAL); } need = sizeof(struct array_strings) + (j - 1) * sizeof(char *); pas = (struct array_strings *)calloc(1, (size_t)need); if (pas == NULL) { return(PBSE_SYSTEM); } pas->as_npointers = j; pas->as_usedptr = 0; pas->as_bufsize = 0; pas->as_buf = NULL; pas->as_next = NULL; attr->at_val.at_arst = pas; } /* END if (pas == NULL) */ if ((op == INCR) && !pas->as_buf) op = SET; /* no current strings, change op to SET */ /* * * At this point we know we have a array_strings struct initialized * */ switch (op) { case SET: /* * * Replace old array of strings with new array, this is * * simply done by deleting old strings and appending the * * new (to the null set). * */ for (i = 0;i < pas->as_usedptr;i++) pas->as_string[i] = NULL; /* clear all pointers */ pas->as_usedptr = 0; pas->as_next = pas->as_buf; if (new_attr->at_val.at_arst == (struct array_strings *)0) break; /* none to set */ nsize = newpas->as_next - newpas->as_buf; /* space needed */ if (nsize > pas->as_bufsize) { /* new data won't fit */ if (pas->as_buf) free(pas->as_buf); nsize += nsize / 2; /* alloc extra space */ if (!(pas->as_buf = (char *)calloc(1, (size_t)nsize))) { pas->as_bufsize = 0; return(PBSE_SYSTEM); } pas->as_bufsize = nsize; } else { /* str fits, clear buf */ memset(pas->as_buf,0,pas->as_bufsize); } pas->as_next = pas->as_buf; /* no break, "SET" falls into "MERGE" to add strings */ case INCR_OLD: case MERGE: nsize = newpas->as_next - newpas->as_buf; /* space needed */ used = pas->as_next - pas->as_buf; if (nsize > (pas->as_bufsize - used)) { need = pas->as_bufsize + 2 * nsize; /* alloc new buf */ if (pas->as_buf) { pc = (char *)realloc(pas->as_buf, (size_t)need); if (pc != NULL) memset(pc + pas->as_bufsize, 0, need - pas->as_bufsize); } else pc = (char *)calloc(1, (size_t)need); if (pc == NULL) { return(PBSE_SYSTEM); } offset = pc - pas->as_buf; pas->as_buf = pc; pas->as_next = pc + used; pas->as_bufsize = need; for (j = 0;j < pas->as_usedptr;j++) /* adjust points */ pas->as_string[j] += offset; } /* END if (nsize > (pas->as_bufsize - used)) */ j = pas->as_usedptr + newpas->as_usedptr; if (j > pas->as_npointers) { struct array_strings *tmpPas; /* need more pointers */ j = 3 * j / 2; /* allocate extra */ need = (int)sizeof(struct array_strings) + (j - 1) * sizeof(char *); tmpPas = (struct array_strings *)realloc((char *)pas,(size_t)need); if (tmpPas == NULL) { return(PBSE_SYSTEM); } tmpPas->as_npointers = j; pas = tmpPas; attr->at_val.at_arst = pas; } /* END if (j > pas->as_npointers) */ /* now append new strings */ for (i = 0;i < newpas->as_usedptr;i++) { char *tail; int len; int MatchFound; /* boolean */ if ((op == MERGE) && (tail = strchr(newpas->as_string[i],'='))) { len = tail - newpas->as_string[i]; MatchFound = 0; for (j = 0;j < pas->as_usedptr;j++) { if (!strncmp(pas->as_string[j],newpas->as_string[i],len)) { MatchFound = 1; break; } } if (MatchFound == 1) continue; } strcpy(pas->as_next,newpas->as_string[i]); pas->as_string[pas->as_usedptr++] = pas->as_next; pas->as_next += strlen(pas->as_next) + 1; } /* END for (i) */ break; case INCR: j = 1.5 * (pas->as_usedptr + newpas->as_usedptr); /* calloc the tmp array strings */ need = sizeof(struct array_strings) + (j-1) * sizeof(char *); tmp_arst = (struct array_strings *)calloc(1, need); if (tmp_arst == NULL) return(PBSE_SYSTEM); memset(tmp_arst,0,need); nsize = newpas->as_next - newpas->as_buf; /* space needed */ used = pas->as_next - pas->as_buf; need = 2 * (nsize + used); tmp_arst->as_bufsize = need; /* calloc the buffer size */ pc = (char *)calloc(1, need); if (pc == NULL) return(PBSE_SYSTEM); memset(pc, 0, need); tmp_arst->as_buf = pc; tmp_arst->as_next = pc; tmp_arst->as_npointers = j; /* now that everything is allocated, copy the strings into the new * * array_strings struct */ /* first, copy the new */ for (i = 0; i < newpas->as_usedptr; i++) { strcpy(tmp_arst->as_next,newpas->as_string[i]); tmp_arst->as_string[tmp_arst->as_usedptr++] = tmp_arst->as_next; tmp_arst->as_next += strlen(tmp_arst->as_next) + 1; } /* second, copy the old if not already there */ for (i = 0; i < pas->as_usedptr; i++) { char *tail; int len; int MatchFound = 0; /* boolean */ if ((tail = strchr(pas->as_string[i],'='))) { len = tail - pas->as_string[i]; for (j = 0;j < newpas->as_usedptr;j++) { if (!strncmp(pas->as_string[i],newpas->as_string[j],len)) { MatchFound = 1; break; } } } if (MatchFound == 0) { strcpy(tmp_arst->as_next, pas->as_string[i]); tmp_arst->as_string[tmp_arst->as_usedptr++] = tmp_arst->as_next; tmp_arst->as_next += strlen(tmp_arst->as_next) + 1; } } /* free the old pas */ free_arst(attr); attr->at_val.at_arst = tmp_arst; break; case DECR: /* decrement (remove) string from array */ for (j = 0;j < newpas->as_usedptr;j++) { for (i = 0;i < pas->as_usedptr;i++) { if (!strcmp(pas->as_string[i], newpas->as_string[j])) { /* compact buffer */ int k; nsize = strlen(pas->as_string[i]) + 1; pc = pas->as_string[i] + nsize; need = pas->as_next - pc; for (k = 0; k < need; k++) pas->as_string[i][k] = *(pc + k); /* memcpy(pas->as_string[i], pc, (size_t)need);*/ pas->as_next -= nsize; /* compact pointers */ for (++i;i < pas->as_npointers;i++) pas->as_string[i - 1] = pas->as_string[i] - nsize; pas->as_string[i - 1] = NULL; pas->as_usedptr--; break; } } } break; default: return(PBSE_INTERNAL); /*NOTREACHED*/ break; } /* END switch(op) */ attr->at_flags |= ATR_VFLAG_SET | ATR_VFLAG_MODIFY; return(0); } /* END set_arst() */
int process_status_info( const char *nd_name, std::vector<std::string> &status_info) { const char *name = nd_name; struct pbsnode *current; long mom_job_sync = FALSE; long auto_np = FALSE; long down_on_error = FALSE; int dont_change_state = FALSE; pbs_attribute temp; int rc = PBSE_NONE; bool send_hello = false; get_svr_attr_l(SRV_ATR_MomJobSync, &mom_job_sync); get_svr_attr_l(SRV_ATR_AutoNodeNP, &auto_np); get_svr_attr_l(SRV_ATR_DownOnError, &down_on_error); /* Before filling the "temp" pbs_attribute, initialize it. * The second and third parameter to decode_arst are never * used, so just leave them empty. (GBS) */ memset(&temp, 0, sizeof(temp)); if ((rc = decode_arst(&temp, NULL, NULL, NULL, 0)) != PBSE_NONE) { log_record(PBSEVENT_DEBUG, PBS_EVENTCLASS_NODE, __func__, "cannot initialize attribute"); return(rc); } /* if original node cannot be found do not process the update */ if ((current = find_nodebyname(nd_name)) == NULL) return(PBSE_NONE); //A node we put to sleep is up and running. if (current->nd_power_state != POWER_STATE_RUNNING) { //Make sure we wait for a stray update that came after we changed the state to pass //by. if((current->nd_power_state_change_time + NODE_POWER_CHANGE_TIMEOUT) < time(NULL)) { current->nd_power_state = POWER_STATE_RUNNING; write_node_power_state(); } } /* loop over each string */ for (unsigned int i = 0; i != status_info.size(); i++) { const char *str = status_info[i].c_str(); /* these two options are for switching nodes */ if (!strncmp(str, NUMA_KEYWORD, strlen(NUMA_KEYWORD))) { /* if we've already processed some, save this before moving on */ if (i != 0) save_node_status(current, &temp); dont_change_state = FALSE; if ((current = get_numa_from_str(str, current)) == NULL) break; else continue; } else if (!strncmp(str, "node=", strlen("node="))) { /* if we've already processed some, save this before moving on */ if (i != 0) save_node_status(current, &temp); dont_change_state = FALSE; if ((current = get_node_from_str(str, name, current)) == NULL) break; else { if (current->nd_mom_reported_down == TRUE) { /* There is a race condition if using a mom hierarchy and manually * shutting down a non-level 1 mom: if its message that the mom is * shutting down gets there before its last status update, the node * can incorrectly be set as free again. For that reason, only set * a mom back up if its reporting for itself. */ if (strcmp(name, str + strlen("node=")) != 0) dont_change_state = TRUE; else current->nd_mom_reported_down = FALSE; } continue; } } /* add the info to the "temp" pbs_attribute */ else if (!strcmp(str, START_GPU_STATUS)) { is_gpustat_get(current, i, status_info); str = status_info[i].c_str(); } else if (!strcmp(str, START_MIC_STATUS)) { process_mic_status(current, i, status_info); str = status_info[i].c_str(); } #ifdef PENABLE_LINUX_CGROUPS else if (!strncmp(str, "layout", 6)) { if (current->nd_layout == NULL) { current->nd_layout = new Machine(status_info[i]); } continue; } #endif else if (!strcmp(str, "first_update=true")) { /* mom is requesting that we send the mom hierarchy file to her */ //remove_hello(&hellos, current->nd_id); send_hello = true; /* reset gpu data in case mom reconnects with changed gpus */ clear_nvidia_gpus(current); } else if ((rc = decode_arst(&temp, NULL, NULL, str, 0)) != PBSE_NONE) { DBPRT(("is_stat_get: cannot add attributes\n")); free_arst(&temp); break; } if (!strncmp(str, "state", 5)) { if (dont_change_state == FALSE) process_state_str(current, str); } else if ((allow_any_mom == TRUE) && (!strncmp(str, "uname", 5))) { process_uname_str(current, str); } else if (!strncmp(str, "me", 2)) /* shorter str compare than "message" */ { if ((!strncmp(str, "message=ERROR", 13)) && (down_on_error == TRUE)) { update_node_state(current, INUSE_DOWN); dont_change_state = TRUE; set_note_error(current, str); } } else if (!strncmp(str,"macaddr=",8)) { update_node_mac_addr(current,str + 8); } else if ((mom_job_sync == TRUE) && (!strncmp(str, "jobdata=", 8))) { /* update job attributes based on what the MOM gives us */ update_job_data(current, str + strlen("jobdata=")); } else if ((mom_job_sync == TRUE) && (!strncmp(str, "jobs=", 5))) { /* walk job list reported by mom */ size_t len = strlen(str) + strlen(current->nd_name) + 2; char *jobstr = (char *)calloc(1, len); sync_job_info *sji = (sync_job_info *)calloc(1, sizeof(sync_job_info)); if ((jobstr != NULL) && (sji != NULL)) { sprintf(jobstr, "%s:%s", current->nd_name, str+5); sji->input = jobstr; sji->timestamp = time(NULL); /* sji must be freed in sync_node_jobs */ enqueue_threadpool_request(sync_node_jobs, sji, task_pool); } else { if (jobstr != NULL) { free(jobstr); } if (sji != NULL) { free(sji); } } } else if (auto_np) { if (!(strncmp(str, "ncpus=", 6))) { handle_auto_np(current, str); } } } /* END processing strings */ if (current != NULL) { save_node_status(current, &temp); unlock_node(current, __func__, NULL, LOGLEVEL); } if ((rc == PBSE_NONE) && (send_hello == true)) rc = SEND_HELLO; return(rc); } /* END process_status_info() */