示例#1
0
/****** sge_complex_schedd/is_attr_prior2() ************************************
*  NAME
*     is_attr_prior2() -- checks, if the set value in the structure has a higher priority
*     than the new one 
*
*  SYNOPSIS
*     static bool is_attr_prior2(lListElem *upper_el, double lower_value, int 
*     t_value, int t_dominant) 
*
*  FUNCTION
*     Computes the priority between a given structure and its values and a new value. This
*     is done on some basic rules. If the value is not set (dominant ==  DOMINANT_TYPE_VALUE)
*     or which relational opperator is used. If this is not enough, the two values are compared
*     and based on the opperator, it returns a true or false:
*     if no value is set in the structure: false
*     if the relops are == or != : true
*     if the relops are >= or > : true, when the new value is smaller than the old one
*     if the relops are <= or < : true, when the new value is bigger than the old one
*
*  INPUTS
*     lListElem *upper_el - target structure 
*     double lower_value  - new value 
*     int t_value         - which field to use (CE_doubleval or CE_pj_doubleval) 
*     int t_dominant      - which dominant field to use (CE_dominant, CE_pj_dominant) 
*
*  RESULT
*     static bool - true, if the value in the structure has the higher priority 
*
*******************************************************************************/
static bool is_attr_prior2(lListElem *upper_el, double lower_value, int t_value, int t_dominant ){
   u_long32 relop;
   u_long32 dom;
   bool ret;
   double upper_value;

   DENTER(BASIS_LAYER, "is_attr_prior2");

   if ((dom = lGetUlong(upper_el, t_dominant)) == 0 || (dom & DOMINANT_TYPE_VALUE) ){
      DRETURN(false);
   }

   relop = lGetUlong(upper_el, CE_relop);
   if ((relop == CMPLXEQ_OP || relop == CMPLXNE_OP)) {
      DRETURN(true);
   }

   upper_value = lGetDouble(upper_el, t_value); 

   if (relop == CMPLXGE_OP || relop == CMPLXGT_OP ){
      ret = upper_value >= lower_value ? true : false;
   } else {
      ret = upper_value <= lower_value ? true : false;
   }
   DRETURN(ret);
}
示例#2
0
/****** sgeobj/usage/usage_list_get_ulong_usage() *****************************
*  NAME
*     usage_list_get_ulong_usage() -- return ulong usage value
*
*  SYNOPSIS
*     u_long64
*     usage_list_get_ulong_usage(const lList *usage_list, const char *name, 
*                                u_long64 def)
*
*  FUNCTION
*     Searches for a usage object with the given name in the given usage
*     list. If such an element is found, returns the value of the 
*     usage object as u_long64 value.
*     If no such element is found, return the given default value.
*
*  INPUTS
*     const lList *usage_list - the usage list
*     const char *name        - name of the element to search
*     u_long64 def            - default value
*
*  RESULT
*     u_long64 - value of found object or default
*
*  SEE ALSO
*     gdi/usage/usage_list_get_double_usage()
*******************************************************************************/
u_long64
usage_list_get_ulong_usage(const lList *usage_list, const char *name,
                           u_long64 def)
{
   lListElem *ep = lGetElemStr(usage_list, UA_name, name);
   if (ep != NULL) {
      return (u_long64)lGetDouble(ep, UA_value);
   } else {
      return def;
   }
}
示例#3
0
/****** sgeobj/usage/usage_list_get_double_usage() ****************************
*  NAME
*     usage_list_get_double_usage() -- return double usage value
*
*  SYNOPSIS
*     double
*     usage_list_get_double_usage(const lList *usage_list, const char *name, 
*                                 double def) 
*
*  FUNCTION
*     Searches a usage object with the given name in the given usage 
*     list. If such an element is found, returns the value of the 
*     usage object as double value.
*     If no such element is found, return the given default value.
*
*  INPUTS
*     const lList *usage_list - the usage list
*     const char *name        - name of the element to search
*     double def              - default value
*
*  RESULT
*     double - value of found object or default
*
*  SEE ALSO
*     gdi/usage/usage_list_get_ulong_usage()
*******************************************************************************/
double
usage_list_get_double_usage(const lList *usage_list, const char *name,
                            double def)
{
   lListElem *ep = lGetElemStr(usage_list, UA_name, name);
   if(ep != NULL) {
      return lGetDouble(ep, UA_value);
   } else {
      return def;
   }
}
示例#4
0
/****** sge_orders/sge_create_orders() *****************************************
*  NAME
*     sge_create_orders() -- Create a new order-list or add orders to an existing one
*
*  SYNOPSIS
*     lList* sge_create_orders(lList *or_list, u_long32 type, lListElem *job, 
*     lListElem *ja_task, lList *granted, bool update_execd) 
*
*  FUNCTION
*     - If the or_list is NULL, a new one will be generated
*
*     - in case of a clear_pri order, teh ja_task is improtant. If NULL is put
*       in for ja_task, only the pendin tasks of the spedified job are set to NULL.
*       If a ja_task is put in, all tasks of the job are set to NULL
*
*  INPUTS
*     lList *or_list     - the order list
*     u_long32 type      - order type
*     lListElem *job     - job
*     lListElem *ja_task - ja_task ref or NULL(there is only one case, where it can be NULL)
*     lList *granted     - granted queue list
*     bool update_execd  - should the execd get new ticket values?
*
*  RESULT
*     lList* - returns the orderlist
*
*  NOTES
*     MT-NOTE: sge_create_orders() is MT safe 
*
*  SEE ALSO
*     ???/???
*******************************************************************************/
lList 
*sge_create_orders(lList *or_list, u_long32 type, lListElem *job, lListElem *ja_task,
                   lList *granted , bool update_execd) 
{
   lList *ql = NULL;
   lListElem *gel, *ep, *ep2;
   u_long32 qslots;
  
   DENTER(TOP_LAYER, "sge_create_orders");
   
   if (!job) {
      lFreeList(&or_list);
      DEXIT;
      return or_list;
   }

   /* create orders list if not existent */
   if (!or_list) {
      or_list = lCreateList("orderlist", OR_Type);
   }   

   /* build sublist of granted */
   if (update_execd) {
      for_each(gel, granted) {
         qslots = lGetUlong(gel, JG_slots);
         if (qslots) { /* ignore Qs with slots==0 */
            ep2=lCreateElem(OQ_Type);

            lSetUlong(ep2, OQ_slots, qslots);
            lSetString(ep2, OQ_dest_queue, lGetString(gel, JG_qname));
            lSetUlong(ep2, OQ_dest_version, lGetUlong(gel, JG_qversion));
            lSetDouble(ep2, OQ_ticket, lGetDouble(gel, JG_ticket));
            lSetDouble(ep2, OQ_oticket, lGetDouble(gel, JG_oticket));
            lSetDouble(ep2, OQ_fticket, lGetDouble(gel, JG_fticket));
            lSetDouble(ep2, OQ_sticket, lGetDouble(gel, JG_sticket));
            if (!ql)
               ql=lCreateList("orderlist",OQ_Type);
            lAppendElem(ql, ep2);
         }
      }
   }
示例#5
0
/****** sgeobj/report/job_report_print_usage() *******************************
*  NAME
*     job_report_print_usage() -- Print usage contained in job report 
*
*  SYNOPSIS
*     void job_report_print_usage(const lListElem *job_report, 
*                                 FILE *fp) 
*
*  FUNCTION
*     Print usage information conatines in "job_report". Print the 
*     information to the given file stream "fp" or as debug messages. 
*
*  INPUTS
*     const lListElem *job_report - JR_Type element 
*     FILE *fp                    - file stream or NULL 
******************************************************************************/
void job_report_print_usage(const lListElem *job_report, FILE *fp) 
{
   lListElem *uep;

   DENTER(TOP_LAYER, "job_report_print_usage");

   if (!job_report) {
      DEXIT;
      return;
   }

   for_each(uep, lGetList(job_report, JR_usage)) {
      if (fp) {
         fprintf(fp, "   \"%s\" =   %.99g\n", lGetString(uep, UA_name),
                 lGetDouble(uep, UA_value));
      } else {
         DPRINTF(("   \"%s\" =   %.99g\n", lGetString(uep, UA_name),
                  lGetDouble(uep, UA_value)));
      }
   }

   DEXIT;
   return;
}
示例#6
0
/****** sge_usage/usage_list_sum() *********************************************
*  NAME
*     usage_list_sum() -- sum up usage of two lists
*
*  SYNOPSIS
*     void 
*     usage_list_sum(lList *usage_list, const lList *add_usage_list) 
*
*  FUNCTION
*     Add the usage reported in add_usage_list to usage_list.
*     Summing up of usage will only be done for certain attributes:
*        - cpu
*        - io
*        - iow
*        - mem
*        - vmem
*        - maxvmem
*        - all ru_* attributes (see man getrusage.2)
*
*  INPUTS
*     lList *usage_list           - the usage list to contain all usage
*     const lList *add_usage_list - usage to add to usage_list
*
*  NOTES
*     MT-NOTE: usage_list_sum() is MT safe 
*******************************************************************************/
void
usage_list_sum(lList *usage_list, const lList *add_usage_list)
{
   const lListElem *usage;

   for_each(usage, add_usage_list) {
      const char *name = lGetString(usage, UA_name);
      /* Sum up all usage attributes. */
      if (strcmp(name, USAGE_ATTR_CPU) == 0 ||
          strcmp(name, USAGE_ATTR_IO) == 0 ||
          strcmp(name, USAGE_ATTR_IOW) == 0 ||
          strcmp(name, USAGE_ATTR_VMEM) == 0 ||
          strcmp(name, USAGE_ATTR_MEM) == 0 || 
          strncmp(name, "acct_", 5) == 0 ||
          strncmp(name, "ru_", 3) == 0) {
         lListElem *sum = lGetElemStr(usage_list, UA_name, name);
         if (sum == NULL) {
            lAppendElem(usage_list, lCopyElem(usage));
         } else {
            lAddDouble(sum, UA_value, lGetDouble(usage, UA_value));
         }
      }
   }
}
示例#7
0
/* if the scaled usage list does not yet exist, it is created and returned */
lList *scale_usage(
lList *scaling,     /* HS_Type */
lList *prev_usage,  /* HS_Type */
lList *scaled_usage /* UA_Type */
) {
   lListElem *sep, *ep, *prev;

   if (!scaling) {
      return NULL;
   }

   if (scaled_usage == NULL) {
      scaled_usage = lCreateList("usage", UA_Type);
   }

   for_each (ep, scaled_usage) {
      if ((sep=lGetElemStr(scaling, HS_name, lGetString(ep, UA_name)))) {
         lSetDouble(ep, UA_value, lGetDouble(ep, UA_value) * lGetDouble(sep, HS_value));
      }
   }

   if ((prev = lGetElemStr(prev_usage, UA_name, USAGE_ATTR_CPU)) != NULL) {
      if ((ep=lGetElemStr(scaled_usage, UA_name, USAGE_ATTR_CPU))) {
         lAddDouble(ep, UA_value, lGetDouble(prev, UA_value));
      } else {
         lAppendElem(scaled_usage, lCopyElem(prev));
      }
   }
   if ((prev = lGetElemStr(prev_usage, UA_name, USAGE_ATTR_IO)) != NULL) {
      if ((ep=lGetElemStr(scaled_usage, UA_name, USAGE_ATTR_IO))) {
         lAddDouble(ep, UA_value, lGetDouble(prev, UA_value));
      } else {
         lAppendElem(scaled_usage, lCopyElem(prev));
      }
   }
   if ((prev = lGetElemStr(prev_usage, UA_name, USAGE_ATTR_IOW)) != NULL) {
      if ((ep=lGetElemStr(scaled_usage, UA_name, USAGE_ATTR_IOW))) {
         lAddDouble(ep, UA_value, lGetDouble(prev, UA_value));
      } else {
         lAppendElem(scaled_usage, lCopyElem(prev));
      }
   }
   if ((prev = lGetElemStr(prev_usage, UA_name, USAGE_ATTR_VMEM)) != NULL) {
      if ((ep=lGetElemStr(scaled_usage, UA_name, USAGE_ATTR_VMEM))) {
         lAddDouble(ep, UA_value, lGetDouble(prev, UA_value));
      } else {
         lAppendElem(scaled_usage, lCopyElem(prev));
      }
   }
   if ((prev = lGetElemStr(prev_usage, UA_name, USAGE_ATTR_MAXVMEM)) != NULL) {
      if ((ep=lGetElemStr(scaled_usage, UA_name, USAGE_ATTR_MAXVMEM))) {
         lAddDouble(ep, UA_value, lGetDouble(prev, UA_value));
      } else {
         lAppendElem(scaled_usage, lCopyElem(prev));
      }
   }
   if ((prev = lGetElemStr(prev_usage, UA_name, USAGE_ATTR_MEM)) != NULL) {
      if ((ep=lGetElemStr(scaled_usage, UA_name, USAGE_ATTR_MEM))) {
         lAddDouble(ep, UA_value, lGetDouble(prev, UA_value));
      } else {
         lAppendElem(scaled_usage, lCopyElem(prev));
      }
   }

   return scaled_usage;
}
示例#8
0
/*-------------------------------------------------------------------------*/
void qmonSet2xN(
Widget w,
lList *lp,
int field1,
int field2 
) {
   lListElem *ep;
   int row;
   int max_rows;
   const char *col1 = NULL, *col2 = NULL;
   int val;
   double dval;
   char buf[128];
   
   DENTER(GUI_LAYER, "qmonSet2xN");
   
   /* clear the area */
   XtVaSetValues(w, XmNcells, NULL, NULL);
   
   if (!lp) {
      DEXIT;
      return;
   }
      
   XtVaGetValues(w, XmNrows, &max_rows, NULL);

   for (ep = lFirst(lp), row = 0; ep; ep = lNext(ep), row++) {
      if (row == max_rows) {
         XbaeMatrixAddRows(w, 
                           max_rows, 
                           NULL,       /* empty rows  */
                           NULL,       /* no lables   */
                           NULL,       /* no different colors */
                           1);         /* we add 1 rows      */
         max_rows++;
      }
      /*
      ** the first column of the matrix can be string or host type
      **
      */
      switch (lGetType(lGetListDescr(lp), field1)) {
         case lStringT:
            col1 = (StringConst)lGetString(ep, field1);
            break;
         case lHostT:
            col1 = (StringConst)lGetHost(ep,field1);
            break;
      }
      /*
      ** the second column can be of different type
      */
      switch (lGetType(lGetListDescr(lp), field2)) {
         case lStringT:
            col2 = (StringConst)lGetString(ep, field2);
            break;
         case lHostT:
            col2 = (StringConst)lGetHost(ep,field2);
            break;
         case lUlongT:
            val = (int)lGetUlong(ep, field2);
            if (val) {
               sprintf(buf, "%d", val);
               col2 = buf;
            }
            else
               col2 = NULL;
            break;
         case lDoubleT:
            dval = lGetDouble(ep, field2);
            sprintf(buf, "%.2f", dval);
            col2 = buf;
            break;
      }

      if (col1) {
         /* FIX_CONST_GUI */
         XbaeMatrixSetCell(w, row, 0 , col1 ? (String)col1 : "");
         /* FIX_CONST_GUI */
         XbaeMatrixSetCell(w, row, 1 , col2 ? (String)col2 : "");
      }
   }
       
   DEXIT;
}
示例#9
0
/*-------------------------------------------------------------------------*/
void qmonSetNxN(Widget w, lList *lp, int num_fields, ...)
{
   lListElem *ep;
   int i, row;
   int max_rows;
   int val;
   double dval;
   char buf[128];
   int *field;
   const char **col;
   va_list ap;
   
   DENTER(GUI_LAYER, "qmonSetNxN");
   
   /* clear the area */
   XtVaSetValues(w, XmNcells, NULL, NULL);
   
   if (!lp)
   {
      DEXIT;
      return;
   }

   field = malloc(num_fields*sizeof(int));
   col   = malloc(num_fields*sizeof(char *));
   if (field == NULL || col == NULL)
      abort();

   va_start(ap, num_fields);
   for(i=0; i<num_fields; i++)
      field[i] = va_arg(ap, int);

   XtVaGetValues(w, XmNrows, &max_rows, NULL);

   for (ep = lFirst(lp), row = 0; ep; ep = lNext(ep), row++)
   {
      if (row == max_rows)
      {
         XbaeMatrixAddRows(w, 
                           max_rows, 
                           NULL,       /* empty rows  */
                           NULL,       /* no lables   */
                           NULL,       /* no different colors */
                           1);         /* we add 1 rows      */
         max_rows++;
      }

      memset(col, 0, num_fields*sizeof(char *));

      /*
       * get column values
       */

      for(i=0; i<num_fields; i++)
      {
         switch (lGetType(lGetListDescr(lp), field[i]))
         {
            case lStringT:
               col[i] = (StringConst)lGetString(ep, field[i]);
               break;
            case lHostT:
               col[i] = (StringConst)lGetHost(ep,field[i]);
               break;
            case lUlongT:
               val = (int)lGetUlong(ep, field[i]);
#if 0
               if (val) {
                  sprintf(buf, "%d", val);
                  col[i] = buf;
               }
               else
                  col[i] = NULL;
#else
               sprintf(buf, "%d", val);
               col[i] = buf;
#endif
               break;
            case lDoubleT:
               dval = lGetDouble(ep, field[i]);
               sprintf(buf, "%.2f", dval);
               col[i] = buf;
               break;
         }
      }

      if (col[0])
      {
         /* FIX_CONST_GUI */
         for(i=0; i<num_fields; i++)
            XbaeMatrixSetCell(w, row, i, col[i] ? (String)col[i] : "");
      }
   }

   va_end(ap);
   free(field);
   free(col);
       
   DEXIT;
}
示例#10
0
/****** sge_select_queue/is_attr_prior() ***************************************
*  NAME
*     is_attr_prior() -- compares two attribut instances with each other 
*
*  SYNOPSIS
*     static bool is_attr_prior(lListElem *upper_el, lListElem *lower_el) 
*
*  FUNCTION
*     checks if the first given attribut instance has a higher priority than
*     second instance.
*     if the first is NULL, it returns false
*     if the second or the second and first is NULL, it returns true
*     if the "==" or "!=" operators are used, it is true
*     if both are the same, it may returns false. 
*     otherwise it computes the minimum or maximum between the values. 
*
*  INPUTS
*     lListElem *upper_el - attribut, which should be overridden by the second one. 
*     lListElem *lower_el - attribut, which want to override the first one. 
*
*  RESULT
*     static bool - true, when the first attribut has a higher priority.
*
*******************************************************************************/
bool is_attr_prior(lListElem *upper_el, lListElem *lower_el){
   u_long32 relop;
   bool ret;
   double upper_value;
   double lower_value;
   u_long32 dom;
   u_long32 used_dom;
   u_long32 used_dom_val;
   u_long32 used_dom_str;

   u_long32 unused_dom_val;
   u_long32 unused_dom_str;
   u_long32 unused_dom;

   DENTER(BASIS_LAYER, "is_attr_prior");

   /* the order is important must not be changed */   
   if(!upper_el){
      DRETURN(false);
   }
   if(!lower_el){
      DRETURN(true);
   }

   relop = lGetUlong(upper_el, CE_relop);
   if ((relop == CMPLXEQ_OP || relop == CMPLXNE_OP)) {
      DRETURN(true);
  }

   /* if both elements are the same, than I can not say which one is more important */
   if(upper_el == lower_el) {
      DRETURN(false);
   }   

   if ((dom = lGetUlong(upper_el, CE_pj_dominant)) == 0 || (dom & DOMINANT_TYPE_VALUE) ){
      used_dom_val = CE_doubleval;
      used_dom_str = CE_stringval;      
      used_dom = CE_dominant;

      unused_dom_val = CE_pj_doubleval;
      unused_dom_str= CE_pj_stringval;
      unused_dom = CE_pj_dominant;
   }
   else {
      used_dom_val = CE_pj_doubleval;
      used_dom_str = CE_pj_stringval;      
      used_dom = CE_pj_dominant;

      unused_dom_val = CE_doubleval;
      unused_dom_str = CE_stringval;
      unused_dom = CE_dominant;
   }

   if ((dom = lGetUlong(lower_el, used_dom)) == 0 || (dom & DOMINANT_TYPE_VALUE) ){
      lSetDouble(lower_el, used_dom_val, lGetDouble(lower_el, unused_dom_val));
      lSetString(lower_el, used_dom_str, lGetString(lower_el, unused_dom_str));
      lSetUlong(lower_el, used_dom, lGetUlong(lower_el, unused_dom));
      lSetUlong(lower_el, unused_dom, DOMINANT_TYPE_VALUE);
   }

   upper_value = lGetDouble(upper_el, used_dom_val);
   lower_value = lGetDouble(lower_el, used_dom_val);

   if (relop == CMPLXGE_OP || relop == CMPLXGT_OP ){
      ret = upper_value >= lower_value ? true : false;
   } else {
      ret = upper_value <= lower_value ? true : false;
   }

   DRETURN(ret);
}
示例#11
0
/****** 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);
}
示例#12
0
/****** qquota_output/qquota_output() ********************************************
*  NAME
*     qquota_output() -- qquota output function
*
*  SYNOPSIS
*     bool qquota_output(void *ctx, lList *host_list, lList *resource_match_list, 
*     lList *user_list, lList *pe_list, lList *project_list, lList 
*     *cqueue_list, lList **alpp, report_handler_t* report_handler) 
*
*  FUNCTION
*     print resource quota rule and the limit
*
*  INPUTS
*     void *ctx                        - gdi handler
*     lList *host_list                 - selected hosts
*     lList *resource_match_list       - selected resources
*     lList *user_list                 - selected users
*     lList *pe_list                   - selecte pes
*     lList *project_list              - selected projects
*     lList *cqueue_list               - selected cluster queues
*     lList **alpp                     - answer list
*     report_handler_t* report_handler - report handler for xml output
*
*  RESULT
*     bool - true on success
*            false on error
*
*  NOTES
*     MT-NOTE: qquota_output() is MT safe 
*
*******************************************************************************/
bool qquota_output(sge_gdi_ctx_class_t *ctx, lList *host_list, lList *resource_match_list, lList *user_list,
                 lList *pe_list, lList *project_list, lList *cqueue_list, lList **alpp,
                 report_handler_t* report_handler) 
{
   lList *rqs_list = NULL;
   lList *centry_list = NULL;
   lList *userset_list = NULL;
   lList *hgroup_list = NULL;
   lList *exechost_list = NULL;

   lListElem* global_host = NULL;
   lListElem* exec_host = NULL;
   lList* printed_rules = NULL;  /* Hash list of already printed resource quota rules (possible with -u user1,user2,user3...) */

   bool ret = true;
   int xml_ret = 0;

   qquota_filter_t qquota_filter = { "*",
                                     "*",
                                     "*",
                                     "*",
                                     "*" };

   dstring rule_name = DSTRING_INIT;

   DENTER(TOP_LAYER, "qquota_output");

   /* If no user is requested on command line we set the current user as default */
   qquota_filter.user = ctx->get_username(ctx);

   ret = get_all_lists(ctx, &rqs_list, &centry_list, &userset_list, &hgroup_list, &exechost_list, host_list, alpp);

   if (ret == true) {
      lListElem *rqs = NULL;
      printed_rules = lCreateList("rule_hash", ST_Type); 
      global_host = host_list_locate(exechost_list, SGE_GLOBAL_NAME);

      if (report_handler != NULL) {
         xml_ret = report_handler->report_started(report_handler, alpp);
         if (xml_ret != QQUOTA_SUCCESS) {
            ret = false;
            goto qquota_output_error;
         }
      }

      for_each(rqs, rqs_list) {
         lListElem *rule = NULL;
         int rule_count = 1;

         if (lGetBool(rqs, RQS_enabled) == false) {
            continue;
         }

         for_each(rule, lGetList(rqs, RQS_rule)) { 
            lListElem *user_ep = lFirst(user_list);
            lListElem *project_ep = lFirst(project_list);
            lListElem *pe_ep = lFirst(pe_list);
            lListElem *queue_ep = lFirst(cqueue_list);
            lListElem *host_ep = lFirst(host_list);
            do {
               if (user_ep != NULL) {
                  qquota_filter.user = lGetString(user_ep, ST_name);
               }
               do {
                  if (project_ep != NULL) {
                     qquota_filter.project = lGetString(project_ep, ST_name);
                  }
                  do {
                     if (pe_ep != NULL) {
                        qquota_filter.pe = lGetString(pe_ep, ST_name);
                     }
                     do {
                        if (queue_ep != NULL) {
                           qquota_filter.queue = lGetString(queue_ep, ST_name);
                        }
                        do {
                           if (host_ep != NULL) {
                              qquota_filter.host = lGetString(host_ep, ST_name);
                           }
                         
                           if (rqs_is_matching_rule(rule, qquota_filter.user, NULL, qquota_filter.project,
                                                     qquota_filter.pe, qquota_filter.host,
                                                     qquota_filter.queue, userset_list, hgroup_list)) {
                              lListElem *limit = NULL;

                              for_each(limit, lGetList(rule, RQR_limit)) {
                                 const char *limit_name = lGetString(limit, RQRL_name);
                                 lList *rue_list = lGetList(limit, RQRL_usage);
                                 lListElem *raw_centry = centry_list_locate(centry_list, limit_name);
                                 lListElem *rue_elem = NULL;

                                 if (raw_centry == NULL) {
                                    /* undefined centries can be ignored */
                                    DPRINTF(("centry %s not defined -> IGNORING\n", limit_name));
                                    continue;
                                 }

                                 if ((resource_match_list != NULL) && 
                                     ((centry_list_locate(resource_match_list, limit_name) == NULL) &&
                                     (centry_list_locate(resource_match_list, lGetString(raw_centry, CE_shortcut)) == NULL))) {
                                    DPRINTF(("centry %s was not requested on CLI -> IGNORING\n", limit_name));
                                    continue;
                                 }

                                 if (lGetString(rule, RQR_name)) {
                                    sge_dstring_sprintf(&rule_name, "%s/%s", lGetString(rqs, RQS_name), lGetString(rule, RQR_name));
                                 } else {
                                    sge_dstring_sprintf(&rule_name, "%s/%d", lGetString(rqs, RQS_name), rule_count);
                                 }

                                 if (lGetUlong(raw_centry, CE_consumable)) {
                                    /* for consumables we need to walk through the utilization and search for matching values */
                                    DPRINTF(("found centry %s - consumable\n", limit_name));
                                    for_each(rue_elem, rue_list) {
                                       u_long32 dominant = 0;
                                       const char *rue_name = lGetString(rue_elem, RUE_name);
                                       char *cp = NULL;
                                       stringT user, project, pe, queue, host;
                                       dstring limit_str = DSTRING_INIT; 
                                       dstring value_str = DSTRING_INIT;
                                       qquota_filter_t qf = { NULL, NULL, NULL, NULL, NULL };

                                       /* check user name */
                                       cp = qquota_get_next_filter(user, rue_name);
                                       /* usergroups have the same beginning character @ as host groups */
                                       if (is_hgroup_name(qquota_filter.user)) {
                                          lListElem *ugroup = NULL;

                                          if ((ugroup = userset_list_locate(userset_list, &qquota_filter.user[1])) != NULL) {
                                             if (sge_contained_in_access_list(user, NULL, ugroup, NULL) == 0) {
                                                continue;
                                             }
                                          }
                                       } else {
                                          if ((strcmp(user, "-") != 0) && (strcmp(qquota_filter.user, "*") != 0)
                                               && (fnmatch(qquota_filter.user, user, 0) != 0)) {
                                             continue;
                                          }
                                       }

                                       /* check project */
                                       cp = qquota_get_next_filter(project, cp);
                                       if ((strcmp(project, "-") != 0) && (strcmp(qquota_filter.project, "*") != 0) 
                                             && (fnmatch(qquota_filter.project, project, 0) != 0)) {
                                          continue;
                                       }
                                       /* check parallel environment */
                                       cp = qquota_get_next_filter(pe, cp);
                                       if ((strcmp(pe, "-") != 0) && (strcmp(qquota_filter.pe, "*") != 0) &&
                                           (fnmatch(qquota_filter.pe, pe, 0) != 0) ) {
                                          continue;
                                       }
                                       /* check cluster queue */
                                       cp = qquota_get_next_filter(queue, cp);
                                       if ((strcmp(queue, "-") != 0) && (strcmp(qquota_filter.queue, "*") != 0) &&
                                           (fnmatch(qquota_filter.queue, queue, 0) != 0)) {
                                          continue;
                                       }
                                       /* check host name */
                                       cp = qquota_get_next_filter(host, cp);
                                       if (is_hgroup_name(qquota_filter.host)) {
                                          lListElem *hgroup = NULL;

                                          if ((hgroup = hgroup_list_locate(hgroup_list, qquota_filter.host)) != NULL) {
                                             lList *host_list = NULL;
                                             hgroup_find_all_references(hgroup, NULL, hgroup_list, &host_list, NULL);
                                             if (host_list == NULL && lGetElemHost(host_list, HR_name, host) == NULL) {
                                                lFreeList(&host_list);
                                                continue;
                                             }
                                             lFreeList(&host_list);
                                          }
                                       } else {
                                          if ((strcmp(host, "-") != 0) && (strcmp(qquota_filter.host, "*") != 0) &&
                                              (fnmatch(qquota_filter.host, host, 0) != 0) ) {
                                             continue;
                                          }
                                       }
                                       if (lGetBool(limit, RQRL_dynamic)) {
                                          exec_host = host_list_locate(exechost_list, host); 
                                          sge_dstring_sprintf(&limit_str, "%d", (int)scaled_mixed_load(lGetString(limit, RQRL_value),
                                                                                                       global_host, exec_host, centry_list));

                                       } else {
                                          lSetDouble(raw_centry, CE_pj_doubleval, lGetDouble(limit, RQRL_dvalue));
                                          sge_get_dominant_stringval(raw_centry, &dominant, &limit_str);
                                       }

                                       lSetDouble(raw_centry,CE_pj_doubleval, lGetDouble(rue_elem, RUE_utilized_now));
                                       sge_get_dominant_stringval(raw_centry, &dominant, &value_str);

                                       qf.user = user;
                                       qf.project = project;
                                       qf.pe = pe;
                                       qf.queue = queue;
                                       qf.host = host;
                                       ret = qquota_print_out_rule(rule, rule_name, limit_name, 
                                                                   sge_dstring_get_string(&value_str), sge_dstring_get_string(&limit_str),
                                                                   qf, raw_centry, report_handler, printed_rules, alpp);

                                       sge_dstring_free(&limit_str);
                                       sge_dstring_free(&value_str);
                                    }
                                 } else {
                                    /* static values */
                                    qquota_filter_t qf = { NULL, NULL, NULL, NULL, NULL };

                                    DPRINTF(("found centry %s - static value\n", limit_name));
                                    ret = qquota_print_out_rule(rule, rule_name, limit_name, 
                                                                NULL, lGetString(limit, RQRL_value),
                                                                qf, raw_centry, report_handler, printed_rules, alpp);

                                 }
                              }
                           }
                        } while ((host_ep = lNext(host_ep)));
                     } while ((queue_ep = lNext(queue_ep)));
                  } while ((pe_ep = lNext(pe_ep)));
               } while ((project_ep = lNext(project_ep)));