/* do everything that needs to be done in common for all schedulers between processing events and dispatching */ int sge_before_dispatch(sge_evc_class_t *evc) { sge_gdi_ctx_class_t *ctx = evc->get_gdi_ctx(evc); const char *cell_root = ctx->get_cell_root(ctx); u_long32 progid = ctx->get_who(ctx); DENTER(TOP_LAYER, "sge_before_dispatch"); /* hostname resolving scheme in global config could have changed get it and use it if we got a notification about a new global config */ if (st_get_flag_new_global_conf()) { lListElem *global = NULL, *local = NULL; if (gdi2_get_configuration(ctx, SGE_GLOBAL_NAME, &global, &local) == 0) { merge_configuration(NULL, progid, cell_root, global, local, NULL); } lFreeElem(&global); lFreeElem(&local); st_set_flag_new_global_conf(false); } /* * job categories are reset here, we need * - an update of the rejected field for every new run * - the resource request dependent urgency contribution is cached * per job category */ sge_reset_job_category(); DRETURN(0); }
/****** sge_cqueue_verify/cqueue_verify_memory_value() **************************** * NAME * cqueue_verify_memory_value() -- verify a queue memory attribute like h_vmem * * SYNOPSIS * bool * cqueue_verify_memory_value(lListElem *cqueue, lList **answer_list, * lListElem *attr_elem) * * FUNCTION * Verifies if a memory attribute of a queue is in the expected range * (0 .. INFINITY) NONE is no allowed value. * * INPUTS * lListElem *cqueue - The queue to verify. * lList **answer_list - answer list to report errors * lListElem *attr_elem - the attribute to verify * * RESULT * bool - true on success, false on error * * NOTES * MT-NOTE: cqueue_verify_memory_value() is MT safe *******************************************************************************/ bool cqueue_verify_memory_value(lListElem *cqueue, lList **answer_list, lListElem *attr_elem) { bool ret = true; DENTER(CQUEUE_VERIFY_LAYER, "cqueue_verify_memory_value"); if (cqueue != NULL && attr_elem != NULL) { const char *memory_string = lGetString(attr_elem, AMEM_value); #if 1 lListElem *copy = lCopyElem(attr_elem); if (!object_parse_field_from_string(copy, answer_list, AMEM_value, memory_string)) { ret = false; } lFreeElem(©); #else if (memory_string == NULL || !strcasecmp(memory_string, "none")) { answer_list_add_sprintf(answer_list, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR, MSG_NONE_NOT_ALLOWED_S, "memory values"); ret = false; } #endif } DEXIT; return ret; }
bool cuser_provide_modify_context(sge_gdi_ctx_class_t *ctx, lListElem **this_elem, lList **answer_list) { bool ret = false; int status = 0; uid_t uid = ctx->get_uid(ctx); gid_t gid = ctx->get_gid(ctx); DENTER(TOP_LAYER, "cuser_provide_modify_context"); if (this_elem != NULL && *this_elem) { char *filename = write_ume(2, 1, *this_elem); status = sge_edit(filename, uid, gid); if (status >= 0) { lListElem *cuser; cuser = cull_read_in_ume(NULL, filename, 1, 0, 0, NULL); if (cuser != NULL) { lFreeElem(this_elem); *this_elem = cuser; ret = true; } else { answer_list_add(answer_list, MSG_FILE_ERRORREADINGINFILE, STATUS_ERROR1, ANSWER_QUALITY_ERROR); } } else { answer_list_add(answer_list, MSG_PARSE_EDITFAILED, STATUS_ERROR1, ANSWER_QUALITY_ERROR); } unlink(filename); } DRETURN(ret); }
bool cuser_modify(sge_gdi_ctx_class_t *ctx, lList **answer_list, const char *name) { bool ret = true; DENTER(TOP_LAYER, "cuser_modify"); if (name != NULL) { lListElem *cuser = cuser_get_via_gdi(ctx, answer_list, name); if (cuser == NULL) { sprintf(SGE_EVENT, MSG_CUSER_DOESNOTEXIST_S, name); answer_list_add(answer_list, SGE_EVENT, STATUS_ERROR1, ANSWER_QUALITY_ERROR); ret = false; } if (ret) { ret &= cuser_provide_modify_context(ctx, &cuser, answer_list); } if (ret) { ret &= cuser_add_del_mod_via_gdi(ctx, cuser, answer_list, SGE_GDI_MOD); } if (cuser) { lFreeElem(&cuser); } } DRETURN(ret); }
bool cuser_modify_from_file(sge_gdi_ctx_class_t *ctx, lList **answer_list, const char *filename) { bool ret = true; DENTER(TOP_LAYER, "cuser_modify_from_file"); if (filename != NULL) { lListElem *cuser; cuser = cull_read_in_ume(NULL, filename, 1, 0, 0, NULL); if (cuser == NULL) { sprintf(SGE_EVENT, MSG_CUSER_FILENOTCORRECT_S, filename); answer_list_add(answer_list, SGE_EVENT, STATUS_ERROR1, ANSWER_QUALITY_ERROR); ret = false; } if (ret) { ret &= cuser_add_del_mod_via_gdi(ctx, cuser, answer_list, SGE_GDI_MOD); } if (cuser != NULL) { lFreeElem(&cuser); } } DRETURN(ret); }
/****** cull/dump_scan/lUndumpObject() ****************************************** * NAME * lUndumpObject() -- Reads a by lDumpList dumped dump * * SYNOPSIS * lListElem* lUndumpObject(FILE *fp) * * FUNCTION * Reads a by lDumpList dumped dump into the memory. * * INPUTS * FILE *fp - file pointer * * RESULT * lListElem* - Read list element * * NOTES * ******************************************************************************/ lListElem *lUndumpObject(FILE *fp) { lListElem *ep; lDescr *dp = NULL; DENTER(CULL_LAYER, "lUndumpObject"); if (!fp) { LERROR(LEFILENULL); DEXIT; return NULL; } /* read bra */ if (fGetBra(fp)) { printf("bra is missing\n"); LERROR(LESYNTAX); DEXIT; return NULL; } /* read Descriptor from file */ if ((dp = lUndumpDescr(fp)) == NULL) { LERROR(LEFGETDESCR); DEXIT; return NULL; } if (lCountDescr(dp) <= 0) { LERROR(LECOUNTDESCR); free(dp); DEXIT; return NULL; } if ((ep = lUndumpElemFp(fp, dp)) == NULL) { LERROR(LEUNDUMPELEM); free(dp); DEXIT; return NULL; } free(dp); /* read ket */ if (fGetKet(fp)) { lFreeElem(&ep); printf("ket is missing\n"); LERROR(LESYNTAX); DEXIT; return NULL; } DEXIT; return ep; }
/****** sgeobj/var/var_list_add_as_set() *************************************** * NAME * var_list_add_as_set() -- Concatenate two lists as sets * * SYNOPSIS * int var_list_add_as_set(lList *lp0, lList *lp1) * * FUNCTION * Concatenate two lists of equal type throwing away the second list. * Elements in the second list will replace elements with the same key in the * the first list. If the first list contains duplicate element keys, only * the first element with a given key will be replaced by an element from the * second list with the same key. * * INPUTS * lList *lp0 - first list * lList *lp1 - second list * * RESULT * int - error state * 0 - OK * -1 - Error ******************************************************************************/ int var_list_add_as_set(lList *lp0, lList *lp1) { lListElem *ep0, *ep1; const lDescr *dp0, *dp1; const char *name, *value; DENTER(CULL_LAYER, "var_list_add_as_set"); if (lp1 == NULL || lp0 == NULL) { DRETURN(-1); } /* Check if the two lists are equal */ dp0 = lGetListDescr(lp0); dp1 = lGetListDescr(lp1); if (lCompListDescr(dp0, dp1) != 0) { DRETURN(-1); } while (lp1->first != NULL) { /* Get the first element from the second list */ if ((ep1 = lDechainElem(lp1, lp1->first)) == NULL) { DRETURN(-1); } /* Get it's name, and use the name to look for a matching element in the * first list. */ name = lGetString(ep1, VA_variable); ep0 = lGetElemStr(lp0, VA_variable, name); /* If there is a matching element in the first list, set it's value to the * value of the element from the second list. */ if (ep0 != NULL) { value = lGetString(ep1, VA_value); lSetString(ep0, VA_value, value); lFreeElem(&ep1); } /* If there is no matching element, add the element from the second list * to the first list. */ else { if (lAppendElem(lp0, ep1) == -1) { DRETURN(-1); } } } /* The second list is no longer needed. */ lFreeList(&lp1); DRETURN(0); }
bool check_range_get_all_ids(void) { bool failed = false; lListElem *range; /* Create preinitialized range element */ if (!failed) { range = lCreateElem(RN_Type); if (range == NULL) { failed = true; } } /* Check NULL pointer */ if (!failed) { u_long32 min = 1, max = 6, step = 2; range_get_all_ids(NULL, &min, &max, &step); if (max != 0 || min != 0 || step != 0) { fprintf(stderr, "NULL range is not correct in range_get_all_ids()\n"); failed = true; } } /* Check preinitialized range */ if (!failed) { u_long32 min = 1, max = 6, step = 2; range_get_all_ids(range, &min, &max, &step); if (max != 0 || min != 0 || step != 0) { fprintf(stderr, "Init range is not correct in range_get_all_ids()\n"); failed = true; } } /* Check range */ if (!failed) { u_long32 min = 1, max = 6, step = 2; range_set_all_ids(range, min, max, step); range_get_all_ids(range, &min, &max, &step); if (min != 1 || max != 6 || step != 2) { fprintf(stderr, "Range is not correct in range_get_all_ids()\n"); failed = true; } } lFreeElem(&range); return failed; }
static int test_normal_utilization(void) { /* * 8-| -------- ---- * | * 4-| ---- * | * 0-----------------------------------> * | | | | * 800 1000 */ int ret = 0; static u_long32 qeti_expected_result[] = { 1200, 1100, 1000, 800 }; test_array_t test_array[] = { {1000, 100, 4}, {1200, 150, 0}, {700, 150, 8}, {0, 0, 0} }; lListElem *cr = lCreateElem(RUE_Type); lSetString(cr, RUE_name, "slots"); printf("\n - test simple reservation - \n\n"); printf("adding a 200s now assignment of 8 starting at 800\n"); utilization_add(cr, 800, 200, 8, 100, 1, PE_TAG, "pe_slots", "STARTING", false, false); printf("adding a 100s now assignment of 4 starting at 1000\n"); utilization_add(cr, 1000, 100, 4, 101, 1, PE_TAG, "pe_slots", "STARTING", false, false); printf("adding a 100s reservation of 8 starting at 1100\n"); utilization_add(cr, 1100, 100, 8, 102, 1, PE_TAG, "pe_slots", "RESERVING", false, false); ret += do_utilization_test(cr, test_array); ret += do_qeti_test(cr, qeti_expected_result); lFreeElem(&cr); return ret; }
int pack_ack(sge_pack_buffer *pb, u_long32 type, u_long32 id, u_long32 id2, const char *str) { int ret; lListElem *ack = lCreateElem(ACK_Type); DENTER(TOP_LAYER, "pack_ack"); lSetUlong(ack, ACK_type, type); lSetUlong(ack, ACK_id, id); lSetUlong(ack, ACK_id2, id2); lSetString(ack, ACK_str, str); ret = cull_pack_elem(pb, ack); lFreeElem(&ack); DRETURN(ret); }
/****** spool/spool_free_context() ************************************** * NAME * spool_free_context() -- free resources of a spooling context * * SYNOPSIS * lListElem* * spool_free_context(lList **answer_list, lListElem *context) * * FUNCTION * Performs a shutdown of the spooling context and releases * all allocated resources. * * INPUTS * lList **answer_list - to return error messages * lListElem *context - the context to free * * RESULT * lListElem* - NULL * * EXAMPLE * lListElem *context; * ... * context = spool_free_context(answer_list, context); * * SEE ALSO * spool/--Spooling * spool/spool_create_context() * spool/spool_shutdown_context() *******************************************************************************/ lListElem * spool_free_context(lList **answer_list, lListElem *context) { DENTER(TOP_LAYER, "spool_free_context"); PROF_START_MEASUREMENT(SGE_PROF_SPOOLING); if (context == NULL) { answer_list_add_sprintf(answer_list, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR, MSG_SPOOL_NOVALIDCONTEXT_S, SGE_FUNC); } else { spool_shutdown_context(answer_list, context); lFreeElem(&context); } PROF_STOP_MEASUREMENT(SGE_PROF_SPOOLING); DRETURN(context); }
static void check_reprioritize_interval(sge_gdi_ctx_class_t *ctx, lList **alpp, char *ruser, char *rhost) { DENTER(TOP_LAYER, "check_reprioritize_interval"); if (((sconf_get_reprioritize_interval() == 0) && (mconf_get_reprioritize())) || ((sconf_get_reprioritize_interval() != 0) && (!mconf_get_reprioritize()))) { bool flag = (sconf_get_reprioritize_interval() != 0) ? true : false; lListElem *conf = sge_get_configuration_for_host(SGE_GLOBAL_NAME); sge_set_conf_reprioritize(conf, flag); sge_mod_configuration(ctx, conf, alpp, ruser, rhost); lFreeElem(&conf); } DEXIT; return; } /* check_reprioritize_interval */
bool cuser_show(sge_gdi_ctx_class_t *ctx, lList **answer_list, const char *name) { bool ret = true; DENTER(TOP_LAYER, "cuser_show"); if (name != NULL) { lListElem *cuser = cuser_get_via_gdi(ctx, answer_list, name); if (cuser != NULL) { write_ume(0, 0, cuser); lFreeElem(&cuser); } else { sprintf(SGE_EVENT, MSG_CUSER_DOESNOTEXIST_S, name); answer_list_add(answer_list, SGE_EVENT, STATUS_ERROR1, ANSWER_QUALITY_ERROR); ret = false; } } DRETURN(ret); }
static int test_extensive_utilization(void) { int ret = 0; lListElem *cr = lCreateElem(RUE_Type); lSetString(cr, RUE_name, "slots"); printf("\n - test INIFNITY reservation & unreservation - \n\n"); { /* * 8-| |-------| |-----...... * | * 4-| |---|----------------.... * | * 0--------------------------------------> * | | | | * 800 1000 2000 */ static u_long32 qeti_expected_result[] = { U_LONG32_MAX, 2000, 1000, 800 }; test_array_t test_array[] = { {1000, 100, 4}, {1200, U_LONG32_MAX, 8}, {200, U_LONG32_MAX, 8}, {700, 150, 8}, {700, 100, 0}, {3600, 150, 8}, {1000, 1000, 4}, {0, 0, 0} }; printf("1. reserved and verify result\n\n"); printf("adding a 200s now assignment of 8 starting at 800\n"); utilization_add(cr, 800, 200, 8, 100, 1, PE_TAG, "pe_slots", "STARTING", false, false); printf("adding a 100s now assignment of 4 starting at 1000\n"); utilization_add(cr, 1000, 100, 4, 101, 1, PE_TAG, "pe_slots", "STARTING", false, false); printf("adding a unlimited reservation of 4 starting at 1100\n"); utilization_add(cr, 1100, U_LONG32_MAX, 4, 102, 1, PE_TAG, "pe_slots", "RESERVING", false, false); printf("adding a unlimited reservation of 4 starting at 2000\n"); utilization_add(cr, 2000, U_LONG32_MAX, 4, 103, 1, PE_TAG, "pe_slots", "RESERVING", false, false); ret += do_utilization_test(cr, test_array); ret += do_qeti_test(cr, qeti_expected_result); } { /* * 8-| |-------| * | * 4-| |-----...... * | * 0--------------------------------------> * | | | | * 800 1000 2000 */ static u_long32 qeti_expected_result[] = { U_LONG32_MAX, 2000, 1000, 800 }; test_array_t test_array[] = { {1000, 100, 0}, {1200, U_LONG32_MAX, 4}, {200, U_LONG32_MAX, 8}, {700, 150, 8}, {700, 100, 0}, {3600, 150, 4}, {1000, 1000, 0}, {0, 0, 0} }; printf("2. unreserve some and test result\n\n"); printf("removing a 100s now assignment of 4 starting at 1000\n"); utilization_add(cr, 1000, 100, -4, 101, 1, PE_TAG, "pe_slots", "STARTING", false, false); printf("removing a unlimited reservation of 4 starting at 1100\n"); utilization_add(cr, 1100, U_LONG32_MAX, -4, 102, 1, PE_TAG, "pe_slots", "RESERVING", false, false); ret += do_utilization_test(cr, test_array); ret += do_qeti_test(cr, qeti_expected_result); } { test_array_t test_array[] = { {1000, 100, 0}, {1200, U_LONG32_MAX, 0}, {200, U_LONG32_MAX, 0}, {700, 150, 0}, {700, 100, 0}, {3600, 150, 0}, {1000, 1000, 0}, {0, 0, 0} }; printf("3. unreserve all\n\n"); printf("removing a 200s now assignment of 8 starting at 800\n"); utilization_add(cr, 800, 200, -8, 100, 1, PE_TAG, "pe_slots", "STARTING", false, false); printf("removing a unlimited reservation of 4 starting at 2000\n"); utilization_add(cr, 2000, U_LONG32_MAX, -4, 103, 1, PE_TAG, "pe_slots", "RESERVING", false, false); ret += do_utilization_test(cr, test_array); ret += do_qeti_test(cr, NULL); } lFreeElem(&cr); return ret; }
bool test_lWhat_lSelect(void) { bool ret = true; lEnumeration *what = lWhat("%T(%I %I -> %T( %I %I -> %T (%I %I %I %I) %I %I) %I -> %T(%I) %I)", TEST_Type, TEST_int, TEST_list, TEST1_Type, TEST1_int, TEST1_list, TEST_Type, TEST_int, TEST_list, TEST_object, TEST_string, TEST1_object, TEST1_string, TEST_object, TEST1_Type, TEST1_string, TEST_string); lListElem *elem; lListElem *elem1; lList *list = lCreateList("", TEST_Type); lList *list1 = NULL; int i; elem = lCreateElem(TEST_Type); lSetInt(elem, TEST_int, 0); lSetHost(elem, TEST_host, "zero"); lSetString(elem, TEST_string, "zero"); lSetFloat(elem, TEST_float, 0); lSetDouble(elem, TEST_double, 0); lSetChar(elem, TEST_char, 'z'); lSetLong(elem, TEST_long, 0); lSetUlong(elem, TEST_ulong, 0); lSetBool(elem, TEST_bool, false); elem1 = lCreateElem(TEST1_Type); lSetInt(elem1, TEST1_int, 1); lSetHost(elem1, TEST1_host, "one"); lSetString(elem1, TEST1_string, "one"); lSetFloat(elem1, TEST1_float, 1); lSetDouble(elem1, TEST1_double, 1); lSetChar(elem1, TEST1_char, 'o'); lSetLong(elem1, TEST1_long, 1); lSetUlong(elem1, TEST1_ulong, 1); lSetBool(elem1, TEST1_bool, true); for (i = 0; i < 5; i++) { lList *tmp_list = lCreateList("", TEST1_Type); lListElem *tmp_elem = lCopyElem(elem); int j; for (j = 0; j < 5; j++) { lList *tmp_list1 = lCreateList("", TEST_Type); lListElem *tmp_elem1 = lCopyElem(elem); int k; for (k = 0; k < 5; k++) { lList *tmp_list2 = lCreateList("", TEST1_Type); lListElem *tmp_elem2 = lCopyElem(elem); lSetList(tmp_elem2, TEST_list, tmp_list2); lAppendElem(tmp_list1, tmp_elem2); } lSetList(tmp_elem1, TEST_list, tmp_list1); lAppendElem(tmp_list, tmp_elem1); } lSetList(tmp_elem, TEST_list, tmp_list); lAppendElem(list, tmp_elem); } list1 = lSelect("", list, NULL, what); /* EB: Replace this function */ #if 0 lWriteListTo(list1, stderr); #endif lFreeWhat(&what); lFreeElem(&elem); lFreeElem(&elem1); lFreeList(&list); lFreeList(&list1); return ret; }
int main(int argc, char *argv[]) { lListElem *queue, *copy; lList *queue_list; lList *answer_list = NULL; const lDescr *descr; spooling_field *fields; const char *filepath; int i; int width; char format[100]; lInit(nmv); queue = queue_create_template(); lSetString(queue, QU_terminate_method, "/tmp/myterminate_method.sh"); lAddSubStr(queue, CE_name, "foo", QU_suspend_thresholds, CE_Type); lAddSubStr(queue, CE_name, "bar", QU_suspend_thresholds, CE_Type); copy = lCreateElem(QU_Type); queue_list = lCreateList("queue_list", QU_Type); lAppendElem(queue_list, queue); lAppendElem(queue_list, copy); descr = lGetElemDescr(queue); fields = spool_get_fields_to_spool(&answer_list, QU_Type, &spool_config_instr); printf("\nthe following fields are spooled:"); for(i = 0; fields[i].nm != NoName; i++) { printf(" %s", lNm2Str(fields[i].nm)); } printf("\n"); spool_flatfile_align_object(&answer_list, fields); width = fields[0].width; printf("alignment for attribute names is %d\n", width); spool_flatfile_align_list(&answer_list, queue_list, fields); printf("field widths for list output is as follows:\n"); sprintf(format, "%%%ds: %%d\n", width); for(i = 0; fields[i].nm != NoName; i++) { printf(format, lNm2Str(fields[i].nm), fields[i].width); } filepath = spool_flatfile_write_object(&answer_list, queue, NULL, &spool_flatfile_instr_config, SP_DEST_STDOUT, SP_FORM_ASCII, NULL); if(filepath != NULL) { printf("\ndata successfully written to stdout\n"); FREE(filepath); } else { answer_list_print_err_warn(&answer_list, NULL, NULL); } printf("\n"); filepath = spool_flatfile_write_object(&answer_list, queue, NULL, &spool_flatfile_instr_config, SP_DEST_TMP, SP_FORM_ASCII, NULL); if(filepath != NULL) { printf("temporary file %s successfully written\n", filepath); sge_unlink(NULL, filepath); FREE(filepath); } else { answer_list_print_err_warn(&answer_list, NULL, NULL); } filepath = spool_flatfile_write_object(&answer_list, queue, NULL, &spool_flatfile_instr_config, SP_DEST_SPOOL, SP_FORM_ASCII, "test_sge_spooling_flatfile.dat"); if(filepath != NULL) { lListElem *reread_queue; printf("spool file %s successfully written\n", filepath); /* reread queue from file */ reread_queue = spool_flatfile_read_object(&answer_list, QU_Type, NULL, NULL, &spool_flatfile_instr_config, SP_FORM_ASCII, NULL, "test_sge_spooling_flatfile.dat"); if(reread_queue == NULL) { answer_list_print_err_warn(&answer_list, NULL, NULL); } else { lWriteElemTo(reread_queue, stdout); lFreeElem(&reread_queue); } sge_unlink(NULL, filepath); FREE(filepath); } else { answer_list_print_err_warn(&answer_list, NULL, NULL); } filepath = spool_flatfile_write_list(&answer_list, queue_list, NULL, &spool_flatfile_instr_config_list, SP_DEST_STDOUT, SP_FORM_ASCII, NULL); if(filepath != NULL) { printf("\ndata successfully written to stdout\n"); FREE(filepath); } else { answer_list_print_err_warn(&answer_list, NULL, NULL); } filepath = spool_flatfile_write_list(&answer_list, queue_list, NULL, &spool_flatfile_instr_config_list, SP_DEST_SPOOL, SP_FORM_ASCII, "test_sge_spooling_flatfile.dat"); if(filepath != NULL) { lList *reread_list; printf("spool file %s successfully written\n", filepath); reread_list = spool_flatfile_read_list(&answer_list, QU_Type, NULL, NULL, &spool_flatfile_instr_config_list, SP_FORM_ASCII, NULL, "test_sge_spooling_flatfile.dat"); if (reread_list == NULL) { answer_list_print_err_warn(&answer_list, NULL, NULL); } else { lWriteListTo(reread_list, stdout); lFreeList(&reread_list); } /* sge_unlink(NULL, filepath); */ FREE(filepath); } else { answer_list_print_err_warn(&answer_list, NULL, NULL); } /* test reading object */ /* test nonexisting filename */ /* test behaviour with NULL-pointer passed */ printf("\n\ntesting error handling, the next calls have to fail\n"); spool_flatfile_align_object(&answer_list, NULL); spool_flatfile_align_list(&answer_list, NULL, fields); spool_flatfile_align_list(&answer_list, queue_list, NULL); answer_list_print_err_warn(&answer_list, NULL, NULL); /* cleanup */ lFreeList(&queue_list); fields = spool_free_spooling_fields(fields); fprintf(stdout, "file handle stdout still alive\n"); fprintf(stderr, "file handle stderr still alive\n"); return EXIT_SUCCESS; }
/****** sge_manop_qmaster/sge_del_manop() ************************************** * NAME * sge_del_manop() -- delete manager or operator * * SYNOPSIS * int * sge_del_manop(sge_gdi_ctx_class_t *ctx, lListElem *ep, lList **alpp, * char *ruser, char *rhost, u_long32 target) * * FUNCTION * Deletes a manager or an operator from the corresponding master list. * * INPUTS * sge_gdi_ctx_class_t *ctx - gdi context * lListElem *ep - the manager/operator to delete * lList **alpp - answer list to return messages * char *ruser - user having triggered the action * char *rhost - host from which the action has been triggered * u_long32 target - SGE_UM_LIST or SGE_UO_LIST * * RESULT * int - STATUS_OK or STATUS_* error code * * NOTES * MT-NOTE: sge_del_manop() is MT safe - if we hold the global lock. *******************************************************************************/ int sge_del_manop(sge_gdi_ctx_class_t *ctx, lListElem *ep, lList **alpp, char *ruser, char *rhost, u_long32 target) { lListElem *found; int pos; const char *manop_name; const char *object_name; lList **lpp = NULL; int key = NoName; ev_event eve = sgeE_EVENTSIZE; DENTER(TOP_LAYER, "sge_del_manop"); if (ep == NULL || ruser == NULL || rhost == NULL) { CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC)); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EUNKNOWN); } switch (target) { case SGE_UM_LIST: lpp = object_type_get_master_list(SGE_TYPE_MANAGER); object_name = MSG_OBJ_MANAGER; key = UM_name; eve = sgeE_MANAGER_DEL; break; case SGE_UO_LIST: lpp = object_type_get_master_list(SGE_TYPE_OPERATOR); object_name = MSG_OBJ_OPERATOR; key = UO_name; eve = sgeE_OPERATOR_DEL; break; default : DPRINTF(("unknown target passed to %s\n", SGE_FUNC)); DRETURN(STATUS_EUNKNOWN); } /* ep is no manop element, if ep has no UM_name/UO_name */ if ((pos = lGetPosViaElem(ep, key, SGE_NO_ABORT)) < 0) { CRITICAL((SGE_EVENT, MSG_SGETEXT_MISSINGCULLFIELD_SS, lNm2Str(key), SGE_FUNC)); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EUNKNOWN); } manop_name = lGetPosString(ep, pos); if (manop_name == NULL) { CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC)); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EUNKNOWN); } /* prevent removing of root from man/op-list */ if (strcmp(manop_name, "root") == 0) { ERROR((SGE_EVENT, MSG_SGETEXT_MAY_NOT_REMOVE_USER_FROM_LIST_SS, "root", object_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } /* prevent removing the admin user from man/op-list */ if (strcmp(manop_name, ctx->get_admin_user(ctx)) == 0) { ERROR((SGE_EVENT, MSG_SGETEXT_MAY_NOT_REMOVE_USER_FROM_LIST_SS, ctx->get_admin_user(ctx), object_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } found = lGetElemStr(*lpp, key, manop_name); if (!found) { ERROR((SGE_EVENT, MSG_SGETEXT_DOESNOTEXIST_SS, object_name, manop_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } lDechainElem(*lpp, found); /* update on file */ if (!sge_event_spool(ctx, alpp, 0, eve, 0, 0, manop_name, NULL, NULL, NULL, NULL, NULL, true, true)) { ERROR((SGE_EVENT, MSG_CANTSPOOL_SS, object_name, manop_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EDISK, ANSWER_QUALITY_ERROR); /* chain in again */ lAppendElem(*lpp, found); DRETURN(STATUS_EDISK); } lFreeElem(&found); INFO((SGE_EVENT, MSG_SGETEXT_REMOVEDFROMLIST_SSSS, ruser, rhost, manop_name, object_name)); answer_list_add(alpp, SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO); DRETURN(STATUS_OK); }
/****** test_category/test() *************************************************** * NAME * test() -- executes one test including a performance test run * * SYNOPSIS * int test(data_entry_t *test, char *result, int count) * * INPUTS * data_entry_t *test - one test setup * char *result - expected category * int count - test number * * RESULT * int - 0 okay, 1 failed * * NOTES * MT-NOTE: test() is MT safe * *******************************************************************************/ static int test(data_entry_t *test, char *result, int count) { int ret = 0; lListElem *job_elem = NULL; lList *access_list = NULL; lList *project_list = NULL; lList *rqs_list = NULL; printf("\ntest %d:\n-------\n", test->test_nr); job_elem = test_create_job(test, 1); if (test->is_access_list == 1) { access_list = test_create_access(); } if (test->project) { project_list = test_create_project(test->project); } if (test->rqs) { rqs_list = test_create_rqs(); } if (job_elem != NULL) { dstring category_str = DSTRING_INIT; sge_build_job_category_dstring(&category_str, job_elem, access_list, project_list, NULL, rqs_list); printf("got : <%s>\n", sge_dstring_get_string(&category_str)!=NULL?sge_dstring_get_string(&category_str):"<NULL>"); if (result != NULL && sge_dstring_get_string(&category_str) != NULL) { if (strcmp(result, sge_dstring_get_string(&category_str)) == 0) { } else { ret = 1; printf("expected: <%s>\n", result!=NULL? result:"<NULL>"); } } else if (result == NULL && sge_dstring_get_string(&category_str) == NULL) { } else { ret = 1; printf("expected: <%s>\n", result!=NULL? result:"<NULL>"); } if (ret == 0) { int i; int max = 10000; printf(" => category outputs match\n"); lFreeElem(&job_elem); for (i = 1; i <= 500; i*=6) { printf("test with %dx :", i); job_elem = test_create_job(test, i); if (job_elem != NULL) { double time = test_performance(job_elem, max, access_list, NULL, rqs_list); if (time > 1) { max /= 10; } lFreeElem(&job_elem); } else { printf("failed to create job\n"); ret = 1; break; } } } else { printf(" => test failed\n"); } sge_dstring_free(&category_str); } else { printf("failed to create job for test %d\n", count); ret = 1; } lFreeElem(&job_elem); lFreeList(&access_list); lFreeList(&project_list); lFreeList(&rqs_list); return ret; }
/****** cull/dump_scan/lUndumpList() ****************************************** * NAME * lUndumpList() -- Reads a by lDumpList dumped dump * * SYNOPSIS * lList* lUndumpList(FILE *fp, const char *name, const lDescr *dp) * * FUNCTION * Reads a by lDumpList dumped dump into the memory. * * INPUTS * FILE *fp - file pointer * const char *name - new name of list or NULL if the old name in the * dumpfile should be used as listname * const lDescr *dp - new list descriptor or NULL if the old list * descriptor should be used as list descriptor * * RESULT * lList* - Read list * * NOTES * Actually a type/name matching is only performed for the list * itself and not for its sublists. * If an implementation of changed sublist descriptors is desired * we can probably use the following syntax for lUndumpList. * lList* lUndumpList(fp, name, formatstring, ...) * with formatstring like "%T(%I -> %T(%I->%T))" and the varargs * list: ".....", lDescr1, fieldname1, lDescr2, fieldname2, lDescr3 * or write a wrapper around lUndumpList which parses this format and * hands over the varargs list to lUndumpList ******************************************************************************/ lList *lUndumpList(FILE *fp, const char *name, const lDescr *dp) { lList *lp = NULL; lListElem *fep, *ep; lDescr *fdp = NULL; int i, j, nelem, n, k; int *found; char *oldname; DENTER(CULL_LAYER, "lUndumpList"); if (!fp) { LERROR(LEFILENULL); DRETURN(NULL); } /* read bra */ if (fGetBra(fp)) { printf("bra is missing\n"); LERROR(LESYNTAX); DRETURN(NULL); } /* read listname */ if (fGetString(fp, &oldname)) { printf("fGetString failed\n"); LERROR(LEFIELDREAD); DRETURN(NULL); } /* read number of elems */ if (fGetInt(fp, &nelem)) { printf("fGetInt failed\n"); LERROR(LEFIELDREAD); DRETURN(NULL); } /* read Descriptor from file */ if (!(fdp = lUndumpDescr(fp))) { LERROR(LEFGETDESCR); DRETURN(NULL); } if (!dp) /* dp is NULL, use lDescr from dumpfile */ dp = fdp; /* use old name (from file) if name is NULL */ if (!(lp = lCreateList((name) ? name : oldname, dp))) { FREE(fdp); LERROR(LECREATELIST); DRETURN(NULL); } free(oldname); /* fGetString strdup's */ if ((n = lCountDescr(dp)) <= 0) { LERROR(LECOUNTDESCR); FREE(fdp); lFreeList(&lp); DRETURN(NULL); } if (!(found = (int *) malloc(sizeof(int) * n))) { LERROR(LEMALLOC); FREE(fdp); lFreeList(&lp); DRETURN(NULL); } /* Initialize found array */ for (i = 0; i < n; i++) found[i] = -1; /* Here warnings are displayed if there are additional or missing fields */ for (j = 0; fdp[j].nm != NoName; j++) { for (i = 0; i < n; i++) { if (dp[i].nm == fdp[j].nm && dp[i].mt == fdp[j].mt) { if (found[i] != -1) DPRINTF(("lUndumpList: field %s found twice\n", lNm2Str(dp[i].nm))); found[i] = j; break; } } if (i == n) DPRINTF(("lUndumpList: field %s not needed\n", lNm2Str(fdp[j].nm))); } for (i = 0; i < n; i++) if (found[i] == -1) DPRINTF(("lUndumpList: field %s not found\n", lNm2Str(dp[i].nm))); /* LOOP OVER THE LIST ELEMENTS */ for (k = 0; k < nelem; k++) { if (!(fep = lUndumpElemFp(fp, fdp))) { LERROR(LEUNDUMPELEM); lFreeList(&lp); FREE(found); FREE(fdp); DRETURN(NULL); } if (!(ep = lCreateElem(dp))) { lFreeList(&lp); FREE(found); FREE(fdp); LERROR(LECREATEELEM); DRETURN(NULL); } for (i = 0; i < n; i++) { if (found[i] == -1) { continue; } else if (lCopySwitchPack(fep, ep, found[i], i, true, NULL, NULL) == -1) { lFreeList(&lp); lFreeElem(&ep); FREE(found); FREE(fdp); LERROR(LECOPYSWITCH); DRETURN(NULL); } } lFreeElem(&fep); if (lAppendElem(lp, ep) == -1) { lFreeList(&lp); lFreeElem(&ep); FREE(found); FREE(fdp); LERROR(LEAPPENDELEM); DRETURN(NULL); } } /* read ket */ if (fGetKet(fp)) { lFreeList(&lp); printf("ket is missing\n"); LERROR(LESYNTAX); } FREE(found); FREE(fdp); DRETURN(lp); }
/* * Delete configuration 'confp' from cluster configuration. * * TODO: A fix for IZ issue #79 is needed. For this to be done it may be * necessary to introduce something like 'protected' configuration entries. */ int sge_del_configuration(sge_gdi_ctx_class_t *ctx, lListElem *aConf, lList **anAnswer, char *aUser, char *aHost) { const char *tmp_name = NULL; char unique_name[CL_MAXHOSTLEN]; int ret = -1; DENTER(TOP_LAYER, "sge_del_configuration"); if (!aConf || !aUser || !aHost) { CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC)); answer_list_add(anAnswer, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EUNKNOWN); } if ((tmp_name = lGetHost(aConf, CONF_name)) == NULL) { CRITICAL((SGE_EVENT, MSG_SGETEXT_MISSINGCULLFIELD_SS, lNm2Str(CONF_name), SGE_FUNC)); answer_list_add(anAnswer, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EUNKNOWN); } /* * Due to CR 6319231 IZ 1760: * try to resolve the hostname * if it is not resolveable then * ignore this and use the hostname stored in the configuration obj * or use the given name if no object can be found */ ret = sge_resolve_hostname(tmp_name, unique_name, EH_name, sizeof(unique_name)); if (ret != CL_RETVAL_OK) { lListElem *conf_obj = NULL; DPRINTF(("%s: error %s resolving host %s\n", SGE_FUNC, cl_get_error_text(ret), tmp_name)); conf_obj = sge_get_configuration_for_host(tmp_name); if (conf_obj != NULL) { DPRINTF(("using hostname stored in configuration object\n")); strcpy(unique_name, lGetHost(conf_obj, CONF_name)); lFreeElem(&conf_obj); } else { ERROR((SGE_EVENT, MSG_SGETEXT_CANT_DEL_CONFIG2_S, tmp_name)); answer_list_add(anAnswer, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } } /* Do not allow to delete global configuration */ if (!strcasecmp(SGE_GLOBAL_NAME, unique_name)) { ERROR((SGE_EVENT, MSG_SGETEXT_CANT_DEL_CONFIG_S, unique_name)); answer_list_add(anAnswer, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } sge_event_spool(ctx, anAnswer, 0, sgeE_CONFIG_DEL, 0, 0, unique_name, NULL, NULL, NULL, NULL, NULL, true, true); remove_conf_by_name(unique_name); INFO((SGE_EVENT, MSG_SGETEXT_REMOVEDFROMLIST_SSSS, aUser, aHost, unique_name, MSG_OBJ_CONF )); answer_list_add(anAnswer, SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO); update_reschedule_unknown_timout_values(unique_name); /* invalidate cached configuration values */ mconf_set_new_config(true); DRETURN(STATUS_OK); }
/* * Read the cluster configuration from secondary storage using 'aSpoolContext'. * This is the bootstrap function for the configuration module. It does populate * the list with the cluster configuration. */ int sge_read_configuration(sge_gdi_ctx_class_t *ctx, lListElem *aSpoolContext, lList **config_list, lList *anAnswer) { lListElem *local = NULL; lListElem *global = NULL; int ret = -1; const char *cell_root = ctx->get_cell_root(ctx); const char *qualified_hostname = ctx->get_qualified_hostname(ctx); u_long32 progid = ctx->get_who(ctx); DENTER(TOP_LAYER, "sge_read_configuration"); SGE_LOCK(LOCK_MASTER_CONF, LOCK_WRITE); spool_read_list(&anAnswer, aSpoolContext, config_list, SGE_TYPE_CONFIG); /* * For Urubu (6.2u2) we won't have and update script. Therefore the master * has to be able to cope with a missing "jsv_url" string. * * TODO: Nethertheless we have to add the "jsv_url" to the update script * for the first release after Urubu. */ { lListElem *global = lGetElemHost(*config_list, CONF_name, "global"); if (global != NULL) { lList *entries = lGetList(global, CONF_entries); lListElem *jsv_url = lGetElemStr(entries, CF_name, "jsv_url"); if (jsv_url == NULL) { jsv_url = lAddSubStr(global, CF_name, "jsv_url", CONF_entries, CF_Type); if (jsv_url != NULL) { lSetString(jsv_url, CF_value, "none"); } } } } /* * For Urubu (6.2u2) we won't have and update script. Therefore the master * has to be able to cope with a missing "jsv_allowed_mod" string. * * TODO: Nethertheless we have to add the "jsv_allowed_mod" to the update * script for the first release after Urubu. */ { lListElem *global = lGetElemHost(*config_list, CONF_name, "global"); if (global != NULL) { lList *entries = lGetList(global, CONF_entries); lListElem *jsv_url = lGetElemStr(entries, CF_name, "jsv_allowed_mod"); if (jsv_url == NULL) { jsv_url = lAddSubStr(global, CF_name, "jsv_allowed_mod", CONF_entries, CF_Type); if (jsv_url != NULL) { lSetString(jsv_url, CF_value, "ac,h,i,e,o,j,M,N,p,w"); } } } } SGE_UNLOCK(LOCK_MASTER_CONF, LOCK_WRITE); answer_list_output(&anAnswer); DPRINTF(("qualified_hostname: '%s'\n", qualified_hostname)); if ((local = sge_get_configuration_for_host(qualified_hostname)) == NULL) { /* write a warning into messages file, if no local config exists*/ WARNING((SGE_EVENT, MSG_CONF_NOLOCAL_S, qualified_hostname)); } if ((global = sge_get_configuration_for_host(SGE_GLOBAL_NAME)) == NULL) { ERROR((SGE_EVENT, SFNMAX, MSG_CONF_NOGLOBAL)); DRETURN(-1); } ret = merge_configuration(&anAnswer, progid, cell_root, global, local, NULL); answer_list_output(&anAnswer); lFreeElem(&local); lFreeElem(&global); if (0 != ret) { ERROR((SGE_EVENT, MSG_CONFIG_ERRORXMERGINGCONFIGURATIONY_IS, ret, qualified_hostname)); DRETURN(-1); } sge_show_conf(); DRETURN(0); }
/****** gdi/sge/sge_qexecve() ************************************************ * NAME * sge_qexecve() -- start a task in a tightly integrated par. job * * SYNOPSIS * sge_tid_t sge_qexecve(const char *hostname, const char *queuename, * const char *cwd, const lList *environment * const lList *path_aliases) * * FUNCTION * Starts a task in a tightly integrated job. * Builds a job object describing the task, * connects to the commd on the targeted execution host, * deliveres the job object and waits for an answer. * The answer from the execution daemon on the execution host * contains a task id that is returned to the caller of the function. * * INPUTS * const char *hostname - name of the host on which to start the task * const lList *environment - list containing environment variable * settings for the task that override the * default environment * const lList *path_aliases - optional a path alias list * * RESULT * sge_tid_t - the task id, if the task can be executed, * a value <= 0 indicates an error. * * NOTES * MT-NOTE: sge_qexecve() is not MT safe ******************************************************************************/ sge_tid_t sge_qexecve(sge_gdi_ctx_class_t *ctx, const char *hostname, const char *queuename, const char *cwd, const lList *environment, const lList *path_aliases) { char myname[256]; const char *s; int ret, uid; sge_tid_t tid = NULL; lListElem *petrep; lListElem *rt; sge_pack_buffer pb; u_long32 jobid, jataskid; u_long32 dummymid = 0; const char *env_var_name = "SGE_TASK_ID"; DENTER(TOP_LAYER, "sge_qexecve"); if (hostname == NULL) { sprintf(lasterror, MSG_GDI_INVALIDPARAMETER_SS, "sge_qexecve", "hostname"); DRETURN(NULL); } /* resolve user */ if (sge_uid2user((uid=getuid()), myname, sizeof(myname)-1, MAX_NIS_RETRIES)) { sprintf(lasterror, MSG_GDI_RESOLVINGUIDTOUSERNAMEFAILED_IS , uid, strerror(errno)); DRETURN(NULL); } if ((s=getenv("JOB_ID")) == NULL) { sprintf(lasterror, MSG_GDI_MISSINGINENVIRONMENT_S, "JOB_ID"); DRETURN(NULL); } if (sscanf(s, sge_u32, &jobid) != 1) { sprintf(lasterror, MSG_GDI_STRINGISINVALID_SS, s, "JOB_ID"); DRETURN(NULL); } if ((s=getenv(env_var_name)) != NULL) { if (strcmp(s, "undefined") == 0) { jataskid = 1; } else { if (sscanf(s, sge_u32, &jataskid) != 1) { sprintf(lasterror, MSG_GDI_STRINGISINVALID_SS, s, env_var_name); DRETURN(NULL); } } } else { sprintf(lasterror, MSG_GDI_MISSINGINENVIRONMENT_S, env_var_name); DRETURN(NULL); } /* ---- build up pe task request structure (see gdilib/sge_petaskL.h) */ petrep = lCreateElem(PETR_Type); lSetUlong(petrep, PETR_jobid, jobid); lSetUlong(petrep, PETR_jataskid, jataskid); lSetString(petrep, PETR_owner, myname); lSetUlong(petrep, PETR_submission_time, sge_get_gmt()); if (cwd != NULL) { lSetString(petrep, PETR_cwd, cwd); } if (environment != NULL) { lSetList(petrep, PETR_environment, lCopyList("environment", environment)); } if (path_aliases != NULL) { lSetList(petrep, PETR_path_aliases, lCopyList("path_aliases", path_aliases)); } if (queuename != NULL) { lSetString(petrep, PETR_queuename, queuename); } if (init_packbuffer(&pb, 1024, 0) != PACK_SUCCESS) { lFreeElem(&petrep); sprintf(lasterror, SFNMAX, MSG_GDI_OUTOFMEMORY); DRETURN(NULL); } pack_job_delivery(&pb, petrep); ret = gdi2_send_message_pb(ctx, 1, prognames[EXECD], 1, hostname, TAG_JOB_EXECUTION, &pb, &dummymid); clear_packbuffer(&pb); lFreeElem(&petrep); if (ret != CL_RETVAL_OK) { sprintf(lasterror, MSG_GDI_SENDTASKTOEXECDFAILED_SS, hostname, cl_get_error_text(ret)); DRETURN(NULL); } /* add list into our remote task list */ rt = lAddElemStr(&remote_task_list, RT_tid, "none", RT_Type); lSetHost(rt, RT_hostname, hostname); lSetUlong(rt, RT_state, RT_STATE_WAIT4ACK); rcv_from_execd(ctx, OPT_SYNCHRON, TAG_JOB_EXECUTION); tid = (sge_tid_t) lGetString(rt, RT_tid); if (strcmp(tid, "none") == 0) { tid = NULL; sprintf(lasterror, MSG_GDI_EXECDONHOSTDIDNTACCEPTTASK_S, hostname); } /* now close message to execd */ cl_commlib_shutdown_handle(cl_com_get_handle("execd_handle", 0), false); DRETURN(tid); }
/****** qmaster/sge_mod_configuration() **************************************** * NAME * sge_mod_configuration() -- modify cluster configuration * * SYNOPSIS * int sge_mod_configuration(lListElem *aConf, lList **anAnswer, char *aUser, * char *aHost) * * FUNCTION * Modify cluster configuration. 'confp' is a pointer to a 'CONF_Type' list * element and does contain the modified configuration entry. Adding a new * configuration entry is also viewed as a modification. * * INPUTS * lListElem *aConf - CONF_Type element containing the modified conf * lList **anAnswer - answer list * char *aUser - target user * char *aHost - target host * * RESULT * int - 0 success * -1 error * * NOTES * MT-NOTE: sge_mod_configuration() is MT safe * *******************************************************************************/ int sge_mod_configuration(sge_gdi_ctx_class_t *ctx, lListElem *aConf, lList **anAnswer, char *aUser, char *aHost) { lListElem *old_conf; const char *tmp_name = NULL; char unique_name[CL_MAXHOSTLEN]; int ret = -1; const char *cell_root = ctx->get_cell_root(ctx); const char *qualified_hostname = ctx->get_qualified_hostname(ctx); u_long32 progid = ctx->get_who(ctx); DENTER(TOP_LAYER, "sge_mod_configuration"); if (!aConf || !aUser || !aHost) { CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC)); answer_list_add(anAnswer, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EUNKNOWN); } if ((tmp_name = lGetHost(aConf, CONF_name)) == NULL) { CRITICAL((SGE_EVENT, MSG_SGETEXT_MISSINGCULLFIELD_SS, lNm2Str(CONF_name), SGE_FUNC)); answer_list_add(anAnswer, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EUNKNOWN); } if ((ret = sge_resolve_hostname(tmp_name, unique_name, EH_name, sizeof(unique_name))) != CL_RETVAL_OK) { DPRINTF(("%s: error %s resolving host %s\n", SGE_FUNC, cl_get_error_text(ret), tmp_name)); ERROR((SGE_EVENT, MSG_SGETEXT_CANTRESOLVEHOST_S, tmp_name)); answer_list_add(anAnswer, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EUNKNOWN); } if ((ret = check_config(anAnswer, aConf))) { DRETURN(ret); } if ((old_conf = sge_get_configuration_for_host(unique_name)) != NULL) { int ret = -1; ret = do_mod_config(ctx, unique_name, old_conf, aConf, anAnswer); lFreeElem(&old_conf); if (ret == 0) { INFO((SGE_EVENT, MSG_SGETEXT_MODIFIEDINLIST_SSSS, aUser, aHost, unique_name, MSG_OBJ_CONF)); answer_list_add(anAnswer, SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO); } else { DRETURN(STATUS_EUNKNOWN); } } else { do_add_config(ctx, unique_name, aConf, anAnswer); INFO((SGE_EVENT, MSG_SGETEXT_ADDEDTOLIST_SSSS, aUser, aHost, unique_name, MSG_OBJ_CONF)); answer_list_add(anAnswer, SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO); } if (strcmp(SGE_GLOBAL_NAME, unique_name) == 0) { sge_add_event(0, sgeE_GLOBAL_CONFIG, 0, 0, NULL, NULL, NULL, NULL); } /* ** is the configuration change relevant for the qmaster itsself? ** if so, initialise conf struct anew */ if (strcmp(unique_name, SGE_GLOBAL_NAME) == 0 || sge_hostcmp(unique_name, qualified_hostname) == 0) { lListElem *local = NULL; lListElem *global = NULL; lList *answer_list = NULL; char* qmaster_params = NULL; int accounting_flush_time = mconf_get_accounting_flush_time(); if ((local = sge_get_configuration_for_host(qualified_hostname)) == NULL) { WARNING((SGE_EVENT, MSG_CONF_NOLOCAL_S, qualified_hostname)); } if ((global = sge_get_configuration_for_host(SGE_GLOBAL_NAME)) == NULL) { ERROR((SGE_EVENT, SFNMAX, MSG_CONF_NOGLOBAL)); } if (merge_configuration(&answer_list, progid, cell_root, global, local, NULL) != 0) { ERROR((SGE_EVENT, MSG_CONF_CANTMERGECONFIGURATIONFORHOST_S, qualified_hostname)); } answer_list_output(&answer_list); /* Restart the accounting flush event if needed. */ if ((accounting_flush_time == 0) && (mconf_get_accounting_flush_time() != 0)) { te_event_t ev = te_new_event(time(NULL), TYPE_ACCOUNTING_TRIGGER, ONE_TIME_EVENT, 1, 0, NULL); te_add_event(ev); te_free_event(&ev); } lFreeElem(&local); lFreeElem(&global); sge_show_conf(); /* 'max_unheard' may have changed */ cl_commlib_set_connection_param(cl_com_get_handle("qmaster", 1), HEARD_FROM_TIMEOUT, mconf_get_max_unheard()); /* fetching qmaster_params and begin to parse */ qmaster_params = mconf_get_qmaster_params(); /* updating the commlib paramterlist and gdi_timeout with new or changed parameters */ cl_com_update_parameter_list(qmaster_params); sge_free(&qmaster_params); } /* invalidate configuration cache */ mconf_set_new_config(true); DRETURN(STATUS_OK); }
/****** sge_select_queue/get_attribute() *************************************** * NAME * get_attribute() -- looks for an attribut, but only for one level (for host, global, or queue) * * SYNOPSIS * static lListElem* get_attribute(const char *attrname, lList *config_attr, * lList *actual_attr, lList *load_attr, lList *centry_list, lListElem * *queue, lListElem *rep, u_long32 layer, double lc_factor, dstring *reason) * * FUNCTION * Extracts the attribut specified with 'attrname' and finds the * more important one, if it is defined multiple times on the same * level. It only cares about one level. * If the attribute is a consumable, one can specify a point in time and a duration. * This will get the caller the min amount of that resource during the time frame. * * INPUTS * const char *attrname - attribute name one is looking for * lList *config_attr - user defined attributes (CE_Type) * lList *actual_attr - current usage of consumables (RUE_Type) * lList *load_attr - load attributes * lList *centry_list - the system wide attribute configuration * lListElem *queue - the current queue, or null, if one works on hosts * u_long32 layer - the current layer * double lc_factor - the load correction value * dstring *reason - space for error messages or NULL * bool zero_utilization - ??? * u_long32 start_time - begin of the time interval, one asks for the resource * u_long32 duration - the duration the interval * * RESULT * static lListElem* - the element one was looking for or NULL * *******************************************************************************/ lListElem* get_attribute(const char *attrname, lList *config_attr, lList *actual_attr, lList *load_attr, const lList *centry_list, lListElem *queue, u_long32 layer, double lc_factor, dstring *reason, bool zero_utilization, u_long32 start_time, u_long32 duration) { lListElem *actual_el=NULL; lListElem *load_el=NULL; lListElem *cplx_el=NULL; DENTER(BASIS_LAYER, "get_attribute"); /* resource_attr is a complex_entry (CE_Type) */ if (config_attr) { lListElem *temp = lGetElemStr(config_attr, CE_name, attrname); if (temp){ cplx_el = lCopyElem(lGetElemStr(centry_list, CE_name, attrname)); if(!cplx_el){ /* error */ DRETURN(NULL); } lSetUlong(cplx_el, CE_dominant, layer | DOMINANT_TYPE_FIXED); lSetUlong(cplx_el, CE_pj_dominant, DOMINANT_TYPE_VALUE); /* default, no value set */ lSetDouble(cplx_el, CE_doubleval, lGetDouble(temp,CE_doubleval) ); lSetString(cplx_el, CE_stringval, lGetString(temp,CE_stringval) ); } } if (cplx_el && lGetUlong(cplx_el, CE_consumable) != CONSUMABLE_NO) { lSetUlong(cplx_el, CE_pj_dominant, layer | DOMINANT_TYPE_CONSUMABLE); lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE); /* treat also consumables as fixed attributes when assuming an empty queuing system */ if (sconf_get_qs_state() == QS_STATE_FULL) { if (actual_attr && (actual_el = lGetElemStr(actual_attr, RUE_name, attrname))){ dstring ds; char as_str[20]; double utilized = zero_utilization ? 0 : utilization_max(actual_el, start_time, duration, false); switch (lGetUlong(cplx_el, CE_relop)) { case CMPLXGE_OP: case CMPLXGT_OP: lSetDouble(cplx_el, CE_pj_doubleval, utilized); break; case CMPLXEQ_OP: case CMPLXLT_OP: case CMPLXLE_OP: case CMPLXNE_OP: default: lSetDouble(cplx_el, CE_pj_doubleval, lGetDouble(cplx_el, CE_doubleval) - utilized); break; } sge_dstring_init(&ds, as_str, sizeof(as_str)); sge_dstring_sprintf(&ds, "%8.3f", (float)lGetDouble(cplx_el, CE_pj_doubleval)); lSetString(cplx_el,CE_pj_stringval, as_str); } else{ sge_dstring_sprintf(reason, MSG_ATTRIB_ACTUALELEMENTTOATTRIBXMISSING_S, attrname); lFreeElem(&cplx_el); DRETURN(NULL); } } else{ lSetDouble(cplx_el, CE_pj_doubleval, lGetDouble(cplx_el, CE_doubleval)); lSetString(cplx_el,CE_pj_stringval, lGetString(cplx_el, CE_stringval)); } } /** check for a load value */ if (load_attr && (load_el = lGetElemStr(load_attr, HL_name, attrname)) && (sconf_get_qs_state()==QS_STATE_FULL || lGetBool(load_el, HL_static)) && (!is_attr_prior(cplx_el, cplx_el))) { lListElem *ep_nproc=NULL; int nproc=1; if (!cplx_el){ cplx_el = lCopyElem(lGetElemStr(centry_list, CE_name, attrname)); if (!cplx_el){ /* error */ DRETURN(NULL); } lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE); lSetUlong(cplx_el, CE_pj_dominant, DOMINANT_TYPE_VALUE); } if ((ep_nproc = lGetElemStr(load_attr, HL_name, LOAD_ATTR_NUM_PROC))) { const char *cp = lGetString(ep_nproc, HL_value); if (cp) nproc = MAX(1, atoi(lGetString(ep_nproc, HL_value))); } { const char *load_value=NULL; u_long32 type; double dval; load_value = lGetString(load_el, HL_value); /* are we working on string values? if though, than it is easy */ if ( (type = lGetUlong(cplx_el, CE_valtype)) == TYPE_STR || type == TYPE_CSTR || type == TYPE_HOST || type == TYPE_RESTR) { lSetString(cplx_el, CE_stringval, load_value); lSetUlong(cplx_el, CE_dominant, layer | DOMINANT_TYPE_LOAD); } else { /* working on numerical values */ lListElem *job_load; char err_str[256]; char sval[100]; u_long32 dom_type = DOMINANT_TYPE_LOAD; lList *load_adjustments = sconf_get_job_load_adjustments(); job_load=lGetElemStr(load_adjustments, CE_name, attrname); if (parse_ulong_val(&dval, NULL, type, load_value, NULL, 0)) { sge_strlcpy(sval, load_value, 100); /* -------------------------------- look for 'name' in our load_adjustments list */ if (job_load) { const char *s; double load_correction; s = lGetString(job_load, CE_stringval); if (!parse_ulong_val(&load_correction, NULL, type, s, err_str, 255)) { ERROR((SGE_EVENT, MSG_SCHEDD_LOADADJUSTMENTSVALUEXNOTNUMERIC_S , attrname)); } else if (lc_factor) { double old_dval; u_long32 relop; if (!strncmp(attrname, "np_", 3) && nproc != 1 ) { DPRINTF(("fillComplexFromHost: dividing lc_factor for \"%s\" with value %f by %d to %f\n", attrname, lc_factor, nproc, lc_factor / nproc)); lc_factor /= nproc; } load_correction *= lc_factor; /* it depends on relop in complex config whether load_correction is pos/neg */ if ( (relop = lGetUlong(cplx_el, CE_relop)) == CMPLXGE_OP || relop == CMPLXGT_OP){ old_dval = dval; dval += load_correction; } else{ old_dval = dval; dval -= load_correction; } sprintf(sval, "%8.3f", dval); DPRINTF(("%s: uc: %f c(%f): %f\n", attrname, old_dval, lc_factor, dval)); dom_type = DOMINANT_TYPE_CLOAD; } } /* we can have a user, who wants to override the incomming load value. This is no problem for consumables, but for fixed values. A custom fixed value is a per slot value (stored in CE_doubleval) and a load value is a per job value (stored in CE_pj_doubleval). This code changes a fixed custom value from a per slot to a per job value!! */ if ( !(lGetUlong(cplx_el, CE_dominant) == DOMINANT_TYPE_VALUE) && (lGetUlong(cplx_el, CE_pj_dominant) == DOMINANT_TYPE_VALUE)){ lSetDouble(cplx_el, CE_pj_doubleval, lGetDouble(cplx_el, CE_doubleval)); lSetString(cplx_el, CE_pj_stringval, lGetString(cplx_el, CE_stringval)); lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE); lSetUlong(cplx_el, CE_pj_dominant, layer | DOMINANT_TYPE_FIXED); } if (!is_attr_prior2(cplx_el, dval, CE_pj_doubleval, CE_pj_dominant)){ lSetString(cplx_el, CE_pj_stringval, load_value); lSetUlong(cplx_el, CE_pj_dominant, layer | dom_type); lSetDouble(cplx_el, CE_pj_doubleval, dval ); } } /* end numerical load value */ lFreeList(&load_adjustments); }/* end block */ } } /* we are working on queue level, so we have to check for queue resource values */ if (queue){ bool created=false; if(!cplx_el){ cplx_el = lCopyElem(lGetElemStr(centry_list, CE_name, attrname)); if(!cplx_el){ /* error */ DRETURN(NULL); } lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE); lSetUlong(cplx_el, CE_pj_dominant, DOMINANT_TYPE_VALUE); created = true; } if (!get_queue_resource(cplx_el, queue, attrname) && created) { lFreeElem(&cplx_el); } } DRETURN(cplx_el); }
int main(int argc, char *argv[]) { int pos_tests_failed = 0; int neg_tests_failed = 0; int i = 0; lList *answer_list = NULL; filter_test_t positiv_test[] = { {"num_proc", 4}, {"$num_proc", 4}, {"$num_proc*2", 8}, {"$num_proc*0.5", 2.0}, {"num_proc*2", 8}, {"num_proc+1", 5}, {"$num_proc-2", 2}, {"$num_proc+0.1", 4.1}, {"1+$num_proc+0.1", 5.1}, {NULL, 0} }; filter_test_t negativ_test[] = { {"2*num_proc", 0}, {"2,0+num_proc", 0}, {"none", 0}, {NULL, 0} }; lList *centry_list; lList *host_centry_list; lListElem *centry; lListElem *host; DENTER_MAIN(TOP_LAYER, "test_sge_load_formula"); lInit(nmv); /* set up centry */ centry_list = lCreateList("", CE_Type); centry = lCreateElem(CE_Type); lSetString(centry, CE_name, "num_proc"); lSetString(centry, CE_stringval, "4"); lSetDouble(centry, CE_doubleval, 4); lAppendElem(centry_list, centry); /* set up host */ host_centry_list = lCreateList("", CE_Type); lAppendElem(host_centry_list, lCopyElem(centry)); host = lCreateElem(EH_Type); lSetList(host, EH_consumable_config_list, host_centry_list); for (i=0; ; i++){ double val; if (positiv_test[i].formula == NULL) { break; } if (!validate_load_formula(positiv_test[i].formula, &answer_list, centry_list, "load_formula")) { answer_list_output(&answer_list); pos_tests_failed++; } val = scaled_mixed_load(positiv_test[i].formula, NULL, host, centry_list); if (val != positiv_test[i].value) { printf("got %f, but expected %f(%g,%g)\n", val, positiv_test[i].value, val, positiv_test[i].value); pos_tests_failed++; } } for (i=0; ; i++){ if (negativ_test[i].formula == NULL) { break; } if (validate_load_formula(negativ_test[i].formula, &answer_list, centry_list, "load_formula") == true) { printf("load_formula \"%s\" returned no error\n", negativ_test[i].formula); neg_tests_failed++; } lFreeList(&answer_list); } lFreeList(¢ry_list); lFreeElem(&host); printf("\n"); printf("%d positiv test(s) failed\n", pos_tests_failed); printf("%d negativ test(s) failed\n", neg_tests_failed); DRETURN(pos_tests_failed + neg_tests_failed); }
/****** test_category/test_create_job() **************************************** * NAME * test_create_job() -- creates a job object * * SYNOPSIS * lListElem* test_create_job(data_entry_t *test, int count) * * FUNCTION * ??? * * INPUTS * data_entry_t *test - string representation of a job * int count - multiplier for the requests * * RESULT * lListElem* - NULL or valid job object * * NOTES * MT-NOTE: test_create_job() is MT safe * *******************************************************************************/ static lListElem *test_create_job(data_entry_t *test, int count) { lListElem *job = NULL; job = lCreateElem(JB_Type); if (job != NULL) { lSetUlong(job, JB_type, test->type); if (test->project != NULL) { lSetString(job, JB_project, test->project); } if (test->owner != NULL) { lSetString(job, JB_owner, test->owner); } if (test->group != NULL) { lSetString(job, JB_group, test->group); } if (test->checkpointing != NULL) { lSetString(job, JB_checkpoint_name, test->checkpointing); } if (test->hard_resource_list != NULL) { lList *requests = test_create_request(test->hard_resource_list, count); if (requests != NULL) { lSetList(job, JB_hard_resource_list, requests); } else { lFreeElem(&job); goto end; } } if (test->soft_resource_list != NULL) { lList *requests = test_create_request(test->soft_resource_list, count); if (requests != NULL) { lSetList(job, JB_soft_resource_list, requests); } else { lFreeElem(&job); goto end; } } if (test->hard_queue_list != NULL) { lList *queues = test_create_queue(test->hard_queue_list, count); if (queues != NULL) { lSetList(job, JB_hard_queue_list, queues); } else { lFreeElem(&job); goto end; } } if (test->hard_master_queue_list != NULL) { lList *queues = test_create_queue(test->hard_master_queue_list, count); if (queues != NULL) { lSetList(job, JB_master_hard_queue_list, queues); } else { lFreeElem(&job); goto end; } } if (test->pe != NULL) { test_create_pe(test->pe, job); } } end: return job; }
int main(int argc, char *argv[]) { lListElem *queue, *copy; const lDescr *descr; spooling_field *fields; dstring queue_str = DSTRING_INIT; dstring copy_str = DSTRING_INIT; lList *answer_list; int i; lInit(nmv); descr = QU_Type; copy = lCreateElem(descr); /* lWriteElemTo(queue, stdout); */ for(i = 0; mt_get_type(descr[i].mt) != lEndT; i++) { int nm; const char *name; const char *value, *reread_value; nm = descr[i].nm; name = lNm2Str(nm); value = object_append_field_to_dstring(queue, &answer_list, &queue_str, nm, '\0'); reread_value = NULL; if(value != NULL) { if(!object_parse_field_from_string(copy, &answer_list, nm, value)) { fprintf(stderr, "setting value for field %s failed\n", name); } else { reread_value = object_append_field_to_dstring(copy, &answer_list, ©_str, nm, '\0'); } } #if 1 printf("%s\t%s\t%s\n", name, value == NULL ? "<null>" : value, reread_value == NULL ? "<null>" : reread_value); #endif if(sge_strnullcmp(value, reread_value) != 0) { fprintf(stderr, "regression test for object_[gs]et_field_contents failed for attribute "SFQ": "SFQ" != "SFQ"\n", name, value != NULL ? value : "<null>", reread_value != NULL ? reread_value : "<null>"); } } fields = spool_get_fields_to_spool(&answer_list, QU_Type, &spool_config_instr); printf("\nthe following fields will be spooled:"); for(i = 0; fields[i].nm != NoName; i++) { printf(" %s", lNm2Str(fields[i].nm)); } printf("\n"); fields = spool_free_spooling_fields(fields); /* cleanup */ lFreeElem(&queue); lFreeElem(©); sge_dstring_free(&queue_str); sge_dstring_free(©_str); return EXIT_SUCCESS; }
/****** cull/dump_scan/lUndumpElemFp() ****************************************** * NAME * lUndumpElemFp() -- Read element from FILE stream * * SYNOPSIS * lListElem* lUndumpElemFp(FILE *fp, const lDescr *dp) * * FUNCTION * Read element from FILE stream * * INPUTS * FILE *fp - file stream * const lDescr *dp - descriptor * * RESULT * lListElem* - Read element ******************************************************************************/ lListElem *lUndumpElemFp(FILE *fp, const lDescr *dp) { lListElem *ep; int n, i; int ret = 0; char *str; u_long32 dummy; DENTER(CULL_LAYER, "lUndumpElemFp"); if (!fp) { LERROR(LEFILENULL); DEXIT; return NULL; } if (!dp) { LERROR(LEDESCRNULL); DEXIT; return NULL; } if (!(ep = lCreateElem(dp))) { LERROR(LECREATEELEM); DEXIT; return NULL; } if ((n = lCountDescr(dp)) <= 0) { LERROR(LECOUNTDESCR); lFreeElem(&ep); DEXIT; return NULL; } /* read bra */ if (fGetBra(fp)) { printf("bra is missing\n"); LERROR(LESYNTAX); lFreeElem(&ep); DEXIT; return NULL; } for (i = 0; i < n && ret == 0; i++) { switch (mt_get_type(dp[i].mt)) { case lIntT: ret = fGetInt(fp, &(ep->cont[i].i)); break; case lUlongT: ret = fGetUlong(fp, &(ep->cont[i].ul)); break; case lStringT: ret = fGetString(fp, &str); if (ret == 0) { lSetPosString(ep, i, str); free(str); /* fGetString strdup's */ } break; case lHostT: ret = fGetHost(fp, &str); if (ret == 0) { lSetPosHost(ep, i, str); free(str); /* fGetHost strdup's */ } break; case lFloatT: ret = fGetFloat(fp, &(ep->cont[i].fl)); break; case lDoubleT: ret = fGetDouble(fp, &(ep->cont[i].db)); break; case lLongT: ret = fGetLong(fp, &(ep->cont[i].l)); break; case lCharT: ret = fGetChar(fp, &(ep->cont[i].c)); break; case lBoolT: ret = fGetBool(fp, &(ep->cont[i].b)); break; case lRefT: /* we will not undump references! But we have to skip the line! */ ret = fGetUlong(fp, &dummy); ep->cont[i].ref = NULL; break; case lObjectT: ret = fGetObject(fp, &(ep->cont[i].obj)); break; case lListT: ret = fGetList(fp, &(ep->cont[i].glp)); break; default: lFreeElem(&ep); unknownType("lUndumpElemFp"); } } /* error handling for loop */ if (ret != 0) { lFreeElem(&ep); LERROR(LEFIELDREAD); DEXIT; return NULL; } /* read ket */ if (fGetKet(fp)) { lFreeElem(&ep); printf("ket is missing\n"); LERROR(LESYNTAX); DEXIT; return NULL; } DEXIT; return ep; }