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

« back to all changes in this revision

Viewing changes to source/libs/gdi/sge_gdi_packet.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
 
 
2
/* ___INFO__MARK_BEGIN__ */
 
3
 
 
4
/*************************************************************************
 
5
 *
 
6
 *  The Contents of this file are made available subject to the terms of
 
7
 *  the Sun Industry Standards Source License Version 1.2
 
8
 *
 
9
 *  Sun Microsystems Inc., March, 2001
 
10
 *
 
11
 *
 
12
 *  Sun Industry Standards Source License Version 1.2
 
13
 *  =================================================
 
14
 *  The contents of this file are subject to the Sun Industry Standards
 
15
 *  Source License Version 1.2 (the "License"); You may not use this file
 
16
 *  except in compliance with the License. You may obtain a copy of the
 
17
 *  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
 
18
 *
 
19
 *  Software provided under this License is provided on an "AS IS" basis,
 
20
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 
21
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 
22
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 
23
 *  See the License for the specific provisions governing your rights and
 
24
 *  obligations concerning the Software.
 
25
 *
 
26
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
27
 *
 
28
 *   Copyright: 2001 by Sun Microsystems, Inc.
 
29
 *
 
30
 *   All Rights Reserved.
 
31
 *
 
32
 ************************************************************************/
 
33
 
 
34
/* ___INFO__MARK_END__ */
 
35
 
 
36
#include <stdlib.h>
 
37
#include <string.h>
 
38
 
 
39
#ifdef KERBEROS
 
40
#include "krb_lib.h"
 
41
#endif
 
42
 
 
43
#include "basis_types.h"
 
44
 
 
45
#include "comm/commlib.h"
 
46
 
 
47
#include "rmon/sgermon.h"
 
48
 
 
49
#include "lck/sge_mtutil.h"
 
50
 
 
51
#include "uti/sge_prog.h"
 
52
#include "uti/sge_log.h"
 
53
#include "uti/sge_stdlib.h"
 
54
#include "uti/sge_string.h"
 
55
#include "uti/sge_thread_ctrl.h"
 
56
 
 
57
#include "gdi/sge_gdi2.h"
 
58
#include "gdi/sge_gdiP.h"
 
59
#include "gdi/sge_gdi_packet.h"
 
60
#include "gdi/sge_gdi_packet_queue.h"
 
61
#include "gdi/sge_gdi_packet_pb_cull.h"
 
62
#include "gdi/version.h"
 
63
#include "gdi/sge_security.h"
 
64
 
 
65
#include "sgeobj/sge_answer.h"
 
66
#include "sgeobj/sge_feature.h"
 
67
#include "sgeobj/sge_multiL.h"
 
68
 
 
69
#include "msg_common.h"
 
70
#include "msg_gdilib.h"
 
71
#include "msg_qmaster.h"
 
72
 
 
73
/****** gdi/request_internal/--Packets_and_Taks() *****************************
 
74
*  NAME
 
75
*     Packets_and_Tasks -- Functions and structures behind GDI
 
76
*
 
77
*  FUNCTION
 
78
*     Packets and tasks are structures which are used in the methods 
 
79
*     implementing GDI. The real C structure names are 
 
80
*
 
81
*        "sge_gdi_packet_cass_t" and 
 
82
*        "sge_gdi_task_class_t". 
 
83
*
 
84
*     An instance of the packet structure represents a GDI request.
 
85
*     Each packet has assigned at least one task. But it may have
 
86
*     multiple tasks. A Packet with one task represents a
 
87
*     singe GDI request and that one with multiple task represents
 
88
*     a multi GDI request.
 
89
*
 
90
*     GDI requests are created by funtion calls sge_gdi() and
 
91
*     sge_gdi_multi(). Internally the packet and task data 
 
92
*     structures are used to represent that request information.
 
93
*
 
94
*     Within the client side code (sge_gdi(), sge_gdi_multi(),
 
95
*     sge_gdi_wait(), sge_extract_answer() ... ) there are multiple
 
96
*     functions used to create and verify packets and tasks:
 
97
*
 
98
*        sge_gdi_packet_append_task()
 
99
*        sge_gdi_packet_create()
 
100
*        sge_gdi_packet_create_base()
 
101
*        sge_gdi_packet_create_multi_answer()
 
102
*        sge_gdi_packet_free()
 
103
*        sge_gdi_packet_get_last_task_id()
 
104
*        sge_gdi_packet_initialize_auth_info()
 
105
*        sge_gdi_task_create()
 
106
*        sge_gdi_task_free()
 
107
*
 
108
*     Following functions are used to handle data transfer
 
109
*     from external GDI clients (qstat, qconf, ...) or internal
 
110
*     GDI clients (scheduler, JVM, ...)
 
111
*
 
112
*        sge_gdi_packet_execute_internal()
 
113
*        sge_gdi_packet_execute_external()
 
114
*        sge_gdi_packet_wait_for_result_internal()
 
115
*        sge_gdi_packet_wait_for_result_external()
 
116
*
 
117
*     Data transfer of packets transfered  between external GDI 
 
118
*     clients is prepared with following functions process:
 
119
*
 
120
*        sge_gdi_packet_get_pb_size()
 
121
*        sge_gdi_packet_initialize_auth_info()
 
122
*        sge_gdi_packet_pack()
 
123
*        sge_gdi_packet_pack_task()
 
124
*        sge_gdi_packet_parse_auth_info()
 
125
*        sge_gdi_packet_unpack()
 
126
*
 
127
*    Within the master process special syncronisation
 
128
*    for the thread accessing packet and task datastructures
 
129
*    is required because the data structures are not thread
 
130
*    safe per default. Only one thread is allowed to access
 
131
*    a packet or task structure at the same time. To synchronize
 
132
*    their activities between "listerner" and "worker"
 
133
*    threads a queue of packet elements is used. This
 
134
*    "Master_Packet_Queue" is guarded by the funtion calls
 
135
*
 
136
*        sge_gdi_packet_queue_wait_for_new_packet()
 
137
*        sge_gdi_packet_queue_store_notify()
 
138
*        sge_gdi_packet_queue_wakeup_all_waiting()
 
139
*
 
140
*     Additional synchronisation functions are
 
141
*
 
142
*        sge_gdi_packet_wait_till_handled()
 
143
*        sge_gdi_packet_broadcast_that_handled()
 
144
*
 
145
*  SEE ALSO
 
146
*     gdi/request_internal/Master_Packet_Queue
 
147
*     gdi/request_internal/sge_gdi_task_create()
 
148
*     gdi/request_internal/sge_gdi_task_free()
 
149
*     gdi/request_internal/sge_gdi_task_get_operation_name()
 
150
*     gdi/request_internal/sge_gdi_packet_append_task()
 
151
*     gdi/request_internal/sge_gdi_packet_broadcast_that_handled()
 
152
*     gdi/request_internal/sge_gdi_packet_create()
 
153
*     gdi/request_internal/sge_gdi_packet_create_base()
 
154
*     gdi/request_internal/sge_gdi_packet_create_multi_answer()
 
155
*     gdi/request_internal/sge_gdi_packet_get_last_task_id()
 
156
*     gdi/request_internal/sge_gdi_packet_execute_internal()
 
157
*     gdi/request_internal/sge_gdi_packet_execute_external()
 
158
*     gdi/request_internal/sge_gdi_packet_free()
 
159
*     gdi/request_internal/sge_gdi_packet_get_pb_size()
 
160
*     gdi/request_internal/sge_gdi_packet_initialize_auth_info()
 
161
*     gdi/request_internal/sge_gdi_packet_pack()
 
162
*     gdi/request_internal/sge_gdi_packet_pack_task()
 
163
*     gdi/request_internal/sge_gdi_packet_parse_auth_info()
 
164
*     gdi/request_internal/sge_gdi_packet_queue_store_notify()
 
165
*     gdi/request_internal/sge_gdi_packet_queue_wait_for_new_packet()
 
166
*     gdi/request_internal/sge_gdi_packet_queue_wakeup_all_waiting()
 
167
*     gdi/request_internal/sge_gdi_packet_unpack()
 
168
*     gdi/request_internal/sge_gdi_packet_initialize_auth_info()
 
169
*     gdi/request_internal/sge_gdi_packet_wait_for_result_internal()
 
170
*     gdi/request_internal/sge_gdi_packet_wait_for_result_external()
 
171
*     gdi/request_internal/sge_gdi_packet_wait_till_handled()
 
172
*******************************************************************************/
 
173
 
 
174
#if 1
 
175
#define SGE_GDI_PACKET_DEBUG
 
176
#endif
 
177
 
 
178
#if defined(SGE_GDI_PACKET_DEBUG)
 
179
bool sge_gdi_task_debug_print(sge_gdi_task_class_t * task);
 
180
#endif
 
181
 
 
182
static bool sge_gdi_task_free(sge_gdi_task_class_t ** task);
 
183
 
 
184
static bool sge_gdi_task_verify(sge_gdi_task_class_t * task,
 
185
                                lList **answer_list);
 
186
 
 
187
static sge_gdi_task_class_t *sge_gdi_task_create(sge_gdi_packet_class_t *
 
188
                                                 packet, lList **answer_list,
 
189
                                                 u_long32 target,
 
190
                                                 u_long32 command, lList **lp,
 
191
                                                 lList **a_list,
 
192
                                                 lCondition **condition,
 
193
                                                 lEnumeration **enumeration,
 
194
                                                 bool do_copy, bool do_verify);
 
195
 
 
196
static bool sge_gdi_task_free(sge_gdi_task_class_t ** task);
 
197
 
 
198
#if defined(SGE_GDI_PACKET_DEBUG)
 
199
bool sge_gdi_packet_debug_print(sge_gdi_packet_class_t * packet);
 
200
#endif
 
201
 
 
202
 
 
203
#if defined(SGE_GDI_PACKET_DEBUG)
 
204
bool 
 
205
sge_gdi_task_debug_print(sge_gdi_task_class_t * task) 
 
206
{
 
207
    bool ret = true;
 
208
    
 
209
    DENTER(TOP_LAYER, "sge_gdi_task_debug_print");
 
210
    if (task != NULL) {
 
211
        DPRINTF(("task->id = " sge_U32CFormat "\n", sge_u32c(task->id)));
 
212
        DPRINTF(("task->command = " sge_U32CFormat "\n",
 
213
                sge_u32c(task->command)));
 
214
        DPRINTF(("task->target = " sge_U32CFormat "\n", sge_u32c(task->target)));
 
215
        DPRINTF(("task->data_list = %p\n", task->data_list));
 
216
        DPRINTF(("task->answer_list = %p\n", task->answer_list));
 
217
        DPRINTF(("task->condition = %p\n", task->condition));
 
218
        DPRINTF(("task->enumeration = %p\n", task->enumeration));
 
219
        DPRINTF(("task->next = %p\n", task->next));
 
220
    } else {
 
221
        DPRINTF(("task is NULL\n"));
 
222
    }
 
223
    DRETURN(ret);
 
224
}
 
225
 
 
226
#endif
 
227
 
 
228
static bool
 
229
sge_gdi_task_verify(sge_gdi_task_class_t * task, lList **answer_list)
 
230
{
 
231
   bool ret = true;
 
232
#if 0
 
233
   int operation = 0;
 
234
   lList *list = NULL;
 
235
   u_long32 target = 0;
 
236
#endif
 
237
 
 
238
   DENTER(TOP_LAYER, "sge_gdi_task_verify");
 
239
#if 0
 
240
   operation = SGE_GDI_GET_OPERATION(task->command);
 
241
   list = task->data_list;
 
242
   target = task->target;
 
243
   /* EB: TODO: this check does not work for AR objects why? */
 
244
   if (!list
 
245
       && !(operation == SGE_GDI_PERMCHECK || operation == SGE_GDI_GET
 
246
            || operation == SGE_GDI_TRIGGER || (operation == SGE_GDI_DEL
 
247
                                                && target ==
 
248
                                                SGE_SHARETREE_LIST))
 
249
      ) {
 
250
      answer_list_add_sprintf(answer_list, STATUS_ESEMANTIC,
 
251
                 ANSWER_QUALITY_ERROR, MSG_GDI_GDI_VERIFY_REQUEST_FAILED);
 
252
      ret = false;
 
253
   }
 
254
#endif
 
255
   DRETURN(ret);
 
256
}
 
257
 
 
258
static sge_gdi_task_class_t *
 
259
sge_gdi_task_create(sge_gdi_packet_class_t * packet, lList **answer_list,
 
260
                    u_long32 target, u_long32 command, lList **lp,
 
261
                    lList **a_list, lCondition **condition,
 
262
                    lEnumeration **enumeration, bool do_copy, bool do_verify)
 
263
{
 
264
   sge_gdi_task_class_t *task = NULL;
 
265
 
 
266
   DENTER(TOP_LAYER, "sge_gdi_task_create");
 
267
 
 
268
   task = (sge_gdi_task_class_t *) sge_malloc(sizeof(sge_gdi_task_class_t));
 
269
   if (task != NULL) {
 
270
      task->id =
 
271
         ((packet->last_task != NULL) ? (packet->last_task->id + 1) : 1);
 
272
      task->command = command;
 
273
      task->target = target;
 
274
      task->next = NULL;
 
275
      task->do_select_pack_simultaneous = false;
 
276
      if (do_copy) {
 
277
         if (enumeration != NULL && *enumeration != NULL) {
 
278
            task->data_list = (((lp != NULL) && (*lp != NULL)) ?
 
279
                               lSelect("", *lp, NULL, *enumeration) : NULL);
 
280
         } else {
 
281
            task->data_list = (((lp != NULL) && (*lp != NULL)) ?
 
282
                               lCopyList("", *lp) : NULL);
 
283
         }
 
284
         task->answer_list = (((a_list != NULL) && (*a_list != NULL)) ?
 
285
                              lCopyList("", *a_list) : NULL);
 
286
         task->condition = (((condition != NULL) && (*condition != NULL)) ?
 
287
                            lCopyWhere(*condition) : NULL);
 
288
         task->enumeration = (((enumeration != NULL) && (*enumeration != NULL)) ?
 
289
                              lCopyWhat(*enumeration) : NULL);
 
290
      } else {
 
291
         if ((lp != NULL) && (*lp != NULL)) {
 
292
            task->data_list = *lp;
 
293
            *lp = NULL;
 
294
         } else {
 
295
            task->data_list = NULL;
 
296
         }
 
297
         if ((a_list != NULL) && (*a_list != NULL)) {
 
298
            task->answer_list = *a_list;
 
299
            *a_list = NULL;
 
300
         } else {
 
301
            task->answer_list = NULL;
 
302
         }
 
303
         if ((condition != NULL) && (*condition != NULL)) {
 
304
            task->condition = *condition;
 
305
            *condition = NULL;
 
306
         } else {
 
307
            task->condition = NULL;
 
308
         }
 
309
         if ((enumeration != NULL) && (*enumeration != NULL)) {
 
310
            task->enumeration = *enumeration;
 
311
            *enumeration = NULL;
 
312
         } else {
 
313
            task->enumeration = NULL;
 
314
         }
 
315
      }
 
316
      if (do_verify && !sge_gdi_task_verify(task, answer_list)) {
 
317
         if (do_copy == true) {
 
318
            lFreeList(&(task->data_list));
 
319
            lFreeList(&(task->answer_list));
 
320
            lFreeWhere(&(task->condition));
 
321
            lFreeWhat(&(task->enumeration));
 
322
         } else {
 
323
            task->data_list = NULL;
 
324
            task->answer_list = NULL;
 
325
            task->condition = NULL;
 
326
            task->enumeration = NULL;
 
327
         }
 
328
         sge_gdi_task_free(&task);
 
329
      }
 
330
   } else {
 
331
      answer_list_add_sprintf(answer_list, STATUS_EMALLOC,
 
332
                              ANSWER_QUALITY_ERROR, MSG_MEMORY_MALLOCFAILED);
 
333
   }
 
334
   DRETURN(task);
 
335
}
 
336
 
 
337
/****** gdi/request_internal/sge_gdi_task_free() ******************************
 
338
*  NAME
 
339
*     sge_gdi_task_free() -- free a gdi task structure
 
340
*
 
341
*  SYNOPSIS
 
342
*     static bool
 
343
*     sge_gdi_task_free(sge_gdi_task_class_t **task)
 
344
*
 
345
*  FUNCTION
 
346
*     free all elements of the gdi task structure and the structure itself.
 
347
*
 
348
*  INPUTS
 
349
*     sge_gdi_task_class_t **task - pointer to the task structure pointer
 
350
*
 
351
*  RESULT
 
352
*     static bool -
 
353
*        true - success (always)
 
354
*
 
355
*  NOTES
 
356
*     MT-NOTE: sge_gdi_task_free() is MT safe as long as the structure
 
357
*              passed to this function is not accessed by more than one
 
358
*              thread simultaniously.
 
359
*
 
360
*  SEE ALSO
 
361
*     gdi/request_internal/sge_gdi_task_create()
 
362
******************************************************************************/
 
363
static bool
 
364
sge_gdi_task_free(sge_gdi_task_class_t ** task)
 
365
{
 
366
   bool ret = true;
 
367
 
 
368
   DENTER(TOP_LAYER, "sge_gdi_task_free");
 
369
   if (task != NULL && *task != NULL) {
 
370
      lFreeList(&((*task)->data_list));
 
371
      lFreeList(&((*task)->answer_list));
 
372
      lFreeWhat(&((*task)->enumeration));
 
373
      lFreeWhere(&((*task)->condition));
 
374
      *task = (sge_gdi_task_class_t *) sge_free((char *) (*task));
 
375
   }
 
376
   DRETURN(ret);
 
377
}
 
378
 
 
379
#if defined(SGE_GDI_PACKET_DEBUG)
 
380
bool
 
381
sge_gdi_packet_debug_print(sge_gdi_packet_class_t * packet)
 
382
{
 
383
   bool ret = true;
 
384
 
 
385
   DENTER(TOP_LAYER, "sge_gdi_packet_debug_print");
 
386
 
 
387
   if (packet != NULL) {
 
388
      sge_gdi_task_class_t *task;
 
389
 
 
390
      DPRINTF(("packet->id = " sge_U32CFormat "\n", sge_u32c(packet->id)));
 
391
      DPRINTF(("packet->host = " SFQ "\n", packet->host ? packet->host : "<null>"));
 
392
      DPRINTF(("packet->commproc = " SFQ "\n", packet->commproc ? packet->commproc : "<null>"));
 
393
      DPRINTF(("packet->auth_info = " SFQ "\n", packet->auth_info ?  packet->auth_info : "<null>"));
 
394
      DPRINTF(("packet->version = " sge_U32CFormat "\n",
 
395
               sge_u32c(packet->version)));
 
396
      DPRINTF(("packet->first_task = %p\n", packet->first_task));
 
397
      DPRINTF(("packet->last_task = %p\n", packet->last_task));
 
398
 
 
399
      task = packet->first_task;
 
400
      while (task != NULL) {
 
401
         sge_gdi_task_debug_print(task);
 
402
         task = task->next;
 
403
      }
 
404
   } else {
 
405
      DPRINTF(("packet is NULL\n"));;
 
406
   }
 
407
   DRETURN(ret);
 
408
}
 
409
 
 
410
#endif
 
411
 
 
412
/****** gdi/request_internal/sge_gdi_packet_create_base() ********************
 
413
*  NAME
 
414
*     sge_gdi_packet_create_base() -- ???
 
415
*
 
416
*  SYNOPSIS
 
417
*     sge_gdi_packet_class_t *
 
418
*     sge_gdi_packet_create_base(lList **answer_list)
 
419
*
 
420
*  FUNCTION
 
421
*     Creates a new GDI packet and initializes all base structure memebers
 
422
*     where necessary information is available.
 
423
*
 
424
*     "uid", "gid", "user" and "group" memebers part of sge_gdi_packet_class_t
 
425
*     will not be initialized with this function. Instead
 
426
*     sge_gdi_packet_create() can be used or the function
 
427
*     sge_gdi_packet_initialize_auth_info() can be called afterwards.
 
428
*
 
429
*  INPUTS
 
430
*     lList **answer_list - answer list in case of error
 
431
*
 
432
*  RESULT
 
433
*     sge_gdi_packet_class_t * - new GDI packet
 
434
*
 
435
*  NOTES
 
436
*     MT-NOTE: sge_gdi_packet_create_base() is MT safe
 
437
*
 
438
*  SEE ALSO
 
439
*     gdi/request_internal/sge_gdi_packet_create()
 
440
*     gdi/request_internal/sge_gdi_packet_initialize_auth_info()
 
441
******************************************************************************/
 
442
sge_gdi_packet_class_t *
 
443
sge_gdi_packet_create_base(lList **answer_list)
 
444
{
 
445
   sge_gdi_packet_class_t *ret = NULL;
 
446
 
 
447
   DENTER(TOP_LAYER, "sge_gdi_packet_create_base");
 
448
   ret = (sge_gdi_packet_class_t *) sge_malloc(sizeof(sge_gdi_packet_class_t));
 
449
   if (ret != NULL) {
 
450
      int local_ret1;
 
451
      int local_ret2;
 
452
 
 
453
      local_ret1 = pthread_mutex_init(&(ret->mutex), NULL);
 
454
      local_ret2 = pthread_cond_init(&(ret->cond), NULL);
 
455
      if (local_ret1 == 0 && local_ret2 == 0) {
 
456
         ret->is_intern_request = false;
 
457
         ret->is_gdi_request = true;
 
458
         ret->is_handled = false;
 
459
         ret->id = 0;
 
460
         ret->host = NULL;
 
461
         ret->commproc = NULL;
 
462
         ret->commproc_id = 0;
 
463
 
 
464
         ret->version = GRM_GDI_VERSION;
 
465
         ret->first_task = NULL;
 
466
         ret->last_task = NULL;
 
467
         ret->auth_info = NULL;
 
468
         ret->next = NULL;
 
469
         memset(&(ret->pb), 0, sizeof(sge_pack_buffer));
 
470
      } else {
 
471
         answer_list_add_sprintf(answer_list, STATUS_EMALLOC,
 
472
                                 ANSWER_QUALITY_ERROR,
 
473
                                 MSG_MEMORY_MALLOCFAILED);
 
474
      }
 
475
   } else {
 
476
      answer_list_add_sprintf(answer_list, STATUS_EMALLOC,
 
477
                              ANSWER_QUALITY_ERROR, MSG_SGETEXT_NOMEM);
 
478
   }
 
479
   DRETURN(ret);
 
480
}
 
481
 
 
482
/****** gdi/request_internal/sge_gdi_packet_create() **************************
 
483
*  NAME
 
484
*     sge_gdi_packet_create() -- create a new GDI packet and initialize it
 
485
*
 
486
*  SYNOPSIS
 
487
*     sge_gdi_packet_class_t *
 
488
*     sge_gdi_packet_create(sge_gdi_ctx_class_t *ctx, lList **answer_list)
 
489
*
 
490
*  FUNCTION
 
491
*     Creates a new GDI packet element and initializes all members of the
 
492
*     structure.
 
493
*
 
494
*  INPUTS
 
495
*     sge_gdi_ctx_class_t *ctx - GDI context
 
496
*     lList **answer_list      - answer list
 
497
*
 
498
*  RESULT
 
499
*     sge_gdi_packet_class_t * - new packet element or NULL in case of errors
 
500
*
 
501
*  NOTES
 
502
*     MT-NOTE: sge_gdi_packet_create() is MT safe
 
503
*
 
504
*  SEE ALSO
 
505
*     gdi/request_internal/sge_gdi_packet_create_base()
 
506
*     gdi/request_internal/sge_gdi_packet_initialize_auth_info()
 
507
******************************************************************************/
 
508
sge_gdi_packet_class_t *
 
509
sge_gdi_packet_create(sge_gdi_ctx_class_t * ctx, lList **answer_list)
 
510
{
 
511
   sge_gdi_packet_class_t *ret = NULL;
 
512
 
 
513
   DENTER(TOP_LAYER, "sge_gdi_packet_create");
 
514
   ret = sge_gdi_packet_create_base(answer_list);
 
515
   if (ret != NULL) {
 
516
      sge_gdi_packet_initialize_auth_info(ctx, ret);
 
517
   }
 
518
   DRETURN(ret);
 
519
}
 
520
 
 
521
/****** gdi/request_internal/sge_gdi_packet_append_task() *********************
 
522
*  NAME
 
523
*     sge_gdi_packet_append_task() -- append an additional GDI task
 
524
*
 
525
*  SYNOPSIS
 
526
*     bool
 
527
*     sge_gdi_packet_append_task(sge_gdi_packet_class_t *packet,
 
528
*                                lList **answer_list, u_long32 target,
 
529
*                                u_long32 command, lList **lp,
 
530
*                                lList **a_list, lCondition **condition,
 
531
*                                lEnumeration **enumeration,
 
532
*                                bool do_copy, bool do_verify)
 
533
*
 
534
*  FUNCTION
 
535
*     This function creates a new GDI task representing one
 
536
*     request of a multi GDI request. The task will be appended to
 
537
*     the list of tasks part of "packet". It will be initialized
 
538
*     with the values given by "target" and "command". Pointer
 
539
*     parameters like "lp", "a_list", "condition", and "enumeration"
 
540
*     will either be copied ("do_copy" == true) or they will just be
 
541
*     used as they are. In that case they will direct to NULL after
 
542
*     the function returns. The memory allocated by the provided
 
543
*     pointer parameters will be released when the task is destroyed
 
544
*     they are part of. "do_verify" defines if the input parameters
 
545
*     are verified after the task element has been created.
 
546
*
 
547
*     In case of any error the function will return "false"
 
548
*     and the "answer_list" will be filled with a message.
 
549
*     Causes for errors are:
 
550
*        - malloc failure
 
551
*        - verification failure (sgee sge_gdi_task_verify)
 
552
*
 
553
*  INPUTS
 
554
*     sge_gdi_packet_class_t *packet - packet
 
555
*     lList **answer_list            - answer list used by this function
 
556
*     u_long32 target                - GDI target value
 
557
*     u_long32 command               - GDI command
 
558
*     lList **lp                     - list pointer
 
559
*     lList **a_list                 - answer list pointer
 
560
*     lCondition **condition         - CULL condition
 
561
*     lEnumeration **enumeration     - CULL enumeration
 
562
*     bool do_copy                   - do copy all elements passed
 
563
*                                      to this structure
 
564
*     bool do_verify                 - do verification of input data
 
565
*
 
566
*  RESULT
 
567
*     bool - error state
 
568
*        true  - success
 
569
*        false - error (answer_list will be filled with detailed information)
 
570
*
 
571
*  NOTES
 
572
*     MT-NOTE: sge_gdi_packet_append_task() is MT safe
 
573
*
 
574
*  SEE ALSO
 
575
*     gdi/request_internal/sge_gdi_task_create()
 
576
*     gdi/request_internal/sge_gdi_task_verify()
 
577
******************************************************************************/
 
578
bool
 
579
sge_gdi_packet_append_task(sge_gdi_packet_class_t * packet,
 
580
                           lList **answer_list, u_long32 target,
 
581
                           u_long32 command, lList **lp, lList **a_list,
 
582
                           lCondition **condition, lEnumeration **enumeration,
 
583
                           bool do_copy, bool do_verify)
 
584
{
 
585
   bool ret = true;
 
586
   sge_gdi_task_class_t *task = NULL;
 
587
 
 
588
   DENTER(TOP_LAYER, "sge_gdi_packet_append_task");
 
589
 
 
590
   task =
 
591
      sge_gdi_task_create(packet, answer_list, target, command, lp, a_list,
 
592
                          condition, enumeration, do_copy, true);
 
593
 
 
594
   if (packet->last_task != NULL) {
 
595
      packet->last_task->next = task;
 
596
      packet->last_task = task;
 
597
   } else {
 
598
      packet->first_task = task;
 
599
      packet->last_task = task;
 
600
   }
 
601
   task = NULL;
 
602
 
 
603
   DRETURN(ret);
 
604
}
 
605
 
 
606
/****** gdi/request_internal/sge_gdi_task_get_operation_name() ****************
 
607
*  NAME
 
608
*     sge_gdi_task_get_operation_name() -- get command name 
 
609
*
 
610
*  SYNOPSIS
 
611
*     const char * 
 
612
*     sge_gdi_task_get_operation_name(sge_gdi_task_class_t *task) 
 
613
*
 
614
*  FUNCTION
 
615
*     This function returns a string of represending the command type
 
616
*     of a task part of a multi GDI request (e.g the function will return
 
617
*     "GET" when (task->command == SGE_GDI_GET))
 
618
*
 
619
*  INPUTS
 
620
*     sge_gdi_task_class_t *task - gdi task 
 
621
*
 
622
*  RESULT
 
623
*     const char * - string
 
624
*
 
625
*  NOTES
 
626
*     MT-NOTE: sge_gdi_task_get_operation_name() is MT safe 
 
627
*******************************************************************************/
 
628
const char *
 
629
sge_gdi_task_get_operation_name(sge_gdi_task_class_t *task)
 
630
{
 
631
   const char *ret = NULL;
 
632
 
 
633
   switch (task->command) {
 
634
      case SGE_GDI_GET:
 
635
         ret = "GET";
 
636
         break;
 
637
      case SGE_GDI_ADD:
 
638
         ret = "ADD";
 
639
         break;
 
640
      case SGE_GDI_DEL:
 
641
         ret = "DEL";
 
642
         break;
 
643
      case SGE_GDI_MOD:
 
644
         ret = "MOD";
 
645
         break;
 
646
      case SGE_GDI_COPY:
 
647
         ret = "COPY";
 
648
         break;
 
649
      case SGE_GDI_TRIGGER:
 
650
         ret = "TRIGGER";
 
651
         break;
 
652
      case SGE_GDI_PERMCHECK:
 
653
         ret = "PERMCHECK";
 
654
         break;
 
655
      case SGE_GDI_REPLACE:
 
656
         ret = "REPLACE";
 
657
         break;
 
658
      default:
 
659
         ret = "???";
 
660
         break;
 
661
   }
 
662
   return ret;
 
663
}
 
664
 
 
665
/****** gdi/request_internal/sge_gdi_packet_get_last_task_id() ****************
 
666
*  NAME
 
667
*     sge_gdi_packet_get_last_task_id() -- returns the last used task id
 
668
*
 
669
*  SYNOPSIS
 
670
*     u_long32
 
671
*     sge_gdi_packet_get_last_task_id(sge_gdi_packet_class_t *packet)
 
672
*
 
673
*  FUNCTION
 
674
*     Returns the last used task id in a package or 0 if there is no task.
 
675
*     Can be used to get the id of the last task created with
 
676
*     sge_gdi_packet_append_task()
 
677
*
 
678
*  INPUTS
 
679
*     sge_gdi_packet_class_t *packet - packet pointer
 
680
*
 
681
*  RESULT
 
682
*     u_long32 - task id in the range [1, ULONG32_MAX]
 
683
*                or 0
 
684
*
 
685
*  NOTES
 
686
*     MT-NOTE: sge_gdi_packet_get_last_task_id() is not MT safe
 
687
*
 
688
*  SEE ALSO
 
689
*     gdi/request_internal/sge_gdi_task_create()
 
690
*     gdi/request_internal/sge_gdi_packet_append_task()
 
691
******************************************************************************/
 
692
u_long32
 
693
sge_gdi_packet_get_last_task_id(sge_gdi_packet_class_t * packet)
 
694
{
 
695
   u_long32 ret = 0;
 
696
 
 
697
   DENTER(TOP_LAYER, "sge_gdi_packet_get_last_task_id");
 
698
 
 
699
   if (packet->last_task != NULL) {
 
700
      ret = packet->last_task->id;
 
701
   }
 
702
   DRETURN(ret);
 
703
}
 
704
 
 
705
/****** gdi/request_internal/sge_gdi_packet_free() ****************************
 
706
*  NAME
 
707
*     sge_gdi_packet_free() -- free memory allocated by packet
 
708
*
 
709
*  SYNOPSIS
 
710
*     bool sge_gdi_packet_free(sge_gdi_packet_class_t **packet)
 
711
*
 
712
*  FUNCTION
 
713
*     Releases the memory allocated by all members of ther "packet"
 
714
*     structure including the list of tasks and sublists part of the
 
715
*     tasks.
 
716
*
 
717
*     The caller has to take care that the packet is not part of
 
718
*     a packet queue when this function is called!
 
719
*
 
720
*  INPUTS
 
721
*     sge_gdi_packet_class_t **packet - packet
 
722
*
 
723
*  RESULT
 
724
*     bool - error state
 
725
*        true  - success
 
726
*        false - error
 
727
*
 
728
*  NOTES
 
729
*     MT-NOTE: sge_gdi_packet_free() is not MT safe
 
730
*
 
731
*  SEE ALSO
 
732
*     gdi/request_internal/sge_gdi_task_create()
 
733
*     gdi/request_internal/sge_gdi_packet_create()
 
734
******************************************************************************/
 
735
bool
 
736
sge_gdi_packet_free(sge_gdi_packet_class_t ** packet)
 
737
{
 
738
   bool ret = true;
 
739
 
 
740
   DENTER(TOP_LAYER, "sge_gdi_packet_free");
 
741
   if (packet != NULL && *packet != NULL) {
 
742
      sge_gdi_task_class_t *task = NULL;
 
743
      sge_gdi_task_class_t *next_task = NULL;
 
744
      int local_ret1;
 
745
      int local_ret2;
 
746
 
 
747
      next_task = (*packet)->first_task;
 
748
      while ((task = next_task) != NULL) {
 
749
         next_task = task->next;
 
750
         sge_gdi_task_free(&task);
 
751
      }
 
752
      local_ret1 = pthread_mutex_destroy(&((*packet)->mutex));
 
753
      local_ret2 = pthread_cond_destroy(&((*packet)->cond));
 
754
      if (local_ret1 != 0 || local_ret2 != 0) {
 
755
         ret = false;
 
756
      }
 
757
      (*packet)->host = sge_free((char *) (*packet)->host);
 
758
      (*packet)->commproc = sge_free((char *) (*packet)->commproc);
 
759
 
 
760
      (*packet)->auth_info = sge_free((char *) (*packet)->auth_info);
 
761
      *packet = (sge_gdi_packet_class_t *)sge_free((char *) *packet);
 
762
   }
 
763
   DRETURN(ret);
 
764
}
 
765
 
 
766
/****** sge_gdi_packet/sge_gdi_packet_verify_version() ************************
 
767
*  NAME
 
768
*     sge_gdi_packet_verify_version() -- verify packet version
 
769
*
 
770
*  SYNOPSIS
 
771
*     bool sge_gdi_packet_verify_version(sge_gdi_packet_class_t *packet,
 
772
*                                        lList **alpp)
 
773
*
 
774
*  FUNCTION
 
775
*     This function is the replacement for the function
 
776
*     verify_request_version() which was part of the source code
 
777
*     before the packet structure was introduced.
 
778
*
 
779
*     It compares the version information of the provided "packet"
 
780
*     with the compiledin version number GRM_GDI_VERSION.
 
781
*
 
782
*     If both versions are not the same then it tries to find
 
783
*     if the client which provided us with this packet structure
 
784
*     has a higer version number or the binary executing
 
785
*     this function. In both cases the answer_list will
 
786
*     be filled with an appropriate message.
 
787
*
 
788
*  INPUTS
 
789
*     sge_gdi_packet_class_t *packet - packet
 
790
*     lList **alpp                   - answer list
 
791
*
 
792
*  RESULT
 
793
*     bool - error state
 
794
*        true  - same version
 
795
*        false - differnet version numbers
 
796
*
 
797
*  NOTES
 
798
*     MT-NOTE: sge_gdi_packet_verify_version() is not MT safe
 
799
******************************************************************************/
 
800
bool
 
801
sge_gdi_packet_verify_version(sge_gdi_packet_class_t * packet, lList **alpp)
 
802
{
 
803
   bool ret = true;
 
804
   char *client_version = NULL;
 
805
   dstring ds;
 
806
   char buffer[256];
 
807
   const vdict_t *vp;
 
808
   const vdict_t *vdict = GRM_GDI_VERSION_ARRAY;
 
809
   u_long32 version = packet->version;
 
810
 
 
811
   DENTER(TOP_LAYER, "sge_gdi_packet_verify_version");
 
812
   sge_dstring_init(&ds, buffer, sizeof(buffer));
 
813
 
 
814
   if (version != GRM_GDI_VERSION) {
 
815
      for (vp = &vdict[0]; vp->version; vp++) {
 
816
         if (version == vp->version) {
 
817
            client_version = vp->release;
 
818
         }
 
819
      }
 
820
 
 
821
      if (client_version) {
 
822
         WARNING((SGE_EVENT, MSG_GDI_WRONG_GDI_SSISS, packet->host,
 
823
                  packet->commproc, (int)(packet->id), client_version,
 
824
                  feature_get_product_name(FS_VERSION, &ds)));
 
825
      } else {
 
826
         WARNING((SGE_EVENT, MSG_GDI_WRONG_GDI_SSIUS, packet->host,
 
827
                  packet->commproc, (int)(packet->id), sge_u32c(version),
 
828
                  feature_get_product_name(FS_VERSION, &ds)));
 
829
      }
 
830
      answer_list_add(alpp, SGE_EVENT, STATUS_EVERSION, ANSWER_QUALITY_ERROR);
 
831
      ret = false;
 
832
   }
 
833
   DRETURN(ret);
 
834
}
 
835