/****** SCHEDD/order_remove_order_and_immediate()******************************* * NAME * order_remove_order_and_immediate() -- add a remove order for the job task * * SYNOPSIS * int order_remove_order_and_immediate(lListElem *job, lListElem *ja_task, order_t *orders) * * FUNCTION * Generates an order of type ORT_remove_immediate_job for the given job * task. Also removes the ORT_start_job order for this task from the order * list. * * INPUTS * lListElem *job - The job to remove (JB_Type) * lListElem *ja_task - The task to remove (JAT_Type) * order_t *orders - The order structurestructure for this scheduler pass be removed * * RESULT * int - Error code: 0 = OK, 1 = Errors * * NOTES * MT-NOTE: order_remove_order_and_immediate() is MT safe * *******************************************************************************/ static void order_remove_order_and_immediate( lListElem *job, lListElem *ja_task, order_t *orders) { /* The possibility exists that this task is part of an array task, that it * already has earned an order to be scheduled, and that one or more other * tasks in this same job were not scheduled, resulting in this delete * order. In this case, we have to remove the schedule order before we add * the delete order. Otherwise, the qmaster will think we're trying to do * an ORT_remove_immediate_job on a non-idle task. */ /* Warning: we have a problem, if we send start orders during the dispatch run. We * might have started a array task of an immediate array job without verifying, that * the whole job can run */ lList *orderList = orders->jobStartOrderList; lCondition *where = lWhere("%T(%I==%u && %I==%u && %I==%u)", OR_Type, OR_type, ORT_start_job, OR_job_number, lGetUlong(job, JB_job_number), OR_ja_task_number, lGetUlong(ja_task, JAT_task_number)); lListElem *ep = lFindFirst (orderList, where); DENTER(TOP_LAYER, "order_remove_order_and_immediate"); if (ep != NULL) { DPRINTF (("Removing job start order for job task "sge_u32"."sge_u32"\n", lGetUlong(job, JB_job_number), lGetUlong(ja_task, JAT_task_number))); lRemoveElem(orderList, &ep); } order_remove_immediate(job, ja_task, orders); lFreeWhere(&where); DEXIT; }
/****** Eventmirror/job/job_update_master_list_usage() ************************* * NAME * job_update_master_list_usage() -- update usage for a jobs tasks * * SYNOPSIS * int job_update_master_list_usage(lListElem *event) * * FUNCTION * Events containing usage reports are sent for a jobs tasks. * This can be array tasks (where a non array job has a single * array task) or tasks of a parallel job. * This function decides which type of task has to receive * the updated usage report and passes the event * information to the corresponding update functions. * * INPUTS * lListElem *event - event object containing the new usage list * lList *job_list - master job list * * RESULT * bool - true, if the operation succeeds, else false * * SEE ALSO * Eventmirror/ja_task/pe_task_update_master_list_usage() * Eventmirror/pe_task/pe_task_update_master_list_usage() *******************************************************************************/ static bool job_update_master_list_usage(lList *job_list, lListElem *event) { bool ret = true; u_long32 job_id, ja_task_id; const char *pe_task_id; DENTER(TOP_LAYER, "job_update_master_list_usage"); job_id = lGetUlong(event, ET_intkey); ja_task_id = lGetUlong(event, ET_intkey2); pe_task_id = lGetString(event, ET_strkey); if(ja_task_id == 0) { dstring id_dstring = DSTRING_INIT; ERROR((SGE_EVENT, MSG_JOB_RECEIVEDINVALIDUSAGEEVENTFORJOB_S, job_get_id_string(job_id, ja_task_id, pe_task_id, &id_dstring))); sge_dstring_free(&id_dstring); ret = false; } if(pe_task_id != NULL) { ret = (pe_task_update_master_list_usage(job_list, event) != SGE_EMA_FAILURE)?true:false; /* usage for a pe task */ } else { ret = (ja_task_update_master_list_usage(job_list, event) != SGE_EMA_FAILURE)?true:false; /* usage for a ja task */ } DEXIT; return ret; }
/****** sge_complex_schedd/is_attr_prior2() ************************************ * NAME * is_attr_prior2() -- checks, if the set value in the structure has a higher priority * than the new one * * SYNOPSIS * static bool is_attr_prior2(lListElem *upper_el, double lower_value, int * t_value, int t_dominant) * * FUNCTION * Computes the priority between a given structure and its values and a new value. This * is done on some basic rules. If the value is not set (dominant == DOMINANT_TYPE_VALUE) * or which relational opperator is used. If this is not enough, the two values are compared * and based on the opperator, it returns a true or false: * if no value is set in the structure: false * if the relops are == or != : true * if the relops are >= or > : true, when the new value is smaller than the old one * if the relops are <= or < : true, when the new value is bigger than the old one * * INPUTS * lListElem *upper_el - target structure * double lower_value - new value * int t_value - which field to use (CE_doubleval or CE_pj_doubleval) * int t_dominant - which dominant field to use (CE_dominant, CE_pj_dominant) * * RESULT * static bool - true, if the value in the structure has the higher priority * *******************************************************************************/ static bool is_attr_prior2(lListElem *upper_el, double lower_value, int t_value, int t_dominant ){ u_long32 relop; u_long32 dom; bool ret; double upper_value; DENTER(BASIS_LAYER, "is_attr_prior2"); if ((dom = lGetUlong(upper_el, t_dominant)) == 0 || (dom & DOMINANT_TYPE_VALUE) ){ DRETURN(false); } relop = lGetUlong(upper_el, CE_relop); if ((relop == CMPLXEQ_OP || relop == CMPLXNE_OP)) { DRETURN(true); } upper_value = lGetDouble(upper_el, t_value); if (relop == CMPLXGE_OP || relop == CMPLXGT_OP ){ ret = upper_value >= lower_value ? true : false; } else { ret = upper_value <= lower_value ? true : false; } DRETURN(ret); }
/****** qmaster/setup_qmaster/sge_setup_job_resend() *************************** * NAME * sge_setup_job_resend() -- Setup job resend events. * * SYNOPSIS * void sge_setup_job_resend(void) * * FUNCTION * Register a job resend event for each job or array task which does have a * 'JTRANSFERING' status. * * INPUTS * void - none * * RESULT * void - none * * NOTES * MT-NOTE: sge_setup_job_resend() is not MT safe * *******************************************************************************/ void sge_setup_job_resend(void) { lListElem *job = NULL; object_description *object_base = object_type_get_object_description(); DENTER(TOP_LAYER, "sge_setup_job_resend"); job = lFirst(*object_base[SGE_TYPE_JOB].list); while (NULL != job) { lListElem *task; u_long32 job_num; job_num = lGetUlong(job, JB_job_number); task = lFirst(lGetList(job, JB_ja_tasks)); while (NULL != task) { if (lGetUlong(task, JAT_status) == JTRANSFERING) { lListElem *granted_queue, *qinstance, *host; const char *qname; u_long32 task_num, when; te_event_t ev; task_num = lGetUlong(task, JAT_task_number); granted_queue = lFirst(lGetList(task, JAT_granted_destin_identifier_list)); qname = lGetString(granted_queue, JG_qname); qinstance = cqueue_list_locate_qinstance(*object_base[SGE_TYPE_CQUEUE].list, qname); host = host_list_locate(*object_base[SGE_TYPE_EXECHOST].list, lGetHost(qinstance, QU_qhostname)); when = lGetUlong(task, JAT_start_time); when += MAX(load_report_interval(host), MAX_JOB_DELIVER_TIME); ev = te_new_event((time_t)when, TYPE_JOB_RESEND_EVENT, ONE_TIME_EVENT, job_num, task_num, "job-resend_event"); te_add_event(ev); te_free_event(&ev); DPRINTF(("Did add job resend for "sge_u32"/"sge_u32" at %d\n", job_num, task_num, when)); } task = lNext(task); } job = lNext(job); } DEXIT; return; } /* sge_setup_job_resend() */
void sge_print_categories(void) { lListElem *cat; DENTER(TOP_LAYER, "sge_print_categories"); for_each (cat, CATEGORY_LIST) { DPRINTF(("PTR: %p CAT: %s REJECTED: "sge_u32" REFCOUNT: "sge_u32"\n", cat, lGetString(cat, CT_str), lGetUlong(cat, CT_rejected), lGetUlong(cat, CT_refcount))); }
/****** Eventmirror/pe_task/pe_task_update_master_list_usage() ***************** * NAME * pe_task_update_master_list_usage() -- update a parallel tasks usage * * SYNOPSIS * bool * pe_task_update_master_list_usage(lList *job_list, lListElem *event) * * FUNCTION * Updates the scaled usage of a parallel task. * * INPUTS * lListElem *job_list - the master job list * lListElem *event - event object containing the new usage list * * RESULT * bool - true, if the operation succeeds, else false * * SEE ALSO * Eventmirror/job/job_update_master_list_usage() * Eventmirror/ja_task/ja_task_update_master_list_usage() *******************************************************************************/ sge_callback_result pe_task_update_master_list_usage(lList *job_list, lListElem *event) { lList *tmp = NULL; u_long32 job_id, ja_task_id; const char *pe_task_id; lListElem *job, *ja_task, *pe_task; DENTER(TOP_LAYER, "pe_task_update_master_list_usage"); job_id = lGetUlong(event, ET_intkey); ja_task_id = lGetUlong(event, ET_intkey2); pe_task_id = lGetString(event, ET_strkey); job = job_list_locate(*(object_type_get_master_list(SGE_TYPE_JOB)), job_id); if (job == NULL) { dstring id_dstring = DSTRING_INIT; ERROR((SGE_EVENT, MSG_JOB_CANTFINDJOBFORUPDATEIN_SS, job_get_id_string(job_id, 0, NULL, &id_dstring), SGE_FUNC)); sge_dstring_free(&id_dstring); DEXIT; return SGE_EMA_FAILURE; } ja_task = job_search_task(job, NULL, ja_task_id); if (ja_task == NULL) { dstring id_dstring = DSTRING_INIT; ERROR((SGE_EVENT, MSG_JOB_CANTFINDJATASKFORUPDATEIN_SS, job_get_id_string(job_id, ja_task_id, NULL, &id_dstring), SGE_FUNC)); sge_dstring_free(&id_dstring); DEXIT; return SGE_EMA_FAILURE; } pe_task = ja_task_search_pe_task(ja_task, pe_task_id); if (pe_task == NULL) { dstring id_dstring = DSTRING_INIT; ERROR((SGE_EVENT, MSG_JOB_CANTFINDPETASKFORUPDATEIN_SS, job_get_id_string(job_id, ja_task_id, pe_task_id, &id_dstring), SGE_FUNC)); sge_dstring_free(&id_dstring); DEXIT; return SGE_EMA_FAILURE; } lXchgList(event, ET_new_version, &tmp); lXchgList(pe_task, PET_scaled_usage, &tmp); lXchgList(event, ET_new_version, &tmp); DEXIT; return SGE_EMA_OK; }
/****** SCHEDD/order_remove_immediate()***************************************** * NAME * order_remove_immediate() -- add a remove order for the job task * * SYNOPSIS * int order_remove_immediate(lListElem *job, lListElem *ja_task, order_t *orders) * * FUNCTION * Generates an order of type ORT_remove_immediate_job for the given job * task. * * INPUTS * lListElem *job - The job to remove (JB_Type) * lListElem *ja_task - The task to remove (JAT_Type) * order_t *orders - The order structure will be extended by one del order * * RESULT * int - Error code: 0 = OK, 1 = Errors * * NOTES * MT-NOTE: order_remove_immediate() is MT safe * *******************************************************************************/ int order_remove_immediate(lListElem *job, lListElem *ja_task, order_t *orders) { DENTER(TOP_LAYER, "order_remove_immediate"); DPRINTF(("JOB "sge_u32"."sge_u32" can't get dispatched - removing\n", lGetUlong(job, JB_job_number), lGetUlong(ja_task, JAT_task_number))); orders->jobStartOrderList = sge_create_orders(orders->jobStartOrderList, ORT_remove_immediate_job, job, ja_task, NULL, true); DEXIT; return (orders->jobStartOrderList == NULL); }
static sge_callback_result analyze_jatask_event(sge_evc_class_t *evc, object_description *object_base,sge_object_type type, sge_event_action action, lListElem *event, void *clientdata) { char buffer[1024]; dstring buffer_wrapper; sge_dstring_init(&buffer_wrapper, buffer, sizeof(buffer)); if (lGetPosViaElem(event, ET_type, SGE_NO_ABORT) >= 0) { u_long32 type = lGetUlong(event, ET_type); if (type == sgeE_JATASK_MOD) { lList *jat = lGetList(event,ET_new_version); lListElem *ep = lFirst(jat); u_long job_status = lGetUlong(ep, JAT_status); int task_running = (job_status==JRUNNING || job_status==JTRANSFERING); if (task_running) { } } if (type == sgeE_JOB_FINAL_USAGE) { } if (type == sgeE_JOB_ADD) { /* lList *jat = lGetList(event,ET_new_version); u_long job_id = lGetUlong(event, ET_intkey); u_long task_id = lGetUlong(event, ET_intkey2); lListElem *ep = lFirst(jat); */ } if (type == sgeE_JOB_DEL) { qevent_trigger_scripts(QEVENT_JB_END, qevent_get_option_struct(), event); } if (type == sgeE_JATASK_DEL) { qevent_trigger_scripts(QEVENT_JB_TASK_END,qevent_get_option_struct() , event); } } /* create a callback error to test error handling */ if(type == SGE_TYPE_GLOBAL_CONFIG) { return SGE_EMA_FAILURE; } return SGE_EMA_OK; }
static void schedd_mes_find_others(lListElem *tmp_sme, lList *job_list, int ignore_category) { if (tmp_sme && job_list) { lListElem *message_elem = NULL; /* MES_Type */ lRef category = NULL; /* Category pointer (void*) */ lList *jid_cat_list = NULL; /* ULNG */ lList *message_list = lGetList(tmp_sme, SME_message_list); /* * Here we have a list of message elements where each * MES_job_number_list contains only one id. * We have to find the other jobs (jids) which have the same category. */ for_each(message_elem, message_list) { lList *jid_list = lGetList(message_elem, MES_job_number_list); u_long32 jid; lRef jid_category; jid = lGetUlong(lFirst(jid_list), ULNG_value); jid_category = schedd_mes_get_category(jid, job_list); /* * Initialize jid_cat_list if not initialized * or if category differs from the last run */ if (category != jid_category || ignore_category) { jid_cat_list = schedd_mes_get_same_category_jids(jid_category, job_list, ignore_category); category = jid_category; lSetList(message_elem, MES_job_number_list, jid_cat_list); } else { lSetList(message_elem, MES_job_number_list, lCopyList("", jid_cat_list)); } }
/*-------------------------------------------------------------------------*/ static void qmonUsersetFillConf( Widget w, lListElem *ep ) { lList *ul; DENTER(GUI_LAYER, "qmonUsersetFillConf"); if (!ep) { /* ** clear the userset_user_list */ XtVaSetValues( userset_user_list, XmNitems, NULL, XmNitemCount, 0, NULL); DEXIT; return; } userset_type_state = (int)lGetUlong(ep, US_type); XmtChooserSetState(userset_type, userset_type_state, False); ul = lGetList(ep, US_entries); lPSortList(ul, "%I+", UE_name); UpdateXmListFromCull(userset_user_list, XmFONTLIST_DEFAULT_TAG, ul, UE_name); DEXIT; }
/************************************************************************ show_sharetree display a tree representation of sharetree ************************************************************************/ int show_sharetree( lListElem *ep, char *indent ) { lListElem *cep; FILE *fp = stdout; static int level = 0; int i; DENTER(TOP_LAYER, "show_sharetree"); if (!ep) { DEXIT; return -1; } for (i=0;i<level;i++) fprintf(fp, "%s", indent ? indent : ""); fprintf(fp, "%s="sge_u32"\n", lGetString(ep, STN_name), lGetUlong(ep, STN_shares)); for_each(cep, lGetList(ep, STN_children)) { level++; show_sharetree(cep, " "); level--; }
/*-------------------------------------------------------------------------*/ static void qmonCalendarOk(Widget w, XtPointer cld, XtPointer cad) { lList *cal = NULL; lList *alp; lEnumeration *what; Boolean status = False; XmString xcalname = NULL; StringConst calname = NULL; DENTER(GUI_LAYER, "qmonCalendarOk"); /* ** get the contents of the dialog fields here, ** build the cull list and send gdi request ** decalnding on success of gdi request close the dialog or stay ocaln */ cal = lCreateElemList("CALENDAR_ADD", CAL_Type, 1); if (cal) { if (qmonCalendarGetAsk(lFirst(cal))) { calname = (StringConst)lGetString(lFirst(cal), CAL_name); /* ** gdi call */ what = lWhat("%T(ALL)", CAL_Type); if (add_mode) { alp = qmonAddList(SGE_CAL_LIST, qmonMirrorListRef(SGE_CAL_LIST), CAL_name, &cal, NULL, what); } else { alp = qmonModList(SGE_CAL_LIST, qmonMirrorListRef(SGE_CAL_LIST), CAL_name, &cal, NULL, what); } if (lFirst(alp) && lGetUlong(lFirst(alp), AN_status) == STATUS_OK) status = True; qmonMessageBox(w, alp, 0); if (status) { XtUnmanageChild(cal_ask_layout); updateCalendarList(); /* ** select the modified or added Calendar */ xcalname = XmtCreateXmString(calname); XmListSelectItem(cal_names, xcalname, True); XmStringFree(xcalname); } lFreeWhat(&what); lFreeList(&cal); lFreeList(&alp); } } DEXIT; }
void job_report_init_from_job_with_usage(lListElem *job_report, lListElem *job, lListElem *ja_task, lListElem *pe_task, u_long32 time_stamp) { lListElem *ep; lListElem *obj; int nm; DENTER(TOP_LAYER, "job_report_init_from_job_with_usage"); /* * initialize the job jeport like any other job report... */ job_report_init_from_job(job_report, job, ja_task, pe_task); /* * ... and now add the online usage plus some fileds which are needed for the accounting */ lSetUlong(job_report, JR_wait_status, SGE_SET_WEXITSTATUS(SGE_WEXITED_BIT, 0)); lSetUlong(job_report, JR_failed, SSTATE_QMASTER_ENFORCED_LIMIT); if (pe_task == NULL) { nm = JAT_scaled_usage_list; obj = ja_task; } else { nm = PET_scaled_usage; obj = pe_task; lSetString(job_report, JR_pe_task_id_str, lGetString(pe_task, PET_id)); } ep = lAddSubStr(obj, UA_name, "submission_time", nm, UA_Type); lSetDouble(ep, UA_value, lGetUlong(job, JB_submission_time)); ep = lAddSubStr(obj, UA_name, "start_time", nm, UA_Type); lSetDouble(ep, UA_value, lGetUlong(ja_task, JAT_start_time)); ep = lAddSubStr(obj, UA_name, "end_time", nm, UA_Type); lSetDouble(ep, UA_value, time_stamp); ep = lAddSubStr(obj, UA_name, "ru_wallclock", nm, UA_Type); lSetDouble(ep, UA_value, 0.0); lSetList(job_report, JR_usage, lCopyList("", lGetList(obj, nm))); DEXIT; }
int job_initialize_job(lListElem *job) { u_long32 job_id; lListElem *ja_task; lListElem *pe_task; DENTER(TOP_LAYER, "job_initialize_job"); job_id = lGetUlong(job, JB_job_number); for_each (ja_task, lGetList(job, JB_ja_tasks)) { u_long32 ja_task_id; ja_task_id = lGetUlong(ja_task, JAT_task_number); add_job_report(job_id, ja_task_id, NULL, job); /* add also job reports for tasks */ for_each (pe_task, lGetList(ja_task, JAT_task_list)) { add_job_report(job_id, ja_task_id, lGetString(pe_task, PET_id), job); }
/****** sgeobj/suser/suser_get_job_counter() ********************************** * NAME * suser_get_job_counter() -- return the users job counter * * SYNOPSIS * u_long32 suser_get_job_counter(lListElem *suser) * * FUNCTION * Returns the current number of jobs registed for "suser" * * INPUTS * lListElem *suser - SU_Type element * * RESULT * u_long32 - number of jobs * * SEE ALSO * sgeobj/suser/SU_Type * sgeobj/suser/Master_SUser_List ******************************************************************************/ u_long32 suser_get_job_counter(lListElem *suser) { u_long32 ret = 0; if (suser != NULL) { ret = lGetUlong(suser, SU_jobs); } return ret; }
/*-------------------------------------------------------------------------*/ static void qmonSchedOk(Widget w, XtPointer cld, XtPointer cad) { lList *scl = NULL; lListElem *sep = NULL; lEnumeration *what = NULL; lList *alp = NULL; Boolean status = False; DENTER(GUI_LAYER, "qmonSchedOk"); /* ** get the contents of the dialog fields here, ** build the cull list and send gdi request */ qmonMirrorMultiAnswer(SC_T, &alp); if (alp) { qmonMessageBox(w, alp, 0); lFreeList(&alp); DEXIT; return; } scl = qmonMirrorList(SGE_SC_LIST); sep = lFirst(scl); if (qmonSchedGet(sep)) { if (rmon_mlgetl(&RMON_DEBUG_ON, GUI_LAYER) & INFOPRINT) { printf("___SCHEDULER_CONF________________________\n"); lWriteListTo(scl, stdout); printf("_______________________________________\n"); } /* ** gdi call */ what = lWhat("%T(ALL)", SC_Type); alp = qmonModList(SGE_SC_LIST, qmonMirrorListRef(SGE_SC_LIST), 0, &scl, NULL, what); if (lFirst(alp) && lGetUlong(lFirst(alp), AN_status) == STATUS_OK) status = True; qmonMessageBox(qmon_sconf, alp, 0); lFreeWhat(&what); lFreeList(&alp); } if (status) XtUnmanageChild(qmon_sconf); DEXIT; }
static int calculate_share_percents(lListElem *node, double parent_percent, double sibling_shares) { lListElem *child; double sum_shares=0; for_each(child, lGetList(node, STN_children)) { sum_shares += lGetUlong(child, STN_shares); }
/****** SCHEDD/remove_immediate_jobs()****************************************** * NAME * remove_immediate_jobs() -- test for and remove immediate jobs which can't * be scheduled * * SYNOPSIS * int remove_immediate_jobs(lList *pending_job_list, lList *running_job_list, order_t *orders) * * FUNCTION * Goes through all jobs in the pending list to see if any are immediate and * not idle. If any are, they are removed. This is done by generating an * order of type ORT_remove_immediate_job. If any array jobs are removed, * the running list is checked for tasks belonging to the job, which are * also removed. This is done by removing the ORT_start_job orders and * adding an order of type ORT_remove_immediate_job. * * INPUTS * lList *pending_job_list - The list of pending jobs for this scheduler * pass (JB_Type) * lList *running_job_list - The list of running jobs for this scheduler * pass (JB_Type) * order_t *orders - The order structure for this scheduler pass * * RESULT * int - Error code: 0 = OK, 1 = Errors -- always returns 0 * * NOTES * MT-NOTE: remove_immediate_jobs() is MT safe * *******************************************************************************/ int remove_immediate_jobs(lList *pending_job_list, lList *running_job_list, order_t *orders) { lListElem *next_job, *job, *ep; lList* lp; DENTER (TOP_LAYER, "remove_immediate_jobs"); next_job = lFirst (pending_job_list); while ((job = next_job)) { lCondition *where = NULL; next_job = lNext(job); /* skip non immediate .. */ if (!JOB_TYPE_IS_IMMEDIATE(lGetUlong(job, JB_type))) { continue; } /* .. and non idle jobs */ if ((lp = lGetList(job, JB_ja_tasks)) && (ep = lFirst(lp)) && lGetUlong(ep, JAT_status)==JIDLE) { continue; } /* Prepare search condition for running list */ where = lWhere("%T(%I==%u)", JB_Type, JB_job_number, lGetUlong(job, JB_job_number)); /* Remove the job from the pending list */ remove_immediate_job(pending_job_list, job, orders, 0); /* If the job also exists in the running list, we need to remove it there * as well since array jobs are all or nothing. */ if ((job = lFindFirst(running_job_list, where)) != NULL) { remove_immediate_job(running_job_list, job, orders, 1); } lFreeWhere(&where); } DEXIT; return 0; }
/****** sge_advance_reservation/sge_ar_has_errors() **************************** * NAME * sge_ar_has_errors() -- Has AR errors? * * SYNOPSIS * bool sge_ar_has_errors(lListElem *ar) * * FUNCTION * Check if one of the reserved queues is in state where jobs can not be * running * * INPUTS * lListElem *ar - advance reservation object (AR_Type) * * RESULT * bool - true if has errors * false if has no errors * * NOTES * MT-NOTE: sge_ar_has_errors() is MT safe *******************************************************************************/ bool sge_ar_has_errors(lListElem *ar) { bool ret = false; DENTER(TOP_LAYER, "sge_ar_has_errors"); if (lGetUlong(ar, AR_qi_errors) != 0) { ret = true; } DRETURN(ret); }
/* select and suspend jobs in susp_queues */ void suspend_job_in_queues( lList *susp_queues, lList *job_list, order_t *orders) { u_long32 now; int i, found; lListElem *jep = NULL, *ja_task = NULL; lListElem *qep; DENTER(TOP_LAYER, "suspend_job_in_queues"); now = sge_get_gmt(); for_each (qep, susp_queues) { u_long32 interval; /* are suspend thresholds enabled? */ parse_ulong_val(NULL, &interval, TYPE_TIM, lGetString(qep, QU_suspend_interval), NULL, 0); if (interval == 0 || !lGetUlong(qep, QU_nsuspend) || !lGetList(qep, QU_suspend_thresholds)) { continue; } /* check time stamp */ if (lGetUlong(qep, QU_last_suspend_threshold_ckeck) && (lGetUlong(qep, QU_last_suspend_threshold_ckeck) + interval> now)) { continue; } for (i = 0, found = 1; i < (int) lGetUlong(qep, QU_nsuspend) && found; i++) { found = 0; /* find one running job in suspend queue */ if (select4suspension(job_list, qep, &jep, &ja_task)) break; /* generate suspend order for found job */ found = 1; orders->configOrderList = sge_create_orders(orders->configOrderList, ORT_suspend_on_threshold, jep, ja_task, NULL, true); DPRINTF(("++++ suspending job "sge_u32"/"sge_u32" on threshold\n", lGetUlong(jep, JB_job_number), lGetUlong(ja_task, JAT_task_number))); /* prevent multiple selection of this job */ lSetUlong(ja_task, JAT_state, lGetUlong(ja_task, JAT_state) | JSUSPENDED_ON_THRESHOLD); } if (i==0 && !found) { DPRINTF(("found no jobs for sot in queue %s\n", lGetString(qep, QU_full_name))); } }
/****** sge_orders/sge_create_orders() ***************************************** * NAME * sge_create_orders() -- Create a new order-list or add orders to an existing one * * SYNOPSIS * lList* sge_create_orders(lList *or_list, u_long32 type, lListElem *job, * lListElem *ja_task, lList *granted, bool update_execd) * * FUNCTION * - If the or_list is NULL, a new one will be generated * * - in case of a clear_pri order, teh ja_task is improtant. If NULL is put * in for ja_task, only the pendin tasks of the spedified job are set to NULL. * If a ja_task is put in, all tasks of the job are set to NULL * * INPUTS * lList *or_list - the order list * u_long32 type - order type * lListElem *job - job * lListElem *ja_task - ja_task ref or NULL(there is only one case, where it can be NULL) * lList *granted - granted queue list * bool update_execd - should the execd get new ticket values? * * RESULT * lList* - returns the orderlist * * NOTES * MT-NOTE: sge_create_orders() is MT safe * * SEE ALSO * ???/??? *******************************************************************************/ lList *sge_create_orders(lList *or_list, u_long32 type, lListElem *job, lListElem *ja_task, lList *granted , bool update_execd) { lList *ql = NULL; lListElem *gel, *ep, *ep2; u_long32 qslots; DENTER(TOP_LAYER, "sge_create_orders"); if (!job) { lFreeList(&or_list); DEXIT; return or_list; } /* create orders list if not existent */ if (!or_list) { or_list = lCreateList("orderlist", OR_Type); } /* build sublist of granted */ if (update_execd) { for_each(gel, granted) { qslots = lGetUlong(gel, JG_slots); if (qslots) { /* ignore Qs with slots==0 */ ep2=lCreateElem(OQ_Type); lSetUlong(ep2, OQ_slots, qslots); lSetString(ep2, OQ_dest_queue, lGetString(gel, JG_qname)); lSetUlong(ep2, OQ_dest_version, lGetUlong(gel, JG_qversion)); lSetDouble(ep2, OQ_ticket, lGetDouble(gel, JG_ticket)); lSetDouble(ep2, OQ_oticket, lGetDouble(gel, JG_oticket)); lSetDouble(ep2, OQ_fticket, lGetDouble(gel, JG_fticket)); lSetDouble(ep2, OQ_sticket, lGetDouble(gel, JG_sticket)); if (!ql) ql=lCreateList("orderlist",OQ_Type); lAppendElem(ql, ep2); } } }
/****** sgeobj/ja_task/ja_task_list_print_to_string() ************************** * NAME * ja_task_list_print_to_string() -- print task id ranges into string * * SYNOPSIS * void ja_task_list_print_to_string(const lList *ja_task_list, * dstring *range_string) * * FUNCTION * The ids of all tasks contained in 'ja_task_list' will be printed * into 'range_string'. * * INPUTS * const lList *ja_task_list - JAT_Type list * dstring *range_string - dynamic string ******************************************************************************/ void ja_task_list_print_to_string(const lList *ja_task_list, dstring *range_string) { lListElem *ja_task = NULL; /* JAT_Type */ lList *range_list = NULL; /* RN_Type */ DENTER(TOP_LAYER, "ja_task_list_print_to_string"); for_each(ja_task, ja_task_list) { u_long32 tid = lGetUlong(ja_task, JAT_task_number); range_list_insert_id(&range_list, NULL, tid); }
/****** SCHEDD/remove_immediate_job()******************************************* * NAME * remove_immediate_job() -- test for and remove immediate job which can't * be scheduled * * SYNOPSIS * int remove_immediate_job(lList *job_list, lListElem *job, order_t *orders, int remove_orders) * * FUNCTION * Removes immediate jobs which cannot be scheduled from the given job list. * This is done by generating an order of type ORT_remove_immediate_job. If * remove_orders is set, the ORT_start_job orders are first removed from the * order list before adding the remove order. * * INPUTS * lList *job_list - The list of jobs from which the job should be * removed (JB_Type) * lListElem *job - The job to remove (JB_Type) * order_t *orders - The order structure for this scheduler pass * int remove_orders - Whether the ORT_start_job orders should also be * be removed * * NOTES * MT-NOTE: remove_immediate_job() is MT safe * *******************************************************************************/ void remove_immediate_job(lList *job_list, lListElem *job, order_t *orders, int remove_orders) { lListElem *ja_task; lListElem *range = NULL; lList *range_list = NULL; u_long32 ja_task_id; DENTER (TOP_LAYER, "remove_immediate_job"); for_each (ja_task, lGetList(job, JB_ja_tasks)) { if (remove_orders) { order_remove_order_and_immediate(job, ja_task, orders); } else { order_remove_immediate(job, ja_task, orders); } } range_list = lGetList(job, JB_ja_n_h_ids); for_each(range, range_list) { for(ja_task_id = lGetUlong(range, RN_min); ja_task_id <= lGetUlong(range, RN_max); ja_task_id += lGetUlong(range, RN_step)) { ja_task = job_get_ja_task_template_pending(job, ja_task_id); /* No need to remove the orders here because tasks in JB_ja_n_h_ids * haven't been scheduled, and hence don't have start orders to * remove. */ order_remove_immediate(job, ja_task, orders); } } lRemoveElem(job_list, &job); DEXIT; }
/****** sgeobj/report/job_report_init_from_job() ***************************** * NAME * job_report_init_from_job() -- initialize job report * * SYNOPSIS * void job_report_init_from_job(lListElem *job_report, * const lListElem *job, * const lListElem *ja_task, * const lListElem *pe_task) * * FUNCTION * Initialize "job_report" from the attributes obtained from * "job", "ja_task" and "pe_task". * * INPUTS * lListElem *job_report - JR_Type object * const lListElem *job - JB_Type object * const lListElem *ja_task - JAT_Type object * const lListElem *pe_task - PET_Type object ******************************************************************************/ void job_report_init_from_job(lListElem *job_report, const lListElem *job, const lListElem *ja_task, const lListElem *pe_task) { u_long32 job_id = lGetUlong(job, JB_job_number); u_long32 ja_task_id = lGetUlong(ja_task, JAT_task_number); lListElem *queue = NULL; /* QU_Type */ DENTER(TOP_LAYER, "job_report_init_from_job"); lSetUlong(job_report, JR_job_number, job_id); lSetUlong(job_report, JR_ja_task_number, ja_task_id); if (pe_task != NULL) { lSetString(job_report, JR_pe_task_id_str, lGetString(pe_task, PET_id)); queue = lFirst(lGetList(pe_task, PET_granted_destin_identifier_list)); } else { queue = lFirst(lGetList(ja_task, JAT_granted_destin_identifier_list)); } if (lGetUlong(ja_task, JAT_status) == JSLAVE){ if (pe_task == NULL) { lSetUlong(job_report, JR_state, JSLAVE); } else { lSetUlong(job_report, JR_state, JWRITTEN); } } else { lSetUlong(job_report, JR_state, JWRITTEN); } if (queue != NULL) { lSetString(job_report, JR_queue_name, lGetString(queue, JG_qname)); } DEXIT; }
/* * * NOTES * MT-NOTE: sge_qwaittid() is not MT safe * */ int sge_qwaittid(sge_gdi_ctx_class_t *ctx, sge_tid_t tid, int *status, int options) { lListElem *rt = NULL; int ret, rcv_opt = 0; DENTER(TOP_LAYER, "sge_qwaittid"); if (!(options&WNOHANG)) rcv_opt |= OPT_SYNCHRON; if (tid != NULL && !(rt=LOCATE_RTASK(tid))) { sprintf(lasterror, MSG_GDI_TASKNOTEXIST_S , tid); DEXIT; return -1; } while ((rt && /* definite one searched */ lGetUlong(rt, RT_state)!=RT_STATE_EXITED && /* not exited */ lGetUlong(rt, RT_state)==RT_STATE_WAIT4ACK) /* waiting for ack */ || (!rt && /* anybody searched */ !lGetElemUlong(remote_task_list, RT_state, RT_STATE_EXITED) && /* none exited */ lGetElemUlong(remote_task_list, RT_state, RT_STATE_WAIT4ACK))) { /* but one is waiting for ack */ /* wait for incoming messeges about exited tasks */ if ((ret=rcv_from_execd(ctx, rcv_opt, TAG_TASK_EXIT))) { DEXIT; return (ret<0)?-1:0; } } if (status) *status = lGetUlong(rt, RT_status); lSetUlong(rt, RT_state, RT_STATE_WAITED); DEXIT; return 0; }
/****** category/sge_build_job_cs_category() *********************************** * NAME * sge_build_job_cs_category() -- generates the category string for the sc * * SYNOPSIS * const char* sge_build_job_cs_category(dstring *category_str, lListElem * *job, lListElem *cat_obj) * * FUNCTION * ??? * * INPUTS * dstring *category_str - storage forthe c string * lListElem *job - job for which to create a category * lListElem *cat_obj - regular category for the job. * * RESULT * const char* - * * EXAMPLE * ??? * * NOTES * MT-NOTE: sge_build_job_cs_category() is MT safe * *******************************************************************************/ const char* sge_build_job_cs_category(dstring *category_str, lListElem *job, lListElem *cat_obj, bool did_project) { const char *p; DENTER(TOP_LAYER, "sge_build_job_cs_category"); /* * deadline */ sge_dstring_sprintf_append(category_str, "-dl "sge_u32, lGetUlong(job, JB_deadline)); /* * priority */ sge_dstring_sprintf_append(category_str, "-p "sge_u32, lGetUlong(job, JB_priority)); sge_dstring_sprintf_append(category_str, "-ot "sge_u32, lGetUlong(job, JB_override_tickets)); sge_dstring_sprintf_append(category_str, "-js "sge_u32, lGetUlong(job, JB_jobshare)); sge_dstring_sprintf_append(category_str, "-u %s", lGetString(job, JB_owner)); /* * ticket assignment can depend on a jobs project. * If the project was not added to the resource categories * it gets added directly to the cs category string */ if ((p=lGetString(job, JB_project)) && !did_project) sge_dstring_sprintf_append(category_str, " -P %s", p); /* * id for the resource category * I use teh address of the resource category as a hash value for its string. */ sge_dstring_sprintf_append(category_str, " %x", cat_obj); DEXIT; return sge_dstring_get_string(category_str); }
/*-------------------------------------------------------------------------*/ static Boolean getCE_TypeValues( lListElem *ep, StringConst *ce_entry ) { DENTER(GUI_LAYER, "getCE_TypeValues"); if (!ep || !ce_entry ) { DEXIT; return False; } /* name type relation value */ ce_entry[CE_NAME] = (StringConst)lGetString(ep, CE_name); ce_entry[CE_SHORTCUT] = (StringConst)lGetString(ep, CE_shortcut); ce_entry[CE_TYPE] = (StringConst)map_type2str(lGetUlong(ep, CE_valtype)); ce_entry[CE_RELOP] = map_op2str(lGetUlong(ep, CE_relop)); ce_entry[CE_REQUEST] = map_req2str(lGetUlong(ep, CE_requestable)); ce_entry[CE_CONSUMABLE] = map_consumable2str(lGetUlong(ep, CE_consumable)); ce_entry[CE_DEFAULT] = (StringConst)lGetString(ep, CE_default); ce_entry[CE_URGENCY] = (StringConst)lGetString(ep, CE_urgency_weight); DEXIT; return True; }
/****** sgeobj/suser/suser_decrease_job_counter() ***************************** * NAME * suser_decrease_job_counter() -- decrease the users job counter * * SYNOPSIS * void suser_decrease_job_counter(lListElem *suser) * * FUNCTION * The job counter within "suser" will be decreased by one * * INPUTS * lListElem *suser - SU_Type list * * RESULT * void - NONE * * SEE ALSO * sgeobj/suser/SU_Type * sgeobj/suser/Master_SUser_List ******************************************************************************/ void suser_decrease_job_counter(lListElem *suser) { DENTER(TOP_LAYER, "suser_decrease_job_counter"); if (suser != NULL) { u_long32 jobs = lGetUlong(suser, SU_jobs); if (jobs == 0) { ERROR((SGE_EVENT, MSG_SUSERCNTISALREADYZERO_S, lGetString(suser, SU_name))); } else { lAddUlong(suser, SU_jobs, -1); } } DEXIT; }
/****** sge_cqueue_verify/cqueue_verify_job_slots() **************************** * NAME * cqueue_verify_job_slots() -- verify the queue slots attribute * * SYNOPSIS * bool * cqueue_verify_job_slots(lListElem *cqueue, lList **answer_list, * lListElem *attr_elem) * * FUNCTION * Verifies if the slots attribute of a queue is in the expected range * (0 .. MAX_SEQNUM). MAX_SEQNUM is 9999999. * * INPUTS * lListElem *cqueue - The queue to verify. * lList **answer_list - answer list to report errors * lListElem *attr_elem - the attribute to verify * * RESULT * bool - true on success, false on error * * NOTES * MT-NOTE: cqueue_verify_job_slots() is MT safe *******************************************************************************/ bool cqueue_verify_job_slots(lListElem *cqueue, lList **answer_list, lListElem *attr_elem) { bool ret = true; DENTER(CQUEUE_VERIFY_LAYER, "cqueue_verify_job_slots"); if (cqueue != NULL && attr_elem != NULL) { u_long32 slots = lGetUlong(attr_elem, AULNG_value); if (slots > MAX_SEQNUM) { answer_list_add_sprintf(answer_list, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR, MSG_ATTR_INVALID_ULONGVALUE_USUU, sge_u32c(slots), "slots", sge_u32c(0), sge_u32c(MAX_SEQNUM)); ret = false; } } DEXIT; return ret; }
static void qevent_start_trigger_script(int qevent_event, const char* script_file, lListElem *event ) { u_long jobid, taskid; const char* event_name; int pid; char buffer[MAX_STRING_SIZE]; char buffer2[MAX_STRING_SIZE]; DENTER(TOP_LAYER, "qevent_start_trigger_script"); jobid = lGetUlong(event, ET_intkey); taskid = lGetUlong(event, ET_intkey2); event_name = qevent_get_event_name(qevent_event); /* test if script is executable and valid file */ if (!sge_is_file(script_file)) { ERROR((SGE_EVENT, "no script file: "SFQ"\n", script_file)); DEXIT; return; } /* is file executable ? */ if (!sge_is_executable(script_file)) { ERROR((SGE_EVENT, "file not executable: "SFQ"\n", script_file)); DEXIT; return; } pid = fork(); if (pid < 0) { ERROR((SGE_EVENT, "fork() error\n")); DEXIT; return; } if (pid > 0) { int exit_status; #if !(defined(CRAY) || defined(INTERIX)) struct rusage rusage; #endif #if defined(SVR3) || defined(_BSD) union wait status; #else int status; #endif #if defined(CRAY) || defined(INTERIX) waitpid(pid, &status, 0); #else wait3(&status, 0, &rusage); #endif #if defined(SVR3) || defined(_BSD) exit_status = status.w_retcode; #else exit_status = status; #endif if ( WEXITSTATUS(exit_status) == 0 ) { INFO((SGE_EVENT,"exit status of script: "sge_U32CFormat"\n", sge_u32c(WEXITSTATUS(exit_status)))); } else { ERROR((SGE_EVENT,"exit status of script: "sge_U32CFormat"\n", sge_u32c(WEXITSTATUS(exit_status)))); } DEXIT; return; } else { const char *basename = sge_basename( script_file, '/' ); /* SETPGRP; */ /* sge_close_all_fds(NULL); */ sprintf(buffer ,sge_U32CFormat,sge_u32c(jobid)); sprintf(buffer2 ,sge_U32CFormat,sge_u32c(taskid)); execlp(script_file, basename, event_name, buffer, buffer2, (char *)0); } exit(1); }