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

« back to all changes in this revision

Viewing changes to source/daemons/qmaster/sge_persistence_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
 
 
33
#include "basis_types.h"
 
34
#include "sgermon.h"
 
35
#include "sge_log.h"
 
36
#include "cull.h"
 
37
#include "sge_bootstrap.h"
 
38
#include "sge_answer.h"
 
39
#include "sge_event.h"
 
40
#include "sge_object.h"
 
41
#include "sge_job.h"
 
42
#include "sge_event_master.h"
 
43
#include "spool/sge_spooling.h"
 
44
#include "spool/loader/sge_spooling_loader.h"
 
45
#include "sge_persistence_qmaster.h"
 
46
#include "sgeobj/sge_host.h"
 
47
 
 
48
#include "msg_qmaster.h"
 
49
 
 
50
static unsigned long spooling_wait_time = 0;
 
51
 
 
52
bool
 
53
sge_initialize_persistence(sge_gdi_ctx_class_t *ctx, lList **answer_list)
 
54
{
 
55
   bool ret = true;
 
56
 
 
57
   lListElem *spooling_context;
 
58
   const char *spooling_method = ctx->get_spooling_method(ctx);
 
59
   const char *spooling_lib = ctx->get_spooling_lib(ctx);
 
60
   const char *spooling_params = ctx->get_spooling_params(ctx);
 
61
 
 
62
   DENTER(TOP_LAYER, "sge_initialize_persistence");
 
63
 
 
64
   if (getenv("SGE_TEST_SPOOLING_WAIT_TIME_US") != NULL) {
 
65
         spooling_wait_time=atoi(getenv("SGE_TEST_SPOOLING_WAIT_TIME_US"));
 
66
   }
 
67
 
 
68
   /* create spooling context */
 
69
   spooling_context = spool_create_dynamic_context(answer_list, 
 
70
                           spooling_method,
 
71
                           spooling_lib, 
 
72
                           spooling_params);
 
73
   if (spooling_context == NULL) {
 
74
      /* error message created in spool_create_dynamic_context */
 
75
      ret = false;
 
76
   } else {
 
77
      /* set options: enable recovery at startup (bdb) */
 
78
      spool_set_option(answer_list, spooling_context, "recover=true");
 
79
 
 
80
      /* startup spooling context */
 
81
      if (!spool_startup_context(answer_list, spooling_context, true)) {
 
82
         /* error message created in spool_startup_context */
 
83
         ret = false;
 
84
      } else {
 
85
         /* set this context as default */
 
86
         spool_set_default_context(spooling_context);
 
87
      }
 
88
   }
 
89
 
 
90
   DEXIT;
 
91
   return ret;
 
92
}
 
93
 
 
94
void
 
95
sge_initialize_persistance_timer(void)
 
96
{
 
97
   te_event_t ev = NULL;
 
98
 
 
99
   DENTER(TOP_LAYER, "sge_initialize_persistance_timer");
 
100
 
 
101
   te_register_event_handler(spooling_trigger_handler, TYPE_SPOOLING_TRIGGER);
 
102
 
 
103
   ev = te_new_event(time(NULL), TYPE_SPOOLING_TRIGGER, ONE_TIME_EVENT, 0, 0, NULL);
 
104
   te_add_event(ev);
 
105
   te_free_event(&ev);
 
106
 
 
107
   DRETURN_VOID;
 
108
}
 
109
 
 
110
bool
 
111
sge_shutdown_persistence(lList **answer_list)
 
112
{
 
113
   bool ret = true;
 
114
   time_t time = 0;
 
115
   lList* alp = NULL;
 
116
   lListElem *context;
 
117
 
 
118
   DENTER(TOP_LAYER, "sge_shutdown_persistence");
 
119
 
 
120
   /* trigger spooling actions (flush data) */
 
121
   if (!spool_trigger_context(&alp, spool_get_default_context(), 0, &time)) {
 
122
      answer_list_output(&alp);
 
123
   }
 
124
 
 
125
   /* shutdown spooling */
 
126
   context = spool_get_default_context();
 
127
   if (context != NULL) {
 
128
      lList *local_answer = NULL;
 
129
 
 
130
      if (answer_list != NULL) {
 
131
         local_answer = *answer_list;
 
132
      }
 
133
 
 
134
      spool_shutdown_context(&local_answer, context);
 
135
      if (answer_list == NULL) {
 
136
         answer_list_output(&local_answer);
 
137
      }
 
138
 
 
139
      lFreeElem(&context);
 
140
      spool_set_default_context(context);
 
141
   }
 
142
 
 
143
   DEXIT;
 
144
   return ret;
 
145
}
 
146
 
 
147
void
 
148
spooling_trigger_handler(sge_gdi_ctx_class_t *ctx, te_event_t anEvent, monitoring_t *monitor)
 
149
{
 
150
   time_t next_trigger = 0;
 
151
   time_t now;
 
152
   lList *answer_list = NULL;
 
153
   te_event_t ev = NULL;
 
154
 
 
155
   DENTER(TOP_LAYER, "deliver_spooling_trigger");
 
156
 
 
157
   /* trigger spooling regular actions */
 
158
   if (!spool_trigger_context(&answer_list, spool_get_default_context(), 
 
159
                              te_get_when(anEvent), &next_trigger)) {
 
160
      answer_list_output(&answer_list);
 
161
   }
 
162
 
 
163
   /* validate next_trigger. If it is invalid, set it to one minute after now */
 
164
   now = time(0);
 
165
   if (next_trigger <= now) {
 
166
      next_trigger = now + 60;
 
167
   }
 
168
 
 
169
   /* set timerevent for next trigger */
 
170
   ev = te_new_event(next_trigger, te_get_type(anEvent), ONE_TIME_EVENT, 0, 0, NULL);
 
171
   te_add_event(ev);
 
172
   te_free_event(&ev);
 
173
 
 
174
   DEXIT;
 
175
   return;
 
176
}
 
177
 
 
178
/****** sge_persistence_qmaster/sge_event_spool() ******************************
 
179
*  NAME
 
180
*     sge_event_spool() -- send event and spool
 
181
*
 
182
*  SYNOPSIS
 
183
*     bool 
 
184
*     sge_event_spool(lList **answer_list, u_long32 timestamp, ev_event event, 
 
185
*                     u_long32 intkey1, u_long32 intkey2, const char *strkey, 
 
186
*                     const char *strkey2, const char *session,
 
187
*                     lListElem *object, lListElem *sub_object1, 
 
188
*                     lListElem *sub_object2, bool send_event, bool spool) 
 
189
*
 
190
*  FUNCTION
 
191
*     Spools (writes or deletes) an object.
 
192
*     If spooling was successfull, send the given event.
 
193
*     Finally, the changed bits (information, which fields of the object
 
194
*     and it's subobjects were changed) is cleared.
 
195
*
 
196
*  INPUTS
 
197
*     lList **answer_list    - to return error messages
 
198
*     u_long32 timestamp     - timestamp of object change, if 0 is passed,
 
199
*                              use current date/time
 
200
*     ev_event event         - the event to send
 
201
*     u_long32 intkey1       - an integer key (job_id)
 
202
*     u_long32 intkey2       - a second integer key (ja_task_id)
 
203
*     const char *strkey     - a string key (all other keys)
 
204
*     const char *strkey2    - a string key (all other keys)
 
205
*     const char *session    - events session key
 
206
*     lListElem *object      - the object to spool and send
 
207
*     lListElem *sub_object1 - optionally a sub object (ja_task)
 
208
*     lListElem *sub_object2 - optionally a sub sub object (pe_task)
 
209
*     bool send_event        - shall we send an event, or only spool?
 
210
*     bool spool             - shall we spool or only send an event?
 
211
*
 
212
*  RESULT
 
213
*     bool - true on success, 
 
214
*            false on error. answer_list will contain an error description 
 
215
*  NOTES
 
216
*     From an academic standpoint, the parameter spool shouldn't be needed.
 
217
*     Whenever an object changes and a change event is created, the data 
 
218
*     basis should also be updated (spooled).
 
219
*
 
220
*  BUGS
 
221
*
 
222
*  SEE ALSO
 
223
*     
 
224
*******************************************************************************/
 
225
bool 
 
226
sge_event_spool(sge_gdi_ctx_class_t *ctx,
 
227
                lList **answer_list, u_long32 timestamp, ev_event event, 
 
228
                u_long32 intkey1, u_long32 intkey2, const char *strkey, 
 
229
                const char *strkey2, const char *session, 
 
230
                lListElem *object, lListElem *sub_object1, 
 
231
                lListElem *sub_object2, bool send_event, bool spool)
 
232
{
 
233
   bool ret = true;
 
234
   const char *key = NULL;
 
235
   sge_object_type object_type;
 
236
   lListElem *element = NULL;
 
237
   bool delete = false;
 
238
   dstring buffer = DSTRING_INIT;
 
239
   bool job_spooling = ctx->get_job_spooling(ctx);
 
240
 
 
241
   DENTER(TOP_LAYER, "sge_event_spool");
 
242
 
 
243
   /*for testing a fixed gid_error, this has been introduced. We need it to slowdown*/
 
244
   /*the spooling mechanism, to simulate the situation where this error appears*/ 
 
245
   if (spooling_wait_time != 0) {
 
246
      static unsigned long sleep_time = 0;
 
247
      if (sleep_time == 0) {
 
248
         sleep_time = spooling_wait_time;
 
249
      }
 
250
      usleep(sleep_time);
 
251
      sleep_time = sleep_time + 100000;
 
252
   }
 
253
 
 
254
   switch (event) {
 
255
      case sgeE_ADMINHOST_LIST:
 
256
      case sgeE_ADMINHOST_ADD:
 
257
      case sgeE_ADMINHOST_DEL:
 
258
      case sgeE_ADMINHOST_MOD:
 
259
         key = strkey;
 
260
         element = object;
 
261
         object_type = SGE_TYPE_ADMINHOST;
 
262
         break;
 
263
      case sgeE_CALENDAR_LIST:
 
264
      case sgeE_CALENDAR_ADD:
 
265
      case sgeE_CALENDAR_DEL:
 
266
      case sgeE_CALENDAR_MOD:
 
267
         key = strkey;
 
268
         element = object;
 
269
         object_type = SGE_TYPE_CALENDAR;
 
270
         break;
 
271
      case sgeE_CKPT_LIST:
 
272
      case sgeE_CKPT_ADD:
 
273
      case sgeE_CKPT_DEL:
 
274
      case sgeE_CKPT_MOD:
 
275
         key = strkey;
 
276
         element = object;
 
277
         object_type = SGE_TYPE_CKPT;
 
278
         break;
 
279
      case sgeE_CENTRY_LIST:
 
280
      case sgeE_CENTRY_ADD:
 
281
      case sgeE_CENTRY_DEL:
 
282
      case sgeE_CENTRY_MOD:
 
283
         key = strkey;
 
284
         element = object;
 
285
         object_type = SGE_TYPE_CENTRY;
 
286
         break;
 
287
      case sgeE_CONFIG_LIST:
 
288
      case sgeE_CONFIG_ADD:
 
289
      case sgeE_CONFIG_DEL:
 
290
      case sgeE_CONFIG_MOD:
 
291
         key = strkey;
 
292
         element = object;
 
293
         object_type = SGE_TYPE_CONFIG;
 
294
         break;
 
295
      case sgeE_EXECHOST_LIST:
 
296
      case sgeE_EXECHOST_ADD:
 
297
      case sgeE_EXECHOST_DEL:
 
298
      case sgeE_EXECHOST_MOD:
 
299
         key = strkey;
 
300
         element = object;
 
301
         object_type = SGE_TYPE_EXECHOST;
 
302
         break;
 
303
      case sgeE_GLOBAL_CONFIG:
 
304
         key = strkey;
 
305
         element = object;
 
306
         /* nothing to spool for this event */
 
307
         object_type = SGE_TYPE_ALL;
 
308
         break;
 
309
      case sgeE_JATASK_ADD:
 
310
      case sgeE_JATASK_DEL:
 
311
      case sgeE_JATASK_MOD:
 
312
         key = job_get_key(intkey1, intkey2, strkey, &buffer);
 
313
         element = sub_object1;
 
314
         object_type = SGE_TYPE_JATASK;
 
315
         break;
 
316
      case sgeE_PETASK_ADD:
 
317
      case sgeE_PETASK_DEL:
 
318
         key = job_get_key(intkey1, intkey2, strkey, &buffer);
 
319
         element = sub_object2;
 
320
         object_type = SGE_TYPE_PETASK;
 
321
         break;
 
322
      case sgeE_JOB_LIST:
 
323
      case sgeE_JOB_ADD:
 
324
      case sgeE_JOB_DEL:
 
325
      case sgeE_JOB_MOD:
 
326
      case sgeE_JOB_MOD_SCHED_PRIORITY:
 
327
      case sgeE_JOB_USAGE:
 
328
      case sgeE_JOB_FINAL_USAGE:
 
329
      case sgeE_JOB_FINISH:
 
330
         key = job_get_key(intkey1, intkey2, strkey, &buffer);
 
331
         element = object;
 
332
         object_type = SGE_TYPE_JOB;
 
333
         break;
 
334
      case sgeE_JOB_SCHEDD_INFO_LIST:
 
335
      case sgeE_JOB_SCHEDD_INFO_ADD:
 
336
      case sgeE_JOB_SCHEDD_INFO_DEL:
 
337
      case sgeE_JOB_SCHEDD_INFO_MOD:
 
338
         key = job_get_key(intkey1, intkey2, strkey, &buffer);
 
339
         element = object;
 
340
         object_type = SGE_TYPE_JOB_SCHEDD_INFO;
 
341
         break;
 
342
      case sgeE_MANAGER_LIST:
 
343
      case sgeE_MANAGER_ADD:
 
344
      case sgeE_MANAGER_DEL:
 
345
      case sgeE_MANAGER_MOD:
 
346
         key = strkey;
 
347
         element = object;
 
348
         object_type = SGE_TYPE_MANAGER;
 
349
         break;
 
350
      case sgeE_OPERATOR_LIST:
 
351
      case sgeE_OPERATOR_ADD:
 
352
      case sgeE_OPERATOR_DEL:
 
353
      case sgeE_OPERATOR_MOD:
 
354
         key = strkey;
 
355
         element = object;
 
356
         object_type = SGE_TYPE_OPERATOR;
 
357
         break;
 
358
      case sgeE_NEW_SHARETREE:
 
359
         /* we have only one sharetree - there is no key */
 
360
         key = "sharetree";
 
361
         element = object;
 
362
         object_type = SGE_TYPE_SHARETREE;
 
363
         break;
 
364
      case sgeE_PE_LIST:
 
365
      case sgeE_PE_ADD:
 
366
      case sgeE_PE_DEL:
 
367
      case sgeE_PE_MOD:
 
368
         key = strkey;
 
369
         element = object;
 
370
         object_type = SGE_TYPE_PE;
 
371
         break;
 
372
      case sgeE_PROJECT_LIST:
 
373
      case sgeE_PROJECT_ADD:
 
374
      case sgeE_PROJECT_DEL:
 
375
      case sgeE_PROJECT_MOD:
 
376
         key = strkey;
 
377
         element = object;
 
378
         object_type = SGE_TYPE_PROJECT;
 
379
         break;
 
380
      case sgeE_QMASTER_GOES_DOWN:
 
381
         key = strkey;
 
382
         element = object;
 
383
         /* nothing to spool for this event */
 
384
         object_type = SGE_TYPE_ALL;
 
385
         break;
 
386
      case sgeE_CQUEUE_LIST:
 
387
      case sgeE_CQUEUE_ADD:
 
388
      case sgeE_CQUEUE_DEL:
 
389
      case sgeE_CQUEUE_MOD:
 
390
         key = strkey;
 
391
         element = object;
 
392
         object_type = SGE_TYPE_CQUEUE;
 
393
         break;
 
394
      case sgeE_QINSTANCE_ADD:
 
395
      case sgeE_QINSTANCE_DEL:
 
396
      case sgeE_QINSTANCE_MOD:
 
397
      case sgeE_QINSTANCE_SOS:
 
398
      case sgeE_QINSTANCE_USOS:
 
399
         sge_dstring_sprintf(&buffer, SFN"/"SFN, strkey, strkey2);
 
400
         key = sge_dstring_get_string(&buffer);
 
401
         element = object;
 
402
         object_type = SGE_TYPE_QINSTANCE;
 
403
         break;
 
404
      case sgeE_SCHED_CONF:
 
405
         key = strkey;
 
406
         element = object;
 
407
         object_type = SGE_TYPE_SCHEDD_CONF;
 
408
         break;
 
409
      case sgeE_SCHEDDMONITOR:
 
410
         key = strkey;
 
411
         element = object;
 
412
         /* nothing to spool for this event */
 
413
         object_type = SGE_TYPE_ALL;
 
414
         break;
 
415
      case sgeE_SHUTDOWN:
 
416
         key = strkey;
 
417
         element = object;
 
418
         /* nothing to spool for this event */
 
419
         object_type = SGE_TYPE_ALL;
 
420
         break;
 
421
      case sgeE_SUBMITHOST_LIST:
 
422
      case sgeE_SUBMITHOST_ADD:
 
423
      case sgeE_SUBMITHOST_DEL:
 
424
      case sgeE_SUBMITHOST_MOD:
 
425
         key = strkey;
 
426
         element = object;
 
427
         object_type = SGE_TYPE_SUBMITHOST;
 
428
         break;
 
429
      case sgeE_USER_LIST:
 
430
      case sgeE_USER_ADD:
 
431
      case sgeE_USER_DEL:
 
432
      case sgeE_USER_MOD:
 
433
         key = strkey;
 
434
         element = object;
 
435
         object_type = SGE_TYPE_USER;
 
436
         break;
 
437
      case sgeE_USERSET_LIST:
 
438
      case sgeE_USERSET_ADD:
 
439
      case sgeE_USERSET_DEL:
 
440
      case sgeE_USERSET_MOD:
 
441
         key = strkey;
 
442
         element = object;
 
443
         object_type = SGE_TYPE_USERSET;
 
444
         break;
 
445
      case sgeE_RQS_LIST:
 
446
      case sgeE_RQS_ADD:
 
447
      case sgeE_RQS_DEL:
 
448
      case sgeE_RQS_MOD:
 
449
         key = strkey;
 
450
         element = object;
 
451
         object_type = SGE_TYPE_RQS;
 
452
         break;
 
453
#ifndef __SGE_NO_USERMAPPING__
 
454
      case sgeE_CUSER_LIST:
 
455
      case sgeE_CUSER_ADD:
 
456
      case sgeE_CUSER_DEL:
 
457
      case sgeE_CUSER_MOD:
 
458
         key = strkey;
 
459
         element = object;
 
460
         object_type = SGE_TYPE_CUSER;
 
461
         break;
 
462
#endif
 
463
      case sgeE_HGROUP_LIST:
 
464
      case sgeE_HGROUP_ADD:
 
465
      case sgeE_HGROUP_DEL:
 
466
      case sgeE_HGROUP_MOD:
 
467
         key = strkey;
 
468
         element = object;
 
469
         object_type = SGE_TYPE_HGROUP;
 
470
         break;
 
471
      case sgeE_AR_LIST:
 
472
      case sgeE_AR_ADD:
 
473
      case sgeE_AR_DEL:
 
474
      case sgeE_AR_MOD:
 
475
         key = strkey;
 
476
         element = object;
 
477
         object_type = SGE_TYPE_AR;
 
478
         break;
 
479
 
 
480
      default:
 
481
         /* nothing to spool */
 
482
         object_type = SGE_TYPE_ALL;
 
483
         ret = false;
 
484
         break;
 
485
   }
 
486
  
 
487
   /* only continue in case of valid event */
 
488
   if (ret) {
 
489
      switch (event) {
 
490
         case sgeE_ADMINHOST_DEL:
 
491
         case sgeE_CALENDAR_DEL:
 
492
         case sgeE_CKPT_DEL:
 
493
         case sgeE_CENTRY_DEL:
 
494
         case sgeE_CONFIG_DEL:
 
495
         case sgeE_EXECHOST_DEL:
 
496
         case sgeE_JATASK_DEL:
 
497
         case sgeE_PETASK_DEL:
 
498
         case sgeE_JOB_DEL:
 
499
         case sgeE_JOB_SCHEDD_INFO_DEL:
 
500
         case sgeE_MANAGER_DEL:
 
501
         case sgeE_OPERATOR_DEL:
 
502
         case sgeE_PE_DEL:
 
503
         case sgeE_PROJECT_DEL:
 
504
         case sgeE_CQUEUE_DEL:
 
505
         case sgeE_QINSTANCE_DEL:
 
506
         case sgeE_SUBMITHOST_DEL:
 
507
         case sgeE_USER_DEL:
 
508
         case sgeE_USERSET_DEL:
 
509
         case sgeE_RQS_DEL:
 
510
#ifndef __SGE_NO_USERMAPPING__
 
511
         case sgeE_CUSER_DEL:
 
512
#endif
 
513
         case sgeE_HGROUP_DEL:
 
514
         case sgeE_AR_DEL:
 
515
            delete = true;
 
516
            break;
 
517
         case sgeE_NEW_SHARETREE:
 
518
            if (object == NULL) {
 
519
               delete = true;
 
520
            }
 
521
            break;
 
522
         default:
 
523
            delete = false;
 
524
            break;
 
525
      }
 
526
 
 
527
      /* if spooling was requested and we have an object type to spool */
 
528
      if (spool && object_type != SGE_TYPE_ALL) {
 
529
         /* use an own answer list for the low level spooling operation. 
 
530
          * in case of error, generate a high level error message.
 
531
          */
 
532
         lList *spool_answer_list = NULL;
 
533
         if (delete) {
 
534
            ret = spool_delete_object(&spool_answer_list, spool_get_default_context(), 
 
535
                                      object_type, key, job_spooling);
 
536
         } else {
 
537
            lList *tmp_list = NULL;
 
538
            lListElem *load_value;
 
539
 
 
540
            /* 
 
541
             *  Only static load values should be spooled, therefore we modify
 
542
             *  the host elem to spool
 
543
             */
 
544
            switch (event) {
 
545
               case sgeE_EXECHOST_LIST:
 
546
               case sgeE_EXECHOST_ADD:
 
547
               case sgeE_EXECHOST_MOD:
 
548
                  tmp_list = lCreateList("", HL_Type);
 
549
                  for_each(load_value, lGetList(object, EH_load_list)) {
 
550
                     if (lGetBool(load_value, HL_static)) {
 
551
                        lAppendElem(tmp_list, lCopyElem(load_value));
 
552
                     }
 
553
                  }
 
554
                  lXchgList(object, EH_load_list, &tmp_list);
 
555
                  break;
 
556
               default:
 
557
                  break;
 
558
            }
 
559
 
 
560
            ret = spool_write_object(&spool_answer_list, spool_get_default_context(), 
 
561
                                     element, key, object_type, job_spooling);
 
562
 
 
563
            switch (event) {
 
564
               case sgeE_EXECHOST_LIST:
 
565
               case sgeE_EXECHOST_ADD:
 
566
               case sgeE_EXECHOST_MOD:
 
567
                  lXchgList(object, EH_load_list, &tmp_list);
 
568
                  lFreeList(&tmp_list);
 
569
                  break;
 
570
               default:
 
571
                  break;
 
572
            }
 
573
         }
 
574
         /* output low level error messages */
 
575
         answer_list_output(&spool_answer_list);
 
576
 
 
577
         /* in case of error: generate error message for caller */
 
578
         if (!ret) {
 
579
            answer_list_add_sprintf(answer_list, STATUS_EUNKNOWN, 
 
580
                                    ANSWER_QUALITY_ERROR, 
 
581
                                    delete ? 
 
582
                                    MSG_PERSISTENCE_DELETE_FAILED_S : 
 
583
                                    MSG_PERSISTENCE_WRITE_FAILED_S,
 
584
                                    key);
 
585
            
 
586
         }
 
587
      }
 
588
   }
 
589
 
 
590
   /* send event only, if spooling succeeded */
 
591
   if (ret) {
 
592
      if (send_event) {
 
593
         sge_add_event(timestamp, event, 
 
594
                       intkey1, intkey2, strkey, strkey2,
 
595
                       session, element);
 
596
      }
 
597
 
 
598
      /* clear the changed bits */
 
599
      lListElem_clear_changed_info(object);
 
600
   }
 
601
 
 
602
   sge_dstring_free(&buffer);
 
603
 
 
604
   DRETURN(ret);
 
605
}
 
606