~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/clients/common/sge_qquota.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*___INFO__MARK_BEGIN__*/
 
2
/*************************************************************************
 
3
 * 
 
4
 *  The Contents of this file are made available subject to the terms of
 
5
 *  the Sun Industry Standards Source License Version 1.2
 
6
 * 
 
7
 *  Sun Microsystems Inc., March, 2001
 
8
 * 
 
9
 * 
 
10
 *  Sun Industry Standards Source License Version 1.2
 
11
 *  =================================================
 
12
 *  The contents of this file are subject to the Sun Industry Standards
 
13
 *  Source License Version 1.2 (the "License"); You may not use this file
 
14
 *  except in compliance with the License. You may obtain a copy of the
 
15
 *  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
 
16
 * 
 
17
 *  Software provided under this License is provided on an "AS IS" basis,
 
18
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 
19
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 
20
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 
21
 *  See the License for the specific provisions governing your rights and
 
22
 *  obligations concerning the Software.
 
23
 * 
 
24
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
25
 * 
 
26
 *   Copyright: 2001 by Sun Microsystems, Inc.
 
27
 * 
 
28
 *   All Rights Reserved.
 
29
 * 
 
30
 ************************************************************************/
 
31
/*___INFO__MARK_END__*/
 
32
#include <stdlib.h>
 
33
#include <string.h>
 
34
#include <sys/stat.h>
 
35
#include <limits.h>
 
36
#include <math.h>
 
37
#include <float.h>
 
38
#include <fnmatch.h>
 
39
 
 
40
#include "rmon/sgermon.h"
 
41
 
 
42
#include "comm/commlib.h"
 
43
 
 
44
#include "uti/sge_profiling.h"
 
45
#include "uti/setup_path.h"
 
46
#include "uti/sge_string.h"
 
47
#include "uti/sge_hostname.h"
 
48
#include "uti/sge_log.h"
 
49
#include "uti/sge_unistd.h"
 
50
#include "uti/sge_stdlib.h"
 
51
#include "uti/sge_prog.h"
 
52
#include "uti/sge_bootstrap.h"
 
53
#include "uti/sge_parse_num_par.h"
 
54
 
 
55
#include "sched/sort_hosts.h"
 
56
#include "sched/load_correction.h"
 
57
#include "sched/sge_complex_schedd.h"
 
58
#include "sched/sge_select_queue.h"
 
59
 
 
60
#include "sgeobj/parse.h"
 
61
#include "sgeobj/sge_schedd_conf.h"
 
62
#include "sgeobj/cull_parse_util.h"
 
63
#include "sgeobj/sge_conf.h"
 
64
#include "sgeobj/sge_range.h"
 
65
#include "sgeobj/sge_resource_quota.h"
 
66
#include "sgeobj/sge_hgroup.h"
 
67
#include "sgeobj/sge_userset.h"
 
68
#include "sgeobj/sge_host.h"
 
69
#include "sgeobj/sge_answer.h"
 
70
#include "sgeobj/sge_qinstance.h"
 
71
#include "sgeobj/sge_qinstance_state.h"
 
72
#include "sgeobj/sge_qinstance_type.h"
 
73
#include "sgeobj/sge_ulong.h"
 
74
#include "sgeobj/sge_centry.h"
 
75
#include "sgeobj/sge_feature.h"
 
76
#include "sgeobj/sge_all_listsL.h"
 
77
 
 
78
#include "gdi/sge_gdi.h"
 
79
#include "gdi/sge_gdi_ctx.h"
 
80
 
 
81
#include "basis_types.h"
 
82
#include "sig_handlers.h"
 
83
#include "qstat_printing.h"
 
84
#include "sge_mt_init.h"
 
85
#include "sge_qstat.h"
 
86
#include "sge_qquota.h"
 
87
#include "sge.h"
 
88
 
 
89
#include "msg_common.h"
 
90
#include "msg_clients_common.h"
 
91
 
 
92
#define HEAD_FORMAT "%-18s %-20.20s %s\n"
 
93
 
 
94
typedef struct {
 
95
   const char* user;
 
96
   const char* project;
 
97
   const char* pe;
 
98
   const char* queue;
 
99
   const char* host;
 
100
} qquota_filter_t;
 
101
 
 
102
static bool get_all_lists(sge_gdi_ctx_class_t *ctx, lList **rqs_l, lList **centry_l, lList **userset_l, lList **hgroup_l, lList **exechost_l, lList *hostref_list, lList **alpp);
 
103
 
 
104
static char *qquota_get_next_filter(stringT filter, const char *cp);
 
105
static bool qquota_print_out_rule(lListElem *rule, dstring rule_name, const char *limit_name,
 
106
                                  const char *usage_value, const char *limit_value, qquota_filter_t filter,
 
107
                                  lListElem *centry, report_handler_t* report_handler, lList *printed_rules, lList **alpp);
 
108
 
 
109
static bool qquota_print_out_filter(lListElem *filter, const char *name, const char *value, dstring *buffer, report_handler_t *report_handler, lList **alpp);
 
110
 
 
111
/****** qquota_output/qquota_output() ********************************************
 
112
*  NAME
 
113
*     qquota_output() -- qquota output function
 
114
*
 
115
*  SYNOPSIS
 
116
*     bool qquota_output(void *ctx, lList *host_list, lList *resource_match_list, 
 
117
*     lList *user_list, lList *pe_list, lList *project_list, lList 
 
118
*     *cqueue_list, lList **alpp, report_handler_t* report_handler) 
 
119
*
 
120
*  FUNCTION
 
121
*     print resource quota rule and the limit
 
122
*
 
123
*  INPUTS
 
124
*     void *ctx                        - gdi handler
 
125
*     lList *host_list                 - selected hosts
 
126
*     lList *resource_match_list       - selected resources
 
127
*     lList *user_list                 - selected users
 
128
*     lList *pe_list                   - selecte pes
 
129
*     lList *project_list              - selected projects
 
130
*     lList *cqueue_list               - selected cluster queues
 
131
*     lList **alpp                     - answer list
 
132
*     report_handler_t* report_handler - report handler for xml output
 
133
*
 
134
*  RESULT
 
135
*     bool - true on success
 
136
*            false on error
 
137
*
 
138
*  NOTES
 
139
*     MT-NOTE: qquota_output() is MT safe 
 
140
*
 
141
*******************************************************************************/
 
142
bool qquota_output(sge_gdi_ctx_class_t *ctx, lList *host_list, lList *resource_match_list, lList *user_list,
 
143
                 lList *pe_list, lList *project_list, lList *cqueue_list, lList **alpp,
 
144
                 report_handler_t* report_handler) 
 
145
{
 
146
   lList *rqs_list = NULL;
 
147
   lList *centry_list = NULL;
 
148
   lList *userset_list = NULL;
 
149
   lList *hgroup_list = NULL;
 
150
   lList *exechost_list = NULL;
 
151
 
 
152
   lListElem* global_host = NULL;
 
153
   lListElem* exec_host = NULL;
 
154
   lList* printed_rules = NULL;  /* Hash list of already printed resource quota rules (possible with -u user1,user2,user3...) */
 
155
 
 
156
   bool ret = true;
 
157
   int xml_ret = 0;
 
158
 
 
159
   qquota_filter_t qquota_filter = { "*",
 
160
                                     "*",
 
161
                                     "*",
 
162
                                     "*",
 
163
                                     "*" };
 
164
 
 
165
   dstring rule_name = DSTRING_INIT;
 
166
 
 
167
   DENTER(TOP_LAYER, "qquota_output");
 
168
 
 
169
   /* If no user is requested on command line we set the current user as default */
 
170
   qquota_filter.user = ctx->get_username(ctx);
 
171
 
 
172
   ret = get_all_lists(ctx, &rqs_list, &centry_list, &userset_list, &hgroup_list, &exechost_list, host_list, alpp);
 
173
 
 
174
   if (ret == true) {
 
175
      lListElem *rqs = NULL;
 
176
      printed_rules = lCreateList("rule_hash", ST_Type); 
 
177
      global_host = host_list_locate(exechost_list, SGE_GLOBAL_NAME);
 
178
 
 
179
      if (report_handler != NULL) {
 
180
         xml_ret = report_handler->report_started(report_handler, alpp);
 
181
         if (xml_ret != QQUOTA_SUCCESS) {
 
182
            ret = false;
 
183
            goto qquota_output_error;
 
184
         }
 
185
      }
 
186
 
 
187
      for_each(rqs, rqs_list) {
 
188
         lListElem *rule = NULL;
 
189
         int rule_count = 1;
 
190
 
 
191
         if (lGetBool(rqs, RQS_enabled) == false) {
 
192
            continue;
 
193
         }
 
194
 
 
195
         for_each(rule, lGetList(rqs, RQS_rule)) { 
 
196
            lListElem *user_ep = lFirst(user_list);
 
197
            lListElem *project_ep = lFirst(project_list);
 
198
            lListElem *pe_ep = lFirst(pe_list);
 
199
            lListElem *queue_ep = lFirst(cqueue_list);
 
200
            lListElem *host_ep = lFirst(host_list);
 
201
            do {
 
202
               if (user_ep != NULL) {
 
203
                  qquota_filter.user = lGetString(user_ep, ST_name);
 
204
               }
 
205
               do {
 
206
                  if (project_ep != NULL) {
 
207
                     qquota_filter.project = lGetString(project_ep, ST_name);
 
208
                  }
 
209
                  do {
 
210
                     if (pe_ep != NULL) {
 
211
                        qquota_filter.pe = lGetString(pe_ep, ST_name);
 
212
                     }
 
213
                     do {
 
214
                        if (queue_ep != NULL) {
 
215
                           qquota_filter.queue = lGetString(queue_ep, ST_name);
 
216
                        }
 
217
                        do {
 
218
                           if (host_ep != NULL) {
 
219
                              qquota_filter.host = lGetString(host_ep, ST_name);
 
220
                           }
 
221
                         
 
222
                           if (rqs_is_matching_rule(rule, qquota_filter.user, NULL, qquota_filter.project,
 
223
                                                     qquota_filter.pe, qquota_filter.host,
 
224
                                                     qquota_filter.queue, userset_list, hgroup_list)) {
 
225
                              lListElem *limit = NULL;
 
226
 
 
227
                              for_each(limit, lGetList(rule, RQR_limit)) {
 
228
                                 const char *limit_name = lGetString(limit, RQRL_name);
 
229
                                 lList *rue_list = lGetList(limit, RQRL_usage);
 
230
                                 lListElem *raw_centry = centry_list_locate(centry_list, limit_name);
 
231
                                 lListElem *rue_elem = NULL;
 
232
 
 
233
                                 if (raw_centry == NULL) {
 
234
                                    /* undefined centries can be ignored */
 
235
                                    DPRINTF(("centry %s not defined -> IGNORING\n", limit_name));
 
236
                                    continue;
 
237
                                 }
 
238
 
 
239
                                 if ((resource_match_list != NULL) && 
 
240
                                     ((centry_list_locate(resource_match_list, limit_name) == NULL) &&
 
241
                                     (centry_list_locate(resource_match_list, lGetString(raw_centry, CE_shortcut)) == NULL))) {
 
242
                                    DPRINTF(("centry %s was not requested on CLI -> IGNORING\n", limit_name));
 
243
                                    continue;
 
244
                                 }
 
245
 
 
246
                                 if (lGetString(rule, RQR_name)) {
 
247
                                    sge_dstring_sprintf(&rule_name, "%s/%s", lGetString(rqs, RQS_name), lGetString(rule, RQR_name));
 
248
                                 } else {
 
249
                                    sge_dstring_sprintf(&rule_name, "%s/%d", lGetString(rqs, RQS_name), rule_count);
 
250
                                 }
 
251
 
 
252
                                 if (lGetBool(raw_centry, CE_consumable)) {
 
253
                                    /* for consumables we need to walk through the utilization and search for matching values */
 
254
                                    DPRINTF(("found centry %s - consumable\n", limit_name));
 
255
                                    for_each(rue_elem, rue_list) {
 
256
                                       u_long32 dominant = 0;
 
257
                                       const char *rue_name = lGetString(rue_elem, RUE_name);
 
258
                                       char *cp = NULL;
 
259
                                       stringT user, project, pe, queue, host;
 
260
                                       dstring limit_str = DSTRING_INIT; 
 
261
                                       dstring value_str = DSTRING_INIT;
 
262
                                       qquota_filter_t qf = { NULL, NULL, NULL, NULL, NULL };
 
263
 
 
264
                                       /* check user name */
 
265
                                       cp = qquota_get_next_filter(user, rue_name);
 
266
                                       /* usergroups have the same beginning character @ as host groups */
 
267
                                       if (is_hgroup_name(qquota_filter.user)) {
 
268
                                          lListElem *ugroup = NULL;
 
269
 
 
270
                                          if ((ugroup = userset_list_locate(userset_list, &qquota_filter.user[1])) != NULL) {
 
271
                                             if (sge_contained_in_access_list(user, NULL, ugroup, NULL) == 0) {
 
272
                                                continue;
 
273
                                             }
 
274
                                          }
 
275
                                       } else {
 
276
                                          if ((strcmp(user, "-") != 0) && (strcmp(qquota_filter.user, "*") != 0)
 
277
                                               && (fnmatch(qquota_filter.user, user, 0) != 0)) {
 
278
                                             continue;
 
279
                                          }
 
280
                                       }
 
281
 
 
282
                                       /* check project */
 
283
                                       cp = qquota_get_next_filter(project, cp);
 
284
                                       if ((strcmp(project, "-") != 0) && (strcmp(qquota_filter.project, "*") != 0) 
 
285
                                             && (fnmatch(qquota_filter.project, project, 0) != 0)) {
 
286
                                          continue;
 
287
                                       }
 
288
                                       /* check parallel environment */
 
289
                                       cp = qquota_get_next_filter(pe, cp);
 
290
                                       if ((strcmp(pe, "-") != 0) && (strcmp(qquota_filter.pe, "*") != 0) &&
 
291
                                           (fnmatch(qquota_filter.pe, pe, 0) != 0) ) {
 
292
                                          continue;
 
293
                                       }
 
294
                                       /* check cluster queue */
 
295
                                       cp = qquota_get_next_filter(queue, cp);
 
296
                                       if ((strcmp(queue, "-") != 0) && (strcmp(qquota_filter.queue, "*") != 0) &&
 
297
                                           (fnmatch(qquota_filter.queue, queue, 0) != 0)) {
 
298
                                          continue;
 
299
                                       }
 
300
                                       /* check host name */
 
301
                                       cp = qquota_get_next_filter(host, cp);
 
302
                                       if (is_hgroup_name(qquota_filter.host)) {
 
303
                                          lListElem *hgroup = NULL;
 
304
 
 
305
                                          if ((hgroup = hgroup_list_locate(hgroup_list, qquota_filter.host)) != NULL) {
 
306
                                             lList *host_list = NULL;
 
307
                                             hgroup_find_all_references(hgroup, NULL, hgroup_list, &host_list, NULL);
 
308
                                             if (host_list == NULL && lGetElemHost(host_list, HR_name, host) == NULL) {
 
309
                                                lFreeList(&host_list);
 
310
                                                continue;
 
311
                                             }
 
312
                                             lFreeList(&host_list);
 
313
                                          }
 
314
                                       } else {
 
315
                                          if ((strcmp(host, "-") != 0) && (strcmp(qquota_filter.host, "*") != 0) &&
 
316
                                              (fnmatch(qquota_filter.host, host, 0) != 0) ) {
 
317
                                             continue;
 
318
                                          }
 
319
                                       }
 
320
                                       if (lGetBool(limit, RQRL_dynamic)) {
 
321
                                          exec_host = host_list_locate(exechost_list, host); 
 
322
                                          sge_dstring_sprintf(&limit_str, "%d", (int)scaled_mixed_load(lGetString(limit, RQRL_value),
 
323
                                                                                                       global_host, exec_host, centry_list));
 
324
 
 
325
                                       } else {
 
326
                                          lSetDouble(raw_centry, CE_pj_doubleval, lGetDouble(limit, RQRL_dvalue));
 
327
                                          sge_get_dominant_stringval(raw_centry, &dominant, &limit_str);
 
328
                                       }
 
329
 
 
330
                                       lSetDouble(raw_centry,CE_pj_doubleval, lGetDouble(rue_elem, RUE_utilized_now));
 
331
                                       sge_get_dominant_stringval(raw_centry, &dominant, &value_str);
 
332
 
 
333
                                       qf.user = user;
 
334
                                       qf.project = project;
 
335
                                       qf.pe = pe;
 
336
                                       qf.queue = queue;
 
337
                                       qf.host = host;
 
338
                                       ret = qquota_print_out_rule(rule, rule_name, limit_name, 
 
339
                                                                   sge_dstring_get_string(&value_str), sge_dstring_get_string(&limit_str),
 
340
                                                                   qf, raw_centry, report_handler, printed_rules, alpp);
 
341
 
 
342
                                       sge_dstring_free(&limit_str);
 
343
                                       sge_dstring_free(&value_str);
 
344
                                    }
 
345
                                 } else {
 
346
                                    /* static values */
 
347
                                    qquota_filter_t qf = { NULL, NULL, NULL, NULL, NULL };
 
348
 
 
349
                                    DPRINTF(("found centry %s - static value\n", limit_name));
 
350
                                    ret = qquota_print_out_rule(rule, rule_name, limit_name, 
 
351
                                                                NULL, lGetString(limit, RQRL_value),
 
352
                                                                qf, raw_centry, report_handler, printed_rules, alpp);
 
353
 
 
354
                                 }
 
355
                              }
 
356
                           }
 
357
                        } while ((host_ep = lNext(host_ep)));
 
358
                     } while ((queue_ep = lNext(queue_ep)));
 
359
                  } while ((pe_ep = lNext(pe_ep)));
 
360
               } while ((project_ep = lNext(project_ep)));
 
361
            } while ((user_ep = lNext(user_ep)));
 
362
            rule_count++;
 
363
         }
 
364
      }
 
365
 
 
366
      if (report_handler != NULL) {
 
367
         report_handler->report_finished(report_handler, alpp);
 
368
      }
 
369
   }
 
370
 
 
371
qquota_output_error:
 
372
   sge_dstring_free(&rule_name);
 
373
   lFreeList(&rqs_list);
 
374
   lFreeList(&centry_list);
 
375
   lFreeList(&userset_list);
 
376
   lFreeList(&hgroup_list);
 
377
   lFreeList(&exechost_list);
 
378
   lFreeList(&printed_rules);
 
379
 
 
380
   DRETURN(ret);
 
381
}
 
382
 
 
383
/****** qquota_output/get_all_lists() ******************************************
 
384
*  NAME
 
385
*     get_all_lists() -- get all lists from qmaster
 
386
*
 
387
*  SYNOPSIS
 
388
*     static bool get_all_lists(sge_gdi_ctx_class_t *ctx, lList **rqs_l, lList 
 
389
*     **centry_l, lList **userset_l, lList **hgroup_l, lList **exechost_l, 
 
390
*     lList *hostref_l, lList **alpp) 
 
391
*
 
392
*  FUNCTION
 
393
*     Gets copies of queue-, job-, complex-, exechost-list  from qmaster.
 
394
*      The lists are stored in the .._l pointerpointer-parameters.
 
395
*      WARNING: Lists previously stored in this pointers are not destroyed!!
 
396
*
 
397
*  INPUTS
 
398
*     void *context      - gdi context
 
399
*     lList **rqs_l     -  resource quota set list (RQS_Type)
 
400
*     lList **centry_l   - consumable resource list (CE_Type)
 
401
*     lList **userset_l  - userset list (US_Type)
 
402
*     lList **hgroup_l   - host group list (HG_Type)
 
403
*     lList **exechost_l - exechost list (EH_Type)
 
404
*     lList *hostref_l   - selected hosts (ST_Type)
 
405
*     lList **alpp       - answer list
 
406
*
 
407
*  RESULT
 
408
*     static bool - true on success
 
409
*                   false on error
 
410
*
 
411
*  NOTES
 
412
*     MT-NOTE: get_all_lists() is MT safe 
 
413
*
 
414
*******************************************************************************/
 
415
static bool
 
416
get_all_lists(sge_gdi_ctx_class_t *ctx, lList **rqs_l, lList **centry_l, lList **userset_l,
 
417
              lList **hgroup_l, lList **exechost_l, lList *hostref_l, lList **alpp)
 
418
{
 
419
   lListElem *ep = NULL;
 
420
   lEnumeration *what = NULL;
 
421
   lCondition *where = NULL, *nw = NULL;
 
422
   lList *mal = NULL;
 
423
   int rqs_id, ce_id, userset_id, hgroup_id, eh_id;
 
424
   state_gdi_multi state = STATE_GDI_MULTI_INIT;
 
425
   
 
426
   DENTER(TOP_LAYER, "get_all_lists");
 
427
 
 
428
   /*
 
429
   ** resource quota sets
 
430
   */
 
431
   what = lWhat("%T(ALL)", RQS_Type);
 
432
   rqs_id = ctx->gdi_multi(ctx, 
 
433
                          alpp, SGE_GDI_RECORD, SGE_RQS_LIST, SGE_GDI_GET, 
 
434
                          NULL, NULL, what, &state, true);
 
435
   lFreeWhat(&what);
 
436
 
 
437
   if (answer_list_has_error(alpp)) {
 
438
      DRETURN(false);
 
439
   }
 
440
   
 
441
   /*
 
442
   ** complexes
 
443
   */
 
444
   what = lWhat("%T(ALL)", CE_Type);
 
445
   ce_id = ctx->gdi_multi(ctx, 
 
446
                          alpp, SGE_GDI_RECORD, SGE_CENTRY_LIST, SGE_GDI_GET, 
 
447
                          NULL, NULL, what, &state, true);
 
448
   lFreeWhat(&what);
 
449
 
 
450
   if (answer_list_has_error(alpp)) {
 
451
      DRETURN(false);
 
452
   }
 
453
   /*
 
454
   ** usersets 
 
455
   */
 
456
   what = lWhat("%T(ALL)", US_Type);
 
457
   userset_id = ctx->gdi_multi(ctx, 
 
458
                          alpp, SGE_GDI_RECORD, SGE_USERSET_LIST, SGE_GDI_GET, 
 
459
                          NULL, NULL, what, &state, true);
 
460
   lFreeWhat(&what);
 
461
 
 
462
   if (answer_list_has_error(alpp)) {
 
463
      DRETURN(false);
 
464
   }
 
465
   /*
 
466
   ** host groups 
 
467
   */
 
468
   what = lWhat("%T(ALL)", HGRP_Type);
 
469
   hgroup_id = ctx->gdi_multi(ctx, 
 
470
                          alpp, SGE_GDI_RECORD, SGE_HGROUP_LIST, SGE_GDI_GET, 
 
471
                          NULL, NULL, what, &state, true);
 
472
   lFreeWhat(&what);
 
473
   /*
 
474
   ** exec hosts
 
475
   */
 
476
   for_each(ep, hostref_l) {
 
477
      nw = lWhere("%T(%I h= %s)", EH_Type, EH_name, lGetString(ep, ST_name));
 
478
      if (!where)
 
479
         where = nw;
 
480
      else
 
481
         where = lOrWhere(where, nw);
 
482
   }
 
483
   /* the global host has to be retrieved as well */
 
484
   if (where != NULL) {
 
485
      nw = lWhere("%T(%I == %s)", EH_Type, EH_name, SGE_GLOBAL_NAME);
 
486
      where = lOrWhere(where, nw);
 
487
   }
 
488
   
 
489
   nw = lWhere("%T(%I != %s)", EH_Type, EH_name, SGE_TEMPLATE_NAME);
 
490
   if (where)
 
491
      where = lAndWhere(where, nw);
 
492
   else
 
493
      where = nw;
 
494
 
 
495
   what = lWhat("%T(%I %I %I %I)", EH_Type, EH_name, EH_load_list, EH_consumable_config_list, EH_resource_utilization);
 
496
   eh_id = ctx->gdi_multi(ctx, alpp, SGE_GDI_SEND, SGE_EXECHOST_LIST, SGE_GDI_GET, 
 
497
                          NULL, where, what, &state, true);
 
498
   ctx->gdi_wait(ctx, alpp, &mal, &state);
 
499
   lFreeWhat(&what);
 
500
   lFreeWhere(&where);
 
501
 
 
502
   if (answer_list_has_error(alpp)) {
 
503
      DRETURN(false);
 
504
   }
 
505
 
 
506
   /* --- resource quota sets */
 
507
   lFreeList(alpp);
 
508
   sge_gdi_extract_answer(alpp, SGE_GDI_GET, SGE_RQS_LIST, rqs_id,
 
509
                                 mal, rqs_l);
 
510
   if (answer_list_has_error(alpp)) {
 
511
      lFreeList(&mal);
 
512
      DRETURN(false);
 
513
   }
 
514
 
 
515
   /* --- complex attribute */
 
516
   lFreeList(alpp);
 
517
   sge_gdi_extract_answer(alpp, SGE_GDI_GET, SGE_CENTRY_LIST, ce_id,
 
518
                                 mal, centry_l);
 
519
   if (answer_list_has_error(alpp)) {
 
520
      lFreeList(&mal);
 
521
      DRETURN(false);
 
522
   }
 
523
   /* --- usersets */
 
524
   lFreeList(alpp);
 
525
   sge_gdi_extract_answer(alpp, SGE_GDI_GET, SGE_USERSET_LIST, userset_id,
 
526
                                 mal, userset_l);
 
527
   if (answer_list_has_error(alpp)) {
 
528
      lFreeList(&mal);
 
529
      DRETURN(false);
 
530
   }
 
531
   /* --- hostgroups */
 
532
   lFreeList(alpp);
 
533
   sge_gdi_extract_answer(alpp, SGE_GDI_GET, SGE_HGROUP_LIST, hgroup_id,
 
534
                                 mal, hgroup_l);
 
535
   if (answer_list_has_error(alpp)) {
 
536
      lFreeList(&mal);
 
537
      DRETURN(false);
 
538
   }
 
539
   /* --- exec hosts*/
 
540
   lFreeList(alpp);
 
541
   sge_gdi_extract_answer(alpp, SGE_GDI_GET, SGE_EXECHOST_LIST, eh_id,
 
542
                                 mal, exechost_l);
 
543
 
 
544
   lFreeList(&mal);
 
545
 
 
546
   if (answer_list_has_error(alpp)) {
 
547
      DRETURN(false);
 
548
   }
 
549
 
 
550
   DRETURN(true);
 
551
}
 
552
 
 
553
/****** qquota_output/qquota_get_next_filter() *********************************
 
554
*  NAME
 
555
*     qquota_get_next_filter() -- tokenize rue_name of usage
 
556
*
 
557
*  SYNOPSIS
 
558
*     static char* qquota_get_next_filter(char *filter, const char *cp) 
 
559
*
 
560
*  FUNCTION
 
561
*     The rue_name has the type /user_name/project_name/pe_name/queue_name/host_name.
 
562
*     This function tokenizes the rue_name and gives always one element back
 
563
*
 
564
*  INPUTS
 
565
*     char *filter   - store for the token 
 
566
*     const char *cp - pointer to rue_name
 
567
*
 
568
*  RESULT
 
569
*     static char* - pointer for the next token
 
570
*
 
571
*  NOTES
 
572
*     MT-NOTE: qquota_get_next_filter() is not MT safe 
 
573
*
 
574
*******************************************************************************/
 
575
static char *qquota_get_next_filter(stringT filter, const char *cp)
 
576
{
 
577
   char *ret = NULL;
 
578
 
 
579
   ret = strchr(cp, '/')+1;
 
580
   if (ret - cp < MAX_STRING_SIZE && ret - cp > 1) { 
 
581
      snprintf(filter, ret - cp, "%s", cp);
 
582
   } else {
 
583
      sprintf(filter, "-");
 
584
   }
 
585
 
 
586
   return ret;
 
587
}
 
588
 
 
589
/****** qquota_output/qquota_print_out_rule() **********************************
 
590
*  NAME
 
591
*     qquota_print_out_rule() -- print out rule
 
592
*
 
593
*  SYNOPSIS
 
594
*     static bool qquota_print_out_rule(lListElem *rule, dstring rule_name, 
 
595
*     const char *limit_name, const char *usage_value, const char *limit_value, 
 
596
*     qquota_filter_t qfilter, lListElem *centry, report_handler_t* 
 
597
*     report_handler, lList **alpp) 
 
598
*
 
599
*  FUNCTION
 
600
*     ??? 
 
601
*
 
602
*  INPUTS
 
603
*     lListElem *rule                  - resouce quota rule (RQR_Type)
 
604
*     dstring rule_name                - rule name (eg. ruleset1/rule1)
 
605
*     const char *limit_name           - limiation name (eg. slots)
 
606
*     const char *usage_value          - debited usage
 
607
*     const char *limit_value          - configured limitation
 
608
*     qquota_filter_t qfilter          - filter touple
 
609
*     lListElem *centry                - limitation centry element
 
610
*     report_handler_t* report_handler - handler for xml output
 
611
*     lList **alpp                     - answer list
 
612
*
 
613
*  RESULT
 
614
*     static bool - true on success
 
615
*                   false on error
 
616
*
 
617
*  NOTES
 
618
*     MT-NOTE: qquota_print_out_rule() is not MT safe 
 
619
*
 
620
*******************************************************************************/
 
621
static bool qquota_print_out_rule(lListElem *rule, dstring rule_name, const char *limit_name,
 
622
                                  const char *usage_value, const char *limit_value, qquota_filter_t qfilter,
 
623
                                  lListElem *centry, report_handler_t* report_handler, lList *printed_rules, lList **alpp) 
 
624
{
 
625
   static bool printheader = true;
 
626
   bool ret = true;
 
627
   dstring filter_str = DSTRING_INIT;
 
628
   dstring limitation = DSTRING_INIT;
 
629
   dstring token = DSTRING_INIT;
 
630
 
 
631
   sge_dstring_sprintf(&token, "%s,%s,%s,%s,%s,%s,%s", sge_dstring_get_string(&rule_name),
 
632
                                                             limit_name,
 
633
                                                             qfilter.user? qfilter.user: "",
 
634
                                                             qfilter.project? qfilter.project: "",
 
635
                                                             qfilter.pe? qfilter.pe: "",
 
636
                                                             qfilter.queue? qfilter.queue: "",
 
637
                                                             qfilter.host? qfilter.host: "");
 
638
 
 
639
   if (lGetElemStr(printed_rules, ST_name, sge_dstring_get_string(&token)) != NULL) {
 
640
      sge_dstring_free(&token);
 
641
      sge_dstring_free(&filter_str);
 
642
      sge_dstring_free(&limitation);
 
643
      return ret;
 
644
   }
 
645
 
 
646
   lAddElemStr(&printed_rules, ST_name, sge_dstring_get_string(&token), ST_Type);
 
647
 
 
648
   if (report_handler != NULL) {
 
649
      report_handler->report_limit_rule_begin(report_handler, sge_dstring_get_string(&rule_name), alpp);
 
650
   } else {
 
651
      if (printheader == true) {
 
652
         printheader = false;
 
653
         printf(HEAD_FORMAT, MSG_HEADER_RULE, MSG_HEADER_LIMIT, MSG_HEADER_FILTER);
 
654
         printf("--------------------------------------------------------------------------------\n");
 
655
      }
 
656
   }
 
657
 
 
658
   qquota_print_out_filter(lGetObject(rule, RQR_filter_users), "users", qfilter.user, &filter_str, report_handler, alpp);
 
659
   qquota_print_out_filter(lGetObject(rule, RQR_filter_projects), "projects", qfilter.project, &filter_str, report_handler, alpp);
 
660
   qquota_print_out_filter(lGetObject(rule, RQR_filter_pes), "pes", qfilter.pe, &filter_str, report_handler, alpp);
 
661
   qquota_print_out_filter(lGetObject(rule, RQR_filter_queues), "queues", qfilter.queue, &filter_str, report_handler, alpp);
 
662
   qquota_print_out_filter(lGetObject(rule, RQR_filter_hosts), "hosts", qfilter.host, &filter_str, report_handler, alpp);
 
663
 
 
664
   if (report_handler != NULL) {
 
665
      report_handler->report_resource_value(report_handler, limit_name,
 
666
                                            limit_value,
 
667
                                            usage_value,
 
668
                                            alpp);
 
669
      report_handler->report_limit_rule_finished(report_handler, sge_dstring_get_string(&rule_name), alpp);
 
670
   } else {
 
671
      if (usage_value == NULL) {
 
672
         sge_dstring_sprintf(&limitation, "%s=%s", limit_name, limit_value);
 
673
      } else {
 
674
         sge_dstring_sprintf(&limitation, "%s=%s/%s", limit_name, usage_value, limit_value);
 
675
      }
 
676
      if (sge_dstring_strlen(&filter_str) == 0) {
 
677
         sge_dstring_append(&filter_str, "-");
 
678
      }
 
679
      printf(HEAD_FORMAT, sge_dstring_get_string(&rule_name), sge_dstring_get_string(&limitation), sge_dstring_get_string(&filter_str));
 
680
   }
 
681
 
 
682
   sge_dstring_free(&token);
 
683
   sge_dstring_free(&filter_str);
 
684
   sge_dstring_free(&limitation);
 
685
   return ret;
 
686
}
 
687
 
 
688
/****** qquota_output/qquota_print_out_filter() ********************************
 
689
*  NAME
 
690
*     qquota_print_out_filter() -- prints out filter element
 
691
*
 
692
*  SYNOPSIS
 
693
*     static bool qquota_print_out_filter(lListElem *filter, const char *name, 
 
694
*     const char *value, dstring *buffer, report_handler_t *report_handler, 
 
695
*     lList **alpp) 
 
696
*
 
697
*  FUNCTION
 
698
*     this function prints out the filter configured in the rule
 
699
*
 
700
*  INPUTS
 
701
*     lListElem *filter                - filter element (RQRF_Type)
 
702
*     const char *name                 - filter type name
 
703
*     const char *value                - filter value
 
704
*     dstring *buffer                  - buffer
 
705
*     report_handler_t *report_handler - handler for report handler
 
706
*     lList **alpp                     - answer list
 
707
*
 
708
*  RESULT
 
709
*     static bool - true on success
 
710
*                   false on error
 
711
*
 
712
*  NOTES
 
713
*     MT-NOTE: qquota_print_out_filter() is MT safe 
 
714
*
 
715
*******************************************************************************/
 
716
static bool
 
717
qquota_print_out_filter(lListElem *filter, const char *name, const char *value,
 
718
                        dstring *buffer, report_handler_t *report_handler, lList **alpp) 
 
719
{
 
720
   bool ret = true;
 
721
   lListElem *scope;
 
722
   
 
723
   if (filter != NULL) {
 
724
      if (!lGetBool(filter, RQRF_expand) || value == NULL) {
 
725
         if (report_handler != NULL) {
 
726
            for_each(scope, lGetList(filter, RQRF_scope)) {
 
727
               report_handler->report_limit_string_value(report_handler, name, lGetString(scope, ST_name), false, alpp);
 
728
            }
 
729
            for_each(scope, lGetList(filter, RQRF_xscope)) {
 
730
               report_handler->report_limit_string_value(report_handler, name, lGetString(scope, ST_name), true, alpp);
 
731
            }
 
732
         } else {
 
733
            if (sge_dstring_strlen(buffer) != 0) {
 
734
               sge_dstring_append(buffer, " ");
 
735
            }
 
736
            sge_dstring_append(buffer, name);
 
737
            sge_dstring_append(buffer, " ");
 
738
            rqs_append_filter_to_dstring(filter, buffer, alpp);
 
739
         }
 
740
      } else {
 
741
        if (report_handler != NULL) {
 
742
          report_handler->report_limit_string_value(report_handler, name, value, false, alpp);
 
743
        } else {
 
744
            if (sge_dstring_strlen(buffer) != 0) {
 
745
               sge_dstring_append(buffer, " ");
 
746
            }
 
747
          sge_dstring_append(buffer, name);
 
748
          sge_dstring_append(buffer, " ");
 
749
          sge_dstring_append(buffer, value);
 
750
        }
 
751
      }
 
752
   }
 
753
 
 
754
   return ret;
 
755
}