1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
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
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.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2001 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
38
#include <sys/types.h>
39
#include <netinet/in.h>
41
#include <rpc/types.h>
44
#include <arpa/inet.h>
49
#include <arpa/inet.h>
52
/* do not compile in monitoring code */
53
#ifndef NO_SGE_COMPILE_DEBUG
54
#define NO_SGE_COMPILE_DEBUG
57
#include "basis_types.h"
59
#include "cull_listP.h"
62
#include "cull_state.h"
64
#include "uti/sge_stdlib.h"
68
# define PACK_LAYER BASIS_LAYER
72
/****** cull/pack/--CULL_Packing ***************************************
75
* CULL_Packing -- platform independent exchange format
78
* The cull packing functions provide a framework for a
79
* platform independent data representation.
81
* Data is written into a packbuffer. Individual data words
82
* are written in network byte order.
84
* Data in the packbuffer can be compressed.
87
* Other platform independent formats, like XML, should be
91
* cull/pack/-Versioncontrol
93
* cull/pack/packbitfield()
94
* cull/pack/unpackbitfield()
95
****************************************************************************
98
/* -------------------------------
103
int pack_get_chunk(void)
108
/****** cull/pack/init_packbuffer() *******************************************
110
* init_packbuffer() -- initialize packing buffer
113
* int init_packbuffer(sge_pack_buffer *pb, int initial_size,
117
* Initialize a packing buffer.
118
* Allocates the necessary memory. If more memory is needed during the use
119
* of the packbuffer, it will be reallocated increasing the size by
120
* chunk_size (see function pack_set_chunk).
122
* Since version 6.0, version information is provided in the packbuffer and
123
* is included in sent messages.
124
* For best possible backward interoperability with former versions, an
125
* integer with value 0 is padded before the version information as first
126
* word in the packbuffer. This triggeres error handling in former versions.
128
* Functions using packing buffers in GDI or related code should use the
129
* function sge_gdi_packet_get_pb_size() to find the correct
133
* sge_pack_buffer *pb - the packbuffer to initialize
134
* int initial_size - the amount of memory to be allocated at
136
* If a value of 0 is given as initial_size, a size
137
* of chunk_size (global variable, see function
138
* pack_set_chunk) will be used.
139
* int just_count - if true, no memory will be allocated and the
140
* "just_count" property of the packbuffer will
144
* int - PACK_SUCCESS on success
145
* PACK_ENOMEM if memory allocation fails
146
* PACK_FORMAT if no valid packbuffer is passed
149
* MT-NOTE: init_packbuffer() is MT safe (assumptions)
152
* cull/pack/-Packing-typedefs
153
* cull/pack/pack_set_chunk()
154
* gdi/request_internal/sge_gdi_packet_get_pb_size()
155
*******************************************************************************/
157
init_packbuffer(sge_pack_buffer *pb, int initial_size, int just_count)
159
DENTER(PACK_LAYER, "init_packbuffer");
162
ERROR((SGE_EVENT, MSG_CULL_ERRORININITPACKBUFFER_S, MSG_CULL_PACK_FORMAT));
168
if (initial_size == 0) {
169
initial_size = CHUNK;
171
initial_size += 2 * INTSIZE; /* space for version information */
174
memset(pb, 0, sizeof(sge_pack_buffer));
176
pb->head_ptr = malloc(initial_size);
178
ERROR((SGE_EVENT, MSG_CULL_NOTENOUGHMEMORY_D, initial_size));
182
pb->cur_ptr = pb->head_ptr;
183
pb->mem_size = initial_size;
185
pb->cur_ptr = pb->head_ptr;
186
pb->mem_size = initial_size;
190
pb->version = CULL_VERSION;
191
packint(pb, 0); /* pad 0 byte -> error handing in former versions */
192
packint(pb, pb->version); /* version information is included in buffer */
194
pb->head_ptr = pb->cur_ptr = NULL;
200
DRETURN(PACK_SUCCESS);
203
/**************************************************************
204
initialize packing buffer out of a normal character buffer
205
set read/write pointer to the beginning
208
MT-NOTE: init_packbuffer_from_buffer() is MT safe (assumptions)
209
**************************************************************/
211
init_packbuffer_from_buffer(sge_pack_buffer *pb, char *buf, u_long32 buflen)
213
DENTER(PACK_LAYER, "init_packbuffer_from_buffer");
216
DRETURN(PACK_FORMAT);
219
memset(pb, 0, sizeof(sge_pack_buffer));
223
pb->mem_size = buflen;
226
/* check cull version (only if buffer contains any data) */
229
u_long32 pad, version;
231
if((ret = unpackint(pb, &pad)) != PACK_SUCCESS) {
236
if((ret = unpackint(pb, &version)) != PACK_SUCCESS) {
241
if(pad != 0 || version != CULL_VERSION) {
242
ERROR((SGE_EVENT, MSG_CULL_PACK_WRONG_VERSION_XX, (unsigned int) version, CULL_VERSION));
247
pb->version = version;
249
pb->version = CULL_VERSION;
256
/**************************************************************/
257
/* MT-NOTE: clear_packbuffer() is MT safe */
258
void clear_packbuffer(sge_pack_buffer *pb) {
265
/*************************************************************
266
look whether pb is filled
267
*************************************************************/
271
/* do we have more bytes used than the version information? */
272
return (pb_used(pb) > (2 * INTSIZE));
275
/*************************************************************
276
look for the number of bytes that are unused
277
i.e. that are not yet consumed
278
*************************************************************/
282
return (pb->mem_size - pb->bytes_used);
285
/*************************************************************
286
look for the number of bytes that are used
287
*************************************************************/
291
return pb->bytes_used;
294
/* --------------------------------------------------------- */
296
/* low level functions for packing */
298
/* --------------------------------------------------------- */
306
int packint(sge_pack_buffer *pb, u_long32 i)
310
DENTER(PACK_LAYER, "packint");
312
if (!pb->just_count) {
313
if (pb->bytes_used + INTSIZE > pb->mem_size) {
314
DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
315
pb->mem_size += CHUNK;
316
pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
321
pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
324
/* copy in packing buffer */
326
memcpy(pb->cur_ptr, (((char *) &J) + INTOFF), INTSIZE);
327
pb->cur_ptr = &(pb->cur_ptr[INTSIZE]);
329
pb->bytes_used += INTSIZE;
335
int repackint(sge_pack_buffer *pb, u_long32 i)
339
DENTER(PACK_LAYER, "repackint");
341
if (!pb->just_count) {
343
memcpy(pb->cur_ptr, (((char *) &J) + INTOFF), INTSIZE);
344
pb->cur_ptr = &(pb->cur_ptr[INTSIZE]);
359
int packdouble(sge_pack_buffer *pb, double d) {
360
/* CygWin does not know RPC u. XDR */
362
#if !(defined(WIN32)) /* var not needed */
366
DENTER(PACK_LAYER, "packdouble");
368
if (!pb->just_count) {
369
if (pb->bytes_used + DOUBLESIZE > pb->mem_size) {
370
DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
371
pb->mem_size += CHUNK;
372
pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
377
pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
380
/* copy in packing buffer */
381
#if !(defined(WIN32) || defined(INTERIX)) /* XDR not called */
382
xdrmem_create(&xdrs, (caddr_t)buf, sizeof(buf), XDR_ENCODE);
384
if (!(xdr_double(&xdrs, &d))) {
385
DPRINTF(("error - XDR of double failed\n"));
391
if (xdr_getpos(&xdrs) != DOUBLESIZE) {
392
DPRINTF(("error - size of XDRed double is %d\n", xdr_getpos(&xdrs)));
397
#endif/* WIN32 || INTERIX */
399
wl_xdrmem_create(&xdrs, (caddr_t)buf, sizeof(buf), XDR_ENCODE);
401
if (!(wl_xdr_double(&xdrs, &d))) {
402
DPRINTF(("error - XDR of double failed\n"));
403
wl_xdr_destroy(&xdrs);
408
if (wl_xdr_getpos(&xdrs) != DOUBLESIZE) {
409
DPRINTF(("error - size of XDRed double is %d\n", wl_xdr_getpos(&xdrs)));
410
wl_xdr_destroy(&xdrs);
416
memcpy(pb->cur_ptr, buf, DOUBLESIZE);
417
/* we have to increment the buffer even through WIN32 will not use it */
418
pb->cur_ptr = &(pb->cur_ptr[DOUBLESIZE]);
420
#if !(defined(WIN32) || defined(INTERIX)) /* XDR not called */
424
wl_xdr_destroy(&xdrs);
427
pb->bytes_used += DOUBLESIZE;
433
/* ---------------------------------------------------------
441
int packstr(sge_pack_buffer *pb, const char *str)
443
DENTER(PACK_LAYER, "packstr");
445
/* determine string length */
447
if (!pb->just_count) {
448
/* is realloc necessary */
449
if ((pb->bytes_used + 1) > pb->mem_size) {
452
DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
453
pb->mem_size += CHUNK;
454
pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
461
pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
463
pb->cur_ptr[0] = '\0';
464
/* update cur_ptr & bytes_packed */
465
pb->cur_ptr = &(pb->cur_ptr[1]);
469
size_t n = strlen(str) + 1;
471
if (!pb->just_count) {
472
/* is realloc necessary */
473
if ((pb->bytes_used + n) > pb->mem_size) {
475
DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
476
while ((pb->bytes_used + n) > pb->mem_size)
477
pb->mem_size += CHUNK;
478
pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
485
pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
487
memcpy(pb->cur_ptr, str, n);
488
/* update cur_ptr & bytes_packed */
489
pb->cur_ptr = &(pb->cur_ptr[n]);
499
/****** cull/pack/packbitfield() ****************************************************
501
* packbitfield() -- pack a bitfield
504
* int packbitfield(sge_pack_buffer *pb, const bitfield *bitfield)
507
* Writes the bitfield into the given packbuffer.
508
* The following information will be written:
509
* - the size of the bitfield in bits
510
* - the bitfield itself as binary buffer
513
* sge_pack_buffer *pb - the target packbuffer
514
* const bitfield *bitfield - the bitfield to pack
517
* int - PACK_SUCCESS on success,
518
* else PACK_* error codes
521
* uti/bitfield/--Bitfield
522
* cull/pack/unpackbitfield()
523
*******************************************************************************/
524
int packbitfield(sge_pack_buffer *pb, const bitfield *bitfield)
530
DENTER(PACK_LAYER, "packbitfield");
532
size = sge_bitfield_get_size(bitfield);
533
char_size = sge_bitfield_get_size_bytes(size);
535
if((ret = packint(pb, size)) != PACK_SUCCESS) {
540
if((ret = packbuf(pb, sge_bitfield_get_buffer(bitfield),
541
char_size)) != PACK_SUCCESS) {
550
/* ---------------------------------------------------------
564
DENTER(PACK_LAYER, "packbuf");
566
if (!pb->just_count) {
567
/* is realloc necessary */
568
#if !(defined(WIN32)) /* cast */
569
if (buf_size + (u_long32) pb->bytes_used > (u_long32) pb->mem_size) {
571
if (buf_size + pb->bytes_used > pb->mem_size) {
575
DPRINTF(("realloc(%d + %d)\n", pb->mem_size, CHUNK));
576
pb->mem_size += CHUNK;
577
pb->head_ptr = sge_realloc(pb->head_ptr, pb->mem_size, 0);
578
if (!(pb->head_ptr)) {
584
pb->cur_ptr = &(pb->head_ptr[pb->bytes_used]);
587
/* copy in packing buffer */
588
memcpy(pb->cur_ptr, buf_ptr, buf_size);
589
/* update cur_ptr & bytes_packed */
590
pb->cur_ptr = &(pb->cur_ptr[buf_size]);
592
pb->bytes_used += buf_size;
599
/* --------------------------------------------------------- */
601
/* low level functions for unpacking */
603
/* --------------------------------------------------------- */
605
/* ---------------------------------------------------------
613
int unpackint(sge_pack_buffer *pb, u_long32 *ip)
615
DENTER(PACK_LAYER, "unpackint");
617
/* are there enough bytes ? */
618
if (pb->bytes_used + INTSIZE > pb->mem_size) {
625
memset(ip, 0, sizeof(u_long32));
626
memcpy(((char *) ip) + INTOFF, pb->cur_ptr, INTSIZE);
629
/* update cur_ptr & bytes_unpacked */
630
pb->cur_ptr = &(pb->cur_ptr[INTSIZE]);
631
pb->bytes_used += INTSIZE;
637
/* ---------------------------------------------------------
645
int unpackdouble(sge_pack_buffer *pb, double *dp)
648
#if !(defined(WIN32)) /* var not needed */
653
DENTER(PACK_LAYER, "unpackdouble");
655
/* are there enough bytes ? */
656
if (pb->bytes_used + DOUBLESIZE > pb->mem_size) {
664
/* CygWin does not know RPC u. XDR */
665
#if !(defined(WIN32) || defined(INTERIX)) /* XDR not called */
666
memcpy(buf, pb->cur_ptr, DOUBLESIZE);
667
xdrmem_create(&xdrs, buf, DOUBLESIZE, XDR_DECODE);
668
if (!(xdr_double(&xdrs, dp))) {
670
DPRINTF(("error unpacking XDRed double\n"));
675
#endif /* WIN32 || INTERIX */
677
memcpy(buf, pb->cur_ptr, DOUBLESIZE);
678
wl_xdrmem_create(&xdrs, buf, DOUBLESIZE, XDR_DECODE);
679
if (!(wl_xdr_double(&xdrs, dp))) {
681
DPRINTF(("error unpacking XDRed double\n"));
682
wl_xdr_destroy(&xdrs);
688
/* update cur_ptr & bytes_unpacked */
689
pb->cur_ptr = &(pb->cur_ptr[DOUBLESIZE]);
690
pb->bytes_used += DOUBLESIZE;
692
#if !(defined(WIN32) || defined(INTERIX)) /* XDR not called */
694
#endif /* WIN32 || INTERIX */
696
wl_xdr_destroy(&xdrs);
703
/* ---------------------------------------------------------
710
int unpackstr(sge_pack_buffer *pb, char **str)
714
DENTER(PACK_LAYER, "unpackstr");
716
/* determine string length */
717
if (!pb->cur_ptr[0]) {
721
/* update cur_ptr & bytes_unpacked */
722
pb->cur_ptr = &(pb->cur_ptr[1]);
725
/* are there enough bytes ? */
726
if (pb->bytes_used > pb->mem_size) {
734
n = strlen(pb->cur_ptr) + 1;
736
/* are there enough bytes ? */
737
if (n + pb->bytes_used > pb->mem_size) {
741
*str = strdup(pb->cur_ptr);
746
/* update cur_ptr & bytes_unpacked */
748
pb->cur_ptr = &(pb->cur_ptr[n]);
755
/* ---------------------------------------------------------
762
int unpackbuf(sge_pack_buffer *pb, char **buf_ptr, int buf_size)
765
DENTER(PACK_LAYER, "unpackbuf");
772
/* are there enough bytes ? */
773
if ((buf_size + pb->bytes_used) > pb->mem_size) {
779
*buf_ptr = malloc(buf_size);
784
memcpy(*buf_ptr, pb->cur_ptr, buf_size);
785
/* update cur_ptr & bytes_unpacked */
786
pb->cur_ptr = &(pb->cur_ptr[buf_size]);
787
pb->bytes_used += buf_size;
793
/****** cull/pack/unpackbitfield() ********************************************
795
* unpackbitfield() -- unpack a bitfield
798
* int unpackbitfield(sge_pack_buffer *pb, bitfield *bitfield)
801
* Unpacks a bitfield from a packbuffer.
803
* If the size of the descriptor doesn't match the size of the unpacked
804
* bitfield, create a new bitfield.
807
* sge_pack_buffer *pb - the source packbuffer
808
* bitfield *bitfield - used to return the unpacked bitfield
809
* int descr_size - size of the corresponding descriptor
812
* int - PACK_SUCCESS on success,
813
* else PACK_* error codes
816
* uti/bitfield/--Bitfield
817
* cull/pack/packbitfield()
818
*******************************************************************************/
819
int unpackbitfield(sge_pack_buffer *pb, bitfield *bitfield, int descr_size)
822
u_long32 size, char_size;
825
DENTER(PACK_LAYER, "unpackbitfield");
827
/* create new bitfield */
828
if (!sge_bitfield_init(bitfield, descr_size)) {
833
/* unpack the size in bits */
834
if((ret = unpackint(pb, &size)) != PACK_SUCCESS) {
839
/* size may not be bigger than bitfield initialized from descr information */
840
if (size > descr_size) {
845
/* unpack contents of the bitfield */
846
char_size = sge_bitfield_get_size_bytes(size);
847
if((ret = unpackbuf(pb, &buffer, char_size)) != PACK_SUCCESS) {
848
sge_bitfield_free_data(bitfield);
853
memcpy(sge_bitfield_get_buffer(bitfield), buffer, char_size);
855
/* free unpacked bitfield buffer */
862
const char *cull_pack_strerror(int errnum)
866
return MSG_CULL_PACK_SUCCESS;
868
return MSG_CULL_PACK_ENOMEM;
870
return MSG_CULL_PACK_FORMAT;
872
return MSG_CULL_PACK_BADARG;
874
return MSG_CULL_PACK_VERSION;
876
/* JG: TODO: we should have some global error message for all strerror functions */
881
/****** cull/pack/pb_are_equivalent() *****************************************
883
* pb_are_equivalent() -- check if both buffers are equivalent
886
* bool pb_are_equivalent(sge_pack_buffer *pb1, sge_pack_buffer *pb2)
889
* Check if size and content of both packbuffers is equivalent
892
* sge_pack_buffer *pb1 - packbuffer
893
* sge_pack_buffer *pb2 - packbuffer
899
*******************************************************************************/
901
pb_are_equivalent(sge_pack_buffer *pb1, sge_pack_buffer *pb2)
905
if (pb1 != NULL && pb2 != NULL) {
906
ret &= (pb1->bytes_used == pb2->bytes_used);
907
ret &= (memcmp(pb1->head_ptr, pb2->head_ptr, pb1->bytes_used) == 0);
912
/****** cull/pack/pb_print_to() ***********************************************
914
* pb_print_to() -- Print content of packbuffer
917
* void pb_print_to(sge_pack_buffer *pb, FILE* file)
920
* Print content of packbuffer into file
923
* sge_pack_buffer *pb - packbuffer pointer
924
* bool only_header - show only summary information
925
* FILE* file - file stream (e.g. stderr)
929
*******************************************************************************/
931
pb_print_to(sge_pack_buffer *pb, bool only_header, FILE* file)
935
fprintf(file, "head_ptr: %p\n", pb->head_ptr);
936
fprintf(file, "cur_ptr: %p\n", pb->cur_ptr);
937
fprintf(file, "mem_size: %d\n", (int)pb->mem_size);
938
fprintf(file, "bytes_used: %d\n", (int)pb->bytes_used);
939
fprintf(file, "buffer:\n");
941
for (i = 0; i < pb->bytes_used; i++) {
942
fprintf(file, "%3d ", pb->head_ptr[i]);
943
if ((i + 1) % 15 == 0) {