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

« back to all changes in this revision

Viewing changes to source/libs/sgeobj/sge_cqueue.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
 
 
33
#include <string.h>
 
34
#include <fnmatch.h>
 
35
 
 
36
#include "sgermon.h"
 
37
#include "sge_string.h"
 
38
#include "sge_log.h"
 
39
#include "cull_list.h"
 
40
#include "symbols.h"
 
41
#include "sge.h"
 
42
 
 
43
#include "gdi/sge_gdi.h"
 
44
 
 
45
#include "parse.h"
 
46
#include "sge_dstring.h"
 
47
#include "sge_object.h"
 
48
#include "sge_answer.h"
 
49
#include "sge_attr.h"
 
50
#include "sge_centry.h"
 
51
#include "sge_cqueue.h"
 
52
#include "sge_cqueue_verify.h"
 
53
#include "sge_qinstance.h"
 
54
#include "sge_qinstance_state.h"
 
55
#include "sge_qinstance_type.h"
 
56
#include "sge_utility_qmaster.h"
 
57
#include "sge_str.h"
 
58
#include "sge_userprj.h"
 
59
#include "sge_userset.h"
 
60
#include "sge_feature.h"
 
61
#include "sge_href.h"
 
62
#include "sge_hgroup.h"
 
63
#include "sge_pe.h"
 
64
#include "sge_calendar.h"
 
65
#include "sge_ckpt.h"
 
66
#include "sge_qref.h"
 
67
#include "sge_range.h"
 
68
#include "sge_subordinate.h"
 
69
#include "sge_hostname.h"
 
70
#include "sge_eval_expression.h"
 
71
#include "commlib.h"
 
72
 
 
73
#include "msg_common.h"
 
74
#include "msg_sgeobjlib.h"
 
75
 
 
76
#define CQUEUE_LAYER TOP_LAYER
 
77
 
 
78
/* *INDENT-OFF* */
 
79
 
 
80
list_attribute_struct cqueue_attribute_array[] = {
 
81
   { CQ_seq_no,                  QU_seq_no,                 AULNG_href,    AULNG_value,      NoName,     SGE_ATTR_SEQ_NO,            false,  false, NULL},
 
82
   { CQ_nsuspend,                QU_nsuspend,               AULNG_href,    AULNG_value,      NoName,     SGE_ATTR_NSUSPEND,          false,  false, NULL},
 
83
   { CQ_job_slots,               QU_job_slots,              AULNG_href,    AULNG_value,      NoName,     SGE_ATTR_SLOTS,             false,  false, cqueue_verify_job_slots},
 
84
 
 
85
   { CQ_tmpdir,                  QU_tmpdir,                 ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_TMPDIR,            false,  false, NULL},
 
86
   { CQ_shell,                   QU_shell,                  ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_SHELL,             false,  true, cqueue_verify_shell},
 
87
   { CQ_calendar,                QU_calendar,               ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_CALENDAR,          false,  false, cqueue_verify_calendar},
 
88
   { CQ_priority,                QU_priority,               ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_PRIORITY,          false,  true,  cqueue_verify_priority},
 
89
   { CQ_processors,              QU_processors,             ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_PROCESSORS,        false,  true,  cqueue_verify_processors},
 
90
   { CQ_prolog,                  QU_prolog,                 ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_PROLOG,            false,  false, NULL},
 
91
   { CQ_epilog,                  QU_epilog,                 ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_EPILOG,            false,  false, NULL},
 
92
   { CQ_shell_start_mode,        QU_shell_start_mode,       ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_SHELL_START_MODE,  false,  true,  cqueue_verify_shell_start_mode},
 
93
   { CQ_starter_method,          QU_starter_method,         ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_STARTER_METHOD,    false,  false, NULL},
 
94
   { CQ_suspend_method,          QU_suspend_method,         ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_SUSPEND_METHOD,    false,  false, NULL},
 
95
   { CQ_resume_method,           QU_resume_method,          ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_RESUME_METHOD,     false,  false, NULL},
 
96
   { CQ_terminate_method,        QU_terminate_method,       ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_TERMINATE_METHOD,  false,  false, NULL},
 
97
   { CQ_initial_state,           QU_initial_state,          ASTR_href,     ASTR_value,       NoName,     SGE_ATTR_INITIAL_STATE,     false,  true,  cqueue_verify_initial_state},
 
98
   
 
99
   { CQ_rerun,                   QU_rerun,                  ABOOL_href,    ABOOL_value,      NoName,     SGE_ATTR_RERUN,             false,  false, NULL},
 
100
 
 
101
   { CQ_s_fsize,                 QU_s_fsize,                AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_S_FSIZE,           false,  false, cqueue_verify_memory_value},
 
102
   { CQ_h_fsize,                 QU_h_fsize,                AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_H_FSIZE,           false,  false, cqueue_verify_memory_value},
 
103
   { CQ_s_data,                  QU_s_data,                 AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_S_DATA,            false,  false, cqueue_verify_memory_value},
 
104
   { CQ_h_data,                  QU_h_data,                 AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_H_DATA,            false,  false, cqueue_verify_memory_value},
 
105
   { CQ_s_stack,                 QU_s_stack,                AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_S_STACK,           false,  false, cqueue_verify_memory_value},
 
106
   { CQ_h_stack,                 QU_h_stack,                AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_H_STACK,           false,  false, cqueue_verify_memory_value},
 
107
   { CQ_s_core,                  QU_s_core,                 AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_S_CORE,            false,  false, cqueue_verify_memory_value},
 
108
   { CQ_h_core,                  QU_h_core,                 AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_H_CORE,            false,  false, cqueue_verify_memory_value},
 
109
   { CQ_s_rss,                   QU_s_rss,                  AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_S_RSS,             false,  false, cqueue_verify_memory_value},
 
110
   { CQ_h_rss,                   QU_h_rss,                  AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_H_RSS,             false,  false, cqueue_verify_memory_value},
 
111
   { CQ_s_vmem,                  QU_s_vmem,                 AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_S_VMEM,            false,  false, cqueue_verify_memory_value},
 
112
   { CQ_h_vmem,                  QU_h_vmem,                 AMEM_href,     AMEM_value,       NoName,     SGE_ATTR_H_VMEM,            false,  false, cqueue_verify_memory_value},
 
113
 
 
114
   { CQ_s_rt,                    QU_s_rt,                   ATIME_href,    ATIME_value,      NoName,     SGE_ATTR_S_RT,              false,  false, cqueue_verify_time_value},
 
115
   { CQ_h_rt,                    QU_h_rt,                   ATIME_href,    ATIME_value,      NoName,     SGE_ATTR_H_RT,              false,  false, cqueue_verify_time_value},
 
116
   { CQ_s_cpu,                   QU_s_cpu,                  ATIME_href,    ATIME_value,      NoName,     SGE_ATTR_S_CPU,             false,  false, cqueue_verify_time_value},
 
117
   { CQ_h_cpu,                   QU_h_cpu,                  ATIME_href,    ATIME_value,      NoName,     SGE_ATTR_H_CPU,             false,  false, cqueue_verify_time_value},
 
118
 
 
119
   { CQ_suspend_interval,        QU_suspend_interval,       AINTER_href,   AINTER_value,     NoName,     SGE_ATTR_SUSPEND_INTERVAL,  false,  false, NULL},
 
120
   { CQ_min_cpu_interval,        QU_min_cpu_interval,       AINTER_href,   AINTER_value,     NoName,     SGE_ATTR_MIN_CPU_INTERVAL,  false,  false, NULL},
 
121
   { CQ_notify,                  QU_notify,                 AINTER_href,   AINTER_value,     NoName,     SGE_ATTR_NOTIFY,            false,  false, NULL},
 
122
 
 
123
   { CQ_qtype,                   QU_qtype,                  AQTLIST_href,  AQTLIST_value,    NoName,     SGE_ATTR_QTYPE,             false,  false, NULL},
 
124
 
 
125
   { CQ_ckpt_list,               QU_ckpt_list,              ASTRLIST_href, ASTRLIST_value,   ST_name,    SGE_ATTR_CKPT_LIST,         false,  false, cqueue_verify_ckpt_list},
 
126
   { CQ_pe_list,                 QU_pe_list,                ASTRLIST_href, ASTRLIST_value,   ST_name,    SGE_ATTR_PE_LIST,           false,  false, cqueue_verify_pe_list},
 
127
 
 
128
   { CQ_owner_list,              QU_owner_list,             AUSRLIST_href, AUSRLIST_value,   US_name,    SGE_ATTR_OWNER_LIST,        false,  false, NULL},
 
129
   { CQ_acl,                     QU_acl,                    AUSRLIST_href, AUSRLIST_value,   US_name,    SGE_ATTR_USER_LISTS,        false,  false, cqueue_verify_user_list},
 
130
   { CQ_xacl,                    QU_xacl,                   AUSRLIST_href, AUSRLIST_value,   US_name,    SGE_ATTR_XUSER_LISTS,       false,  false, cqueue_verify_user_list},
 
131
 
 
132
   { CQ_projects,                QU_projects,               APRJLIST_href, APRJLIST_value,   PR_name,    SGE_ATTR_PROJECTS,          true,   false, cqueue_verify_project_list},
 
133
   { CQ_xprojects,               QU_xprojects,              APRJLIST_href, APRJLIST_value,   PR_name,    SGE_ATTR_XPROJECTS,         true,   false, cqueue_verify_project_list},
 
134
 
 
135
   { CQ_consumable_config_list,  QU_consumable_config_list, ACELIST_href,  ACELIST_value,    CE_name,    SGE_ATTR_COMPLEX_VALUES,    false,  false, cqueue_verify_consumable_config_list},
 
136
   { CQ_load_thresholds,         QU_load_thresholds,        ACELIST_href,  ACELIST_value,    CE_name,    SGE_ATTR_LOAD_THRESHOLD,    false,  false, NULL},
 
137
   { CQ_suspend_thresholds,      QU_suspend_thresholds,     ACELIST_href,  ACELIST_value,    CE_name,    SGE_ATTR_SUSPEND_THRESHOLD, false,  false, NULL},
 
138
 
 
139
   { CQ_subordinate_list,        QU_subordinate_list,       ASOLIST_href,  ASOLIST_value,    SO_name,    SGE_ATTR_SUBORDINATE_LIST,  false,  false, cqueue_verify_subordinate_list},
 
140
 
 
141
   { NoName,                     NoName,                    NoName,        NoName,           NoName,     NULL,                       false,  false, NULL}
 
142
};
 
143
 
 
144
/* *INDENT-ON* */
 
145
 
 
146
/* EB: ADOC: add commets */
 
147
 
 
148
lEnumeration *
 
149
enumeration_create_reduced_cq(bool fetch_all_qi, bool fetch_all_nqi)
 
150
{
 
151
   lEnumeration *ret;
 
152
   dstring format_string = DSTRING_INIT;
 
153
   lDescr *descr = CQ_Type;
 
154
   int name_array[100];
 
155
   int names = -1;
 
156
   int attr;
 
157
 
 
158
   DENTER(CQUEUE_LAYER, "enumeration_create_reduced_cq");
 
159
   for_each_attr(attr, descr) {
 
160
      if (names == -1) {
 
161
         sge_dstring_clear(&format_string);
 
162
         sge_dstring_append(&format_string, "%T(");
 
163
      }
 
164
      if ((attr == CQ_name) ||
 
165
          (fetch_all_qi && attr == CQ_qinstances) ||
 
166
          (fetch_all_nqi && attr != CQ_qinstances)) {
 
167
         names++;
 
168
         name_array[names] = attr;
 
169
         sge_dstring_append(&format_string, "%I");
 
170
      }
 
171
   }
 
172
   sge_dstring_append(&format_string, ")");
 
173
   ret = _lWhat(sge_dstring_get_string(&format_string), CQ_Type, 
 
174
                name_array, ++names);
 
175
   sge_dstring_free(&format_string);
 
176
   
 
177
   DEXIT;
 
178
   return ret;
 
179
}
 
180
 
 
181
/****** sgeobj/cqueue/cqueue_name_split() *************************************
 
182
*  NAME
 
183
*     cqueue_name_split() -- Get the CQ and host part of a QI name 
 
184
*
 
185
*  SYNOPSIS
 
186
*     bool 
 
187
*     cqueue_name_split(const char *name, 
 
188
*                       dstring *cqueue_name, 
 
189
*                       dstring *host_domain, 
 
190
*                       bool *has_hostname, 
 
191
*                       bool *has_domain) 
 
192
*
 
193
*  FUNCTION
 
194
*     Splits a qinstance name into its components.
 
195
*
 
196
*     Examples:
 
197
*  
 
198
*     QI-name         cqueue_name  host_domain  has_hostname  has_domain
 
199
*     ------------------------------------------------------------------
 
200
*     all.q           all.q        ""           false         false
 
201
*     all.q@hostname  all.q        hostname     true          false
 
202
*     all.q@@hgrp     all.q        @hgrp        false         true
 
203
*
 
204
*  INPUTS
 
205
*     const char *name     - CQ/QD or QI name 
 
206
*     dstring *cqueue_name - CQ part of the name 
 
207
*     dstring *host_domain - host or hostgroup or nothing 
 
208
*     bool *has_hostname   - is "host_domain" a hostname 
 
209
*     bool *has_domain     - if "host_domain" a hostgroup 
 
210
*
 
211
*  RESULT
 
212
*     bool - error state
 
213
*     always true  - success
 
214
*******************************************************************************/
 
215
bool
 
216
cqueue_name_split(const char *name, 
 
217
                  dstring *cqueue_name, dstring *host_domain, 
 
218
                  bool *has_hostname, bool *has_domain)
 
219
{
 
220
   bool ret = true;
 
221
 
 
222
   DENTER(CQUEUE_LAYER, "cqueue_name_split");
 
223
 
 
224
   if (has_hostname)
 
225
      *has_hostname = false;
 
226
   if (has_domain)
 
227
      *has_domain = false;
 
228
 
 
229
   if (name != NULL && cqueue_name != NULL && host_domain != NULL ) {
 
230
      bool at_skiped = false;
 
231
 
 
232
      sge_dstring_clear(cqueue_name);
 
233
      sge_dstring_clear(host_domain);
 
234
 
 
235
      while (*name != '\0') {
 
236
         if (!at_skiped && *name == '@') {
 
237
            at_skiped = true;
 
238
            name++;
 
239
            if (*name == '@') {
 
240
               if (has_domain)
 
241
                  *has_domain = true;
 
242
               if (has_hostname)
 
243
                  *has_hostname = false;
 
244
            } else {
 
245
               if (has_domain)
 
246
                  *has_domain = false;
 
247
               if (has_hostname)
 
248
                  *has_hostname = true;
 
249
            }
 
250
            continue; 
 
251
         }
 
252
         if (!at_skiped) {
 
253
            sge_dstring_append_char(cqueue_name, name[0]);
 
254
         } else {
 
255
            sge_dstring_append_char(host_domain, name[0]);
 
256
         }
 
257
         name++;
 
258
      }
 
259
   }
 
260
   DRETURN(ret);
 
261
}
 
262
 
 
263
/****** sge_cqueue/cqueue_get_name_from_qinstance() ****************************
 
264
*  NAME
 
265
*     cqueue_get_name_from_qinstance() -- returns the cluster queue part of a queue
 
266
*
 
267
*  SYNOPSIS
 
268
*     char* cqueue_get_name_from_qinstance(const char *queue_instance) 
 
269
*
 
270
*  FUNCTION
 
271
*     Returns a character pointer to a newly malloced string containing the cluster
 
272
*     queue part of a queue instance name.
 
273
*
 
274
*     The memory needs to be free'd by the caller
 
275
*
 
276
*  INPUTS
 
277
*     const char *queue_instance - queue instance or cluster queue
 
278
*
 
279
*  RESULT
 
280
*     char* - cluster queue name
 
281
*
 
282
*  NOTES
 
283
*     MT-NOTE: cqueue_get_name_from_qinstance() is MT safe 
 
284
*
 
285
*******************************************************************************/
 
286
char* cqueue_get_name_from_qinstance(const char *queue_instance)
 
287
{
 
288
   char *at_sign = NULL;
 
289
   char *cqueue = NULL; 
 
290
 
 
291
   if ((at_sign = strchr(queue_instance, '@'))) {
 
292
      int size = at_sign - queue_instance;
 
293
      cqueue = malloc(sizeof(char) * (size + 1));
 
294
      cqueue = strncpy(cqueue, queue_instance, size);
 
295
      cqueue[size] = '\0';
 
296
   } else {
 
297
      cqueue = strdup(queue_instance);
 
298
   }
 
299
 
 
300
   return cqueue;
 
301
}
 
302
 
 
303
/****** sgeobj/cqueue/cqueue_create() *****************************************
 
304
*  NAME
 
305
*     cqueue_create() -- Create a new cluster queue object 
 
306
*
 
307
*  SYNOPSIS
 
308
*     lListElem *
 
309
*     cqueue_create(lList **answer_list, 
 
310
*                   const char *name) 
 
311
*
 
312
*  FUNCTION
 
313
*     Returns a new cluster queue object with the name "name". 
 
314
*
 
315
*  INPUTS
 
316
*     lList **answer_list - AN_Type list 
 
317
*     const char *name    - cluster queue name 
 
318
*
 
319
*  RESULT
 
320
*     lListElem * - CQ_Type object or NULL
 
321
*******************************************************************************/
 
322
lListElem *
 
323
cqueue_create(lList **answer_list, const char *name)
 
324
{
 
325
   lListElem *ret = NULL;
 
326
 
 
327
   DENTER(CQUEUE_LAYER, "cqueue_create");
 
328
   if (name != NULL) {
 
329
      ret = lCreateElem(CQ_Type);
 
330
 
 
331
      if (ret != NULL) {
 
332
         lSetString(ret, CQ_name, name);
 
333
      } else {
 
334
         SGE_ADD_MSG_ID(sprintf(SGE_EVENT, 
 
335
                                MSG_MEM_MEMORYALLOCFAILED_S, SGE_FUNC));
 
336
         answer_list_add(answer_list, SGE_EVENT,
 
337
                         STATUS_EMALLOC, ANSWER_QUALITY_ERROR);
 
338
      }
 
339
   }
 
340
   DEXIT;
 
341
   return ret;
 
342
}
 
343
 
 
344
/****** sgeobj/cqueue/cqueue_is_href_referenced() *****************************
 
345
*  NAME
 
346
*     cqueue_is_href_referenced() -- is a host/hostgroup referenced in cqueue 
 
347
*
 
348
*  SYNOPSIS
 
349
*     bool 
 
350
*     cqueue_is_href_referenced(const lListElem *this_elem, 
 
351
*                               const lListElem *href) 
 
352
*
 
353
*  FUNCTION
 
354
*     Is the given "href" (host or hostgroup referenece) used in the
 
355
*     definition of the cluster queue "this_elem"?
 
356
*
 
357
*  INPUTS
 
358
*     const lListElem *this_elem - CQ_Type 
 
359
*     const lListElem *href      - HR_Type 
 
360
*
 
361
*  RESULT
 
362
*     bool - true if it is referenced
 
363
*******************************************************************************/
 
364
bool 
 
365
cqueue_is_href_referenced(const lListElem *this_elem, const lListElem *href)
 
366
{
 
367
   bool ret = false;
 
368
 
 
369
   if (this_elem != NULL && href != NULL) {
 
370
      const char *href_name = lGetHost(href, HR_name);
 
371
      
 
372
      if (href_name != NULL) {
 
373
         lList *href_list = lGetList(this_elem, CQ_hostlist);
 
374
         lListElem *tmp_href = lGetElemHost(href_list, HR_name, href_name);
 
375
         int index;
 
376
 
 
377
         /*
 
378
          * Is the host group part of the hostlist definition ...
 
379
          */
 
380
         if (tmp_href != NULL) {
 
381
            ret = true;
 
382
         }
 
383
         /*
 
384
          * ... or is it contained on one of the attribute lists
 
385
          */
 
386
         index = 0;
 
387
         while (cqueue_attribute_array[index].cqueue_attr != NoName && !ret) {
 
388
            lList *attr_list = lGetList(this_elem,
 
389
                                    cqueue_attribute_array[index].cqueue_attr);
 
390
            lListElem *attr_elem = lGetElemHost(attr_list,
 
391
                           cqueue_attribute_array[index].href_attr, href_name);
 
392
                                                                                
 
393
            if (attr_elem != NULL) {
 
394
               ret = true;
 
395
            }
 
396
            index++;
 
397
         }
 
398
      }
 
399
   }
 
400
   return ret;
 
401
 
402
 
 
403
/****** sgeobj/cqueue/cqueue_is_hgroup_referenced() ***************************
 
404
*  NAME
 
405
*     cqueue_is_hgroup_referenced() -- is a hgroup referenced in cqueue 
 
406
*
 
407
*  SYNOPSIS
 
408
*     bool 
 
409
*     cqueue_is_hgroup_referenced(const lListElem *this_elem, 
 
410
*                                 const lListElem *hgroup) 
 
411
*
 
412
*  FUNCTION
 
413
*     Is the given "hgroup" object referenced in the cluster queue
 
414
*     "this_elem".  
 
415
*
 
416
*  INPUTS
 
417
*     const lListElem *this_elem - CQ_Type 
 
418
*     const lListElem *hgroup    - HGRP_Type 
 
419
*
 
420
*  RESULT
 
421
*     bool - true if "hgroup" is referenced
 
422
*******************************************************************************/
 
423
bool 
 
424
cqueue_is_hgroup_referenced(const lListElem *this_elem, const lListElem *hgroup)
 
425
{
 
426
   bool ret = false;
 
427
 
 
428
   if (this_elem != NULL && hgroup != NULL) {
 
429
      const char *name = lGetHost(hgroup, HGRP_name);
 
430
      
 
431
      if (name != NULL) {
 
432
         lList *href_list = lGetList(this_elem, CQ_hostlist);
 
433
         lListElem *tmp_href = lGetElemHost(href_list, HR_name, name);
 
434
 
 
435
         if (tmp_href != NULL) {
 
436
            ret = true;
 
437
         }
 
438
      }
 
439
   }
 
440
   return ret;
 
441
 
442
 
 
443
/****** sgeobj/cqueue/cqueue_is_a_href_referenced() ***************************
 
444
*  NAME
 
445
*     cqueue_is_a_href_referenced() -- Is one href referenced 
 
446
*
 
447
*  SYNOPSIS
 
448
*     bool 
 
449
*     cqueue_is_a_href_referenced(const lListElem *this_elem, 
 
450
*                                 const lList *href_list) 
 
451
*
 
452
*  FUNCTION
 
453
*     Is at least one host reference contained in "href_list" referenced
 
454
*     in the cluster queue "this_elem" 
 
455
*
 
456
*  INPUTS
 
457
*     const lListElem *this_elem - CQ_Type object
 
458
*     const lList *href_list     - HR_Type list 
 
459
*
 
460
*  RESULT
 
461
*     bool - at least one object is referenced
 
462
*******************************************************************************/
 
463
bool 
 
464
cqueue_is_a_href_referenced(const lListElem *this_elem, const lList *href_list)
 
465
{
 
466
   bool ret = false;
 
467
  
 
468
   if (this_elem != NULL && href_list != NULL) { 
 
469
      lListElem *href;
 
470
 
 
471
      for_each(href, href_list) {
 
472
         if (cqueue_is_href_referenced(this_elem, href)) {
 
473
            ret = true;
 
474
            break;
 
475
         }
 
476
      }
 
477
   }
 
478
   return ret;
 
479
 
480
 
 
481
/****** sgeobj/cqueue/cqueue_set_template_attributes() ************************
 
482
*  NAME
 
483
*     cqueue_set_template_attributes() -- Set default attributes 
 
484
*
 
485
*  SYNOPSIS
 
486
*     bool 
 
487
*     cqueue_set_template_attributes(lListElem *this_elem, 
 
488
*                                    lList **answer_list) 
 
489
*
 
490
*  FUNCTION
 
491
*     This function initializes all attributes of an empty cluster
 
492
*     queue with default values. Please note that "this_elem" has to
 
493
*     be "empty" before this function is called.  
 
494
*
 
495
*  INPUTS
 
496
*     lListElem *this_elem - CQ_Type 
 
497
*     lList **answer_list  - AN_Type 
 
498
*
 
499
*  RESULT
 
500
*     bool - error state
 
501
*        true  - success
 
502
*        false - error
 
503
*******************************************************************************/
 
504
bool
 
505
cqueue_set_template_attributes(lListElem *this_elem, lList **answer_list)
 
506
{
 
507
   bool ret = true;
 
508
 
 
509
   DENTER(CQUEUE_LAYER, "cqueue_set_template_attributes");
 
510
   if (this_elem != NULL) {
 
511
      /*
 
512
       * initialize u_long32 values
 
513
       */
 
514
      if (ret) {
 
515
         const u_long32 value[] = {
 
516
            0, 1, 1, 0 
 
517
         }; 
 
518
         const int attr[] = {
 
519
            CQ_seq_no, CQ_nsuspend, CQ_job_slots, NoName
 
520
         };
 
521
         int index = 0;
 
522
 
 
523
         while (attr[index] != NoName) {
 
524
            lList *attr_list = NULL;
 
525
            lListElem *attr_elem = lAddElemHost(&attr_list, AULNG_href, 
 
526
                                                HOSTREF_DEFAULT, AULNG_Type);
 
527
 
 
528
            lSetUlong(attr_elem, AULNG_value, value[index]);
 
529
            lSetList(this_elem, attr[index], attr_list);
 
530
            index++;
 
531
         }
 
532
      }
 
533
 
 
534
#if 0
 
535
      /*
 
536
       * initialize u_long32 values (SGEEE attributes)
 
537
       */
 
538
      if (ret ) {
 
539
         const u_long32 value[] = {
 
540
            0, 0, 0 
 
541
         }; 
 
542
         const int attr[] = {
 
543
            CQ_fshare, CQ_oticket, NoName
 
544
         };
 
545
         int index = 0;
 
546
 
 
547
         while (attr[index] != NoName) {
 
548
            lList *attr_list = NULL;
 
549
            lListElem *attr_elem = lAddElemHost(&attr_list, AULNG_href, 
 
550
                                                HOSTREF_DEFAULT, AULNG_Type);
 
551
 
 
552
            lSetUlong(attr_elem, AULNG_value, value[index]);
 
553
            lSetList(this_elem, attr[index], attr_list);
 
554
            index++;
 
555
         }
 
556
      }
 
557
#endif
 
558
 
 
559
      /*
 
560
       * qtype
 
561
       */
 
562
      if (ret) {
 
563
         const char *string = "BATCH INTERACTIVE";
 
564
         u_long32 value = 0;
 
565
         lList *attr_list = NULL;
 
566
         lListElem *attr_elem = lAddElemHost(&attr_list, AQTLIST_href,
 
567
                                             HOSTREF_DEFAULT, AQTLIST_Type);
 
568
 
 
569
         sge_parse_bitfield_str(string, queue_types, &value, "",
 
570
                                answer_list, true);
 
571
 
 
572
         lSetUlong(attr_elem, AQTLIST_value, value);
 
573
         lSetList(this_elem, CQ_qtype, attr_list);
 
574
      }
 
575
 
 
576
      /*
 
577
       * initialize bool values
 
578
       */
 
579
      if (ret) {
 
580
         lList *attr_list = NULL;
 
581
         lListElem *attr = lAddElemHost(&attr_list, ABOOL_href, 
 
582
                                        HOSTREF_DEFAULT, ABOOL_Type);
 
583
 
 
584
         lSetBool(attr, ABOOL_value, false);
 
585
         lSetList(this_elem, CQ_rerun, attr_list);
 
586
      }
 
587
 
 
588
      /*
 
589
       * initialize memory values
 
590
       */
 
591
      if (ret) {
 
592
         const char *value[] = {
 
593
            "INFINITY", "INFINITY", "INFINITY", "INFINITY",
 
594
            "INFINITY", "INFINITY", "INFINITY", "INFINITY",
 
595
            "INFINITY", "INFINITY", "INFINITY", "INFINITY",
 
596
            NULL
 
597
         }; 
 
598
         const int attr[] = {
 
599
            CQ_s_fsize, CQ_h_fsize, CQ_s_data, CQ_h_data,
 
600
            CQ_s_stack, CQ_h_stack, CQ_s_core, CQ_h_core,
 
601
            CQ_s_rss, CQ_h_rss, CQ_s_vmem, CQ_h_vmem,
 
602
            NoName
 
603
         };
 
604
         int index = 0;
 
605
 
 
606
         while (attr[index] != NoName) {
 
607
            lList *attr_list = NULL;
 
608
            lListElem *attr_elem = lAddElemHost(&attr_list, AMEM_href, 
 
609
                                                HOSTREF_DEFAULT, AMEM_Type);
 
610
 
 
611
            lSetString(attr_elem, AMEM_value, value[index]);
 
612
            lSetList(this_elem, attr[index], attr_list);
 
613
            index++;
 
614
         }
 
615
      }
 
616
      
 
617
      /*
 
618
       * initialize time values
 
619
       */
 
620
      if (ret) {
 
621
         const char *value[] = {
 
622
            "INFINITY", "INFINITY", "INFINITY", "INFINITY",
 
623
            NULL
 
624
         }; 
 
625
         const int attr[] = {
 
626
            CQ_s_rt, CQ_h_rt, CQ_s_cpu, CQ_h_cpu,
 
627
            NoName
 
628
         };
 
629
         int index = 0;
 
630
 
 
631
         while (attr[index] != NoName) {
 
632
            lList *attr_list = NULL;
 
633
            lListElem *attr_elem = lAddElemHost(&attr_list, ATIME_href, 
 
634
                                                HOSTREF_DEFAULT, ATIME_Type);
 
635
 
 
636
            lSetString(attr_elem, ATIME_value, value[index]);
 
637
            lSetList(this_elem, attr[index], attr_list);
 
638
            index++;
 
639
         }
 
640
      }
 
641
 
 
642
      /*
 
643
       * initialize interval values
 
644
       */
 
645
      if (ret) {
 
646
         const char *value[] = {
 
647
            "00:05:00", "00:05:00", "00:00:60",
 
648
            NULL
 
649
         }; 
 
650
         const int attr[] = {
 
651
            CQ_suspend_interval, CQ_min_cpu_interval, CQ_notify,
 
652
            NoName
 
653
         };
 
654
         int index = 0;
 
655
 
 
656
         while (attr[index] != NoName) {
 
657
            lList *attr_list = NULL;
 
658
            lListElem *attr_elem = lAddElemHost(&attr_list, AINTER_href, 
 
659
                                                HOSTREF_DEFAULT, AINTER_Type);
 
660
 
 
661
            lSetString(attr_elem, AINTER_value, value[index]);
 
662
            lSetList(this_elem, attr[index], attr_list);
 
663
            index++;
 
664
         }
 
665
      }
 
666
 
 
667
      /*
 
668
       * initialize string values
 
669
       */
 
670
      if (ret) {
 
671
         const char *value[] = {
 
672
            "/tmp", "/bin/csh", "NONE",
 
673
            "0", "UNDEFINED", "NONE",
 
674
            "NONE", "posix_compliant", "NONE",
 
675
            "NONE", "NONE", "NONE",
 
676
            "default", 
 
677
            NULL
 
678
         }; 
 
679
         const int attr[] = {
 
680
            CQ_tmpdir, CQ_shell, CQ_calendar,
 
681
            CQ_priority, CQ_processors, CQ_prolog,
 
682
            CQ_epilog, CQ_shell_start_mode, CQ_starter_method,
 
683
            CQ_suspend_method, CQ_resume_method, CQ_terminate_method,
 
684
            CQ_initial_state,
 
685
            NoName
 
686
         };
 
687
         int index = 0;
 
688
 
 
689
         while (attr[index] != NoName) {
 
690
            lList *attr_list = NULL;
 
691
            lListElem *attr_elem = lAddElemHost(&attr_list, ASTR_href, 
 
692
                                                HOSTREF_DEFAULT, ASTR_Type);
 
693
 
 
694
            lSetString(attr_elem, ASTR_value, value[index]);
 
695
            lSetList(this_elem, attr[index], attr_list);
 
696
            index++;
 
697
         }
 
698
      }
 
699
 
 
700
      /*
 
701
       * initialize string-list values
 
702
       */
 
703
      if (ret) {
 
704
         const int attr[] = {
 
705
            CQ_pe_list, CQ_ckpt_list,
 
706
            NoName
 
707
         };
 
708
         int index = 0;
 
709
         lList *value[] = {
 
710
            NULL, NULL, NULL
 
711
         };
 
712
 
 
713
         value[0] = lCreateList("", ST_Type);
 
714
         lAddElemStr(&(value[0]), ST_name, "make", ST_Type);
 
715
 
 
716
         while (attr[index] != NoName) {
 
717
            lList *attr_list = NULL;
 
718
            lListElem *attr_elem = lAddElemHost(&attr_list, ASTRLIST_href, 
 
719
                                                HOSTREF_DEFAULT, ASTRLIST_Type);
 
720
 
 
721
            lSetList(attr_elem, ASTRLIST_value, value[index]);
 
722
            lSetList(this_elem, attr[index], attr_list);
 
723
            index++;
 
724
         }
 
725
      }
 
726
 
 
727
      /*
 
728
       * initialize AUSRLIST_Type-list values
 
729
       */
 
730
      if (ret) {
 
731
         const int attr[] = {
 
732
            CQ_owner_list, CQ_acl, CQ_xacl,
 
733
            NoName
 
734
         };
 
735
         int index = 0;
 
736
 
 
737
         while (attr[index] != NoName) {
 
738
            lList *attr_list = NULL;
 
739
            lListElem *attr_elem = lAddElemHost(&attr_list, AUSRLIST_href, 
 
740
                                                HOSTREF_DEFAULT, AUSRLIST_Type);
 
741
 
 
742
            lSetList(attr_elem, AUSRLIST_value, NULL);
 
743
            lSetList(this_elem, attr[index], attr_list);
 
744
            index++;
 
745
         }
 
746
      }
 
747
 
 
748
      /*
 
749
       * initialize APRJLIST_Type-list values (only sgeee mode)
 
750
       */
 
751
      if (ret) {
 
752
         const int attr[] = {
 
753
            CQ_projects, CQ_xprojects,
 
754
            NoName
 
755
         };
 
756
         int index = 0;
 
757
 
 
758
         while (attr[index] != NoName) {
 
759
            lList *attr_list = NULL;
 
760
            lListElem *attr_elem = lAddElemHost(&attr_list, APRJLIST_href, 
 
761
                                                HOSTREF_DEFAULT, APRJLIST_Type);
 
762
 
 
763
            lSetList(attr_elem, APRJLIST_value, NULL);
 
764
            lSetList(this_elem, attr[index], attr_list);
 
765
            index++;
 
766
         }
 
767
      }
 
768
 
 
769
      /*
 
770
       * initialize ACELIST_Type-list values
 
771
       */
 
772
      if (ret) {
 
773
         const int attr[] = {
 
774
            CQ_load_thresholds, CQ_suspend_thresholds, 
 
775
            CQ_consumable_config_list,
 
776
            NoName
 
777
         };
 
778
         lList *value[] = {
 
779
            NULL, NULL, NULL, NULL
 
780
         };
 
781
         int index = 0;
 
782
         lListElem *elem;
 
783
 
 
784
         value[0] = lCreateList("", CE_Type);
 
785
         elem = lAddElemStr(&(value[0]), CE_name, "np_load_avg", CE_Type); 
 
786
         lSetString(elem, CE_stringval, "1.75");
 
787
 
 
788
         while (attr[index] != NoName) {
 
789
            lList *attr_list = NULL;
 
790
            lListElem *attr_elem = lAddElemHost(&attr_list, ACELIST_href, 
 
791
                                                HOSTREF_DEFAULT, ACELIST_Type);
 
792
 
 
793
            lSetList(attr_elem, ACELIST_value, value[index]);
 
794
            lSetList(this_elem, attr[index], attr_list);
 
795
            index++;
 
796
         }
 
797
      }
 
798
 
 
799
      /*
 
800
       * initialize ASOLIST_Type-list values
 
801
       */
 
802
      if (ret) {
 
803
         const int attr[] = {
 
804
            CQ_subordinate_list,
 
805
            NoName
 
806
         };
 
807
         int index = 0;
 
808
 
 
809
         while (attr[index] != NoName) {
 
810
            lList *attr_list = NULL;
 
811
            lListElem *attr_elem = lAddElemHost(&attr_list, ASOLIST_href, 
 
812
                                                HOSTREF_DEFAULT, ASOLIST_Type);
 
813
 
 
814
            lSetList(attr_elem, ASOLIST_value, NULL);
 
815
            lSetList(this_elem, attr[index], attr_list);
 
816
            index++;
 
817
         }
 
818
      }
 
819
   }
 
820
   DEXIT;
 
821
   return ret;
 
822
}
 
823
 
 
824
/****** sgeobj/cqueue/cqueue_list_add_cqueue() ********************************
 
825
*  NAME
 
826
*     cqueue_list_add_cqueue() -- Add a cluster queue to its master list 
 
827
*
 
828
*  SYNOPSIS
 
829
*     bool 
 
830
*     cqueue_list_add_cqueue(lListElem *queue) 
 
831
*
 
832
*  FUNCTION
 
833
*     Add a cluster queue in its master list. 
 
834
*
 
835
*  INPUTS
 
836
*     lListElem *queue - CQ_Type 
 
837
*
 
838
*  RESULT
 
839
*     bool - error state
 
840
*        true  - success
 
841
*        false - error
 
842
*******************************************************************************/
 
843
bool
 
844
cqueue_list_add_cqueue(lList *this_list, lListElem *queue)
 
845
{
 
846
   bool ret = false;
 
847
   static lSortOrder *so = NULL;
 
848
 
 
849
   DENTER(TOP_LAYER, "cqueue_list_add_cqueue");
 
850
 
 
851
   if (queue != NULL) {
 
852
      if (so == NULL) {
 
853
         so = lParseSortOrderVarArg(CQ_Type, "%I+", CQ_name);
 
854
      }
 
855
 
 
856
      lInsertSorted(so, queue, this_list);
 
857
      ret = true;
 
858
   } 
 
859
   DEXIT;
 
860
   return ret;
 
861
}
 
862
 
 
863
/****** sgeobj/cqueue/cqueue_list_locate() ************************************
 
864
*  NAME
 
865
*     cqueue_list_locate() -- Find a cluster queue in list 
 
866
*
 
867
*  SYNOPSIS
 
868
*     lListElem * 
 
869
*     cqueue_list_locate(const lList *this_list, 
 
870
*                        const char *name) 
 
871
*
 
872
*  FUNCTION
 
873
*    Find the cluster queue with name "name" in the list "this_list". 
 
874
*
 
875
*  INPUTS
 
876
*     const lList *this_list - CQ_Type list 
 
877
*     const char *name       - cluster queue name 
 
878
*
 
879
*  RESULT
 
880
*     lListElem * - cluster queue object or NULL
 
881
*******************************************************************************/
 
882
lListElem *
 
883
cqueue_list_locate(const lList *this_list, const char *name)
 
884
{
 
885
   return lGetElemStr(this_list, CQ_name, name);
 
886
}
 
887
 
 
888
/****** sgeobj/cqueue/cqueue_locate_qinstance() *******************************
 
889
*  NAME
 
890
*     cqueue_locate_qinstance() -- returns one qinstance from a cqueue 
 
891
*
 
892
*  SYNOPSIS
 
893
*     lListElem * 
 
894
*     cqueue_locate_qinstance(const lListElem *this_elem, 
 
895
*                             const char *hostname) 
 
896
*
 
897
*  FUNCTION
 
898
*     Finds the queue instance locateted on the host "hostname" of a
 
899
*     given cluster queue "this_elem". 
 
900
*
 
901
*  INPUTS
 
902
*     const lListElem *this_elem - CQ_Type object 
 
903
*     const char *hostname       - resolved hostname  
 
904
*
 
905
*  RESULT
 
906
*     lListElem * - qinstance object or NULL
 
907
*******************************************************************************/
 
908
lListElem *
 
909
cqueue_locate_qinstance(const lListElem *this_elem, const char *hostname)
 
910
{
 
911
   lList *qinstance_list = lGetList(this_elem, CQ_qinstances);
 
912
 
 
913
   return qinstance_list_locate(qinstance_list, hostname, NULL);
 
914
}
 
915
 
 
916
/****** sgeobj/cqueue/cqueue_verify_attributes() ******************************
 
917
*  NAME
 
918
*     cqueue_verify_attributes() -- check all cluster queue attributes 
 
919
*
 
920
*  SYNOPSIS
 
921
*     bool 
 
922
*     cqueue_verify_attributes(lListElem *cqueue, 
 
923
*                              lList **answer_list, 
 
924
*                              lListElem *reduced_elem, 
 
925
*                              bool in_master) 
 
926
*
 
927
*  FUNCTION
 
928
*     Check all cluster queue settings (and correct them if possible).
 
929
*
 
930
*        - test that there is exact one default setting 
 
931
*        - check that there is only one setting for used hgroups/hosts
 
932
*        - resolve hostnames
 
933
*        - test attribute values  
 
934
*
 
935
*  INPUTS
 
936
*     lListElem *cqueue       - CQ_Type object to be verified 
 
937
*     lList **answer_list     - AN_Type list 
 
938
*     lListElem *reduced_elem - reduced CQ_Type. Containes
 
939
*                               only those attributes to be checked  
 
940
*     bool in_master          - true if this function is called in the
 
941
*                               master code 
 
942
*
 
943
*  RESULT
 
944
*     bool - error state
 
945
*        true  - success
 
946
*        false - error
 
947
*******************************************************************************/
 
948
bool 
 
949
cqueue_verify_attributes(lListElem *cqueue, lList **answer_list,
 
950
                         lListElem *reduced_elem, bool in_master)
 
951
{
 
952
   bool ret = true;
 
953
 
 
954
   DENTER(CQUEUE_LAYER, "cqueue_verify_attributes");
 
955
   if (cqueue != NULL && reduced_elem != NULL) {
 
956
      int index = 0;
 
957
 
 
958
      while (cqueue_attribute_array[index].cqueue_attr != NoName && ret) {
 
959
         int pos = lGetPosViaElem(reduced_elem,
 
960
                                  cqueue_attribute_array[index].cqueue_attr, SGE_NO_ABORT);
 
961
 
 
962
         if (pos >= 0) {
 
963
            lList *list = NULL;
 
964
 
 
965
            list = lGetList(cqueue,
 
966
                            cqueue_attribute_array[index].cqueue_attr);
 
967
 
 
968
            /*
 
969
             * Configurations without default setting are rejected
 
970
             */
 
971
            if (ret) {
 
972
               lListElem *elem = lGetElemHost(list, 
 
973
                   cqueue_attribute_array[index].href_attr, HOSTREF_DEFAULT);
 
974
 
 
975
               if (elem == NULL) {
 
976
                  SGE_ADD_MSG_ID(sprintf(SGE_EVENT,
 
977
                                 MSG_CQUEUE_NODEFVALUE_S, 
 
978
                                 cqueue_attribute_array[index].name));
 
979
                  answer_list_add(answer_list, SGE_EVENT,
 
980
                                  STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
 
981
                  ret = false;
 
982
               } 
 
983
            }
 
984
 
 
985
            /*
 
986
             * Reject multiple settings for one domain/host
 
987
             * Resolve all hostnames
 
988
             * Verify host group names
 
989
             */
 
990
            if (ret) {
 
991
               lListElem *elem = NULL;
 
992
 
 
993
               for_each(elem, list) {
 
994
                  const char *hostname = NULL;
 
995
                  const void *iterator = NULL;
 
996
                  lListElem *first_elem = NULL;
 
997
 
 
998
                  hostname = lGetHost(elem, 
 
999
                        cqueue_attribute_array[index].href_attr);
 
1000
                  first_elem = lGetElemHostFirst(list,
 
1001
                        cqueue_attribute_array[index].href_attr,
 
1002
                        hostname, &iterator);
 
1003
 
 
1004
                  if (elem != first_elem) {
 
1005
                     SGE_ADD_MSG_ID(sprintf(SGE_EVENT,
 
1006
                                   MSG_CQUEUE_MULVALNOTALLOWED_S, hostname));
 
1007
                     answer_list_add(answer_list, SGE_EVENT,
 
1008
                                     STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
 
1009
                     ret = false;
 
1010
                     break;
 
1011
                  }
 
1012
                  if (is_hgroup_name(hostname)) {
 
1013
                     if (in_master && strcmp(hostname, HOSTREF_DEFAULT)) {
 
1014
                        const lList *master_list = 
 
1015
                              *(object_type_get_master_list(SGE_TYPE_HGROUP));
 
1016
                        const lListElem *hgroup = 
 
1017
                                    hgroup_list_locate(master_list, hostname);
 
1018
 
 
1019
                        if (hgroup == NULL) {
 
1020
                           ERROR((SGE_EVENT, MSG_CQUEUE_INVALIDDOMSETTING_SS, 
 
1021
                                  cqueue_attribute_array[index].name,
 
1022
                                  hostname));
 
1023
                           answer_list_add(answer_list, SGE_EVENT,
 
1024
                                         STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
 
1025
                           ret = false;
 
1026
                           break;
 
1027
                        } 
 
1028
                     }
 
1029
                  } else {
 
1030
                     char resolved_name[CL_MAXHOSTLEN+1];
 
1031
                     int back = getuniquehostname(hostname, resolved_name, 0);
 
1032
 
 
1033
                     if (back == CL_RETVAL_OK) {
 
1034
                        lSetHost(elem, 
 
1035
                                 cqueue_attribute_array[index].href_attr, 
 
1036
                                 resolved_name);
 
1037
                     } else {
 
1038
                        /*
 
1039
                         * Due to CR 6319231, IZ 1760 this is allowed
 
1040
                         */
 
1041
                     }
 
1042
                  }
 
1043
               }
 
1044
            }
 
1045
      
 
1046
            /*
 
1047
             * Call native verify function if it is possible
 
1048
             */
 
1049
            if (ret && 
 
1050
                cqueue_attribute_array[index].verify_function != NULL &&
 
1051
                (cqueue_attribute_array[index].verify_client || in_master)) {
 
1052
               lListElem *elem = NULL;
 
1053
 
 
1054
               for_each(elem, list) {
 
1055
                  ret &= cqueue_attribute_array[index].
 
1056
                                 verify_function(cqueue, answer_list, elem);
 
1057
               }
 
1058
            }
 
1059
         }
 
1060
         
 
1061
         index++;
 
1062
      }
 
1063
   }
 
1064
   DEXIT;
 
1065
   return ret;
 
1066
}
 
1067
 
 
1068
/****** sgeobj/cqueue/cqueue_list_find_all_matching_references() **************
 
1069
*  NAME
 
1070
*     cqueue_list_find_all_matching_references() -- as it says 
 
1071
*
 
1072
*  SYNOPSIS
 
1073
*     bool 
 
1074
*     cqueue_list_find_all_matching_references(const lList *this_list, 
 
1075
*                                              lList **answer_list, 
 
1076
*                                              const char *cqueue_pattern, 
 
1077
*                                              lList **qref_list) 
 
1078
*
 
1079
*  FUNCTION
 
1080
*     Find all cqueues in "this_list" where the cqueue name matches 
 
1081
*     the pattern "cqueue_pattern". The names of that cqueues will
 
1082
*     be added to the sublist "qref_list" (QR_Type). "answer_list" will
 
1083
*     contain an error message if this function failes.
 
1084
*
 
1085
*  INPUTS
 
1086
*     const lList *this_list     - CQ_Type 
 
1087
*     lList **answer_list        - AN_Type 
 
1088
*     const char *cqueue_pattern - fnmatch patterm 
 
1089
*     lList **qref_list          - QR_Type list 
 
1090
*
 
1091
*  RESULT
 
1092
*     bool - error state
 
1093
*        true  - success
 
1094
*        false - error 
 
1095
*
 
1096
*  NOTES
 
1097
*     MT-NOTE: cqueue_list_find_all_matching_references() is MT safe 
 
1098
*******************************************************************************/
 
1099
bool
 
1100
cqueue_list_find_all_matching_references(const lList *this_list,
 
1101
                                         lList **answer_list,
 
1102
                                         const char *cqueue_pattern,
 
1103
                                         lList **qref_list)
 
1104
{
 
1105
   bool ret = true;
 
1106
 
 
1107
   DENTER(CQUEUE_LAYER, "cqueue_list_find_all_matching_references");
 
1108
   if (this_list != NULL && cqueue_pattern != NULL && qref_list != NULL) {
 
1109
      lListElem *cqueue;
 
1110
 
 
1111
      for_each(cqueue, this_list) {
 
1112
         const char *cqueue_name = lGetString(cqueue, CQ_name);
 
1113
         /* use cqueue expression */         
 
1114
         if (!sge_eval_expression(TYPE_STR,cqueue_pattern, cqueue_name, NULL)) {
 
1115
            if (*qref_list == NULL) {
 
1116
               *qref_list = lCreateList("", QR_Type);
 
1117
            }
 
1118
            if (*qref_list != NULL) {
 
1119
               lAddElemStr(qref_list, QR_name, cqueue_name, QR_Type);
 
1120
            }
 
1121
         }
 
1122
      }
 
1123
   }
 
1124
   DEXIT;
 
1125
   return ret;
 
1126
}
 
1127
 
 
1128
/****** sgeobj/cqueue/cqueue_xattr_pre_gdi() **********************************
 
1129
*  NAME
 
1130
*     cqueue_xattr_pre_gdi() --  
 
1131
*
 
1132
*  SYNOPSIS
 
1133
*     bool 
 
1134
*     cqueue_xattr_pre_gdi(lList *this_list, lList **answer_list) 
 
1135
*
 
1136
*  FUNCTION
 
1137
*     This function makes sure that a cqueue elements has the necessary
 
1138
*     information before it is sent to qmaster as a modify gdi request
 
1139
*
 
1140
*  INPUTS
 
1141
*     lList *this_list    - CQ_Type 
 
1142
*     lList **answer_list - AN_Type 
 
1143
*
 
1144
*  RESULT
 
1145
*     bool - error state
 
1146
*        true  - success
 
1147
*        false - error ("answer_list" containes more information
 
1148
*
 
1149
*  NOTES
 
1150
*     MT-NOTE: cqueue_xattr_pre_gdi() is MT safe 
 
1151
*******************************************************************************/
 
1152
bool
 
1153
cqueue_xattr_pre_gdi(lList *this_list, lList **answer_list) 
 
1154
{
 
1155
   bool ret = true;
 
1156
   dstring cqueue_name = DSTRING_INIT;
 
1157
   dstring host_domain = DSTRING_INIT;
 
1158
 
 
1159
   DENTER(CQUEUE_LAYER, "cqueue_xattr_pre_gdi");
 
1160
   if (this_list != NULL) {
 
1161
      lListElem *cqueue = NULL;
 
1162
   
 
1163
      for_each(cqueue, this_list) {
 
1164
         const char *name = lGetString(cqueue, CQ_name);
 
1165
         bool has_hostname = false;
 
1166
         bool has_domain = false;
 
1167
 
 
1168
         cqueue_name_split(name, &cqueue_name, &host_domain,
 
1169
                           &has_hostname, &has_domain);
 
1170
         if (has_domain || has_hostname) {
 
1171
            int index = 0;
 
1172
 
 
1173
            /*
 
1174
             * Change QI/QD name to CQ name
 
1175
             */
 
1176
            lSetString(cqueue, CQ_name, sge_dstring_get_string(&cqueue_name));
 
1177
 
 
1178
            /*
 
1179
             * Make sure that there is only a default entry
 
1180
             * and change that default entry to be a QD/QI entry
 
1181
             */
 
1182
            while (cqueue_attribute_array[index].cqueue_attr != NoName && ret) {
 
1183
               int pos = lGetPosViaElem(cqueue,
 
1184
                                  cqueue_attribute_array[index].cqueue_attr, SGE_NO_ABORT);
 
1185
 
 
1186
               if (pos >= 0) {
 
1187
                  lList *list = lGetPosList(cqueue, pos);
 
1188
                  lListElem *elem = NULL;
 
1189
 
 
1190
                  for_each(elem, list) {
 
1191
                     const char *attr_hostname = lGetHost(elem, 
 
1192
                                       cqueue_attribute_array[index].href_attr);
 
1193
 
 
1194
                     if (strcmp(HOSTREF_DEFAULT, attr_hostname)) {
 
1195
                        SGE_ADD_MSG_ID(sprintf(SGE_EVENT,
 
1196
                                       MSG_CQUEUE_NONDEFNOTALLOWED));
 
1197
                        answer_list_add(answer_list, SGE_EVENT,
 
1198
                                        STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); 
 
1199
                        ret = false;
 
1200
                     } else {
 
1201
                        lSetHost(elem, cqueue_attribute_array[index].href_attr,
 
1202
                                 sge_dstring_get_string(&host_domain));
 
1203
                     }
 
1204
                  }
 
1205
               }
 
1206
               index++;
 
1207
            }
 
1208
         }
 
1209
      }
 
1210
   }
 
1211
 
 
1212
   sge_dstring_free(&host_domain);
 
1213
   sge_dstring_free(&cqueue_name);
 
1214
   DRETURN(ret);
 
1215
}
 
1216
 
 
1217
/****** sgeobj/cqueue_is_used_in_subordinate() ****************************
 
1218
*  NAME
 
1219
*     cqueue_is_used_in_subordinate() -- checks for cqueue references
 
1220
*
 
1221
*  SYNOPSIS
 
1222
*     bool cqueue_is_used_in_subordinate(const char *cqueue_name, 
 
1223
*                                        lListElem *cqueue)
 
1224
*
 
1225
*  FUNCTION
 
1226
*     The function goes through all cq subordinate definition and looks
 
1227
*     for the cq_name handed in. If it is found, the function will return
 
1228
*     true.
 
1229
*
 
1230
*  INPUTS
 
1231
*     const char *cqueue_name - cq name to look for
 
1232
*     const lListElem *cqueue - cq to look in
 
1233
*     
 
1234
*
 
1235
*  RESULT
 
1236
*     bool - true - a reference was found     
 
1237
*
 
1238
*  NOTES
 
1239
*     MT-NOTE: cqueue_is_used_in_subordinate() is MT safe 
 
1240
*******************************************************************************/
 
1241
bool
 
1242
cqueue_is_used_in_subordinate(const char *cqueue_name, const lListElem *cqueue)
 
1243
{
 
1244
   bool ret = false;
 
1245
 
 
1246
   DENTER(CQUEUE_LAYER, "cqueue_is_used_in_subordinate");
 
1247
 
 
1248
   if (cqueue != NULL && cqueue_name != NULL) {
 
1249
      const lList *sub_list = lGetList(cqueue, CQ_subordinate_list);
 
1250
      const lListElem *sub_el;
 
1251
      const lListElem *so;
 
1252
 
 
1253
      for_each(sub_el, sub_list) {
 
1254
         so = lGetSubStr(sub_el, SO_name, cqueue_name, ASOLIST_value);
 
1255
 
 
1256
         if (so != NULL) { /* we found a reference */
 
1257
            ret = true;
 
1258
            break;
 
1259
         }
 
1260
      }
 
1261
   }
 
1262
 
 
1263
   DEXIT;
 
1264
   return ret;
 
1265
}
 
1266
 
 
1267
/****** sgeobj/cqueue/cqueue_list_find_hgroup_references() ********************
 
1268
*  NAME
 
1269
*     cqueue_list_find_hgroup_references() -- find hgroup references 
 
1270
*
 
1271
*  SYNOPSIS
 
1272
*     bool 
 
1273
*     cqueue_list_find_hgroup_references(const lList *this_list, 
 
1274
*                                        lList **answer_list, 
 
1275
*                                        const lListElem *hgroup, 
 
1276
*                                        lList **string_list) 
 
1277
*
 
1278
*  FUNCTION
 
1279
*     This function add each cqueue name contained in "this_list" 
 
1280
*     to "string_list" where "hgroup" is referenced. Errors will
 
1281
*     be reported via "answer_list".
 
1282
*
 
1283
*  INPUTS
 
1284
*     const lList *this_list  - CQ_Type 
 
1285
*     lList **answer_list     - AN_Type 
 
1286
*     const lListElem *hgroup - HGRP_Type 
 
1287
*     lList **string_list     - ST_Type 
 
1288
*
 
1289
*  RESULT
 
1290
*     bool - error state
 
1291
*        true  - success
 
1292
*        false - error
 
1293
*
 
1294
*  NOTES
 
1295
*     MT-NOTE: cqueue_list_find_hgroup_references() is MT safe 
 
1296
*******************************************************************************/
 
1297
bool
 
1298
cqueue_list_find_hgroup_references(const lList *this_list, lList **answer_list,
 
1299
                                   const lListElem *hgroup, lList **string_list)
 
1300
{
 
1301
   bool ret = true;
 
1302
   lListElem *cqueue;
 
1303
 
 
1304
   DENTER(CQUEUE_LAYER, "cqueue_list_find_hgroup_references");
 
1305
   if (this_list != NULL && hgroup != NULL && string_list != NULL) {
 
1306
      for_each(cqueue, this_list) {
 
1307
         if (cqueue_is_hgroup_referenced(cqueue, hgroup)) {
 
1308
            const char *name = lGetString(cqueue, CQ_name);
 
1309
 
 
1310
            lAddElemStr(string_list, ST_name, name, ST_Type);
 
1311
         }
 
1312
      }
 
1313
   }
 
1314
   DEXIT;
 
1315
   return ret;
 
1316
}
 
1317
 
 
1318
/****** sgeobj/cqueue/cqueue_list_set_tag() ***********************************
 
1319
*  NAME
 
1320
*     cqueue_list_set_tag() -- tags each cqueue and optionally qinstance 
 
1321
*
 
1322
*  SYNOPSIS
 
1323
*     void 
 
1324
*     cqueue_list_set_tag(lList *this_list, 
 
1325
*                         u_long32 tag_value, bool tag_qinstances) 
 
1326
*
 
1327
*  FUNCTION
 
1328
*     Tags all cqueues contained in "this_list" with the value 
 
1329
*     "tag_value". Optionally all qinstances contained in the
 
1330
*     CQ_qinstances-sublist will be tagged too if "tag_qinstances" 
 
1331
*     is true. 
 
1332
*
 
1333
*  INPUTS
 
1334
*     lList *this_list    - CQ_Type 
 
1335
*     u_long32 tag_value  - value 
 
1336
*     bool tag_qinstances - true if instances should be tagged 
 
1337
*
 
1338
*  RESULT
 
1339
*     void - None
 
1340
*
 
1341
*  NOTES
 
1342
*     MT-NOTE: cqueue_list_set_tag() is MT safe 
 
1343
*******************************************************************************/
 
1344
void
 
1345
cqueue_list_set_tag(lList *this_list, u_long32 tag_value, bool tag_qinstances)
 
1346
{
 
1347
   DENTER(TOP_LAYER, "cqueue_list_set_tag");
 
1348
   if (this_list != NULL) {
 
1349
      lListElem *cqueue = NULL;
 
1350
 
 
1351
      for_each(cqueue, this_list) {
 
1352
         lSetUlong(cqueue, CQ_tag, tag_value);
 
1353
         if (tag_qinstances) {
 
1354
            lList *qinstance_list = lGetList(cqueue, CQ_qinstances);
 
1355
 
 
1356
            qinstance_list_set_tag(qinstance_list, tag_value);
 
1357
         }
 
1358
      }
 
1359
   }
 
1360
   DEXIT;
 
1361
}
 
1362
 
 
1363
/****** sgeobj/cqueue/cqueue_list_locate_qinstance() **************************
 
1364
*  NAME
 
1365
*     cqueue_list_locate_qinstance() -- finds a certain qinstance 
 
1366
*
 
1367
*  SYNOPSIS
 
1368
*     lListElem * 
 
1369
*     cqueue_list_locate_qinstance(lList *cqueue_list, const char *full_name) 
 
1370
*
 
1371
*  FUNCTION
 
1372
*     Returns a certain qinstance with the name "full_name" from
 
1373
*     the master cqueue list given by "cqueue_list". 
 
1374
*
 
1375
*  INPUTS
 
1376
*     lList *cqueue_list    - CQ_Type 
 
1377
*     const char *full_name - qinstance name of the form <CQNAME>@<HOSTNAME> 
 
1378
*
 
1379
*  RESULT
 
1380
*     lListElem * - QU_Type
 
1381
*
 
1382
*  NOTES
 
1383
*     MT-NOTE: cqueue_list_locate_qinstance() is MT safe 
 
1384
*******************************************************************************/
 
1385
lListElem *
 
1386
cqueue_list_locate_qinstance(lList *cqueue_list, const char *full_name)
 
1387
{
 
1388
   return cqueue_list_locate_qinstance_msg(cqueue_list, full_name, true);
 
1389
}
 
1390
 
 
1391
/****** sgeobj/cqueue/cqueue_list_locate_qinstance_msg() ***********************
 
1392
*  NAME
 
1393
*     cqueue_list_locate_qinstance_msg() -- finds a certain qinstance 
 
1394
*
 
1395
*  SYNOPSIS
 
1396
*     lListElem * 
 
1397
*     cqueue_list_locate_qinstance_msg(lList *cqueue_list, const char *full_name, bool raise_error) 
 
1398
*
 
1399
*  FUNCTION
 
1400
*     Returns a certain qinstance with the name "full_name" from
 
1401
*     the master cqueue list given by "cqueue_list". 
 
1402
*
 
1403
*  INPUTS
 
1404
*     lList *cqueue_list    - CQ_Type 
 
1405
*     const char *full_name - qinstance name of the form <CQNAME>@<HOSTNAME> 
 
1406
*     bool raise_error      - true - show error messages
 
1407
*                           - false - suppress error messages
 
1408
*
 
1409
*  RESULT
 
1410
*     lListElem * - QU_Type
 
1411
*
 
1412
*  NOTES
 
1413
*     MT-NOTE: cqueue_list_locate_qinstance_msg() is MT safe 
 
1414
*******************************************************************************/
 
1415
lListElem *
 
1416
cqueue_list_locate_qinstance_msg(lList *cqueue_list, const char *full_name, bool raise_error) 
 
1417
{
 
1418
   lListElem *ret = NULL;
 
1419
 
 
1420
   DENTER(TOP_LAYER, "cqueue_list_locate_qinstance");
 
1421
   if (full_name != NULL) {
 
1422
      lListElem *cqueue = NULL;
 
1423
      dstring cqueue_name_buffer = DSTRING_INIT;
 
1424
      dstring host_domain_buffer = DSTRING_INIT;
 
1425
      const char *cqueue_name = NULL;
 
1426
      const char *hostname = NULL;
 
1427
      bool has_hostname = false;
 
1428
      bool has_domain = false;
 
1429
 
 
1430
      cqueue_name_split(full_name, &cqueue_name_buffer, 
 
1431
                        &host_domain_buffer, &has_hostname, &has_domain);
 
1432
      cqueue_name = sge_dstring_get_string(&cqueue_name_buffer);
 
1433
      hostname = sge_dstring_get_string(&host_domain_buffer);
 
1434
      cqueue = lGetElemStr(cqueue_list, CQ_name, cqueue_name);
 
1435
      if (cqueue != NULL) {
 
1436
         lList *qinstance_list = lGetList(cqueue, CQ_qinstances);
 
1437
 
 
1438
         ret = lGetElemHost(qinstance_list, QU_qhostname, hostname);
 
1439
      } else {
 
1440
         if (raise_error) {
 
1441
            ERROR((SGE_EVENT, MSG_CQUEUE_CQUEUEISNULL_SSSII, full_name, 
 
1442
                    cqueue_name != NULL ? cqueue_name : "<null>", 
 
1443
                    hostname != NULL ? hostname: "<null>", 
 
1444
                    (int)has_hostname, (int)has_domain));
 
1445
         }
 
1446
      }
 
1447
      sge_dstring_free(&cqueue_name_buffer);
 
1448
      sge_dstring_free(&host_domain_buffer);
 
1449
   } else {
 
1450
      if (raise_error) {
 
1451
         ERROR((SGE_EVENT, MSG_CQUEUE_FULLNAMEISNULL));
 
1452
      }
 
1453
   }
 
1454
   DRETURN(ret);
 
1455
}
 
1456
 
 
1457
/****** sge_cqueue/cqueue_find_used_href() *************************************
 
1458
*  NAME
 
1459
*     cqueue_find_used_href() -- Finds used host references  
 
1460
*
 
1461
*  SYNOPSIS
 
1462
*     bool 
 
1463
*     cqueue_find_used_href(lListElem *this_elem, 
 
1464
*                           lList **answer_list, 
 
1465
*                           lList **href_list) 
 
1466
*
 
1467
*  FUNCTION
 
1468
*     This function returns all host references in "href_list"
 
1469
*     for which attribute specific overwritings exist in the cqueue 
 
1470
*     "this_elem". 
 
1471
*
 
1472
*  INPUTS
 
1473
*     lListElem *this_elem - CQ_Type 
 
1474
*     lList **answer_list  - AN_Type 
 
1475
*     lList **href_list    - HR_Type 
 
1476
*
 
1477
*  RESULT
 
1478
*     bool - error state
 
1479
*        true  - success
 
1480
*        false - error
 
1481
*
 
1482
*  NOTES
 
1483
*     MT-NOTE: cqueue_find_used_href() is MT safe 
 
1484
*******************************************************************************/
 
1485
bool
 
1486
cqueue_find_used_href(lListElem *this_elem, lList **answer_list, 
 
1487
                      lList **href_list) 
 
1488
{
 
1489
   bool ret = true;
 
1490
 
 
1491
   DENTER(CQUEUE_LAYER, "cqueue_find_used_href");
 
1492
   if (this_elem != NULL) {
 
1493
      int index=0;
 
1494
 
 
1495
      while (cqueue_attribute_array[index].cqueue_attr != NoName && ret) {
 
1496
         int pos = lGetPosViaElem(this_elem,
 
1497
                            cqueue_attribute_array[index].cqueue_attr, SGE_NO_ABORT);
 
1498
 
 
1499
         if (pos >= 0) {
 
1500
            lList *list = lGetPosList(this_elem, pos);
 
1501
            lListElem *elem = NULL;
 
1502
 
 
1503
            for_each(elem, list) {
 
1504
               const char *attr_hostname = lGetHost(elem, 
 
1505
                                 cqueue_attribute_array[index].href_attr);
 
1506
 
 
1507
               ret = href_list_add(href_list, answer_list, attr_hostname);
 
1508
            }
 
1509
         }
 
1510
         index++;
 
1511
      }
 
1512
   }
 
1513
   DEXIT;
 
1514
   return ret;
 
1515
}
 
1516
 
 
1517
/****** sgeobj/cqueue/cqueue_trash_used_href_setting() ************************
 
1518
*  NAME
 
1519
*     cqueue_trash_used_href_setting() -- trash certain setting 
 
1520
*
 
1521
*  SYNOPSIS
 
1522
*     bool 
 
1523
*     cqueue_trash_used_href_setting(lListElem *this_elem, 
 
1524
*                                    lList **answer_list, 
 
1525
*                                    const char *hgroup_or_hostname) 
 
1526
*
 
1527
*  FUNCTION
 
1528
*     Trash all attribute specific overwritings in "this_elem" for
 
1529
*     the give host or hgroup "hgroup_or_hostname". Errors will be 
 
1530
*     reported in "answer_list". 
 
1531
*
 
1532
*  INPUTS
 
1533
*     lListElem *this_elem           - CQ_Type 
 
1534
*     lList **answer_list            - AN_Type 
 
1535
*     const char *hgroup_or_hostname - host or hgroup name 
 
1536
*
 
1537
*  RESULT
 
1538
*     bool - error result
 
1539
*        true  - success
 
1540
*        false - error
 
1541
*
 
1542
*  NOTES
 
1543
*     MT-NOTE: cqueue_trash_used_href_setting() is MT safe 
 
1544
*******************************************************************************/
 
1545
bool
 
1546
cqueue_trash_used_href_setting(lListElem *this_elem, lList **answer_list, 
 
1547
                               const char *hgroup_or_hostname) 
 
1548
{
 
1549
   bool ret = true;
 
1550
 
 
1551
   DENTER(CQUEUE_LAYER, "cqueue_trash_used_href_setting");
 
1552
   if (this_elem != NULL) {
 
1553
      int index=0;
 
1554
 
 
1555
      while (cqueue_attribute_array[index].cqueue_attr != NoName && ret) {
 
1556
         int pos = lGetPosViaElem(this_elem,
 
1557
                            cqueue_attribute_array[index].cqueue_attr, SGE_NO_ABORT);
 
1558
 
 
1559
         if (pos >= 0) {
 
1560
            lList *list = lGetPosList(this_elem, pos);
 
1561
            lListElem *elem = NULL;
 
1562
            lListElem *next_elem = NULL;
 
1563
 
 
1564
            next_elem = lFirst(list);
 
1565
            while ((elem = next_elem) != NULL) {
 
1566
               const char *attr_hostname = lGetHost(elem, 
 
1567
                                 cqueue_attribute_array[index].href_attr);
 
1568
 
 
1569
               next_elem = lNext(elem);
 
1570
               if (!sge_hostcmp(hgroup_or_hostname, attr_hostname)) {
 
1571
                  lRemoveElem(list, &elem);
 
1572
               }
 
1573
            }
 
1574
         }
 
1575
         index++;
 
1576
      }
 
1577
   }
 
1578
   DEXIT;
 
1579
   return ret;
 
1580
}
 
1581
 
 
1582
/****** sge_cqueue/cqueue_purge_host() *****************************************
 
1583
*  NAME
 
1584
*     cqueue_purge_host() -- purge attributes from queue
 
1585
*
 
1586
*  SYNOPSIS
 
1587
*     bool cqueue_purge_host(lListElem *this_elem, lList **answer_list, lList 
 
1588
*     *attr_list, const char *hgroup_or_hostname) 
 
1589
*
 
1590
*  FUNCTION
 
1591
*     ??? 
 
1592
*
 
1593
*  INPUTS
 
1594
*     lListElem *this_elem           - cqueue list element 
 
1595
*     lList **answer_list            - answer list 
 
1596
*     lList *attr_list               - list with attributes to search for
 
1597
*                                      hgroup_or_hostname      
 
1598
*                                      wildcards allowed 
 
1599
*     const char *hgroup_or_hostname -  host group or hostname which should be purged 
 
1600
*
 
1601
*  RESULT
 
1602
*     bool -  
 
1603
*        true     - hostname found and purged
 
1604
*        false    - attribute or hostname not found    
 
1605
*
 
1606
*  NOTES
 
1607
*     MT-NOTE: cqueue_purge_host() is not MT safe 
 
1608
*
 
1609
*******************************************************************************/
 
1610
bool 
 
1611
cqueue_purge_host(lListElem *this_elem, lList **answer_list, 
 
1612
                  lList *attr_list, const char *hgroup_or_hostname)
 
1613
{
 
1614
   bool ret = false;
 
1615
   int index;
 
1616
 
 
1617
   lList *sublist = NULL;
 
1618
   lListElem *ep = NULL;
 
1619
   const char *attr_name = NULL;
 
1620
 
 
1621
   DENTER(CQUEUE_LAYER, "cqueue_purge_host");
 
1622
 
 
1623
   if (this_elem != NULL) {
 
1624
      for_each (ep, attr_list) {
 
1625
         attr_name = lGetString(ep, US_name);
 
1626
         DPRINTF((SFQ"\n", attr_name));
 
1627
      
 
1628
         /* purge hostlist */         
 
1629
         if (!sge_eval_expression(TYPE_HOST, attr_name, SGE_ATTR_HOSTLIST, NULL)) {
 
1630
            sublist = NULL;
 
1631
            lXchgList(this_elem, CQ_hostlist, &sublist);
 
1632
            if (lDelElemHost(&sublist, HR_name, hgroup_or_hostname) == 1) {
 
1633
               DPRINTF((SFQ" deleted in "SFQ"\n", hgroup_or_hostname, 
 
1634
                        SGE_ATTR_HOSTLIST ));
 
1635
               ret = true;
 
1636
            }
 
1637
            lXchgList(this_elem, CQ_hostlist, &sublist);
 
1638
         }
 
1639
         
 
1640
         /* purge attributes */ 
 
1641
         index = 0;
 
1642
         while(cqueue_attribute_array[index].name != NULL) {
 
1643
 
 
1644
            /* Does the given attr_wildcard match with the actual attr_name */         
 
1645
            if (!sge_eval_expression(TYPE_STR, attr_name, cqueue_attribute_array[index].name, NULL)) {
 
1646
               sublist = lGetList(this_elem, 
 
1647
                                  cqueue_attribute_array[index].cqueue_attr );
 
1648
 
 
1649
               if (lDelElemHost(&sublist, 
 
1650
                                cqueue_attribute_array[index].href_attr, 
 
1651
                                hgroup_or_hostname) == 1) {
 
1652
                  DPRINTF((SFQ" deleted in "SFQ"\n", hgroup_or_hostname, 
 
1653
                           cqueue_attribute_array[index].name ));
 
1654
                  ret = true;
 
1655
               }
 
1656
            }
 
1657
            index++;
 
1658
         }
 
1659
      }
 
1660
   }
 
1661
 
 
1662
   DEXIT;
 
1663
   return ret;
 
1664
}
 
1665
 
 
1666
bool
 
1667
cqueue_sick(lListElem *cqueue, lList **answer_list, 
 
1668
            lList *master_hgroup_list, dstring *ds)
 
1669
{
 
1670
   bool ret = true;
 
1671
 
 
1672
   DENTER(TOP_LAYER, "cqueue_sick");
 
1673
 
 
1674
   /*
 
1675
    * Warn about:
 
1676
    *    - unused setting for attributes
 
1677
    *    - hgroup settings were not all hosts are contained in hostlist
 
1678
    */
 
1679
   {
 
1680
      const char *cqueue_name = lGetString(cqueue, CQ_name);
 
1681
      lList *used_hosts = NULL;
 
1682
      lList *used_groups = NULL;
 
1683
      lList **answer_list = NULL;
 
1684
      int index;
 
1685
      
 
1686
      /*
 
1687
       * resolve href list of cqueue
 
1688
       */
 
1689
      href_list_find_all_references(lGetList(cqueue, CQ_hostlist), answer_list,
 
1690
                                    master_hgroup_list, &used_hosts,
 
1691
                                    &used_groups);
 
1692
 
 
1693
      index = 0;
 
1694
      while (cqueue_attribute_array[index].cqueue_attr != NoName) {
 
1695
         /*
 
1696
          * Skip geee attributes in ge mode
 
1697
          */
 
1698
         lList *attr_list = lGetList(cqueue,
 
1699
                                 cqueue_attribute_array[index].cqueue_attr);
 
1700
         lListElem *next_attr = lFirst(attr_list);
 
1701
         lListElem *attr = NULL;
 
1702
 
 
1703
         /*
 
1704
          * Test each attribute setting if it is really used in the
 
1705
          * current configuration
 
1706
          */
 
1707
         while((attr = next_attr) != NULL) { 
 
1708
            const char *name = lGetHost(attr, 
 
1709
                                   cqueue_attribute_array[index].href_attr);
 
1710
 
 
1711
            next_attr = lNext(attr);
 
1712
            if (is_hgroup_name(name)) {
 
1713
               if (strcmp(name, HOSTREF_DEFAULT)) {
 
1714
                  lListElem *hgroup = NULL;
 
1715
                  lList *used_hgroup_hosts = NULL;
 
1716
                  lList *used_hgroup_groups = NULL;
 
1717
                  lList *add_hosts = NULL;
 
1718
                  lList *equity_hosts = NULL;
 
1719
 
 
1720
                  hgroup = hgroup_list_locate(master_hgroup_list, name);
 
1721
 
 
1722
                  /*
 
1723
                   * hgroup specific setting:
 
1724
                   *    make sure each host of hgroup is part of 
 
1725
                   *    resolved list
 
1726
                   */
 
1727
                  hgroup_find_all_references(hgroup, answer_list, 
 
1728
                                             master_hgroup_list, 
 
1729
                                             &used_hgroup_hosts,
 
1730
                                             &used_hgroup_groups);
 
1731
                  href_list_compare(used_hgroup_hosts, answer_list,
 
1732
                                    used_hosts, &add_hosts, NULL,
 
1733
                                    &equity_hosts, NULL);
 
1734
 
 
1735
                  if (lGetNumberOfElem(add_hosts)) {
 
1736
                     DTRACE;
 
1737
                     sge_dstring_sprintf_append(ds, 
 
1738
                             MSG_CQUEUE_DEFOVERWRITTEN_SSSSS,
 
1739
                             cqueue_attribute_array[index].name,
 
1740
                             name, cqueue_name, name, cqueue_name);
 
1741
                     sge_dstring_append(ds, "\n");
 
1742
                  }
 
1743
 
 
1744
                  lFreeList(&add_hosts);
 
1745
                  lFreeList(&equity_hosts);
 
1746
                  lFreeList(&used_hgroup_hosts);
 
1747
                  lFreeList(&used_hgroup_groups);
 
1748
               } else {
 
1749
                  DTRACE;
 
1750
               }
 
1751
            } else {
 
1752
               /*
 
1753
                * host specific setting:
 
1754
                *    make sure the host is contained in resolved list 
 
1755
                */ 
 
1756
               if (!href_list_has_member(used_hosts, name)) {
 
1757
                  DTRACE;
 
1758
                  sge_dstring_sprintf_append(ds, 
 
1759
                             MSG_CQUEUE_UNUSEDATTRSETTING_SS,
 
1760
                             cqueue_attribute_array[index].name,
 
1761
                             name, cqueue_name);
 
1762
                  sge_dstring_append(ds, "\n");
 
1763
               } else {
 
1764
                  DTRACE;
 
1765
               }
 
1766
            }
 
1767
         }
 
1768
            
 
1769
         index++;
 
1770
      }
 
1771
      lFreeList(&used_hosts);
 
1772
      lFreeList(&used_groups);
 
1773
   }
 
1774
   
 
1775
   DRETURN(ret);
 
1776
}
 
1777