2
/* ___INFO__MARK_BEGIN__ */
4
/*************************************************************************
6
* The Contents of this file are made available subject to the terms of
7
* the Sun Industry Standards Source License Version 1.2
9
* Sun Microsystems Inc., March, 2001
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
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.
26
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
28
* Copyright: 2001 by Sun Microsystems, Inc.
30
* All Rights Reserved.
32
************************************************************************/
34
/* ___INFO__MARK_END__ */
43
#include "basis_types.h"
45
#include "comm/commlib.h"
47
#include "rmon/sgermon.h"
49
#include "lck/sge_mtutil.h"
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"
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"
65
#include "sgeobj/sge_answer.h"
66
#include "sgeobj/sge_feature.h"
67
#include "sgeobj/sge_multiL.h"
69
#include "msg_common.h"
70
#include "msg_gdilib.h"
71
#include "msg_qmaster.h"
73
/****** gdi/request_internal/--Packets_and_Taks() *****************************
75
* Packets_and_Tasks -- Functions and structures behind GDI
78
* Packets and tasks are structures which are used in the methods
79
* implementing GDI. The real C structure names are
81
* "sge_gdi_packet_cass_t" and
82
* "sge_gdi_task_class_t".
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.
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.
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:
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()
108
* Following functions are used to handle data transfer
109
* from external GDI clients (qstat, qconf, ...) or internal
110
* GDI clients (scheduler, JVM, ...)
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()
117
* Data transfer of packets transfered between external GDI
118
* clients is prepared with following functions process:
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()
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
136
* sge_gdi_packet_queue_wait_for_new_packet()
137
* sge_gdi_packet_queue_store_notify()
138
* sge_gdi_packet_queue_wakeup_all_waiting()
140
* Additional synchronisation functions are
142
* sge_gdi_packet_wait_till_handled()
143
* sge_gdi_packet_broadcast_that_handled()
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
*******************************************************************************/
175
#define SGE_GDI_PACKET_DEBUG
178
#if defined(SGE_GDI_PACKET_DEBUG)
179
bool sge_gdi_task_debug_print(sge_gdi_task_class_t * task);
182
static bool sge_gdi_task_free(sge_gdi_task_class_t ** task);
184
static bool sge_gdi_task_verify(sge_gdi_task_class_t * task,
185
lList **answer_list);
187
static sge_gdi_task_class_t *sge_gdi_task_create(sge_gdi_packet_class_t *
188
packet, lList **answer_list,
190
u_long32 command, lList **lp,
192
lCondition **condition,
193
lEnumeration **enumeration,
194
bool do_copy, bool do_verify);
196
static bool sge_gdi_task_free(sge_gdi_task_class_t ** task);
198
#if defined(SGE_GDI_PACKET_DEBUG)
199
bool sge_gdi_packet_debug_print(sge_gdi_packet_class_t * packet);
203
#if defined(SGE_GDI_PACKET_DEBUG)
205
sge_gdi_task_debug_print(sge_gdi_task_class_t * task)
209
DENTER(TOP_LAYER, "sge_gdi_task_debug_print");
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));
221
DPRINTF(("task is NULL\n"));
229
sge_gdi_task_verify(sge_gdi_task_class_t * task, lList **answer_list)
238
DENTER(TOP_LAYER, "sge_gdi_task_verify");
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? */
245
&& !(operation == SGE_GDI_PERMCHECK || operation == SGE_GDI_GET
246
|| operation == SGE_GDI_TRIGGER || (operation == SGE_GDI_DEL
250
answer_list_add_sprintf(answer_list, STATUS_ESEMANTIC,
251
ANSWER_QUALITY_ERROR, MSG_GDI_GDI_VERIFY_REQUEST_FAILED);
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)
264
sge_gdi_task_class_t *task = NULL;
266
DENTER(TOP_LAYER, "sge_gdi_task_create");
268
task = (sge_gdi_task_class_t *) sge_malloc(sizeof(sge_gdi_task_class_t));
271
((packet->last_task != NULL) ? (packet->last_task->id + 1) : 1);
272
task->command = command;
273
task->target = target;
275
task->do_select_pack_simultaneous = false;
277
if (enumeration != NULL && *enumeration != NULL) {
278
task->data_list = (((lp != NULL) && (*lp != NULL)) ?
279
lSelect("", *lp, NULL, *enumeration) : NULL);
281
task->data_list = (((lp != NULL) && (*lp != NULL)) ?
282
lCopyList("", *lp) : NULL);
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);
291
if ((lp != NULL) && (*lp != NULL)) {
292
task->data_list = *lp;
295
task->data_list = NULL;
297
if ((a_list != NULL) && (*a_list != NULL)) {
298
task->answer_list = *a_list;
301
task->answer_list = NULL;
303
if ((condition != NULL) && (*condition != NULL)) {
304
task->condition = *condition;
307
task->condition = NULL;
309
if ((enumeration != NULL) && (*enumeration != NULL)) {
310
task->enumeration = *enumeration;
313
task->enumeration = NULL;
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));
323
task->data_list = NULL;
324
task->answer_list = NULL;
325
task->condition = NULL;
326
task->enumeration = NULL;
328
sge_gdi_task_free(&task);
331
answer_list_add_sprintf(answer_list, STATUS_EMALLOC,
332
ANSWER_QUALITY_ERROR, MSG_MEMORY_MALLOCFAILED);
337
/****** gdi/request_internal/sge_gdi_task_free() ******************************
339
* sge_gdi_task_free() -- free a gdi task structure
343
* sge_gdi_task_free(sge_gdi_task_class_t **task)
346
* free all elements of the gdi task structure and the structure itself.
349
* sge_gdi_task_class_t **task - pointer to the task structure pointer
353
* true - success (always)
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.
361
* gdi/request_internal/sge_gdi_task_create()
362
******************************************************************************/
364
sge_gdi_task_free(sge_gdi_task_class_t ** task)
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));
379
#if defined(SGE_GDI_PACKET_DEBUG)
381
sge_gdi_packet_debug_print(sge_gdi_packet_class_t * packet)
385
DENTER(TOP_LAYER, "sge_gdi_packet_debug_print");
387
if (packet != NULL) {
388
sge_gdi_task_class_t *task;
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));
399
task = packet->first_task;
400
while (task != NULL) {
401
sge_gdi_task_debug_print(task);
405
DPRINTF(("packet is NULL\n"));;
412
/****** gdi/request_internal/sge_gdi_packet_create_base() ********************
414
* sge_gdi_packet_create_base() -- ???
417
* sge_gdi_packet_class_t *
418
* sge_gdi_packet_create_base(lList **answer_list)
421
* Creates a new GDI packet and initializes all base structure memebers
422
* where necessary information is available.
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.
430
* lList **answer_list - answer list in case of error
433
* sge_gdi_packet_class_t * - new GDI packet
436
* MT-NOTE: sge_gdi_packet_create_base() is MT safe
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)
445
sge_gdi_packet_class_t *ret = NULL;
447
DENTER(TOP_LAYER, "sge_gdi_packet_create_base");
448
ret = (sge_gdi_packet_class_t *) sge_malloc(sizeof(sge_gdi_packet_class_t));
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;
461
ret->commproc = NULL;
462
ret->commproc_id = 0;
464
ret->version = GRM_GDI_VERSION;
465
ret->first_task = NULL;
466
ret->last_task = NULL;
467
ret->auth_info = NULL;
469
memset(&(ret->pb), 0, sizeof(sge_pack_buffer));
471
answer_list_add_sprintf(answer_list, STATUS_EMALLOC,
472
ANSWER_QUALITY_ERROR,
473
MSG_MEMORY_MALLOCFAILED);
476
answer_list_add_sprintf(answer_list, STATUS_EMALLOC,
477
ANSWER_QUALITY_ERROR, MSG_SGETEXT_NOMEM);
482
/****** gdi/request_internal/sge_gdi_packet_create() **************************
484
* sge_gdi_packet_create() -- create a new GDI packet and initialize it
487
* sge_gdi_packet_class_t *
488
* sge_gdi_packet_create(sge_gdi_ctx_class_t *ctx, lList **answer_list)
491
* Creates a new GDI packet element and initializes all members of the
495
* sge_gdi_ctx_class_t *ctx - GDI context
496
* lList **answer_list - answer list
499
* sge_gdi_packet_class_t * - new packet element or NULL in case of errors
502
* MT-NOTE: sge_gdi_packet_create() is MT safe
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)
511
sge_gdi_packet_class_t *ret = NULL;
513
DENTER(TOP_LAYER, "sge_gdi_packet_create");
514
ret = sge_gdi_packet_create_base(answer_list);
516
sge_gdi_packet_initialize_auth_info(ctx, ret);
521
/****** gdi/request_internal/sge_gdi_packet_append_task() *********************
523
* sge_gdi_packet_append_task() -- append an additional GDI task
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)
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.
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:
551
* - verification failure (sgee sge_gdi_task_verify)
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
564
* bool do_verify - do verification of input data
569
* false - error (answer_list will be filled with detailed information)
572
* MT-NOTE: sge_gdi_packet_append_task() is MT safe
575
* gdi/request_internal/sge_gdi_task_create()
576
* gdi/request_internal/sge_gdi_task_verify()
577
******************************************************************************/
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)
586
sge_gdi_task_class_t *task = NULL;
588
DENTER(TOP_LAYER, "sge_gdi_packet_append_task");
591
sge_gdi_task_create(packet, answer_list, target, command, lp, a_list,
592
condition, enumeration, do_copy, true);
594
if (packet->last_task != NULL) {
595
packet->last_task->next = task;
596
packet->last_task = task;
598
packet->first_task = task;
599
packet->last_task = task;
606
/****** gdi/request_internal/sge_gdi_task_get_operation_name() ****************
608
* sge_gdi_task_get_operation_name() -- get command name
612
* sge_gdi_task_get_operation_name(sge_gdi_task_class_t *task)
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))
620
* sge_gdi_task_class_t *task - gdi task
623
* const char * - string
626
* MT-NOTE: sge_gdi_task_get_operation_name() is MT safe
627
*******************************************************************************/
629
sge_gdi_task_get_operation_name(sge_gdi_task_class_t *task)
631
const char *ret = NULL;
633
switch (task->command) {
649
case SGE_GDI_TRIGGER:
652
case SGE_GDI_PERMCHECK:
655
case SGE_GDI_REPLACE:
665
/****** gdi/request_internal/sge_gdi_packet_get_last_task_id() ****************
667
* sge_gdi_packet_get_last_task_id() -- returns the last used task id
671
* sge_gdi_packet_get_last_task_id(sge_gdi_packet_class_t *packet)
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()
679
* sge_gdi_packet_class_t *packet - packet pointer
682
* u_long32 - task id in the range [1, ULONG32_MAX]
686
* MT-NOTE: sge_gdi_packet_get_last_task_id() is not MT safe
689
* gdi/request_internal/sge_gdi_task_create()
690
* gdi/request_internal/sge_gdi_packet_append_task()
691
******************************************************************************/
693
sge_gdi_packet_get_last_task_id(sge_gdi_packet_class_t * packet)
697
DENTER(TOP_LAYER, "sge_gdi_packet_get_last_task_id");
699
if (packet->last_task != NULL) {
700
ret = packet->last_task->id;
705
/****** gdi/request_internal/sge_gdi_packet_free() ****************************
707
* sge_gdi_packet_free() -- free memory allocated by packet
710
* bool sge_gdi_packet_free(sge_gdi_packet_class_t **packet)
713
* Releases the memory allocated by all members of ther "packet"
714
* structure including the list of tasks and sublists part of the
717
* The caller has to take care that the packet is not part of
718
* a packet queue when this function is called!
721
* sge_gdi_packet_class_t **packet - packet
729
* MT-NOTE: sge_gdi_packet_free() is not MT safe
732
* gdi/request_internal/sge_gdi_task_create()
733
* gdi/request_internal/sge_gdi_packet_create()
734
******************************************************************************/
736
sge_gdi_packet_free(sge_gdi_packet_class_t ** packet)
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;
747
next_task = (*packet)->first_task;
748
while ((task = next_task) != NULL) {
749
next_task = task->next;
750
sge_gdi_task_free(&task);
752
local_ret1 = pthread_mutex_destroy(&((*packet)->mutex));
753
local_ret2 = pthread_cond_destroy(&((*packet)->cond));
754
if (local_ret1 != 0 || local_ret2 != 0) {
757
(*packet)->host = sge_free((char *) (*packet)->host);
758
(*packet)->commproc = sge_free((char *) (*packet)->commproc);
760
(*packet)->auth_info = sge_free((char *) (*packet)->auth_info);
761
*packet = (sge_gdi_packet_class_t *)sge_free((char *) *packet);
766
/****** sge_gdi_packet/sge_gdi_packet_verify_version() ************************
768
* sge_gdi_packet_verify_version() -- verify packet version
771
* bool sge_gdi_packet_verify_version(sge_gdi_packet_class_t *packet,
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.
779
* It compares the version information of the provided "packet"
780
* with the compiledin version number GRM_GDI_VERSION.
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.
789
* sge_gdi_packet_class_t *packet - packet
790
* lList **alpp - answer list
794
* true - same version
795
* false - differnet version numbers
798
* MT-NOTE: sge_gdi_packet_verify_version() is not MT safe
799
******************************************************************************/
801
sge_gdi_packet_verify_version(sge_gdi_packet_class_t * packet, lList **alpp)
804
char *client_version = NULL;
808
const vdict_t *vdict = GRM_GDI_VERSION_ARRAY;
809
u_long32 version = packet->version;
811
DENTER(TOP_LAYER, "sge_gdi_packet_verify_version");
812
sge_dstring_init(&ds, buffer, sizeof(buffer));
814
if (version != GRM_GDI_VERSION) {
815
for (vp = &vdict[0]; vp->version; vp++) {
816
if (version == vp->version) {
817
client_version = vp->release;
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)));
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)));
830
answer_list_add(alpp, SGE_EVENT, STATUS_EVERSION, ANSWER_QUALITY_ERROR);