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

« back to all changes in this revision

Viewing changes to source/libs/sgeobj/sge_ckpt.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 <strings.h>
 
34
#include <ctype.h>
 
35
 
 
36
#include "sgermon.h"
 
37
#include "sge_log.h"
 
38
#include "cull_list.h"
 
39
 
 
40
#include "config_file.h"
 
41
#include "sge_signal.h"
 
42
 
 
43
#include "sge_answer.h"
 
44
#include "sge_job.h"
 
45
#include "sge_cqueue.h"
 
46
#include "sge_attrL.h"
 
47
#include "sge_qinstance.h"
 
48
#include "sge_utility.h"
 
49
#include "sge_ckpt.h"
 
50
#include "symbols.h"
 
51
#include "sge_str.h"
 
52
#include "sgeobj/sge_object.h"
 
53
 
 
54
#include "msg_common.h"
 
55
#include "msg_sgeobjlib.h"
 
56
 
 
57
/****** sgeobj/ckpt/ckpt_is_referenced() **************************************
 
58
*  NAME
 
59
*     ckpt_is_referenced() -- Is a given CKPT referenced in other objects? 
 
60
*
 
61
*  SYNOPSIS
 
62
*     bool ckpt_is_referenced(const lListElem *ckpt, lList **answer_list, 
 
63
*                             const lList *master_job_list,
 
64
*                             const lList *master_cqueue_list) 
 
65
*
 
66
*  FUNCTION
 
67
*     This function returns true if the given "ckpt" is referenced
 
68
*     in at least one of the objects contained in "master_job_list" or
 
69
*     "master_cqueue_list". If this is the case than
 
70
*     a corresponding message will be added to the "answer_list". 
 
71
*
 
72
*  INPUTS
 
73
*     const lListElem *ckpt           - CK_Type object 
 
74
*     lList **answer_list             - AN_Type list 
 
75
*     const lList *master_job_list    - JB_Type list 
 
76
*     const lList *master_cqueue_list - CQ_Type list
 
77
*
 
78
*  RESULT
 
79
*     bool - true or false  
 
80
******************************************************************************/
 
81
bool ckpt_is_referenced(const lListElem *ckpt, lList **answer_list,
 
82
                        const lList *master_job_list, 
 
83
                        const lList *master_cqueue_list)
 
84
{
 
85
   bool ret = false;
 
86
 
 
87
   {
 
88
      lListElem *job = NULL;
 
89
 
 
90
      for_each(job, master_job_list) {
 
91
         if (job_is_ckpt_referenced(job, ckpt)) {
 
92
            const char *ckpt_name = lGetString(ckpt, CK_name);
 
93
            u_long32 job_id = lGetUlong(job, JB_job_number);
 
94
 
 
95
            answer_list_add_sprintf(answer_list, STATUS_EUNKNOWN,
 
96
                                    ANSWER_QUALITY_INFO, MSG_CKPTREFINJOB_SU,
 
97
                                    ckpt_name, sge_u32c(job_id));
 
98
            ret = true;
 
99
            break;
 
100
         }
 
101
      } 
 
102
   }
 
103
   if (!ret) {
 
104
      lListElem *queue = NULL, *ckl = NULL;
 
105
 
 
106
      /* fix for bug 6422335
 
107
       * check the cq configuration for ckpt references instead of qinstances
 
108
       */
 
109
      const char *ckpt_name = lGetString(ckpt, CK_name);
 
110
 
 
111
      for_each(queue, master_cqueue_list) {
 
112
         for_each(ckl, lGetList(queue, CQ_ckpt_list)){
 
113
            if (lGetSubStr(ckl, ST_name, ckpt_name, ASTRLIST_value))  {
 
114
               answer_list_add_sprintf(answer_list, STATUS_EUNKNOWN,
 
115
                                       ANSWER_QUALITY_INFO, 
 
116
                                       MSG_CKPTREFINQUEUE_SS,
 
117
                                       ckpt_name, lGetString(queue, CQ_name));
 
118
               ret = true;
 
119
               break;
 
120
            }
 
121
         }
 
122
      }
 
123
   }
 
124
   return ret;
 
125
}
 
126
 
 
127
/****** sgeobj/ckpt/ckpt_list_locate() ***************************************
 
128
*  NAME
 
129
*     ckpt_list_locate -- find a ckpt object in a list 
 
130
*
 
131
*  SYNOPSIS
 
132
*     lListElem *ckpt_list_locate(lList *ckpt_list, const char *ckpt_name)
 
133
*
 
134
*  FUNCTION
 
135
*     This function will return a ckpt object by name if it exists.
 
136
*
 
137
*
 
138
*  INPUTS
 
139
*     lList *ckpt_list      - CK_Type object
 
140
*     const char *ckpt_name - name of the ckpt object. 
 
141
*
 
142
*  RESULT
 
143
*     NULL - ckpt object with name "ckpt_name" does not exist
 
144
*     !NULL - pointer to the cull element (CK_Type) 
 
145
******************************************************************************/
 
146
lListElem *ckpt_list_locate(const lList *ckpt_list, const char *ckpt_name)
 
147
{
 
148
   return lGetElemStr(ckpt_list, CK_name, ckpt_name);
 
149
}
 
150
 
 
151
/****** sgeobj/ckpt/sge_parse_checkpoint_attr() *******************************
 
152
*  NAME
 
153
*     sge_parse_checkpoint_attr() -- make "when" bitmask from string 
 
154
*
 
155
*  SYNOPSIS
 
156
*     int sge_parse_checkpoint_attr(const char *attr_str) 
 
157
*
 
158
*  FUNCTION
 
159
*     Parse checkpoint "when" string and return a bitmask. 
 
160
*
 
161
*  INPUTS
 
162
*     const char *attr_str - when string 
 
163
*
 
164
*  RESULT
 
165
*     int - bitmask of checkpoint specifers
 
166
*           0 if attr_str == NULL or nothing set or value 
 
167
*           may be a time value 
 
168
*
 
169
*  NOTES
 
170
*     MT-NOTE: sge_parse_checkpoint_attr() is MT safe
 
171
*******************************************************************************/
 
172
int sge_parse_checkpoint_attr(const char *attr_str)
 
173
{
 
174
   int opr;
 
175
 
 
176
   if (attr_str == NULL) {
 
177
      return 0;
 
178
   }
 
179
 
 
180
   /* May be it's a time value */
 
181
   if (isdigit((int) *attr_str) || (*attr_str == ':')) {
 
182
      return 0;
 
183
   }
 
184
 
 
185
   opr = 0;
 
186
   while (*attr_str) {
 
187
      if (*attr_str == CHECKPOINT_AT_MINIMUM_INTERVAL_SYM)
 
188
         opr = opr | CHECKPOINT_AT_MINIMUM_INTERVAL;
 
189
      else if (*attr_str == CHECKPOINT_AT_SHUTDOWN_SYM)
 
190
         opr = opr | CHECKPOINT_AT_SHUTDOWN;
 
191
      else if (*attr_str == CHECKPOINT_SUSPEND_SYM)
 
192
         opr = opr | CHECKPOINT_SUSPEND;
 
193
      else if (*attr_str == NO_CHECKPOINT_SYM)
 
194
         opr = opr | NO_CHECKPOINT;
 
195
      else if (*attr_str == CHECKPOINT_AT_AUTO_RES_SYM)
 
196
         opr = opr | CHECKPOINT_AT_AUTO_RES;
 
197
      else {
 
198
         opr = -1;
 
199
         break;
 
200
      }
 
201
      attr_str++;
 
202
   }
 
203
 
 
204
   return opr;
 
205
}
 
206
 
 
207
/****** sgeobj/ckpt/ckpt_validate() ******************************************
 
208
*  NAME
 
209
*     ckpt_validate -- validate all ckpt interface parameters
 
210
*
 
211
*  SYNOPSIS
 
212
*     int ckpt_validate(lListElem *ep, lList **alpp);
 
213
*
 
214
*  FUNCTION
 
215
*     This function will test all ckpt interface parameters.
 
216
*     If all are valid then it will return successfull.
 
217
*
 
218
*  INPUTS
 
219
*     ep     - element which sould be verified.
 
220
*     answer - answer list where the function stored error messages
 
221
*
 
222
*  RESULT
 
223
*     [answer] - error messages will be added to this list
 
224
*     STATUS_OK - success
 
225
*     STATUS_EUNKNOWN or STATUS_EEXIST - error
 
226
*
 
227
*  NOTES
 
228
*     MT-NOTE: ckpt_validate() is not MT safe
 
229
******************************************************************************/
 
230
int ckpt_validate(const lListElem *this_elem, lList **alpp)
 
231
{
 
232
   static const char* ckpt_interfaces[] = {
 
233
      "USERDEFINED",
 
234
      "HIBERNATOR",
 
235
      "TRANSPARENT",
 
236
      "APPLICATION-LEVEL",
 
237
      "CPR",
 
238
      "CRAY-CKPT"
 
239
   };
 
240
   static struct attr {
 
241
      int nm;
 
242
      char *text;
 
243
   } ckpt_commands[] = {
 
244
      { CK_ckpt_command, "ckpt_command" },
 
245
      { CK_migr_command, "migr_command" },
 
246
      { CK_rest_command, "restart_command"},
 
247
      { CK_clean_command, "clean_command"},
 
248
      { NoName,           NULL} };
 
249
 
 
250
   int i;
 
251
   int found = 0;
 
252
   const char *s, *interface;
 
253
 
 
254
   DENTER(TOP_LAYER, "ckpt_validate");
 
255
 
 
256
   if (!this_elem) {
 
257
      CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC));
 
258
      answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
 
259
      DEXIT;
 
260
      return STATUS_EUNKNOWN;
 
261
   }
 
262
 
 
263
   /* -------- CK_name */
 
264
   if (verify_str_key(
 
265
         alpp, lGetString(this_elem, CK_name), 
 
266
         MAX_VERIFY_STRING, "checkpoint interface", KEY_TABLE) != STATUS_OK) {
 
267
      DEXIT;
 
268
      return STATUS_EUNKNOWN;
 
269
   }
 
270
 
 
271
   /*
 
272
    * check if ckpt obj can be added
 
273
    * check allowed interfaces and license
 
274
    */
 
275
   interface = lGetString(this_elem, CK_interface);
 
276
   found = 0;
 
277
   /* handle NULL pointer for interface name */
 
278
   if (interface == NULL) {
 
279
      interface = "<null>";
 
280
   } else {
 
281
 
 
282
      for (i=0; i < (sizeof(ckpt_interfaces)/sizeof(char*)); i++) {
 
283
         if (!strcasecmp(interface, ckpt_interfaces[i])) {
 
284
            found = 1;
 
285
            break;
 
286
         }
 
287
      }
 
288
   }
 
289
 
 
290
   if (!found) {
 
291
      ERROR((SGE_EVENT, MSG_SGETEXT_NO_INTERFACE_S, interface));
 
292
      answer_list_add(alpp, SGE_EVENT, 
 
293
                      STATUS_ESEMANTIC, ANSWER_QUALITY_ERROR);
 
294
      DEXIT;
 
295
      return STATUS_EEXIST;
 
296
   }
 
297
 
 
298
   for (i = 0; ckpt_commands[i].nm != NoName; i++) {
 
299
      if (replace_params(lGetString(this_elem, ckpt_commands[i].nm),
 
300
               NULL, 0, ckpt_variables)) {
 
301
         ERROR((SGE_EVENT, MSG_OBJ_CKPTENV_SSS,
 
302
               ckpt_commands[i].text, lGetString(this_elem, CK_name), err_msg));
 
303
         answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR);
 
304
         DEXIT;
 
305
         return STATUS_EEXIST;
 
306
      }
 
307
   }
 
308
 
 
309
   /* -------- CK_signal */
 
310
   if ((s=lGetString(this_elem, CK_signal)) &&
 
311
         strcasecmp(s, "none") &&
 
312
         sge_sys_str2signal(s)==-1) {
 
313
      ERROR((SGE_EVENT, MSG_CKPT_XISNOTASIGNALSTRING_S , s));
 
314
      answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR);
 
315
      DEXIT;
 
316
      return STATUS_EEXIST;
 
317
   }
 
318
 
 
319
   DEXIT;
 
320
   return STATUS_OK;
 
321
}
 
322
 
 
323
/****** sgeobj/ckpt/ckpt_list_get_master_list() *******************************
 
324
*  NAME
 
325
*     ckpt_list_get_master_list() -- Return pointer to master ckpt list 
 
326
*
 
327
*  SYNOPSIS
 
328
*     lList ** ckpt_list_get_master_list(void) 
 
329
*
 
330
*  FUNCTION
 
331
*     Return pointer to master ckpt list 
 
332
*
 
333
*  RESULT
 
334
*     lList ** - master ckpt list
 
335
*******************************************************************************/
 
336
lList **
 
337
ckpt_list_get_master_list(void)
 
338
{
 
339
   return object_type_get_master_list(SGE_TYPE_CKPT);
 
340
}
 
341
 
 
342
/****** sgeobj/ckpt/ckpt_list_do_all_exist() **********************************
 
343
*  NAME
 
344
*     ckpt_list_do_all_exist() -- Do all ckpt's exist? 
 
345
*
 
346
*  SYNOPSIS
 
347
*     bool 
 
348
*     ckpt_list_do_all_exist(const lList *ckpt_list, 
 
349
*                            lList **answer_list, 
 
350
*                            const lList *ckpt_ref_list) 
 
351
*
 
352
*  FUNCTION
 
353
*     Test if the checkpointing objects whose name is contained in
 
354
*     "ckpt_ref_list" is contained in "ckpt_list". 
 
355
*
 
356
*  INPUTS
 
357
*     const lList *ckpt_list     - CK_Type list 
 
358
*     lList **answer_list        - AN_Type list 
 
359
*     const lList *ckpt_ref_list - ST_Type list containing ckpt names 
 
360
*
 
361
*  RESULT
 
362
*     bool - true if all ckpt objects exist 
 
363
*******************************************************************************/
 
364
bool
 
365
ckpt_list_do_all_exist(const lList *ckpt_list, lList **answer_list,
 
366
                       const lList *ckpt_ref_list)
 
367
{
 
368
   bool ret = true;
 
369
   lListElem *ckpt_ref_elem = NULL;
 
370
 
 
371
   DENTER(TOP_LAYER, "ckpt_list_do_all_exist");
 
372
   for_each(ckpt_ref_elem, ckpt_ref_list) {
 
373
      const char *ckpt_ref_string = lGetString(ckpt_ref_elem, ST_name);
 
374
 
 
375
      if (ckpt_list_locate(ckpt_list, ckpt_ref_string) == NULL) {
 
376
         answer_list_add_sprintf(answer_list, STATUS_EEXIST,
 
377
                                 ANSWER_QUALITY_ERROR,
 
378
                                 MSG_CKPTREFDOESNOTEXIST_S, ckpt_ref_string);
 
379
         ret = false;
 
380
         break;
 
381
      }
 
382
   }
 
383
   DEXIT;
 
384
   return ret;
 
385
}
 
386
 
 
387
 
 
388
/****** src/sge_generic_ckpt() **********************************************
 
389
*
 
390
*  NAME
 
391
*     sge_generic_ckpt -- build up a generic ckpt object
 
392
*
 
393
*  SYNOPSIS
 
394
*     lListElem* sge_generic_ckpt(
 
395
*        char *ckpt_name
 
396
*     );
 
397
*
 
398
*  FUNCTION
 
399
*     build up a generic ckpt object
 
400
*
 
401
*  INPUTS
 
402
*     ckpt_name - name used for the CK_name attribute of the generic
 
403
*               pe object. If NULL then "template" is the default name.
 
404
*
 
405
*  RESULT
 
406
*     !NULL - Pointer to a new CULL object of type CK_Type
 
407
*     NULL - Error
 
408
*
 
409
*  EXAMPLE
 
410
*
 
411
*  NOTES
 
412
*
 
413
*  BUGS
 
414
*
 
415
*  SEE ALSO
 
416
*
 
417
*****************************************************************************/   
 
418
lListElem* sge_generic_ckpt(
 
419
char *ckpt_name 
 
420
) {
 
421
   lListElem *ep;
 
422
 
 
423
   DENTER(TOP_LAYER, "sge_generic_ckpt");
 
424
 
 
425
   ep = lCreateElem(CK_Type);
 
426
 
 
427
   if (ckpt_name)
 
428
      lSetString(ep, CK_name, ckpt_name);
 
429
   else
 
430
      lSetString(ep, CK_name, "template");
 
431
 
 
432
   lSetString(ep, CK_interface, "userdefined");
 
433
   lSetString(ep, CK_ckpt_command, "none");
 
434
   lSetString(ep, CK_migr_command, "none");
 
435
   lSetString(ep, CK_rest_command, "none");
 
436
   lSetString(ep, CK_clean_command, "none");
 
437
   lSetString(ep, CK_ckpt_dir, "/tmp");
 
438
   lSetString(ep, CK_when, "sx");
 
439
   lSetString(ep, CK_signal, "none");
 
440
   lSetUlong(ep, CK_job_pid, 0);
 
441
 
 
442
   DEXIT;
 
443
   return ep;
 
444
}
 
445