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

« back to all changes in this revision

Viewing changes to source/daemons/qmaster/sge_utility_qmaster.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 <string.h>
 
33
#include <ctype.h>
 
34
 
 
35
#include "cull.h"
 
36
#include "sgermon.h"
 
37
#include "sge_string.h"
 
38
#include "sge_log.h"
 
39
#include "gdi/sge_gdi.h"
 
40
#include "sge_answer.h"
 
41
#include "sge_utility.h"
 
42
#include "sge_parse_num_par.h"
 
43
#include "sge_complex_schedd.h"
 
44
#include "msg_sgeobjlib.h"
 
45
#include "sort_hosts.h"
 
46
#include "config_file.h"
 
47
#include "sge_host.h"
 
48
#include "sge_userset.h"
 
49
#include "sge_centry.h"
 
50
#include "cl_errors.h"
 
51
#include "cl_commlib.h"
 
52
#include "sge_object.h"
 
53
#include "msg_common.h"
 
54
#include "msg_qmaster.h"
 
55
#include "sge_host_qmaster.h"
 
56
 
 
57
#define CQUEUE_LAYER TOP_LAYER
 
58
 
 
59
/****** sge_utility_qmaster/attr_mod_procedure() *******************************
 
60
*  NAME
 
61
*     attr_mod_procedure() -- modify the prolog/epilog/pe_start/pe_stop procedures
 
62
*
 
63
*  SYNOPSIS
 
64
*     int attr_mod_procedure(lList **alpp, lListElem *qep, lListElem *new_ep, 
 
65
*     int nm, char *attr_name, char *variables[]) 
 
66
*
 
67
*  FUNCTION
 
68
*     This function modifies a prolog/epilog/pe_start/pe_stop of "new_qep".
 
69
*     The attribute of "qep" element is identified by nm.
 
70
*     Possible errors will be reported in "alpp". "qep"
 
71
*     "qep" element will be used to identify the changes which have been done.
 
72
*     "attr_name" is used to report errors
 
73
*
 
74
*  INPUTS
 
75
*     lList **alpp      - AN_Type, The answer list 
 
76
*     lListElem *qep    - CQ_Type, reduced changes source element 
 
77
*     lListElem *new_ep - CQ_Type, target element 
 
78
*     int nm            - CULL attribute name (CQ_Type)
 
79
*     char *attr_name   - CULL sublist attribute name of that
 
80
*                              field which containes the value of
 
81
*                              the attribute to be modified. 
 
82
*     char *variables[] - procedure variables 
 
83
*
 
84
*  RESULT
 
85
*     int - 0 success, error othewise
 
86
*
 
87
*  NOTES
 
88
*     MT-NOTE: attr_mod_procedure() is MT safe 
 
89
*
 
90
*******************************************************************************/
 
91
int attr_mod_procedure( lList **alpp, lListElem *qep, lListElem *new_ep, int nm, char *attr_name, char *variables[])
 
92
{
 
93
   DENTER(TOP_LAYER, "attr_mod_procedure");
 
94
 
 
95
   /* ---- attribute nm */
 
96
   if (lGetPosViaElem(qep, nm, SGE_NO_ABORT)>=0) {
 
97
      const char *s; 
 
98
      DPRINTF(("got new %s\n", attr_name));
 
99
 
 
100
      s = lGetString(qep, nm);
 
101
      if (s) {
 
102
         char *t; 
 
103
         const char *script = s;
 
104
 
 
105
         /* skip user name */
 
106
         if ((t = strpbrk(script, "@ ")) && *t == '@')
 
107
            script = &t[1];
 
108
 
 
109
         /* force use of absolut pathes */ 
 
110
         if (script[0] != '/' ) { 
 
111
            ERROR((SGE_EVENT, MSG_GDI_APATH_S, attr_name));
 
112
            answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
 
113
            DEXIT;
 
114
            return STATUS_EEXIST;
 
115
         } 
 
116
        
 
117
         /* ensure that variables are valid */
 
118
         if (replace_params(script, NULL, 0, variables )) {
 
119
            ERROR((SGE_EVENT, MSG_GDI_VARS_SS, attr_name, err_msg));
 
120
            answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR);
 
121
            DEXIT;
 
122
            return STATUS_EEXIST;
 
123
         }
 
124
      }
 
125
      lSetString(new_ep, nm, s);
 
126
   }
 
127
 
 
128
   DEXIT;
 
129
   return 0;
 
130
}
 
131
 
 
132
/****** sge_utility_qmaster/attr_mod_zerostr() *********************************
 
133
*  NAME
 
134
*     attr_mod_zerostr() -- modify strings, no verification 
 
135
*
 
136
*  SYNOPSIS
 
137
*     int attr_mod_zerostr(lListElem *qep, lListElem *new_ep, int nm, char 
 
138
*     *attr_name) 
 
139
*
 
140
*  FUNCTION
 
141
*      This function modifies "new_qep" attribute with string from "qep 
 
142
*      without any verification. NULL is a valid value.  
 
143
*
 
144
*  INPUTS
 
145
*     lListElem *qep    - CQ_Type, source of the modification 
 
146
*     lListElem *new_ep - CQ_Type, destination of the modification 
 
147
*     int nm            - CULL attribute name (CQ_Type) of the element
 
148
*     char *attr_name   - CULL sublist attribute name 
 
149
*
 
150
*  RESULT
 
151
*     int - 0, success, othewise error
 
152
*
 
153
*  NOTES
 
154
*     MT-NOTE: attr_mod_zerostr() is MT safe 
 
155
*
 
156
*******************************************************************************/
 
157
int attr_mod_zerostr( lListElem *qep, lListElem *new_ep, int nm, char *attr_name )
 
158
{
 
159
   DENTER(TOP_LAYER, "attr_mod_zerostr");
 
160
 
 
161
   /* ---- attribute nm */
 
162
   if (lGetPosViaElem(qep, nm, SGE_NO_ABORT)>=0) {
 
163
      DPRINTF(("got new %s\n", attr_name));
 
164
      lSetString(new_ep, nm, lGetString(qep, nm));
 
165
   }
 
166
 
 
167
   DEXIT;
 
168
   return 0;
 
169
}
 
170
 
 
171
/****** sge_utility_qmaster/attr_mod_str() *************************************
 
172
*  NAME
 
173
*     attr_mod_str() -- modify strings except that it may not be NULL 
 
174
*
 
175
*  SYNOPSIS
 
176
*     int attr_mod_str(lList **alpp, lListElem *qep, lListElem *new_ep, int nm, 
 
177
*     char *attr_name) 
 
178
*
 
179
*  FUNCTION
 
180
*      This function modifies "new_qep" attribute with string from "qep 
 
181
*      except that the value of an attribute may not be NULL.  
 
182
*
 
183
*  INPUTS
 
184
*     lList **alpp      - AN_Type, The answer list 
 
185
*     lListElem *qep    - CQ_Type, source of the modification 
 
186
*     lListElem *new_ep - CQ_Type, destination of the modification 
 
187
*     int nm            - CULL attribute name (CQ_Type) of the element
 
188
*     char *attr_name   - CULL sublist attribute name 
 
189
*
 
190
*  RESULT
 
191
*     int -  0 success, othewise error
 
192
*
 
193
*  NOTES
 
194
*     MT-NOTE: attr_mod_str() is MT safe 
 
195
*     
 
196
*******************************************************************************/
 
197
int attr_mod_str(lList **alpp, lListElem *qep, lListElem *new_ep, int nm, char *attr_name)
 
198
{
 
199
   int dataType;
 
200
   int pos;
 
201
  
 
202
   DENTER(TOP_LAYER, "attr_mod_str");
 
203
 
 
204
   /* ---- attribute nm */
 
205
   if ((pos=lGetPosViaElem(qep, nm, SGE_NO_ABORT))>=0) {
 
206
      const char *s;
 
207
 
 
208
      DPRINTF(("got new %s\n", attr_name));
 
209
 
 
210
      dataType = lGetPosType(lGetElemDescr(qep),pos);
 
211
      switch (dataType) {
 
212
         case lStringT:
 
213
            if (!(s = lGetString(qep, nm))) {
 
214
               ERROR((SGE_EVENT, MSG_GDI_VALUE_S, lNm2Str(nm)));
 
215
               answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
 
216
               DEXIT;
 
217
               return STATUS_EUNKNOWN;
 
218
            }
 
219
            lSetString(new_ep, nm, s);
 
220
            break;
 
221
         case lHostT:
 
222
            if (!(s = lGetHost(qep, nm))) {
 
223
               ERROR((SGE_EVENT, MSG_GDI_VALUE_S, attr_name));
 
224
               answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
 
225
               DEXIT;
 
226
               return STATUS_EUNKNOWN;
 
227
            }
 
228
            lSetHost(new_ep, nm, s);
 
229
            break;
 
230
         default:
 
231
            DPRINTF(("unexpected data type\n"));
 
232
            DEXIT;
 
233
            return STATUS_EUNKNOWN;
 
234
      }
 
235
   }
 
236
 
 
237
   DEXIT;
 
238
   return 0;
 
239
}
 
240
 
 
241
/****** sge_utility_qmaster/attr_mod_bool() ************************************
 
242
*  NAME
 
243
*     attr_mod_bool() -- modify raw boolean, no verification 
 
244
*
 
245
*  SYNOPSIS
 
246
*     int attr_mod_bool(lListElem *qep, lListElem *new_ep, int nm, char 
 
247
*     *attr_name) 
 
248
*
 
249
*  FUNCTION
 
250
*     This function modifies "new_qep" attribute with boolean value from "qep"
 
251
*
 
252
*  INPUTS
 
253
*     lListElem *qep    - CQ_Type, source of the modification 
 
254
*     lListElem *new_ep - CQ_Type, destination of the modification 
 
255
*     int nm            - CULL attribute name (CQ_Type) of the element
 
256
*     char *attr_name   - CULL sublist attribute name 
 
257
*
 
258
*  RESULT
 
259
*     int - 0 succes, othewise error
 
260
*
 
261
*  NOTES
 
262
*     MT-NOTE: attr_mod_bool() is MT safe 
 
263
*
 
264
*******************************************************************************/
 
265
int attr_mod_bool( lListElem *qep, lListElem *new_ep, int nm, char *attr_name)
 
266
{
 
267
   DENTER(TOP_LAYER, "attr_mod_ulong");
 
268
 
 
269
   /* ---- attribute nm */
 
270
   if (lGetPosViaElem(qep, nm, SGE_NO_ABORT)>=0) {
 
271
      DPRINTF(("got new %s\n", attr_name));
 
272
      lSetBool(new_ep, nm, lGetBool(qep, nm));
 
273
   }
 
274
 
 
275
   DEXIT;
 
276
   return 0;
 
277
}
 
278
 
 
279
/****** sge_utility_qmaster/attr_mod_ulong() ***********************************
 
280
*  NAME
 
281
*     attr_mod_ulong() -- modify raw ulong, no verification 
 
282
*
 
283
*  SYNOPSIS
 
284
*     int attr_mod_ulong(lListElem *qep, lListElem *new_ep, int nm, char 
 
285
*     *attr_name) 
 
286
*
 
287
*  FUNCTION
 
288
*     This function modifies "new_qep" attribute with boolean value from "qep"
 
289
*
 
290
*  INPUTS
 
291
*     lListElem *qep    - CQ_Type, source of the modification 
 
292
*     lListElem *new_ep - CQ_Type, destination of the modification 
 
293
*     int nm            - CULL attribute name (CQ_Type) of the element
 
294
*     char *attr_name   - CULL sublist attribute name 
 
295
*
 
296
*  RESULT
 
297
*     int - 0 succes, othewise error
 
298
*
 
299
*  NOTES
 
300
*     MT-NOTE: attr_mod_ulong() is MT safe 
 
301
*    
 
302
*******************************************************************************/
 
303
int attr_mod_ulong(lListElem *qep, lListElem *new_ep, int nm, char *attr_name)
 
304
{
 
305
   DENTER(TOP_LAYER, "attr_mod_ulong");
 
306
 
 
307
   /* ---- attribute nm */
 
308
   if (lGetPosViaElem(qep, nm, SGE_NO_ABORT)>=0) {
 
309
      DPRINTF(("got new %s\n", attr_name));
 
310
      lSetUlong(new_ep, nm, lGetUlong(qep, nm));
 
311
   }
 
312
 
 
313
   DRETURN(0);
 
314
}
 
315
 
 
316
/****** sge_utility_qmaster/attr_mod_double() **********************************
 
317
*  NAME
 
318
*     attr_mod_double() --  modify raw double, no verification 
 
319
*
 
320
*  SYNOPSIS
 
321
*     int attr_mod_double(lListElem *qep, lListElem *new_ep, int nm, char 
 
322
*     *attr_name) 
 
323
*
 
324
*  FUNCTION
 
325
*    This function modifies "new_qep" attribute with double value from "qep" 
 
326
*
 
327
*  INPUTS
 
328
*     lListElem *qep    - CQ_Type, source of the modification 
 
329
*     lListElem *new_ep - CQ_Type, destination of the modification 
 
330
*     int nm            - CULL attribute name (CQ_Type) of the element
 
331
*     char *attr_name   - CULL sublist attribute name 
 
332
*
 
333
*  RESULT
 
334
*     int - 0 success, othewise error
 
335
*
 
336
*  NOTES
 
337
*     MT-NOTE: attr_mod_double() is MT safe 
 
338
*
 
339
*******************************************************************************/
 
340
int attr_mod_double(lListElem *qep, lListElem *new_ep, int nm, char *attr_name)
 
341
{
 
342
   DENTER(TOP_LAYER, "attr_mod_double");
 
343
 
 
344
   /* ---- attribute nm */
 
345
   if (lGetPosViaElem(qep, nm, SGE_NO_ABORT)>=0) {
 
346
      DPRINTF(("got new %s\n", attr_name));
 
347
      lSetDouble(new_ep, nm, lGetDouble(qep, nm));
 
348
   }
 
349
 
 
350
   DEXIT;
 
351
   return 0;
 
352
}
 
353
 
 
354
/****** sge_utility_qmaster/attr_mod_mem_str() *********************************
 
355
*  NAME
 
356
*     attr_mod_mem_str() -- modify memory string, NULL is not allowed 
 
357
*
 
358
*  SYNOPSIS
 
359
*     int attr_mod_mem_str(lList **alpp, lListElem *qep, lListElem *new_ep, int 
 
360
*     nm, char *attr_name) 
 
361
*
 
362
*  FUNCTION
 
363
*      This function modifies "new_qep" attribute with string from "qep 
 
364
*      except that the value of an memory attribute may not be NULL.  
 
365
*
 
366
*  INPUTS
 
367
*     lList **alpp      - AN_Type, The answer list 
 
368
*     lListElem *qep    - CQ_Type, source of the modification 
 
369
*     lListElem *new_ep - CQ_Type, destination of the modification 
 
370
*     int nm            - CULL attribute name (CQ_Type) of the element
 
371
*     char *attr_name   - CULL sublist attribute name
 
372
*
 
373
*  RESULT
 
374
*     int - 0 success, othewise error
 
375
*
 
376
*  NOTES
 
377
*     MT-NOTE: attr_mod_mem_str() is MT safe 
 
378
*
 
379
*******************************************************************************/
 
380
int attr_mod_mem_str(lList **alpp, lListElem *qep, lListElem *new_ep, int nm, char *attr_name)
 
381
{
 
382
   DENTER(TOP_LAYER, "attr_mod_mem_str");
 
383
 
 
384
   /* ---- attribute nm */
 
385
   if (lGetPosViaElem(qep, nm, SGE_NO_ABORT)>=0) {
 
386
      const char *str;
 
387
 
 
388
      str = lGetString(qep, nm);
 
389
      DPRINTF(("got new %s\n", attr_name));
 
390
 
 
391
      if(!parse_ulong_val(NULL, NULL, TYPE_MEM, str, NULL, 0)) {
 
392
         SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_GDI_TYPE_MEM_SS, attr_name, str?str:"(null)"));
 
393
         answer_list_add(alpp, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
 
394
         DEXIT;
 
395
         return STATUS_ESYNTAX;
 
396
      }
 
397
 
 
398
      lSetString(new_ep, nm, str);
 
399
   }
 
400
 
 
401
   DEXIT;
 
402
   return 0;
 
403
}
 
404
 
 
405
/****** sge_utility_qmaster/attr_mod_time_str() ********************************
 
406
*  NAME
 
407
*     attr_mod_time_str() -- modify a valid time string
 
408
*
 
409
*  SYNOPSIS
 
410
*     int attr_mod_time_str(lList **alpp, lListElem *qep, lListElem *new_ep, 
 
411
*     int nm, char *attr_name, int enable_infinity) 
 
412
*
 
413
*  FUNCTION
 
414
*     This function modifies "new_qep" attribute with string from "qep" 
 
415
*     The value of an time_str attribute may not be NULL and must be valid.
 
416
*       
 
417
*  INPUTS
 
418
*     lList **alpp      - AN_Type, The answer list 
 
419
*     lListElem *qep    - CQ_Type, source of the modification 
 
420
*     lListElem *new_ep - CQ_Type, destination of the modification 
 
421
*     int nm            - CULL attribute name (CQ_Type) of the element
 
422
*     char *attr_name   - CULL sublist attribute name 
 
423
*     int enable_infinity - The "infinity" string can be there
 
424
*
 
425
*  RESULT
 
426
*     int - 0 on success, othewise error
 
427
*
 
428
*  NOTES
 
429
*     MT-NOTE: attr_mod_time_str() is MT safe 
 
430
*
 
431
*******************************************************************************/
 
432
int attr_mod_time_str(lList **alpp, lListElem *qep, lListElem *new_ep, int nm, char *attr_name, int enable_infinity)
 
433
{
 
434
   DENTER(TOP_LAYER, "attr_mod_time_str");
 
435
 
 
436
   /* ---- attribute nm */
 
437
   if (lGetPosViaElem(qep, nm, SGE_NO_ABORT)>=0) {
 
438
      const char *str; 
 
439
 
 
440
      str = lGetString(qep, nm);
 
441
      DPRINTF(("got new %s\n", attr_name));
 
442
 
 
443
      if (str != NULL ) {
 
444
         /* don't allow infinity for these parameters */
 
445
         if ((strcasecmp(str, "infinity") == 0) && (enable_infinity == 0)) { 
 
446
              DPRINTF(("ERROR! Infinity value for \"%s\"\n",attr_name));
 
447
              SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_GDI_SIG_DIGIT_SS, attr_name, str));
 
448
              answer_list_add(alpp, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
 
449
              DEXIT;
 
450
              return STATUS_ESYNTAX;
 
451
         }
 
452
      }
 
453
 
 
454
      if(!parse_ulong_val(NULL, NULL, TYPE_TIM, str, NULL, 0)) {
 
455
         SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_GDI_TYPE_TIME_SS, attr_name, str?str:"(null)"));
 
456
         answer_list_add(alpp, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
 
457
         DEXIT;
 
458
         return STATUS_ESYNTAX;
 
459
      }
 
460
 
 
461
      lSetString(new_ep, nm, str);
 
462
   }
 
463
 
 
464
   DEXIT;
 
465
   return 0;
 
466
}
 
467
 
 
468
/****** sge_utility_qmaster/attr_mod_sub_list() ********************************
 
469
*  NAME
 
470
*     attr_mod_sub_list() -- This function modifies a certain configuration sublist 
 
471
*
 
472
*  SYNOPSIS
 
473
*     bool attr_mod_sub_list(lList **alpp, lListElem *this_elem, int 
 
474
*     this_elem_name, int this_elem_primary_key, lListElem *delta_elem, int 
 
475
*     sub_command, const char *sub_list_name, const char *object_name, int 
 
476
*     no_info) 
 
477
*
 
478
*  FUNCTION
 
479
*     This function modifies a certain configuration sublist of "this_elem".
 
480
*     Possible errors will be reported in answer_list "alpp". The reduced_elem 
 
481
*     "delta_elem" will be used to identify the changes which have been made.
 
482
*     "sub_command" defines how these changes should be applied to "this_elem".
 
483
*
 
484
*  INPUTS
 
485
*     lList **alpp              - The AN_Type, answer_list
 
486
*     lListElem *this_elem      - The target object element, CQ_Type 
 
487
*     int this_elem_name        - The name of the list elemet (lList) 
 
488
*     int this_elem_primary_key - The primary field for sublist 
 
489
*     lListElem *delta_elem     - The source (probably reduced) list of the elements, CQ_Type 
 
490
*     int sub_command           - The add, modify, remove command, GDI subcommand
 
491
*     const char *sub_list_name - The sublist name
 
492
*     const char *object_name   - The target object name
 
493
*     int no_info               - Skip or add the info messages 
 
494
*
 
495
*  RESULT
 
496
*     bool - true, the success
 
497
*
 
498
*  NOTES
 
499
*     MT-NOTE: attr_mod_sub_list() is MT safe 
 
500
*
 
501
*******************************************************************************/
 
502
bool attr_mod_sub_list(lList **alpp, lListElem *this_elem, int this_elem_name,
 
503
                  int this_elem_primary_key, lListElem *delta_elem,
 
504
                  int sub_command, const char *sub_list_name, 
 
505
                  const char *object_name,
 
506
                  int no_info) 
 
507
{
 
508
   bool ret = true;
 
509
 
 
510
   DENTER(TOP_LAYER, "attr_mod_sub_list");
 
511
   if (lGetPosViaElem(delta_elem, this_elem_name, SGE_NO_ABORT) >= 0) {
 
512
      if (SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_CHANGE) ||
 
513
          SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_APPEND) ||
 
514
          SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_REMOVE)) {
 
515
         lList *reduced_sublist;
 
516
         lList *full_sublist;
 
517
         lListElem *reduced_element, *next_reduced_element;
 
518
         lListElem *full_element, *next_full_element;
 
519
 
 
520
         reduced_sublist = lGetList(delta_elem, this_elem_name);
 
521
         full_sublist = lGetList(this_elem, this_elem_name);
 
522
         next_reduced_element = lFirst(reduced_sublist);
 
523
         /*
 
524
         ** we try to find each element of the delta_elem
 
525
         ** in the sublist if this_elem. Elements which can be found
 
526
         ** will be moved into sublist of this_elem.
 
527
         */
 
528
         while ((reduced_element = next_reduced_element)) {
 
529
            int restart_loop = 0;
 
530
 
 
531
            next_reduced_element = lNext(reduced_element);
 
532
            next_full_element = lFirst(full_sublist);
 
533
            while ((full_element = next_full_element)) {
 
534
               int pos, type;
 
535
               const char *rstring = NULL, *fstring = NULL;
 
536
 
 
537
               next_full_element = lNext(full_element);
 
538
 
 
539
               pos = lGetPosViaElem(reduced_element, this_elem_primary_key, SGE_NO_ABORT);
 
540
               type = lGetPosType(lGetElemDescr(reduced_element), pos);            
 
541
               if (type == lStringT) {
 
542
                  rstring = lGetString(reduced_element, this_elem_primary_key);
 
543
                  fstring = lGetString(full_element, this_elem_primary_key);
 
544
               } else if (type == lHostT) {
 
545
                  rstring = lGetHost(reduced_element, this_elem_primary_key);
 
546
                  fstring = lGetHost(full_element, this_elem_primary_key);
 
547
               }
 
548
 
 
549
               if (rstring == NULL || fstring == NULL) {
 
550
                  ERROR((SGE_EVENT, MSG_OBJECT_VALUEMISSING));
 
551
                  answer_list_add(alpp, SGE_EVENT, STATUS_ESEMANTIC,
 
552
                                  ANSWER_QUALITY_ERROR);
 
553
                  ret = false;
 
554
               }
 
555
 
 
556
               if (ret && 
 
557
                   (((type == lStringT) && strcmp(rstring, fstring) == 0) ||
 
558
                   ((type == lHostT) && sge_hostcmp(rstring, fstring) == 0))) {
 
559
                  lListElem *new_sub_elem;
 
560
                  lListElem *old_sub_elem;
 
561
 
 
562
                  next_reduced_element = lNext(reduced_element);
 
563
                  new_sub_elem =
 
564
                     lDechainElem(reduced_sublist, reduced_element);
 
565
                  old_sub_elem = lDechainElem(full_sublist, full_element);
 
566
                  if (SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_CHANGE) ||
 
567
                      SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_APPEND)) {
 
568
 
 
569
                     if (!no_info && SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_APPEND)) {
 
570
                        INFO((SGE_EVENT, MSG_OBJECT_ALREADYEXIN_SSS,
 
571
                              rstring, sub_list_name, object_name));
 
572
                        answer_list_add(alpp, SGE_EVENT, STATUS_OK, 
 
573
                                        ANSWER_QUALITY_INFO);
 
574
                        ret = false;
 
575
                        /* break; No "break" here. It will follow below! */
 
576
                     }
 
577
 
 
578
                     lFreeElem(&old_sub_elem);
 
579
                     lAppendElem(full_sublist, new_sub_elem);
 
580
 
 
581
                     restart_loop = 1;
 
582
                     break;
 
583
                  } else if (SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_REMOVE)) {
 
584
 
 
585
                     lFreeElem(&old_sub_elem);
 
586
                     lFreeElem(&new_sub_elem);
 
587
 
 
588
                     restart_loop = 1;
 
589
                     break;
 
590
                  }
 
591
               }
 
592
            }
 
593
            if (!ret) {
 
594
               break;
 
595
            }
 
596
            if (restart_loop) {
 
597
               next_reduced_element = lFirst(reduced_sublist);
 
598
            }
 
599
         }
 
600
         if (ret && (SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_CHANGE) ||
 
601
             SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_APPEND) ||
 
602
             SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_REMOVE))) {
 
603
             next_reduced_element = lFirst(reduced_sublist);
 
604
 
 
605
            while ((reduced_element = next_reduced_element)) {
 
606
               int pos, type;
 
607
               const char *rstring = NULL;
 
608
               lListElem *new_sub_elem;
 
609
 
 
610
               next_reduced_element = lNext(reduced_element);
 
611
 
 
612
               pos = lGetPosViaElem(reduced_element, this_elem_primary_key, SGE_NO_ABORT);
 
613
               type = lGetPosType(lGetElemDescr(reduced_element), pos);            
 
614
               if (type == lStringT) {
 
615
                  rstring = lGetString(reduced_element, this_elem_primary_key);
 
616
               } else if (type == lHostT) {
 
617
                  rstring = lGetHost(reduced_element, this_elem_primary_key);
 
618
               }
 
619
 
 
620
               if (rstring == NULL) {
 
621
                  ERROR((SGE_EVENT, MSG_OBJECT_VALUEMISSING));
 
622
                  answer_list_add(alpp, SGE_EVENT, STATUS_ESEMANTIC,
 
623
                                  ANSWER_QUALITY_ERROR);
 
624
                  ret = false;
 
625
               }
 
626
 
 
627
               if (ret) {
 
628
                  if (!no_info && SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_REMOVE)) {
 
629
                     INFO((SGE_EVENT, SFQ" does not exist in "SFQ" of "SFQ"\n",
 
630
                           rstring, sub_list_name, object_name));
 
631
                     answer_list_add(alpp, SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO);
 
632
                  } else {
 
633
                     if (!full_sublist) {
 
634
                        if (!no_info && SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_CHANGE)) {
 
635
                           INFO((SGE_EVENT, SFQ" of "SFQ" is empty - "
 
636
                              "Adding new element(s).\n",
 
637
                              sub_list_name, object_name));
 
638
                           answer_list_add(alpp, SGE_EVENT, STATUS_OK, 
 
639
                                           ANSWER_QUALITY_INFO);
 
640
                        }
 
641
                        lSetList(this_elem, this_elem_name, lCopyList("",
 
642
                           lGetList(delta_elem, this_elem_name)));
 
643
                        full_sublist = lGetList(this_elem, this_elem_name);
 
644
                        break;
 
645
                     } else {
 
646
                        if (!no_info && SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_CHANGE)) {
 
647
                           INFO((SGE_EVENT, "Unable to find "SFQ" in "SFQ" of "SFQ
 
648
                              " - Adding new element.\n", rstring,
 
649
                              sub_list_name, object_name));
 
650
                           answer_list_add(alpp, SGE_EVENT, STATUS_OK, 
 
651
                                           ANSWER_QUALITY_INFO);
 
652
                        }
 
653
                        new_sub_elem =
 
654
                           lDechainElem(reduced_sublist, reduced_element);
 
655
                        lAppendElem(full_sublist, new_sub_elem);
 
656
                     }
 
657
                  }
 
658
               }
 
659
            }
 
660
         }
 
661
      } else {
 
662
         /*
 
663
         ** Overwrite the complete list
 
664
         */
 
665
         lSetList(this_elem, this_elem_name, lCopyList("",
 
666
            lGetList(delta_elem, this_elem_name)));
 
667
      }
 
668
      /*
 
669
      ** If the list does not contain any elements, we will delete
 
670
      ** the list itself
 
671
      */
 
672
      if (ret) {
 
673
         const lList *tmp_list = lGetList(this_elem, this_elem_name);
 
674
 
 
675
         if (tmp_list != NULL && lGetNumberOfElem(tmp_list) == 0) {
 
676
            lSetList(this_elem, this_elem_name, NULL);
 
677
         }
 
678
      }
 
679
   } else {
 
680
      ret = false;
 
681
   }
 
682
   DRETURN(ret);
 
683
}
 
684
 
 
685
 
 
686
/****** sgeobj/cqueue/cqueue_mod_sublist() ***********************************
 
687
*  NAME
 
688
*     cqueue_mod_sublist() -- modify cqueues configuration sublist 
 
689
*
 
690
*  SYNOPSIS
 
691
*     bool 
 
692
*     cqueue_mod_sublist(lListElem *this_elem, lList **answer_list, 
 
693
*                        lListElem *reduced_elem, int sub_command, 
 
694
*                        int attribute_name, int sublist_host_name, 
 
695
*                        int sublist_value_name, int subsub_key, 
 
696
*                        const char *attribute_name_str, 
 
697
*                        const char *object_name_str) 
 
698
*
 
699
*  FUNCTION
 
700
*     This function modifies a certain configuration sublist of "this_elem".
 
701
*     Possible errors will be reported in "answer_list". "reduced_elem"
 
702
*     will be used to identify the changes which have been done.
 
703
*     "sub_command" defines how these changes should be applied to 
 
704
*     "this_elem". "sublist_value_name" is the sublist of "this_elem" which
 
705
*     should be modified whereas "subsub_key" defines the attribute
 
706
*     which containes the primary key of that sublist. "attribute_name_str"
 
707
*     is the name of the cqueue attribute which will be modified with
 
708
*     this operation. It will be used for error output. "object_name_str"
 
709
*     is the name of the cqueue which will be modified by this operation.
 
710
*      
 
711
*
 
712
*  INPUTS
 
713
*     lListElem *this_elem           - CQ_Type 
 
714
*     lList **answer_list            - AN_Type 
 
715
*     lListElem *reduced_elem        - reduced CQ_Type element 
 
716
*     int sub_command                - GDI subcommand 
 
717
*     int attribute_name             - CULL attribute name (CQ_Type)
 
718
*     int sublist_host_name          - CULL sublist attribute name
 
719
*                                      depend on sublist of CQ_Type 
 
720
*     int sublist_value_name         - CULL sublist attribute name of that
 
721
*                                      field which containes the value of
 
722
*                                      the attribute to be modified.
 
723
*     int subsub_key                 - CULL sublist attribute key
 
724
*     const char *attribute_name_str - string used for user output 
 
725
*     const char *object_name_str    - cqueue name 
 
726
*
 
727
*  RESULT
 
728
*     bool - error state
 
729
*        true  - success
 
730
*        false - error
 
731
*
 
732
*  NOTES
 
733
*     MT-NOTE: cqueue_mod_sublist() is MT safe 
 
734
*******************************************************************************/
 
735
bool
 
736
cqueue_mod_sublist(lListElem *this_elem, lList **answer_list,
 
737
                   lListElem *reduced_elem, int sub_command,
 
738
                   int attribute_name, int sublist_host_name,
 
739
                   int sublist_value_name, int subsub_key,
 
740
                   const char *attribute_name_str, 
 
741
                   const char *object_name_str) 
 
742
{
 
743
   bool ret = true;
 
744
   int pos;
 
745
 
 
746
   DENTER(CQUEUE_LAYER, "cqueue_mod_sublist");
 
747
 
 
748
   pos = lGetPosViaElem(reduced_elem, attribute_name, SGE_NO_ABORT);
 
749
   if (pos >= 0) {
 
750
      lList *mod_list = lGetPosList(reduced_elem, pos);
 
751
      lList *org_list = lGetList(this_elem, attribute_name);
 
752
      lListElem *mod_elem;
 
753
 
 
754
      /* 
 
755
       * Delete all configuration lists except the default-configuration
 
756
       * if sub_command is SGE_GDI_SET_ALL
 
757
       */
 
758
      if (SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_SET_ALL)) {
 
759
         lListElem *elem, *next_elem;
 
760
 
 
761
         next_elem = lFirst(org_list);
 
762
         while ((elem = next_elem)) {
 
763
            const char *name = lGetHost(elem, sublist_host_name);
 
764
 
 
765
            next_elem = lNext(elem); 
 
766
            mod_elem = lGetElemHost(mod_list, sublist_host_name, name);
 
767
            if (mod_elem == NULL) {
 
768
               DPRINTF(("Removing attribute list for "SFQ"\n", name));
 
769
               lRemoveElem(org_list, &elem);
 
770
            }
 
771
         }
 
772
      }
 
773
 
 
774
      /*
 
775
       * Do modifications for all given elements of 
 
776
       * domain/host-configuration list
 
777
       */
 
778
      for_each(mod_elem, mod_list) {
 
779
         const char *name = lGetHost(mod_elem, sublist_host_name);
 
780
         char resolved_name[CL_MAXHOSTLEN+1];
 
781
         lListElem *org_elem = NULL;
 
782
         
 
783
         if (name == NULL) {
 
784
            ERROR((SGE_EVENT, MSG_SGETEXT_INVALIDHOST_S, ""));
 
785
            answer_list_add(answer_list, SGE_EVENT,
 
786
                            STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
 
787
            ret = false;
 
788
            break;
 
789
         }
 
790
         /* Don't try to resolve hostgroups */
 
791
         if (name[0] != '@') {
 
792
            int back = getuniquehostname(name, resolved_name, 0);
 
793
 
 
794
            if (back == CL_RETVAL_OK) {
 
795
               /* 
 
796
                * This assignment is ok because preious name contained a const
 
797
                * string from the mod_elem that we didn't need to free.  
 
798
                * Now it will contain a string that's on the stack, 
 
799
                * so we still don't have to free it. 
 
800
                */
 
801
               name = resolved_name;
 
802
            } else {
 
803
               /*
 
804
                * Due to CR 6319231, IZ 1760 this is allowed
 
805
                */
 
806
            }
 
807
         }
 
808
         
 
809
         org_elem = lGetElemHost(org_list, sublist_host_name, name);
 
810
 
 
811
         /*
 
812
          * Create element if it does not exist
 
813
          */
 
814
         if (org_elem == NULL && !SGE_GDI_IS_SUBCOMMAND_SET(sub_command, SGE_GDI_REMOVE)) {
 
815
            if (org_list == NULL) {
 
816
               org_list = lCreateList("", lGetElemDescr(mod_elem));
 
817
               lSetList(this_elem, attribute_name, org_list);
 
818
            } 
 
819
            org_elem = lCreateElem(lGetElemDescr(mod_elem));
 
820
            lSetHost(org_elem, sublist_host_name, name);
 
821
            lAppendElem(org_list, org_elem);
 
822
         }
 
823
 
 
824
         /*
 
825
          * Modify sublist according to subcommand
 
826
          */
 
827
         if (org_elem != NULL) {
 
828
            if (subsub_key != NoName) {
 
829
               attr_mod_sub_list(answer_list, org_elem, sublist_value_name, 
 
830
                                 subsub_key, mod_elem, sub_command, 
 
831
                                 attribute_name_str, object_name_str, 0);
 
832
            } else {
 
833
               object_replace_any_type(org_elem, sublist_value_name, mod_elem);
 
834
            }
 
835
         }
 
836
      }
 
837
   }
 
838
 
 
839
   DEXIT;
 
840
   return ret;
 
841
}
 
842
 
 
843
int multiple_occurances(
 
844
lList **alpp,
 
845
lList *lp1,
 
846
lList *lp2,
 
847
int nm,
 
848
const char *name,
 
849
const char *obj_name 
 
850
) {
 
851
   lListElem *ep1;
 
852
   const char *s;
 
853
 
 
854
   DENTER(TOP_LAYER, "multiple_occurances");
 
855
 
 
856
   if (!lp1 || !lp2) {
 
857
      DEXIT;
 
858
      return 0;
 
859
   }
 
860
 
 
861
   for_each (ep1, lp1) {
 
862
      s = lGetString(ep1, nm);
 
863
      if (lGetElemStr(lp2, nm, s)) {
 
864
         SGE_ADD_MSG_ID(sprintf(SGE_EVENT, MSG_GDI_MULTIPLE_OCCUR_SSSS, 
 
865
                  (nm==US_name)?MSG_OBJ_USERSET:MSG_JOB_PROJECT, s, obj_name, name));
 
866
         answer_list_add(alpp, SGE_EVENT, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
 
867
         DEXIT;
 
868
         return -1;
 
869
      }
 
870
   }
 
871
 
 
872
   DEXIT;
 
873
   return 0;
 
874
}
 
875
 
 
876
void normalize_sublist(
 
877
lListElem *ep,
 
878
int nm 
 
879
) {
 
880
   lList *lp;
 
881
 
 
882
   if ((lp=lGetList(ep, nm)) && lGetNumberOfElem(lp)==0)
 
883
      lSetList(ep, nm, NULL);
 
884
}
 
885