/*___INFO__MARK_BEGIN__*/ /************************************************************************* * * The Contents of this file are made available subject to the terms of * the Sun Industry Standards Source License Version 1.2 * * Sun Microsystems Inc., March, 2001 * * * Sun Industry Standards Source License Version 1.2 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.2 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2001 by Sun Microsystems, Inc. * * All Rights Reserved. * ************************************************************************/ /*___INFO__MARK_END__*/ #include #include #include "rmon/sgermon.h" #include "cull/cull.h" #include "uti/sge_log.h" #include "uti/sge_stdio.h" #include "uti/sge_stdlib.h" #include "uti/sge_string.h" #include "uti/sge_parse_num_par.h" #include "lck/sge_lock.h" #include "lck/sge_mtutil.h" #include "sched/msg_schedd.h" #include "sge.h" #include "sge_object.h" #include "sge_answer.h" #include "sge_centry.h" #include "sge_feature.h" #include "sge_usage.h" #include "sge_range.h" #include "sge_schedd_conf.h" #include "cull_parse_util.h" #include "msg_sgeobjlib.h" #include "msg_common.h" /****************************************************** * * All configuration values are stored in one cull * master list: Master_Sched_Config_List. This list * has only one element: the config element (SC_Type). * * The configuratin is stored in a CULL list due to the * current configuration handling in the system. There * are methods outside this module, which need complete * access to the list. Therefore exist two methods to * access the whole configuration: * * - sconf_get_config_list * (returns a pointer to the cull list * * - sconf_get_config * returns a const pointer the config object. * * Both methods should only be used, when there is no * other way. Usualy the values in the configuration * should be accessed via access-function. The module * stores the position for each config element for * fast access, validates the configuration, when it * is changed, and pre-computes some values to return * them in the right way. * * If the configuration is changed directly in the CULL * list without using * "sconf_set_config" * , the * "sconf_validate_config" * needs to be called to ensure that the internal data * is updated. * * The access is not thread save. The current implementation * of the configuration does not allow an easy way to * make it thread save. But if only access functions * are used it should be easy to make this module thread * save, when the configuration is made thread save. * ******************************************************/ /* default values for scheduler configuration * not all defaults are defined here :-) */ #define DEFAULT_LOAD_ADJUSTMENTS_DECAY_TIME "0:7:30" #define _DEFAULT_LOAD_ADJUSTMENTS_DECAY_TIME 7*60+30 #define DEFAULT_LOAD_FORMULA "np_load_avg" #define SCHEDULE_TIME "0:0:15" #define _SCHEDULE_TIME 15 #define REPRIORITIZE_INTERVAL "0:0:0" #define REPRIORITIZE_INTERVAL_I 0 #define MAXUJOBS 0 #define MAXGJOBS 0 #define SCHEDD_JOB_INFO "true" #define DEFAULT_DURATION "INFINITY" /* the default_duration and default_duration_I have to be */ #define DEFAULT_DURATION_I 600 /* in sync. On is the strin version of the other (based on seconds)*/ #define DEFAULT_DURATION_OFFSET 60 /** * multithreading support, thread local **/ static pthread_key_t sc_state_key; static pthread_once_t sc_once = PTHREAD_ONCE_INIT; /* a scheduling configuration structure which is stored thread local */ typedef struct { qs_state_t queue_state; bool global_load_correction; int schedd_job_info; bool host_order_changed; int last_dispatch_type; int search_alg[SCHEDD_PE_ALG_MAX]; /* stores the weighting for the different algorithms*/ int scheduled_pe_jobs; /* counts the dispatched pe jobs */ int scheduled_fast_jobs; /* counts the dispatched sequential jobs */ double decay_constant; /* used in the share tree */ /* temporary data used for scheduling messages */ lListElem *sme; /* Job scheduling informations store if not disabled */ lListElem *tmp_sme; /* Job scheduling informations store if not disabled */ bool mes_schedd_info; /* write scheduling information into logfile */ int log_schedd_info; /* write scheduling information into logfile */ } sc_state_t; /****** sge_schedd_conf/sc_state_init() **************************************** * NAME * sc_state_init() -- resets the thread local structure * * SYNOPSIS * static void sc_state_init(sc_state_t* state) * * FUNCTION * resets the thread local structure, which collects information during * a scheduling run. * * INPUTS * sc_state_t* state - the thread local structure * * NOTES * MT-NOTE: sc_state_init() is MT safe * * SEE ALSO * sc_state_destroy *******************************************************************************/ static void sc_state_init(sc_state_t* state) { state->queue_state = QS_STATE_FULL; state->global_load_correction = true; state->schedd_job_info = SCHEDD_JOB_INFO_FALSE; state->host_order_changed = true; state->last_dispatch_type = 0; state->search_alg[SCHEDD_PE_LOW_FIRST] = 0; state->search_alg[SCHEDD_PE_HIGH_FIRST] = 0; state->search_alg[SCHEDD_PE_BINARY] = 0; state->scheduled_fast_jobs = 0; state->scheduled_pe_jobs = 0; state->decay_constant = 0.0; /* temp data for scheduler messages */ state->sme = NULL; state->tmp_sme = NULL; state->mes_schedd_info = false; state->log_schedd_info = 0; } static void sc_state_destroy(void* state) { free(state); } static void sc_thread_local_once_init(void) { pthread_key_create(&sc_state_key, &sc_state_destroy); } void sc_mt_init(void) { pthread_once(&sc_once, sc_thread_local_once_init); } /*-----*/ /* end */ /*-----*/ /* * addes a parameter to the config_pos.params list and evaluates the settings * * Parameters: * - lList *param_list : target list * - lList ** answer_list : error messages * - const char* param : the character version of the paramter * * Return: * - bool : true, when everything was fine, otherwise false * * See: * - sconf_eval_set_profiling */ typedef bool (*setParam)(lList *param_list, lList **answer_list, const char* param); /** * specifies an array of valid parameters and its validation functions */ typedef struct { const char* name; setParam setParam; }parameters_t; /** * stores the positions of all structure elemens and some * precalculated settings. */ typedef struct{ pthread_mutex_t mutex; bool empty; /* marks this structure as empty or set */ int algorithm; /* pos settings */ int schedule_interval; int maxujobs; int queue_sort_method; int job_load_adjustments; int load_adjustment_decay_time; int load_formula; int schedd_job_info; int flush_submit_sec; int flush_finish_sec; int params; int reprioritize_interval; int halftime; int usage_weight_list; int compensation_factor; int weight_user; int weight_project; int weight_department; int weight_job; int weight_tickets_functional; int weight_tickets_share; int weight_tickets_override; int share_override_tickets; int share_functional_shares; int max_functional_jobs_to_schedule; int report_pjob_tickets; int max_pending_tasks_per_job; int halflife_decay_list; int policy_hierarchy; int weight_ticket; int weight_waiting_time; int weight_deadline; int weight_urgency; int max_reservation; int weight_priority; int default_duration; int c_is_schedd_job_info; /* cached configuration */ u_long32 s_duration_offset; lList *c_schedd_job_info_range; lList *c_halflife_decay_list; lList *c_params; u_long32 c_default_duration; bool new_config; /* identifies an update in the configuration */ }config_pos_type; static bool schedd_profiling = false; static bool is_category_job_filtering = false; static bool current_serf_do_monitoring = false; static schedd_pe_algorithm pe_algorithm = SCHEDD_PE_AUTO; static bool calc_pos(void); static void sconf_clear_pos(void); static bool is_config_set(void); static const char * get_algorithm(void); static const char *get_schedule_interval_str(void); static const char *get_load_adjustment_decay_time_str(void); static const char *reprioritize_interval_str(void); static const char *get_halflife_decay_list_str(void); static const char *get_default_duration_str(void); static const lList *get_usage_weight_list(void); static const lList *get_job_load_adjustments(void); static const char* get_load_formula(void); static bool sconf_eval_set_profiling(lList *param_list, lList **answer_list, const char* param); static bool sconf_eval_set_monitoring(lList *param_list, lList **answer_list, const char* param); static bool sconf_eval_set_job_category_filtering(lList *param_list, lList **answer_list, const char* param); static bool sconf_eval_set_duration_offset(lList *param_list, lList **answer_list, const char* param); static bool sconf_eval_set_pe_range_alg(lList *param_list, lList **answer_list, const char* param); static char policy_hierarchy_enum2char(policy_type_t value); static policy_type_t policy_hierarchy_char2enum(char character); static int policy_hierarchy_verify_value(const char* value); /* array structure. pre-init. Make sure that a default value is added * when the config_pos_type is edited */ static config_pos_type pos = {PTHREAD_MUTEX_INITIALIZER, true, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, SCHEDD_JOB_INFO_UNDEF, 0, NULL, NULL, NULL, U_LONG32_MAX, false}; /* * a list of all valid "params" parameters * * The implementation has a problem. If an entry is removed, its setting is not * changed, but it should be turned off. This means we have to turn everything off, * before we work on the params */ const parameters_t params[] = { {"PROFILE", sconf_eval_set_profiling}, {"MONITOR", sconf_eval_set_monitoring}, {"JC_FILTER", sconf_eval_set_job_category_filtering}, {"DURATION_OFFSET", sconf_eval_set_duration_offset}, {"PE_RANGE_ALG", sconf_eval_set_pe_range_alg}, {"NONE", NULL}, {NULL, NULL} }; const char *const policy_hierarchy_chars = "OFS"; /* SG: TODO: should be const */ int load_adjustment_fields[] = { CE_name, CE_stringval, 0 }; /* SG: TODO: should be const */ int usage_fields[] = { UA_name, UA_value, 0 }; const char *delis[] = {"=", ",", ""}; /****** sge_schedd_conf/clear_pos() ******************************************** * NAME * clear_pos() -- resets the position information * * SYNOPSIS * static void clear_pos(void) * * FUNCTION * is needed, when a new configuration is set * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(write) * *******************************************************************************/ static void sconf_clear_pos(void){ /* set config empty */ pos.empty = true; /* reset positions */ pos.algorithm = -1; pos.schedule_interval = -1; pos.maxujobs = -1; pos.queue_sort_method = -1; pos.job_load_adjustments = -1; pos.load_formula = -1; pos.schedd_job_info = -1; pos.flush_submit_sec = -1; pos.flush_finish_sec = -1; pos.params = -1; pos.reprioritize_interval= -1; pos.halftime = -1; pos.usage_weight_list = -1; pos.compensation_factor = -1; pos.weight_user = -1; pos.weight_project = -1; pos.weight_department = -1; pos.weight_job = -1; pos.weight_tickets_functional = -1; pos.weight_tickets_share = -1; pos.weight_tickets_override = -1; pos.share_override_tickets = -1; pos.share_functional_shares = -1; pos.max_functional_jobs_to_schedule = -1; pos.report_pjob_tickets = -1; pos.max_pending_tasks_per_job = -1; pos.halflife_decay_list = -1; pos.policy_hierarchy = -1; pos.weight_ticket = -1; pos.weight_waiting_time = -1; pos.weight_deadline = -1; pos.weight_urgency = -1; pos.max_reservation = -1; pos.weight_priority = -1; pos.default_duration = -1; /* reseting cached values */ pos.c_is_schedd_job_info = SCHEDD_JOB_INFO_UNDEF; lFreeList(&(pos.c_schedd_job_info_range)); lFreeList(&(pos.c_halflife_decay_list)); lFreeList(&(pos.c_params)); pos.c_default_duration = DEFAULT_DURATION_I; } /****** sge_schedd_conf/calc_pos() ******************************************** * NAME * calc_pos() -- * * SYNOPSIS * static void calc_pos(void) * * FUNCTION * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(write) * *******************************************************************************/ static bool calc_pos(void) { bool ret = true; DENTER(TOP_LAYER, "calc_pos"); if (pos.empty) { const lListElem *config = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (config) { pos.empty = false; ret &= (pos.algorithm = lGetPosViaElem(config, SC_algorithm, SGE_NO_ABORT )) != -1; ret &= (pos.schedule_interval = lGetPosViaElem(config, SC_schedule_interval, SGE_NO_ABORT)) != -1; ret &= (pos.maxujobs = lGetPosViaElem(config, SC_maxujobs, SGE_NO_ABORT)) != -1; ret &= (pos.queue_sort_method = lGetPosViaElem(config, SC_queue_sort_method, SGE_NO_ABORT)) != -1; ret &= (pos.job_load_adjustments = lGetPosViaElem(config,SC_job_load_adjustments, SGE_NO_ABORT )) != -1; ret &= (pos.load_adjustment_decay_time = lGetPosViaElem(config, SC_load_adjustment_decay_time, SGE_NO_ABORT)) != -1; ret &= (pos.load_formula = lGetPosViaElem(config, SC_load_formula, SGE_NO_ABORT)) != -1; ret &= (pos.schedd_job_info = lGetPosViaElem(config, SC_schedd_job_info, SGE_NO_ABORT)) != -1; ret &= (pos.flush_submit_sec = lGetPosViaElem(config, SC_flush_submit_sec, SGE_NO_ABORT)) != -1; ret &= (pos.flush_finish_sec = lGetPosViaElem(config, SC_flush_finish_sec, SGE_NO_ABORT)) != -1; ret &= (pos.params = lGetPosViaElem(config, SC_params, SGE_NO_ABORT)) != -1; ret &= (pos.reprioritize_interval = lGetPosViaElem(config, SC_reprioritize_interval, SGE_NO_ABORT)) != -1; ret &= (pos.halftime = lGetPosViaElem(config, SC_halftime, SGE_NO_ABORT)) != -1; ret &= (pos.usage_weight_list = lGetPosViaElem(config, SC_usage_weight_list, SGE_NO_ABORT)) != -1; ret &= (pos.compensation_factor = lGetPosViaElem(config, SC_compensation_factor, SGE_NO_ABORT)) != -1; ret &= (pos.weight_user = lGetPosViaElem(config, SC_weight_user, SGE_NO_ABORT)) != -1; ret &= (pos.weight_project = lGetPosViaElem(config, SC_weight_project, SGE_NO_ABORT)) != -1; ret &= (pos.weight_department = lGetPosViaElem(config, SC_weight_department, SGE_NO_ABORT)) != -1; ret &= (pos.weight_job = lGetPosViaElem(config, SC_weight_job, SGE_NO_ABORT)) != -1; ret &= (pos.weight_tickets_functional = lGetPosViaElem(config, SC_weight_tickets_functional, SGE_NO_ABORT)) != -1; ret &= (pos.weight_tickets_share = lGetPosViaElem(config, SC_weight_tickets_share, SGE_NO_ABORT)) != -1; ret &= (pos.weight_tickets_override = lGetPosViaElem(config, SC_weight_tickets_override, SGE_NO_ABORT)) != -1; ret &= (pos.share_override_tickets = lGetPosViaElem(config, SC_share_override_tickets, SGE_NO_ABORT)) != -1; ret &= (pos.share_functional_shares = lGetPosViaElem(config, SC_share_functional_shares, SGE_NO_ABORT)) != -1; ret &= (pos.max_functional_jobs_to_schedule = lGetPosViaElem(config, SC_max_functional_jobs_to_schedule, SGE_NO_ABORT)) != -1; ret &= (pos.report_pjob_tickets = lGetPosViaElem(config, SC_report_pjob_tickets, SGE_NO_ABORT)) != -1; ret &= (pos.max_pending_tasks_per_job = lGetPosViaElem(config, SC_max_pending_tasks_per_job, SGE_NO_ABORT)) != -1; ret &= (pos.halflife_decay_list = lGetPosViaElem(config, SC_halflife_decay_list, SGE_NO_ABORT)) != -1; ret &= (pos.policy_hierarchy = lGetPosViaElem(config, SC_policy_hierarchy, SGE_NO_ABORT)) != -1; ret &= (pos.weight_ticket = lGetPosViaElem(config, SC_weight_ticket, SGE_NO_ABORT)) != -1; ret &= (pos.weight_waiting_time = lGetPosViaElem(config, SC_weight_waiting_time, SGE_NO_ABORT)) != -1; ret &= (pos.weight_deadline = lGetPosViaElem(config, SC_weight_deadline, SGE_NO_ABORT)) != -1; ret &= (pos.weight_urgency = lGetPosViaElem(config, SC_weight_urgency, SGE_NO_ABORT)) != -1; ret &= (pos.weight_priority = lGetPosViaElem(config, SC_weight_priority, SGE_NO_ABORT)) != -1; ret &= (pos.max_reservation = lGetPosViaElem(config, SC_max_reservation, SGE_NO_ABORT)) != -1; ret &= (pos.default_duration = lGetPosViaElem(config, SC_default_duration, SGE_NO_ABORT)) != -1; } else { ret = false; } } DRETURN(ret); } /****** sge_schedd_conf/schedd_conf_set_config() ******************************* * NAME * schedd_conf_set_config() -- overwrites the existing configuration * * SYNOPSIS * bool schedd_conf_set_config(lList **config, lList **answer_list) * * FUNCTION * - validates the new configuration * - precalculates some values and caches them * - stores the position of each attribute in the structure * - and sets the new configuration, if the validation worked * * If the new configuration is a NULL pointer, the current configuration * if deleted. * * INPUTS * lList **config - new configuration (SC_Type) * lList **answer_list - error messages * * RESULT * bool - true, if it worked * * MT-NOTE: is MT-safe, uses LOCK_SCHED_CONF(write) * * * SG TODO: use a internal eval config function and not the external one. * *******************************************************************************/ bool sconf_set_config(lList **config, lList **answer_list) { lList *store = NULL; bool ret = true; lList **master_sconf_list = NULL; DENTER(TOP_LAYER,"sconf_set_config"); sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); master_sconf_list = object_type_get_master_list(SGE_TYPE_SCHEDD_CONF); #if 0 store = Master_Sched_Config_List; #else store = *master_sconf_list; #endif if (config) { #if 0 Master_Sched_Config_List = *config; #endif *master_sconf_list = *config; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); ret = sconf_validate_config_(answer_list); sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (ret) { lFreeList(&store); *config = NULL; } else { *master_sconf_list = store; if (!*master_sconf_list) { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_USE_DEFAULT_CONFIG)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_WARNING); *master_sconf_list = lCreateList("schedd config list", SC_Type); lAppendElem(*master_sconf_list, sconf_create_default()); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); sconf_validate_config_(NULL); sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); } } else { sconf_clear_pos(); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); DRETURN(ret); } /****** sge_schedd_conf/sconf_is_valid_load_formula() ******************* * NAME * sconf_is_valid_load_formula() -- ??? * * SYNOPSIS * bool sconf_is_valid_load_formula_(lList **answer_list, lList * *centry_list) * * INPUTS * lList **answer_list - ??? * lList *centry_list - ??? * * RESULT * bool - * * MT-NOTE: is MT safe, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ bool sconf_is_valid_load_formula(lList **answer_list, lList *centry_list) { bool is_valid = false; lListElem *schedd_conf = NULL; const char *load_formula = NULL; DENTER(TOP_LAYER, "sconf_is_valid_load_formula"); sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); schedd_conf = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); /* Modify input */ load_formula = lGetString(schedd_conf, SC_load_formula); sge_strip_blanks((char *)load_formula); is_valid = validate_load_formula(load_formula, answer_list, centry_list, SGE_ATTR_LOAD_FORMULA); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); DRETURN(is_valid); } /****** sge_schedd_conf/sconf_create_default() *************************** * NAME * sconf_create_default() -- returns a default configuration * * SYNOPSIS * lListElem* sconf_create_default() * * FUNCTION * Creates a default configuration, but does not change the current * active configuration. A set config has to be used to make the * current configuration the active one. * * RESULT * lListElem* - default configuration (SC_Type) * * MT-NOTE: is MT-safe, does not use global variables * *******************************************************************************/ lListElem *sconf_create_default() { lListElem *ep, *added; DENTER(TOP_LAYER, "sconf_create_default"); ep = lCreateElem(SC_Type); lSetString(ep, SC_algorithm, "default"); lSetString(ep, SC_schedule_interval, SCHEDULE_TIME); lSetUlong(ep, SC_maxujobs, MAXUJOBS); lSetUlong(ep, SC_queue_sort_method, QSM_LOAD); added = lAddSubStr(ep, CE_name, "np_load_avg", SC_job_load_adjustments, CE_Type); lSetString(added, CE_stringval, "0.50"); lSetString(ep, SC_load_adjustment_decay_time, DEFAULT_LOAD_ADJUSTMENTS_DECAY_TIME); lSetString(ep, SC_load_formula, DEFAULT_LOAD_FORMULA); lSetString(ep, SC_schedd_job_info, SCHEDD_JOB_INFO); lSetUlong(ep, SC_flush_submit_sec, 0); lSetUlong(ep, SC_flush_finish_sec, 0); lSetString(ep, SC_params, "none"); lSetString(ep, SC_reprioritize_interval, REPRIORITIZE_INTERVAL); lSetUlong(ep, SC_halftime, 168); added = lAddSubStr(ep, UA_name, USAGE_ATTR_CPU, SC_usage_weight_list, UA_Type); lSetDouble(added, UA_value, 1.00); added = lAddSubStr(ep, UA_name, USAGE_ATTR_MEM, SC_usage_weight_list, UA_Type); lSetDouble(added, UA_value, 0.0); added = lAddSubStr(ep, UA_name, USAGE_ATTR_IO, SC_usage_weight_list, UA_Type); lSetDouble(added, UA_value, 0.0); lSetDouble(ep, SC_compensation_factor, 5); lSetDouble(ep, SC_weight_user, 0.25); lSetDouble(ep, SC_weight_project, 0.25); lSetDouble(ep, SC_weight_department, 0.25); lSetDouble(ep, SC_weight_job, 0.25); lSetUlong(ep, SC_weight_tickets_functional, 0); lSetUlong(ep, SC_weight_tickets_share, 0); lSetBool(ep, SC_share_override_tickets, true); lSetBool(ep, SC_share_functional_shares, true); lSetUlong(ep, SC_max_functional_jobs_to_schedule, 200); lSetBool(ep, SC_report_pjob_tickets, true); lSetUlong(ep, SC_max_pending_tasks_per_job, 50); lSetString(ep, SC_halflife_decay_list, "none"); lSetString(ep, SC_policy_hierarchy, policy_hierarchy_chars ); lSetDouble(ep, SC_weight_ticket, 0.5); lSetDouble(ep, SC_weight_waiting_time, 0.278); lSetDouble(ep, SC_weight_deadline, 3600000 ); lSetDouble(ep, SC_weight_urgency, 0.5 ); lSetUlong(ep, SC_max_reservation, 0); lSetDouble(ep, SC_weight_priority, 0.0 ); lSetString(ep, SC_default_duration, DEFAULT_DURATION); DRETURN(ep); } /****** sge_schedd_conf/sconf_is_centry_referenced() *************************** * NAME * sconf_is_centry_referenced() -- ??? * * SYNOPSIS * bool sconf_is_centry_referenced(const lListElem *this_elem, const * lListElem *centry) * * FUNCTION * ??? * * INPUTS * const lListElem *centry - ??? * * RESULT * bool - * * MT-NOTE: is MT save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ bool sconf_is_centry_referenced(const lListElem *centry) { bool ret = false; const lListElem *sc_ep = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (sc_ep != NULL) { const char *name = lGetString(centry, CE_name); lList *centry_list = lGetList(sc_ep, SC_job_load_adjustments); lListElem *centry_ref = lGetElemStr(centry_list, CE_name, name); ret = ((centry_ref != NULL)? true : false); if (!ret) { if (load_formula_is_centry_referenced(lGetString(sc_ep, SC_load_formula), centry)) { ret = true; } } } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return ret; } /****** sge_schedd_conf/get_load_adjustment_decay_time_str() ************* * NAME * get_load_adjustment_decay_time_str() -- ??? * * SYNOPSIS * const char * get_load_adjustment_decay_time_str() * * FUNCTION * ??? * * INPUTS * * RESULT * const char * - * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(read) * *******************************************************************************/ static const char * get_load_adjustment_decay_time_str() { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (pos.load_adjustment_decay_time != -1) { return lGetPosString(sc_ep, pos.load_adjustment_decay_time ); } else { return DEFAULT_LOAD_ADJUSTMENTS_DECAY_TIME; } } /****** sge_schedd_conf/sconf_get_load_adjustment_decay_time() ***************** * NAME * sconf_get_load_adjustment_decay_time() -- ??? * * SYNOPSIS * u_long32 sconf_get_load_adjustment_decay_time() * * FUNCTION * ??? * * INPUTS * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_load_adjustment_decay_time() { u_long32 uval; const char *time = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); time = get_load_adjustment_decay_time_str(); if (!extended_parse_ulong_val(NULL, &uval, TYPE_TIM, time, NULL, 0, 0, true)) { uval = _DEFAULT_LOAD_ADJUSTMENTS_DECAY_TIME; } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return uval; } /****** sge_schedd_conf/sconf_get_job_load_adjustments() *********************** * NAME * sconf_get_job_load_adjustments() -- ??? * * SYNOPSIS * const lList* sconf_get_job_load_adjustments(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const lList* - returns a copy, needs to be freed * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ lList *sconf_get_job_load_adjustments(void) { lList *load_adjustments = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); load_adjustments = lCopyList("load_adj_copy", get_job_load_adjustments()); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return load_adjustments; } /****** sge_schedd_conf/get_job_load_adjustments() *********************** * NAME * get_job_load_adjustments() -- ??? * * SYNOPSIS * const lList* get_job_load_adjustments(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const lList* - * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(read) * *******************************************************************************/ static const lList *get_job_load_adjustments(void) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (pos.job_load_adjustments!= -1) { return lGetPosList(sc_ep, pos.job_load_adjustments); } else { return NULL; } } /****** sge_schedd_conf/sconf_get_load_formula() ******************************* * NAME * sconf_get_load_formula() -- ??? * * SYNOPSIS * const char* sconf_get_load_formula(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const char* - this is a copy of the load formula, the caller has to free it * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ char* sconf_get_load_formula(void) { char *formula = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); formula = sge_strdup(formula, get_load_formula()); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return formula; } /****** sge_schedd_conf/get_load_formula() ******************************* * NAME * get_load_formula() -- ??? * * SYNOPSIS * const char* get_load_formula(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const char* - * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(read) * *******************************************************************************/ static const char* get_load_formula(void) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (pos.load_formula != -1) { return lGetPosString(sc_ep, pos.load_formula); } else { return DEFAULT_LOAD_FORMULA; } } /****** sge_schedd_conf/sconf_get_queue_sort_method() ************************** * NAME * sconf_get_queue_sort_method() -- ??? * * SYNOPSIS * u_long32 sconf_get_queue_sort_method(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_queue_sort_method(void) { const lListElem *sc_ep = NULL; u_long32 sort_method = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.queue_sort_method != -1) { sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); sort_method = lGetPosUlong(sc_ep, pos.queue_sort_method); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return sort_method; } /****** sge_schedd_conf/sconf_get_maxujobs() *********************************** * NAME * sconf_get_maxujobs() -- ??? * * SYNOPSIS * u_long32 sconf_get_maxujobs(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_maxujobs(void) { u_long32 jobs = MAXUJOBS; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.maxujobs != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); jobs = lGetPosUlong(sc_ep, pos.maxujobs ); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return jobs; } /****** sge_schedd_conf/get_schedule_interval_str() ********************** * NAME * get_schedule_interval_str() -- ??? * * SYNOPSIS * const char* get_schedule_interval_str(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const char* - * * MT-NOTE: is not MT-safe, the caller needs to hold the LOCK_SCHED_CONF(read) * *******************************************************************************/ static const char *get_schedule_interval_str(void) { if (pos.schedule_interval != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (sc_ep != NULL) { return lGetPosString(sc_ep, pos.schedule_interval); } else { return NULL; } } else { return SCHEDULE_TIME; } } /****** sge_schedd_conf/sconf_get_schedule_interval() ************************** * NAME * sconf_get_schedule_interval() -- ??? * * SYNOPSIS * u_long32 sconf_get_schedule_interval(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_schedule_interval(void) { u_long32 uval = _SCHEDULE_TIME; const char *time = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); time = get_schedule_interval_str(); if (!extended_parse_ulong_val(NULL, &uval, TYPE_TIM, time, NULL, 0, 0, true) ) { uval = _SCHEDULE_TIME; } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return uval; } /****** sge_schedd_conf/reprioritize_interval_str() ******************** * NAME * reprioritize_interval_str() -- ??? * * SYNOPSIS * const char* reprioritize_interval_str(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const char* - * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(read) * *******************************************************************************/ static const char *reprioritize_interval_str(void) { if (pos.reprioritize_interval!= -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); return lGetPosString(sc_ep, pos.reprioritize_interval); } else { return REPRIORITIZE_INTERVAL; } } /****** sge_schedd_conf/sconf_get_reprioritize_interval() ******************** * NAME * sconf_get_reprioritize_interval() -- ??? * * SYNOPSIS * u_long32 sconf_get_reprioritize_interval(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_reprioritize_interval(void) { u_long32 uval = REPRIORITIZE_INTERVAL_I; const char *time = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); time = reprioritize_interval_str(); if (!extended_parse_ulong_val(NULL, &uval, TYPE_TIM,time, NULL, 0 , 0, true)) { uval = REPRIORITIZE_INTERVAL_I; } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return uval; } /****** sge_schedd_conf/sconf_enable_schedd_job_info() ************************* * NAME * sconf_enable_schedd_job_info() -- ??? * * SYNOPSIS * void sconf_enable_schedd_job_info() * * FUNCTION * ??? * * INPUTS * * RESULT * void - * * MT-NOTE: is thread save, uses local storage * *******************************************************************************/ void sconf_enable_schedd_job_info() { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_enable_schedd_job_info"); sc_state->schedd_job_info = SCHEDD_JOB_INFO_TRUE; } /****** sge_schedd_conf/sconf_disable_schedd_job_info() ************************ * NAME * sconf_disable_schedd_job_info() -- ??? * * SYNOPSIS * void sconf_disable_schedd_job_info() * * FUNCTION * ??? * * INPUTS * * RESULT * void - * * MT-NOTE: is thread save, uses local storage * *******************************************************************************/ void sconf_disable_schedd_job_info() { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_disable_schedd_job_info"); sc_state->schedd_job_info = SCHEDD_JOB_INFO_FALSE; } /****** sge_schedd_conf/sconf_best_pe_alg() ************************************ * NAME * sconf_best_pe_alg() -- returns the alg to use for pe-range jobs * * SYNOPSIS * schedd_pe_algorithm sconf_best_pe_alg() * * FUNCTION * It checks for the alg. to use. If the user did not set a custom one, it * will evaluate the weights and return the most sucessful one. * * RESULT * schedd_pe_algorithm - pe-range alg. * * NOTES * MT-NOTE: sconf_best_pe_alg() is MT safe * * SEE ALSO * sconf_best_pe_alg *******************************************************************************/ schedd_pe_algorithm sconf_best_pe_alg() { schedd_pe_algorithm alg; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); alg = pe_algorithm; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (alg != SCHEDD_PE_AUTO) { return alg; } else { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_best_pe_alg"); if ((sc_state->search_alg[SCHEDD_PE_BINARY] >= sc_state->search_alg[SCHEDD_PE_LOW_FIRST]) && (sc_state->search_alg[SCHEDD_PE_BINARY] >= sc_state->search_alg[SCHEDD_PE_HIGH_FIRST])) { return SCHEDD_PE_BINARY; } else if (sc_state->search_alg[SCHEDD_PE_HIGH_FIRST] >= sc_state->search_alg[SCHEDD_PE_LOW_FIRST]){ return SCHEDD_PE_HIGH_FIRST; } else { return SCHEDD_PE_LOW_FIRST; } } } /****** sge_schedd_conf/sconf_update_pe_alg() ********************************** * NAME * sconf_update_pe_alg() -- updates the weights for the different algorithms * * SYNOPSIS * void sconf_update_pe_alg(int runs, int current, int max) * * FUNCTION * updates the weights for the different algorithms. Since the alg. with * the bigest number is taken, the numbers are negative. It uses the running * averages to ensure, that the numbers are not getting to big and that the * scheduler can reakt to changes. * * * INPUTS * int runs - number of runs it would have taken with the bin search alg. * int current - number of runs it took * int max - max runs * * NOTES * MT-NOTE: sconf_update_pe_alg() is MT safe * * SEE ALSO * sconf_best_pe_alg * *******************************************************************************/ void sconf_update_pe_alg(int runs, int current, int max) { const int HISTORY = 66; const int PRESENT = 34; if (max > 1) { int low_run = current+1; int high_run = max - current+1; GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_update_pe_alg"); /* we calculate 2 digits behind the commma*/ runs *= 100; low_run *= 100; high_run *= 100; sc_state->search_alg[SCHEDD_PE_BINARY] = (sc_state->search_alg[SCHEDD_PE_BINARY] * HISTORY) / 100; sc_state->search_alg[SCHEDD_PE_HIGH_FIRST] = (sc_state->search_alg[SCHEDD_PE_HIGH_FIRST] * HISTORY) / 100; sc_state->search_alg[SCHEDD_PE_LOW_FIRST] = (sc_state->search_alg[SCHEDD_PE_LOW_FIRST] * HISTORY) / 100; sc_state->search_alg[SCHEDD_PE_BINARY] -= runs * PRESENT / 100; sc_state->search_alg[SCHEDD_PE_LOW_FIRST] -= low_run * PRESENT / 100; sc_state->search_alg[SCHEDD_PE_HIGH_FIRST] -= high_run * PRESENT / 100; } } int sconf_get_pe_alg_value(schedd_pe_algorithm alg) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_update_pe_alg"); return sc_state->search_alg[alg]; } void sconf_inc_fast_jobs(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_inc_fast_jobs"); sc_state->scheduled_fast_jobs++; } int sconf_get_fast_jobs(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_fast_jobs"); return sc_state->scheduled_fast_jobs; } void sconf_inc_pe_jobs(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_inc_pe_jobs"); sc_state->scheduled_pe_jobs++; } int sconf_get_pe_jobs(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_pe_jobs"); return sc_state->scheduled_pe_jobs; } void sconf_reset_jobs(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_reset_jobs"); sc_state->scheduled_fast_jobs = 0; sc_state->scheduled_pe_jobs = 0; } /****** sge_schedd_conf/sconf_get_schedd_job_info() **************************** * NAME * sconf_get_schedd_job_info() -- ??? * * SYNOPSIS * u_long32 sconf_get_schedd_job_info(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) and local storage * *******************************************************************************/ u_long32 sconf_get_schedd_job_info(void) { u_long32 info = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); info = pos.c_is_schedd_job_info; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (info == SCHEDD_JOB_INFO_FALSE) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_schedd_job_info"); info = sc_state->schedd_job_info; } return info; } /****** sge_schedd_conf/sconf_get_schedd_job_info_range() ********************** * NAME * sconf_get_schedd_job_info_range() -- ??? * * SYNOPSIS * const lList* sconf_get_schedd_job_info_range(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const lList* - returns a copy, needs to be freed * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ lList *sconf_get_schedd_job_info_range(void) { lList *range_copy = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); range_copy = lCopyList("copy_range", pos.c_schedd_job_info_range); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return range_copy; } /****** sge_schedd_conf/sconf_is_id_in_schedd_job_info_range() ********************** * NAME * sconf_is_id_in_schedd_job_info_range() -- ??? * * SYNOPSIS * const lList* sconf_is_id_in_schedd_job_info_range(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * bool - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ bool sconf_is_id_in_schedd_job_info_range(u_long32 job_number) { bool is_in_range = false; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); is_in_range = range_list_is_id_within(pos.c_schedd_job_info_range, job_number); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return is_in_range; } /****** sge_schedd_conf/get_algorithm() ********************************** * NAME * get_algorithm() -- ??? * * SYNOPSIS * const char* get_algorithm(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const char* - * * MT-NOTE: is not MT-safe, the caller needs the LOCK_SCHED_CONF(read) * *******************************************************************************/ static const char * get_algorithm(void) { if (pos.algorithm!= -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); return lGetPosString(sc_ep, pos.algorithm); } else { return "default"; } } /****** sge_schedd_conf/sconf_get_usage_weight_list() ************************** * NAME * sconf_get_usage_weight_list() -- ??? * * SYNOPSIS * const lList* sconf_get_usage_weight_list(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * lList* - returns a copy, needs to be freed * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ lList *sconf_get_usage_weight_list(void) { lList *weight_list = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); weight_list = lCopyList("copy_weight", get_usage_weight_list()); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight_list; } /****** sge_schedd_conf/get_usage_weight_list() ************************** * NAME * get_usage_weight_list() -- ??? * * SYNOPSIS * const lList* get_usage_weight_list(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const lList* - * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(read) * *******************************************************************************/ static const lList *get_usage_weight_list(void) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (pos.usage_weight_list != -1) { return lGetPosList(sc_ep, pos.usage_weight_list ); } else { return NULL; } } /****** sge_schedd_conf/sconf_get_weight_user() ******************************** * NAME * sconf_get_weight_user() -- ??? * * SYNOPSIS * double sconf_get_weight_user(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_weight_user(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_user!= -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosDouble(sc_ep, pos.weight_user); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_weight_department() ************************** * NAME * sconf_get_weight_department() -- ??? * * SYNOPSIS * double sconf_get_weight_department(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_weight_department(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_department != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosDouble(sc_ep, pos.weight_department); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_weight_project() ***************************** * NAME * sconf_get_weight_project() -- ??? * * SYNOPSIS * double sconf_get_weight_project(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_weight_project(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_project != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosDouble(sc_ep, pos.weight_project); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_weight_job() ********************************* * NAME * sconf_get_weight_job() -- ??? * * SYNOPSIS * double sconf_get_weight_job(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_weight_job(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_job != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosDouble(sc_ep, pos.weight_job); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_weight_tickets_share() *********************** * NAME * sconf_get_weight_tickets_share() -- ??? * * SYNOPSIS * u_long32 sconf_get_weight_tickets_share(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_weight_tickets_share(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_tickets_share != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosUlong(sc_ep, pos.weight_tickets_share ); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_weight_tickets_functional() ****************** * NAME * sconf_get_weight_tickets_functional() -- ??? * * SYNOPSIS * u_long32 sconf_get_weight_tickets_functional(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_weight_tickets_functional(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_tickets_functional != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosUlong(sc_ep, pos.weight_tickets_functional); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_halftime() *********************************** * NAME * sconf_get_halftime() -- ??? * * SYNOPSIS * u_long32 sconf_get_halftime(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_halftime(void) { const lListElem *sc_ep = NULL; u_long32 halftime = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.halftime != -1) { sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); halftime = lGetPosUlong(sc_ep, pos.halftime); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return halftime; } /****** sge_schedd_conf/sconf_set_weight_tickets_override() ******************** * NAME * sconf_set_weight_tickets_override() -- ??? * * SYNOPSIS * void sconf_set_weight_tickets_override(u_long32 active) * * FUNCTION * ??? * * INPUTS * u_long32 active - ??? * * RESULT * void - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(write) * *******************************************************************************/ void sconf_set_weight_tickets_override(u_long32 active) { lListElem *sc_ep = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (pos.weight_tickets_override!= -1) { lSetPosUlong(sc_ep, pos.weight_tickets_override, active); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return; } /****** sge_schedd_conf/sconf_get_weight_tickets_override() ******************** * NAME * sconf_get_weight_tickets_override() -- ??? * * SYNOPSIS * void sconf_get_weight_tickets_override(u_long32 active) * * FUNCTION * ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_weight_tickets_override() { u_long32 tickets = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_tickets_override!= -1) { lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); tickets = lGetPosUlong(sc_ep, pos.weight_tickets_override); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return tickets; } /****** sge_schedd_conf/sconf_get_compensation_factor() ************************ * NAME * sconf_get_compensation_factor() -- ??? * * SYNOPSIS * double sconf_get_compensation_factor(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_compensation_factor(void) { double factor = 1; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.compensation_factor!= -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); factor = lGetPosDouble(sc_ep, pos.compensation_factor); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return factor; } /****** sge_schedd_conf/sconf_get_weight_ticket() **************************** * NAME * sconf_get_weight_ticket() -- ??? * * SYNOPSIS * double sconf_get_weight_ticket(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_weight_ticket(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_ticket != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosDouble(sc_ep, pos.weight_ticket); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } void sconf_get_weight_ticket_urgency_priority(double *ticket, double *urgency, double *priority) { sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_ticket != -1 && pos.weight_urgency != -1 && pos.weight_priority != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); *ticket = lGetPosDouble(sc_ep, pos.weight_ticket); *urgency = lGetPosDouble(sc_ep, pos.weight_urgency); *priority = lGetPosDouble(sc_ep, pos.weight_priority); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); } /****** sge_schedd_conf/sconf_get_weight_waiting_time() ************************ * NAME * sconf_get_weight_waiting_time() -- ??? * * SYNOPSIS * double sconf_get_weight_waiting_time(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_weight_waiting_time(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_waiting_time != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosDouble(sc_ep, pos.weight_waiting_time); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_weight_deadline() **************************** * NAME * sconf_get_weight_deadline() -- ??? * * SYNOPSIS * double sconf_get_weight_deadline(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_weight_deadline(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_deadline != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosDouble(sc_ep, pos.weight_deadline); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_weight_urgency() **************************** * NAME * sconf_get_weight_urgency() -- ??? * * SYNOPSIS * double sconf_get_weight_urgency(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_weight_urgency(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_urgency != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosDouble(sc_ep, pos.weight_urgency); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_max_reservations() *************************** * NAME * sconf_get_max_reservations() -- Max reservation tuning parameter * * SYNOPSIS * int sconf_get_max_reservations(void) * * FUNCTION * Tuning parameter. * Returns maximum number of reservations that should be done by * scheduler. If 0 is returned this no single job shall get a reservation * and assignments are to be made for 'now' only. * * RESULT * int - Max. number of reservations * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_max_reservations(void) { u_long32 max_res = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (!pos.empty && (pos.max_reservation != -1)) { lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); max_res = lGetPosUlong(sc_ep, pos.max_reservation); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return max_res; } /****** sge_schedd_conf/get_default_duration_str() ********************** * NAME * get_default_duration_str() -- Return default_duration string * * SYNOPSIS * const char* get_default_duration_str(void) * * FUNCTION * Returns default duration string from scheduler configuration. * * RESULT * const char* - * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(read) * *******************************************************************************/ static const char *get_default_duration_str(void) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (pos.schedule_interval != -1) { return lGetPosString(sc_ep, pos.default_duration); } else { return DEFAULT_DURATION; } } /****** sge_schedd_conf/sconf_get_weight_priority() **************************** * NAME * sconf_get_weight_priority() -- ??? * * SYNOPSIS * double sconf_get_weight_priority(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * double - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ double sconf_get_weight_priority(void) { double weight = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.weight_priority != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); weight = lGetPosDouble(sc_ep, pos.weight_priority); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return weight; } /****** sge_schedd_conf/sconf_get_share_override_tickets() ********************* * NAME * sconf_get_share_override_tickets() -- ??? * * SYNOPSIS * bool sconf_get_share_override_tickets(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * bool - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ bool sconf_get_share_override_tickets(void) { bool is_share = false; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.share_override_tickets != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); is_share = lGetPosBool(sc_ep, pos.share_override_tickets) ? true : false; } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return is_share; } /****** sge_schedd_conf/sconf_get_share_functional_shares() ******************** * NAME * sconf_get_share_functional_shares() -- ??? * * SYNOPSIS * bool sconf_get_share_functional_shares(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * bool - *******************************************************************************/ bool sconf_get_share_functional_shares(void) { bool is_share = true; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.share_functional_shares != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); is_share = lGetPosBool(sc_ep, pos.share_functional_shares) ? true : false; } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return is_share; } /****** sge_schedd_conf/sconf_get_report_pjob_tickets() ************************* * NAME * sconf_get_report_pjob_tickets() -- ??? * * SYNOPSIS * bool sconf_get_report_pjob_tickets(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * bool - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ bool sconf_get_report_pjob_tickets(void) { bool is_report = true; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.report_pjob_tickets!= -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); is_report = lGetPosBool(sc_ep, pos.report_pjob_tickets) ? true : false; } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return is_report; } /****** sge_schedd_conf/sconf_is_job_category_filtering() ********************** * NAME * sconf_is_job_category_filtering() -- true, if the job_category_filtering is on * * SYNOPSIS * bool sconf_is_job_category_filtering(void) * * FUNCTION * returns the status of the job category filtering * * RESULT * bool - true, the job category filtering is on * * NOTES * MT-NOTE: is MT save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ bool sconf_is_job_category_filtering(void){ bool filtering = false; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); filtering = is_category_job_filtering; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return filtering; } /****** sge_schedd_conf/sconf_get_flush_submit_sec() *************************** * NAME * sconf_get_flush_submit_sec() -- ??? * * SYNOPSIS * int sconf_get_flush_submit_sec(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * int - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_flush_submit_sec(void) { const lListElem *sc_ep = NULL; u_long32 flush_sec = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.flush_submit_sec != -1) { sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (sc_ep != NULL) { flush_sec = lGetPosUlong(sc_ep, pos.flush_submit_sec); } } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return flush_sec; } /****** sge_schedd_conf/sconf_get_flush_finish_sec() *************************** * NAME * sconf_get_flush_finish_sec() -- ??? * * SYNOPSIS * int sconf_get_flush_finish_sec(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * int - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_flush_finish_sec(void) { const lListElem *sc_ep = NULL; u_long32 flush_sec = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.flush_finish_sec!= -1) { sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (sc_ep != NULL) { flush_sec = lGetPosUlong(sc_ep, pos.flush_finish_sec); } } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return flush_sec; } /****** sge_schedd_conf/sconf_get_max_functional_jobs_to_schedule() ************ * NAME * sconf_get_max_functional_jobs_to_schedule() -- ??? * * SYNOPSIS * u_long32 sconf_get_max_functional_jobs_to_schedule(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_max_functional_jobs_to_schedule(void) { u_long32 amount = 200; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.max_functional_jobs_to_schedule != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); amount = lGetPosUlong(sc_ep, pos.max_functional_jobs_to_schedule); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return amount; } /****** sge_schedd_conf/sconf_get_max_pending_tasks_per_job() ****************** * NAME * sconf_get_max_pending_tasks_per_job() -- ??? * * SYNOPSIS * u_long32 sconf_get_max_pending_tasks_per_job(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * u_long32 - * * MT-NOTE: is MT save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ u_long32 sconf_get_max_pending_tasks_per_job(void) { u_long32 max_pending = 50; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); if (pos.max_pending_tasks_per_job != -1) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); max_pending = lGetPosUlong(sc_ep, pos.max_pending_tasks_per_job); } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return max_pending; } /****** sge_schedd_conf/get_halflife_decay_list_str() ******************** * NAME * get_halflife_decay_list_str() -- ??? * * SYNOPSIS * const char* get_halflife_decay_list_str(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const char* - * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(read) * *******************************************************************************/ static const char *get_halflife_decay_list_str(void) { const lListElem *sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); if (pos.halflife_decay_list != -1) { return lGetPosString(sc_ep, pos.halflife_decay_list); } else { return "none"; } } /****** sge_schedd_conf/sconf_get_halflife_decay_list() ************************ * NAME * sconf_get_halflife_decay_list() -- ??? * * SYNOPSIS * const lList* sconf_get_halflife_decay_list(void) * * FUNCTION * ??? * * INPUTS * void - ??? * * RESULT * const lList* - * * MT-NOTE: is MT save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ lList* sconf_get_halflife_decay_list(void){ lList *decay_list = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); decay_list = lCopyList("copy_decay_list",pos.c_halflife_decay_list); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return decay_list; } /****** sge_schedd_conf/is_config_set() ********************************************* * NAME * is_config_set() -- checks, if a configuration exists * * SYNOPSIS * bool is_config_set(void) * * RESULT * bool - true, if a configuration exists * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(read) * *******************************************************************************/ static bool is_config_set(void) { const lListElem *sc_ep = NULL; if (*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))) { sc_ep = lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); } return ((sc_ep != NULL) ? true : false); } /****** sge_schedd_conf/sconf_is() ********************************************* * NAME * sconf_is() -- checks, if a configuration exists * * SYNOPSIS * bool sconf_is(void) * * RESULT * bool - true, if a configuration exists * * * MT-NOTE: is MT save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ bool sconf_is(void) { bool is = false; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); is = is_config_set(); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return is; } /****** sge_schedd_conf/sconf_get_config() ************************************* * NAME * sconf_get_config() -- returns a config object. * * SYNOPSIS * const lListElem* sconf_get_config(void) * * RESULT * const lListElem* - a copy of the current config object * * NOTE * DO NOT USE this method. ONLY when there is NO OTHER way. All config * settings can be accessed via access function. * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ lListElem *sconf_get_config(void) { lListElem *config = NULL; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); config = lCopyElem(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF)))); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return config; } /****** sge_schedd_conf/sconf_get_config_list() ******************************** * NAME * sconf_get_config_list() -- returns a pointer to the list, which contains * the configuration * * SYNOPSIS * lList* sconf_get_config_list(void) * * RESULT * lList* - a copy of the config list * * MT-NOTE: is thread save, uses LOCK_SCHED_CONF(read) * * NOTE * DO NOT USE this method. ONLY when there is NO OTHER way. All config * settings can be accessed via access function. The config can be set * via sconf_set_config(...) * * IMPORTANT * * If you modify the configuration by directly accessing, you have to call * sconf_validate_config_ afterwards to ensure, that the caches reflect * your changes. * *******************************************************************************/ lList *sconf_get_config_list(void) { lList *copy_list = NULL; DENTER(TOP_LAYER, "sconf_get_config_list"); sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); copy_list = lCopyList("sched_conf_copy", *(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); DRETURN(copy_list); } /****** sge_schedd_conf/sconf_print_config() *********************************** * NAME * sconf_print_config() -- prints the current configuration to the INFO stream * * SYNOPSIS * void sconf_print_config() * * MT-NOTE: is MT safe, uses LOCK_SCHED_CONF(read/write) * *******************************************************************************/ void sconf_print_config(void){ char tmp_buffer[1024]; u_long32 uval; const char *s; const lList *lval= NULL; double dval; DENTER(TOP_LAYER, "sconf_print_config"); if (!sconf_is()){ ERROR((SGE_EVENT, MSG_SCONF_NO_CONFIG)); DRETURN_VOID; } sconf_validate_config_(NULL); sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); /* --- SC_algorithm */ s = get_algorithm(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXASY_SS , s, "algorithm")); /* --- SC_schedule_interval */ s = get_schedule_interval_str(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_SS , s, "schedule_interval")); /* --- SC_load_adjustment_decay_time */ s = get_load_adjustment_decay_time_str(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_SS, s, "load_adjustment_decay_time")); /* --- SC_load_formula */ INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_SS, get_load_formula(), "load_formula")); /* --- SC_schedd_job_info */ INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_SS, lGetString(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))), SC_schedd_job_info), "schedd_job_info")); /* --- SC_params */ s=lGetString(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))), SC_params); INFO((SGE_EVENT, MSG_READ_PARAM_S, s)); /* --- SC_reprioritize_interval */ s = reprioritize_interval_str(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_SS, s, "reprioritize_interval")); /* --- SC_usage_weight_list */ uni_print_list(NULL, tmp_buffer, sizeof(tmp_buffer), get_usage_weight_list(), usage_fields, delis, 0); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_SS, tmp_buffer, "usage_weight_list")); /* --- SC_halflife_decay_list_str */ s = get_halflife_decay_list_str(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_SS, s, "halflife_decay_list")); /* --- SC_policy_hierarchy */ s = lGetString(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))), SC_policy_hierarchy); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_SS, s, "policy_hierarchy")); /* --- SC_job_load_adjustments */ lval = get_job_load_adjustments(); uni_print_list(NULL, tmp_buffer, sizeof(tmp_buffer), lval, load_adjustment_fields, delis, 0); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_SS, tmp_buffer, "job_load_adjustments")); sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); /* --- SC_maxujobs */ uval = sconf_get_maxujobs(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US, sge_u32c( uval), "maxujobs")); /* --- SC_queue_sort_method (was: SC_sort_seq_no) */ uval = sconf_get_queue_sort_method(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval), "queue_sort_method")); /* --- SC_flush_submit_sec */ uval = sconf_get_flush_submit_sec(); INFO((SGE_EVENT,MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval) , "flush_submit_sec")); /* --- SC_flush_finish_sec */ uval = sconf_get_flush_finish_sec(); INFO((SGE_EVENT,MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval) , "flush_finish_sec")); /* --- SC_halftime */ uval = sconf_get_halftime(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US , sge_u32c (uval), "halftime")); /* --- SC_compensation_factor */ dval = sconf_get_compensation_factor(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "compensation_factor")); /* --- SC_weight_user */ dval = sconf_get_weight_user(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "weight_user")); /* --- SC_weight_project */ dval = sconf_get_weight_project(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "weight_project")); /* --- SC_weight_department */ dval = sconf_get_weight_department(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "weight_department")); /* --- SC_weight_job */ dval = sconf_get_weight_job(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "weight_job")); /* --- SC_weight_tickets_functional */ uval = sconf_get_weight_tickets_functional(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval), "weight_tickets_functional")); /* --- SC_weight_tickets_share */ uval = sconf_get_weight_tickets_share(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval), "weight_tickets_share")); /* --- SC_share_override_tickets */ uval = sconf_get_share_override_tickets(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval), "share_override_tickets")); /* --- SC_share_functional_shares */ uval = sconf_get_share_functional_shares(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval), "share_functional_shares")); /* --- SC_max_functional_jobs_to_schedule */ uval = sconf_get_max_functional_jobs_to_schedule(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval), "max_functional_jobs_to_schedule")); /* --- SC_report_job_tickets */ uval = sconf_get_report_pjob_tickets(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval), "report_pjob_tickets")); /* --- SC_max_pending_tasks_per_job */ uval = sconf_get_max_pending_tasks_per_job(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_US, sge_u32c (uval), "max_pending_tasks_per_job")); /* --- SC_weight_ticket */ dval = sconf_get_weight_ticket(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "weight_ticket")); /* --- SC_weight_waiting_time */ dval = sconf_get_weight_waiting_time(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "weight_waiting_time")); /* --- SC_weight_deadline */ dval = sconf_get_weight_deadline(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "weight_deadline")); /* --- SC_weight_urgency */ dval = sconf_get_weight_urgency(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "weight_urgency")); /* --- SC_weight_priority */ dval = sconf_get_weight_priority(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "weight_priority")); /* --- SC_max_reservation */ dval = sconf_get_max_reservations(); INFO((SGE_EVENT, MSG_ATTRIB_USINGXFORY_6FS, dval, "max_reservation")); DRETURN_VOID; } /****** sge_schedd_conf/sconf_is_new_config() ******************************* * NAME * sconf_is_new_config() -- * * SYNOPSIS * bool sconf_is_new_config() * * FUNCTION * * RESULT * bool - * * MT-NOTE: is MT safe, uses LOCK_SCHED_CONF(read) * *******************************************************************************/ bool sconf_is_new_config() { bool is_new_config = false; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); is_new_config = pos.new_config; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return is_new_config; } /****** sge_schedd_conf/sconf_reset_new_config() ******************************* * NAME * sconf_reset_new_config() -- * * SYNOPSIS * bool sconf_reset_new_config() * * FUNCTION * * MT-NOTE: is MT safe, uses LOCK_SCHED_CONF(write) * *******************************************************************************/ void sconf_reset_new_config() { sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); pos.new_config = false; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); } /****** sge_schedd_conf/sconf_validate_config_() ******************************* * NAME * sconf_validate_config_() -- validates the current config * * SYNOPSIS * bool sconf_validate_config_(lList **answer_list) * * FUNCTION * validates the current config and updates the caches. * * INPUTS * lList **answer_list - error messages * * RESULT * bool - false for invalid scheduler configuration * * MT-NOTE: is MT safe, uses LOCK_SCHED_CONF(read/write) * *******************************************************************************/ bool sconf_validate_config_(lList **answer_list) { char tmp_buffer[1024], tmp_error[1024]; u_long32 uval; const char *s; const lList *lval= NULL; bool ret = true; u_long32 max_reservation = 0; DENTER(TOP_LAYER, "sconf_validate_config_"); if (!sconf_is()){ DPRINTF(("sconf_validate: no config to validate\n")); DRETURN(true); } sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); sconf_clear_pos(); pos.new_config = true; if (!calc_pos()){ SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_INCOMPLETE_SCHEDD_CONFIG)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } /* --- SC_params */ { const char *sparams = lGetString(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))), SC_params); char *s = NULL; /* the implementation has a problem. If an entry is removed, its setting is not changed, but it should be turned off. This means we have to turn everything off, before we work on the params */ schedd_profiling = false; is_category_job_filtering = false; current_serf_do_monitoring = false; pos.s_duration_offset = DEFAULT_DURATION_OFFSET; pe_algorithm = SCHEDD_PE_AUTO; if (sparams) { struct saved_vars_s *context = NULL; if (pos.c_params == NULL) { pos.c_params = lCreateList("params", PARA_Type); } for (s=sge_strtok_r(sparams, ",; ", &context); s; s=sge_strtok_r(NULL, ",; ", &context)) { int i = 0; bool added = false; for(i=0; params[i].name ;i++ ){ if (!strncasecmp(s, params[i].name, sizeof(params[i].name)-1)){ if (params[i].setParam) { ret &= params[i].setParam(pos.c_params, answer_list, s); } added = true; } } if (!added){ SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_UNKNOWN_PARAM_S, s)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } } sge_free_saved_vars(context); } else { lSetString(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))), SC_params, "none"); } } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); max_reservation = sconf_get_max_reservations(); sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); /* --- SC_algorithm */ s = get_algorithm(); if ( !s || (strcmp(s, "default") && strcmp(s, "simple_sched") && strncmp(s, "ext_", 4))) { if (!s) s = "not defined"; SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_ALGORITHMNOVALIDNAME_S, s)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } /* --- SC_schedule_interval */ s = get_schedule_interval_str(); if (!s || !extended_parse_ulong_val(NULL, &uval, TYPE_TIM, s, tmp_error, sizeof(tmp_error), 0, true) ) { if (!s) SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_XISNOTAY_SS , "schedule_interval", "not defined")); else SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_XISNOTAY_SS , "schedule_interval", tmp_error)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } /* --- SC_load_adjustment_decay_time */ s = get_load_adjustment_decay_time_str(); if (!s || !extended_parse_ulong_val(NULL, &uval, TYPE_TIM, s, tmp_error, sizeof(tmp_error), 0, true)) { if (!s) { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_XISNOTAY_SS , "schedule_interval", "not defined")); } else { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_XISNOTAY_SS, "load_adjustment_decay_time", tmp_error)); } answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } /* --- SC_schedd_job_info */ { char buf[4096]; char* key = NULL; int ikey = 0; lList *rlp=NULL, *alp=NULL; const char *schedd_info = lGetString(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))), SC_schedd_job_info); if (schedd_info == NULL){ SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_SCHEDDJOBINFONOVALIDPARAM )); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } else { struct saved_vars_s *context = NULL; strcpy(buf, schedd_info); /* on/off or watch a set of jobs */ key = sge_strtok_r(buf, " \t", &context); if (!strcmp("true", key)) ikey = SCHEDD_JOB_INFO_TRUE; else if (!strcmp("false", key)) ikey = SCHEDD_JOB_INFO_FALSE; else if (!strcmp("job_list", key)) ikey = SCHEDD_JOB_INFO_JOB_LIST; else { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_SCHEDDJOBINFONOVALIDPARAM )); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } /* check list of groups */ if (ikey == SCHEDD_JOB_INFO_JOB_LIST) { key = sge_strtok_r(NULL, "\n", &context); range_list_parse_from_string(&rlp, &alp, key, false, false, INF_NOT_ALLOWED); if (rlp == NULL) { lFreeList(&alp); SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_SCHEDDJOBINFONOVALIDJOBLIST)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } else{ pos.c_is_schedd_job_info = ikey; pos.c_schedd_job_info_range = rlp; } } else{ pos.c_is_schedd_job_info = ikey; } sge_free_saved_vars(context); } } /* --- SC_reprioritize_interval */ s = reprioritize_interval_str(); if (s == NULL || !extended_parse_ulong_val(NULL, &uval, TYPE_TIM, s, tmp_error, sizeof(tmp_error), 0, true)) { if (s == NULL) { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_XISNOTAY_SS , "schedule_interval", "not defined")); } else { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_XISNOTAY_SS , "reprioritize_interval", tmp_error)); } answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } /* --- SC_halflife_decay_list_str */ { s = get_halflife_decay_list_str(); if (s && (strcasecmp(s, "none") != 0)) { lList *halflife_decay_list = NULL; lListElem *ep = NULL; const char *s0 = NULL; const char *s1 = NULL; const char *s2 = NULL; const char *s3 = NULL; double value; struct saved_vars_s *sv1=NULL; struct saved_vars_s *sv2=NULL; s0 = s; for(s1=sge_strtok_r(s0, ":", &sv1); s1 != NULL; s1=sge_strtok_r(NULL, ":", &sv1)) { if (((s2=sge_strtok_r(s1, "=", &sv2)) != NULL) && ((s3=sge_strtok_r(NULL, "=", &sv2)) != NULL) && (sscanf(s3, "%lf", &value) == 1)) { ep = lAddElemStr(&halflife_decay_list, UA_name, s2, UA_Type); lSetDouble(ep, UA_value, value); } FREE(sv2); } FREE(sv1); if (lGetNumberOfElem(halflife_decay_list) == 0) { answer_list_add(answer_list, MSG_GDI_INVALIDHALFLIFE_DECAY, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } pos.c_halflife_decay_list = halflife_decay_list; } } /* --- SC_policy_hierarchy */ { const char *value_string = lGetString(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))), SC_policy_hierarchy); if (value_string) { if (policy_hierarchy_verify_value(value_string) != 0) { answer_list_add(answer_list, MSG_GDI_INVALIDPOLICYSTRING, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; lSetString(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))), SC_policy_hierarchy, policy_hierarchy_chars); } } else { if (!s) value_string = "not defined"; SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_XISNOTAY_SS , "policy hierarchy", value_string)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } } /* --- SC_max_reservation and SC_default_duration */ { const char *s = get_default_duration_str(); if (s == NULL || !extended_parse_ulong_val(NULL, &uval, TYPE_TIM, s, tmp_error, sizeof(tmp_error), 1, true) ) { if (s == NULL) { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_XISNOTAY_SS , "default_duration", "not defined")); } else { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_XISNOTAY_SS , "default_duration", tmp_error)); } answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } else { /* ensure we get a non-zero/non-infinity duration default in reservation scheduling mode */ if (max_reservation != 0 && uval == 0) { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_RR_REQUIRES_DEFAULT_DURATION)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } else { pos.c_default_duration = uval; } } } /* --- SC_usage_weight_list */ if (uni_print_list(NULL, tmp_buffer, sizeof(tmp_buffer), get_usage_weight_list(), usage_fields, delis, 0) < 0) { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_SCHEDD_USAGE_WEIGHT_LIST_S, tmp_error)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } /* --- SC_job_load_adjustments */ lval = get_job_load_adjustments(); if (uni_print_list(NULL, tmp_buffer, sizeof(tmp_buffer), lval, load_adjustment_fields, delis, 0) < 0) { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_SCHEDD_JOB_LOAD_ADJUSTMENTS_S, s)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); /* --- SC_load_formula */ { lList *master_centry_list = *object_type_get_master_list(SGE_TYPE_CENTRY); if (master_centry_list != NULL && !sconf_is_valid_load_formula(answer_list, master_centry_list)) { ret = false; } } /* --- max_pending_tasks_per_job */ if (sconf_get_max_pending_tasks_per_job() == 0) { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_ATTRIB_WRONG_SETTING_SS, "max_pending_tasks_per_job", ">0")); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } DRETURN(ret); } /****** sge_schedd_conf/sconf_validate_config() ******************************** * NAME * sconf_validate_config() -- validate a given configuration * * SYNOPSIS * bool sconf_validate_config(lList **answer_list, lList *config) * * INPUTS * lList **answer_list - error messages * lList *config - config to validate * * RESULT * bool - true, if the config is valid * * MT-NOTE: is MT safe, uses LOCK_SCHED_CONF(write) * * SG TODO: needs cleanup!! * *******************************************************************************/ bool sconf_validate_config(lList **answer_list, lList *config){ lList *store = NULL; bool ret = true; DENTER(TOP_LAYER, "sconf_validate_config"); if (config){ sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); store = *(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF)); *(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF)) = config; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); ret = sconf_validate_config_(answer_list); sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); *(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF)) = store; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); sconf_validate_config_(NULL); } DRETURN(ret); } /****** sgeobj/conf/policy_hierarchy_verify_value() *************************** * NAME * policy_hierarchy_verify_value() -- verify a policy string * * SYNOPSIS * int policy_hierarchy_verify_value(const char* value) * * FUNCTION * The function tests whether the given policy string (value) is i * valid. * * INPUTS * const char* value - policy string * * RESULT * int - 0 -> OK * 1 -> ERROR: one char is at least twice in "value" * 2 -> ERROR: invalid char in "value" * 3 -> ERROR: value == NULL * * MT-NOTE: is MT safe, uses only the given data. * ******************************************************************************/ static int policy_hierarchy_verify_value(const char* value) { int ret = 0; DENTER(TOP_LAYER, "policy_hierarchy_verify_value"); if (value != NULL) { if (strcmp(value, "") && strcasecmp(value, "NONE")) { int is_contained[POLICY_VALUES]; int i; for (i = 0; i < POLICY_VALUES; i++) { is_contained[i] = 0; } for (i = 0; i < strlen(value); i++) { char c = value[i]; int index = policy_hierarchy_char2enum(c); if (is_contained[index]) { DPRINTF(("character \'%c\' is contained at least twice\n", c)); ret = 1; break; } is_contained[index] = 1; if (is_contained[INVALID_POLICY]) { DPRINTF(("Invalid character \'%c\'\n", c)); ret = 2; break; } } } } else { ret = 3; } DRETURN(ret); } /****** sgeobj/conf/sconf_ph_fill_array() ***************************** * NAME * sconf_ph_fill_array() -- fill the policy array * * SYNOPSIS * void sconf_ph_fill_array(policy_hierarchy_t array[], * const char *value) * * FUNCTION * Fill the policy "array" according to the characters given by * "value". * * value == "FODS": * policy_hierarchy_t array[4] = { * {FUNCTIONAL_POLICY, 1}, * {OVERRIDE_POLICY, 1}, * {DEADLINE_POLICY, 1}, * {SHARE_TREE_POLICY, 1} * }; * * value == "FS": * policy_hierarchy_t array[4] = { * {FUNCTIONAL_POLICY, 1}, * {SHARE_TREE_POLICY, 1}, * {OVERRIDE_POLICY, 0}, * {DEADLINE_POLICY, 0} * }; * * value == "OFS": * policy_hierarchy_t hierarchy[4] = { * {OVERRIDE_POLICY, 1}, * {FUNCTIONAL_POLICY, 1}, * {SHARE_TREE_POLICY, 1}, * {DEADLINE_POLICY, 0} * }; * * value == "NONE": * policy_hierarchy_t hierarchy[4] = { * {OVERRIDE_POLICY, 0}, * {FUNCTIONAL_POLICY, 0}, * {SHARE_TREE_POLICY, 0}, * {DEADLINE_POLICY, 0} * }; * * INPUTS * policy_hierarchy_t array[] - array with at least POLICY_VALUES * values * const char* value - "NONE" or any combination * of the first letters of the policy * names (e.g. "OFSD") * * RESULT * "array" will be modified * * MT-NOTE: is MT safe, uses LOCK_SCHED_CONF(read) * ******************************************************************************/ void sconf_ph_fill_array(policy_hierarchy_t array[]) { int is_contained[POLICY_VALUES]; int index = 0; int i; const char *policy_hierarchy_string = NULL; DENTER(TOP_LAYER, "sconf_ph_fill_array"); sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); policy_hierarchy_string = lGetPosString(lFirst(*(object_type_get_master_list(SGE_TYPE_SCHEDD_CONF))), pos.policy_hierarchy); for (i = 0; i < POLICY_VALUES; i++) { is_contained[i] = 0; array[i].policy = INVALID_POLICY; } if (policy_hierarchy_string != NULL && strcmp(policy_hierarchy_string, "") && strcasecmp(policy_hierarchy_string, "NONE")) { for (i = 0; i < strlen(policy_hierarchy_string); i++) { char c = policy_hierarchy_string[i]; policy_type_t enum_value = policy_hierarchy_char2enum(c); is_contained[enum_value] = 1; array[index].policy = enum_value; array[index].dependent = 1; index++; } } for (i = INVALID_POLICY + 1; i < LAST_POLICY_VALUE; i++) { if (!is_contained[i]) { array[index].policy = (policy_type_t)i; array[index].dependent = 0; index++; } } sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); DRETURN_VOID; } /****** sgeobj/conf/policy_hierarchy_char2enum() ****************************** * NAME * policy_hierarchy_char2enum() -- Return value for a policy char * * SYNOPSIS * policy_type_t policy_hierarchy_char2enum(char character) * * FUNCTION * This function returns a enum value for the first letter of a * policy name. * * INPUTS * char character - "O", "F" or "S" * * RESULT * policy_type_t - enum value * * MT-NOTE: * not thread safe, needs LOCK_SCHED_CONF(read) * ******************************************************************************/ static policy_type_t policy_hierarchy_char2enum(char character) { const char *pointer; policy_type_t ret; pointer = strchr(policy_hierarchy_chars, character); if (pointer != NULL) { ret = (policy_type_t)((pointer - policy_hierarchy_chars) + 1); } else { ret = INVALID_POLICY; } return ret; } /****** sgeobj/conf/sconf_ph_print_array() **************************** * NAME * sconf_ph_print_array() -- print hierarchy array * * SYNOPSIS * void sconf_ph_print_array(policy_hierarchy_t array[]) * * FUNCTION * Print hierarchy array in the debug output * * INPUTS * policy_hierarchy_t array[] - array with at least * POLICY_VALUES values * * MT-NOTE: is MT save, no lock needed, works on the passed in data * ******************************************************************************/ void sconf_ph_print_array(policy_hierarchy_t array[]) { int i; DENTER(TOP_LAYER, "sconf_ph_print_array"); for (i = INVALID_POLICY + 1; i < LAST_POLICY_VALUE; i++) { char character = policy_hierarchy_enum2char(array[i-1].policy); DPRINTF(("policy: %c; dependent: %d\n", character, array[i-1].dependent)); } DRETURN_VOID; } /****** sgeobj/conf/policy_hierarchy_enum2char() ****************************** * NAME * policy_hierarchy_enum2char() -- Return policy char for a value * * SYNOPSIS * char policy_hierarchy_enum2char(policy_type_t value) * * FUNCTION * Returns the first letter of a policy name corresponding to the * enum "value". * * INPUTS * policy_type_t value - enum value * * RESULT * char - "O", "F", "S", "D" * * MT-NOTE: * not thread safe, needs LOCK_SCHED_CONF(read) * ******************************************************************************/ static char policy_hierarchy_enum2char(policy_type_t value) { return policy_hierarchy_chars[value - 1]; } /****** sge_schedd_conf/sconf_eval_set_profiling() ***************************** * NAME * sconf_eval_set_profiling() -- ??? * * SYNOPSIS * static bool sconf_eval_set_profiling(lList *param_list, lList * **answer_list, const char* param) * * FUNCTION * ??? * * INPUTS * lList *param_list - ??? * lList **answer_list - ??? * const char* param - ??? * * RESULT * static bool - * * MT-NOTE: * not thread safe, needs LOCK_SCHED_CONF(write) * *******************************************************************************/ static bool sconf_eval_set_profiling(lList *param_list, lList **answer_list, const char* param){ bool ret = true; lListElem *elem = NULL; DENTER(TOP_LAYER, "sconf_eval_set_profiling"); schedd_profiling = false; if (!strncasecmp(param, "PROFILE=1", sizeof("PROFILE=1")-1) || !strncasecmp(param, "PROFILE=TRUE", sizeof("PROFILE=TRUE")-1) ) { schedd_profiling = true; elem = lCreateElem(PARA_Type); lSetString(elem, PARA_name, "profile"); lSetString(elem, PARA_value, "true"); } else if (!strncasecmp(param, "PROFILE=0", sizeof("PROFILE=0")-1) || !strncasecmp(param, "PROFILE=FALSE", sizeof("PROFILE=FALSE")-1) ) { elem = lCreateElem(PARA_Type); lSetString(elem, PARA_name, "profile"); lSetString(elem, PARA_value, "false"); } else { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_INVALID_PARAM_SETTING_S, param)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } if (elem){ lAppendElem(param_list, elem); } DRETURN(ret); } /****** sge_schedd_conf/sconf_eval_set_job_category_filtering() **************** * NAME * sconf_eval_set_job_category_filtering() -- enable jc filtering or not. * * SYNOPSIS * static bool sconf_eval_set_job_category_filtering(lList *param_list, * lList **answer_list, const char* param) * * FUNCTION * A parsing function for the prama settings in the scheduler configuration. * It is looking for JC_FILTER to be set to true, or false and updates the * settings accordingly. * * INPUTS * lList *param_list - the param list * lList **answer_list - the answer list, in case of an error * const char* param - the param string * * RESULT * static bool - true, if everything went fine * * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(write) * *******************************************************************************/ static bool sconf_eval_set_job_category_filtering(lList *param_list, lList **answer_list, const char* param){ bool ret = true; lListElem *elem = NULL; DENTER(TOP_LAYER, "sconf_eval_set_job_category_filtering"); is_category_job_filtering= false; if (!strncasecmp(param, "JC_FILTER=1", sizeof("JC_FILTER=1")-1) || !strncasecmp(param, "JC_FILTER=TRUE", sizeof("JC_FILTER=TRUE")-1) ) { is_category_job_filtering= true; elem = lCreateElem(PARA_Type); lSetString(elem, PARA_name, "jc_filter"); lSetString(elem, PARA_value, "true"); } else if (!strncasecmp(param, "JC_FILTER=0", sizeof("JC_FILTER=1")-1) || !strncasecmp(param, "JC_FILTER=FALSE", sizeof("JC_FILTER=FALSE")-1) ) { elem = lCreateElem(PARA_Type); lSetString(elem, PARA_name, "jc_filter"); lSetString(elem, PARA_value, "false"); } else { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_INVALID_PARAM_SETTING_S, param)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } if (elem){ lAppendElem(param_list, elem); } DRETURN(ret); } /****** sge_schedd_conf/sconf_eval_set_monitoring() **************************** * NAME * sconf_eval_set_monitoring() -- Control SERF on/off via MONITOR param * * SYNOPSIS * static bool sconf_eval_set_monitoring(lList *param_list, lList * **answer_list, const char* param) * * FUNCTION * The MONITOR param allows schedule entry recording facility module * be switched on/off. * * INPUTS * lList *param_list - ??? * lList **answer_list - ??? * const char* param - ??? * * RESULT * static bool - parsing error * * NOTES * MT-NOTE: is not MT safe, the calling function needs to lock LOCK_SCHED_CONF(write) * *******************************************************************************/ static bool sconf_eval_set_monitoring(lList *param_list, lList **answer_list, const char* param){ bool ret = true; lListElem *elem = NULL; const char mon_true[] = "MONITOR=TRUE", mon_one[] = "MONITOR=1"; const char mon_false[] = "MONITOR=FALSE", mon_zero[] = "MONITOR=0"; bool do_monitoring = false; DENTER(TOP_LAYER, "sconf_eval_set_monitoring"); if (!strncasecmp(param, mon_one, sizeof(mon_one)-1) || !strncasecmp(param, mon_true, sizeof(mon_true)-1) ) { do_monitoring = true; elem = lCreateElem(PARA_Type); lSetString(elem, PARA_name, "monitor"); lSetString(elem, PARA_value, "true"); } else if (!strncasecmp(param, mon_zero, sizeof(mon_zero)-1) || !strncasecmp(param, mon_false, sizeof(mon_false)-1) ) { elem = lCreateElem(PARA_Type); lSetString(elem, PARA_name, "monitor"); lSetString(elem, PARA_value, "false"); } else { SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_INVALID_PARAM_SETTING_S, param)); answer_list_add(answer_list, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR); ret = false; } if (elem){ lAppendElem(param_list, elem); } current_serf_do_monitoring = do_monitoring; DRETURN(ret); } static bool sconf_eval_set_duration_offset(lList *param_list, lList **answer_list, const char* param) { u_long32 uval; char *s; if (!(s=strchr(param, '=')) || !extended_parse_ulong_val(NULL, &uval, TYPE_TIM, ++s, NULL, 0, 0, true)) { pos.s_duration_offset = DEFAULT_DURATION_OFFSET; return false; } pos.s_duration_offset = uval; return true; } /****** sge_schedd_conf/sconf_eval_set_pe_range_alg() ************************** * NAME * sconf_eval_set_pe_range_alg() -- parses the sched. param * * SYNOPSIS * static bool sconf_eval_set_pe_range_alg(lList *param_list, lList * **answer_list, const char* param) * * RESULT * static bool - true, if successful * * NOTES * MT-NOTE: sconf_eval_set_pe_range_alg() is not MT safe, caller needs LOCK_SCHED_CONF(write) * *******************************************************************************/ static bool sconf_eval_set_pe_range_alg(lList *param_list, lList **answer_list, const char* param) { char *s; DENTER(TOP_LAYER, "sconf_eval_set_monitoring"); if ((s=strchr(param, '=')) != NULL) { s++; if (strncasecmp(s, "auto", sizeof("auto")-1) == 0) { pe_algorithm = SCHEDD_PE_AUTO; } else if (strncasecmp(s, "least", sizeof("least")-1) == 0) { pe_algorithm = SCHEDD_PE_LOW_FIRST; } else if (strncasecmp(s, "bin", sizeof("bin")-1) == 0) { pe_algorithm = SCHEDD_PE_BINARY; } else if (strncasecmp(s, "highest", sizeof("highest")-1) == 0) { pe_algorithm = SCHEDD_PE_HIGH_FIRST; } else { DRETURN(false); } DRETURN(true); } DRETURN(false); } /* QS_STATE_FULL All debitations caused by running jobs are in effect. QS_STATE_EMPTY We ignore all debitations caused by running jobs. Ignore all but static load values. */ void sconf_set_qs_state(qs_state_t qs_state) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_set_qs_state"); sc_state->queue_state = qs_state; } qs_state_t sconf_get_qs_state(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_qs_state"); return sc_state->queue_state; } void sconf_set_global_load_correction(bool flag) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_set_global_load_correction"); sc_state->global_load_correction = flag; } bool sconf_get_global_load_correction(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_global_load_correction"); return sc_state->global_load_correction; } u_long32 sconf_get_default_duration(void) { return pos.c_default_duration; } bool sconf_get_host_order_changed(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_host_order_changed"); return sc_state->host_order_changed; } void sconf_set_host_order_changed(bool changed) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_set_host_order_changed"); sc_state->host_order_changed = changed; } int sconf_get_last_dispatch_type(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_last_dispatch_type"); return sc_state->last_dispatch_type; } void sconf_set_last_dispatch_type(int last) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_set_last_dispatch_type"); sc_state->last_dispatch_type = last; } void sconf_set_decay_constant(double decay) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_set_decay_constant"); sc_state->decay_constant = decay; } double sconf_get_decay_constant(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_decay_constant"); return sc_state->decay_constant; } void sconf_set_mes_schedd_info(bool newval) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_set_mes_schedd_info"); if (newval == true) { if (sc_state->sme == NULL || sc_state->tmp_sme == NULL) { /* if one of the values is NULL the messaging framework is initialized in this case just ignore the activate request */ return; } } sc_state->mes_schedd_info = newval; } bool sconf_get_mes_schedd_info() { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_mes_schedd_info"); return sc_state->mes_schedd_info; } void schedd_mes_set_logging(int bval) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "schedd_mes_set_logging"); sc_state->log_schedd_info = bval; } int schedd_mes_get_logging(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "schedd_mes_get_logging"); return sc_state->log_schedd_info; } lListElem *sconf_get_sme(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_sme"); return sc_state->sme; } void sconf_set_sme(lListElem *sme) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_sme"); sc_state->sme = sme; } lListElem *sconf_get_tmp_sme(void) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_tmp_sme"); return sc_state->tmp_sme; } void sconf_set_tmp_sme(lListElem *sme) { GET_SPECIFIC(sc_state_t, sc_state, sc_state_init, sc_state_key, "sconf_get_tmp_sme"); sc_state->tmp_sme = sme; } u_long32 sconf_get_duration_offset(void) { u_long32 offset = 0; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); offset = pos.s_duration_offset; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return offset; } /****** sge_resource_utilization/serf_control() ******************************** * NAME * serf_get_active() -- Retrieve whether SERF is active or not * * SYNOPSIS * bool serf_get_active(void); * * FUNCTION * Returns whether SERF is active or not * * RETURN * bool - true = on * false = off * * MT-NOTE: is MT safe, uses LOCK_SCHED_CONF(read) * * NOTES * Actually belongs to sge_serf.c but this would cause a link dependency * libsgeobj -> libschedd !! *******************************************************************************/ bool serf_get_active(void) { bool is = false; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); is = current_serf_do_monitoring; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return is; } bool sconf_get_profiling(void) { bool profiling = false; sge_mutex_lock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); profiling = schedd_profiling; sge_mutex_unlock("Sched_Conf_Lock", "", __LINE__, &pos.mutex); return profiling; }