~ubuntu-branches/ubuntu/precise/ncbi-tools6/precise

« back to all changes in this revision

Viewing changes to connect/lbapi/lbapi.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2005-03-27 12:00:15 UTC
  • mfrom: (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050327120015-embhesp32nj73p9r
Tags: 6.1.20041020-3
* Fix FTBFS under GCC 4.0 caused by inconsistent use of "static" on
  functions.  (Closes: #295110.)
* Add a watch file, now that we can.  (Upstream's layout needs version=3.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: lbapi.c,v 1.11 1999/02/26 21:17:36 shavirin Exp $
2
 
* ===========================================================================
3
 
*
4
 
*                            PUBLIC DOMAIN NOTICE
5
 
*               National Center for Biotechnology Information
6
 
*
7
 
*  This software/database is a "United States Government Work" under the
8
 
*  terms of the United States Copyright Act.  It was written as part of
9
 
*  the author's official duties as a United States Government employee and
10
 
*  thus cannot be copyrighted.  This software/database is freely available
11
 
*  to the public for use. The National Library of Medicine and the U.S.
12
 
*  Government have not placed any restriction on its use or reproduction.
13
 
*
14
 
*  Although all reasonable efforts have been taken to ensure the accuracy
15
 
*  and reliability of the software and data, the NLM and the U.S.
16
 
*  Government do not and cannot warrant the performance or results that
17
 
*  may be obtained by using this software or data. The NLM and the U.S.
18
 
*  Government disclaim all warranties, express or implied, including
19
 
*  warranties of performance, merchantability or fitness for any particular
20
 
*  purpose.
21
 
*
22
 
*  Please cite the author in any work or product based on this material.
23
 
*
24
 
* ===========================================================================
25
 
*
26
 
* File Name:  $RCSfile: lbapi.c,v $
27
 
*
28
 
* Author:  Sergei Shavirin
29
 
*
30
 
* Initial Version Creation Date: 03/24/1997
31
 
*
32
 
* $Revision: 1.11 $
33
 
*
34
 
* File Description:
35
 
*        Utilities for the load balancing client library
36
 
*
37
 
* $Log: lbapi.c,v $
38
 
* Revision 1.11  1999/02/26 21:17:36  shavirin
39
 
* Moved al ntohl function to the lbdaemon area.
40
 
*
41
 
* Revision 1.10  1999/02/02 21:10:28  shavirin
42
 
* Changed formula to calculate status:
43
 
* Added adjustment of load and used 4th lb-parameter.
44
 
*
45
 
* Revision 1.9  1998/12/07 19:01:50  shavirin
46
 
* Added complience with little-big endian platforms.
47
 
*
48
 
* Revision 1.8  1998/09/22 17:22:57  yaschenk
49
 
* LBCalculateStatus: changed additive constant 1 which is very high to 0.01
50
 
*
51
 
* Revision 1.7  1998/05/08 15:26:57  vakatov
52
 
* [LB_DIRECT]  now can skip IP addresses(for the dispatcher hosts) which
53
 
* were already offered by the load-balancing daemon but failed by some reason
54
 
*
55
 
* Revision 1.6  1998/04/23 14:26:18  shavirin
56
 
* Added include #include <sys/ipc.h>
57
 
*
58
 
* Revision 1.5  1998/04/07 14:17:27  vakatov
59
 
* Skip all code(#ifdef'd) if LB_DIRECT is not defined or if compiled on
60
 
* any platform but Solaris and IRIX
61
 
*
62
 
* Revision 1.4  1998/04/03 21:50:08  shavirin
63
 
* Added include file for TCP/IP address define
64
 
*
65
 
* Revision 1.3  1998/04/03 21:16:47  vakatov
66
 
* Cleaned up the code and prepared "lbapi.[ch]" to be moved to "netcli" lib
67
 
*
68
 
* Revision 1.2  1998/04/02 17:36:04  yaschenk
69
 
* Adding dispd-ncbid shortcut when they are on the same server, adding preference to same server in stateless mode
70
 
*
71
 
* Revision 1.1  1998/03/06 18:54:25  shavirin
72
 
* Initial revision
73
 
* ==========================================================================
74
 
*/
75
 
 
76
 
#include <lbapi.h>
77
 
 
78
 
#ifdef LB_DIRECT
79
 
 
80
 
#include <stdio.h>
81
 
#include <stdlib.h>
82
 
#include <string.h>
83
 
#include <time.h>
84
 
#include <netinet/in.h>
85
 
#include <arpa/inet.h>
86
 
#include <netdb.h>
87
 
#include <sys/socket.h>
88
 
#include <sys/ipc.h>
89
 
#include <sys/shm.h>
90
 
 
91
 
#define SHM_FLAGS ((SHM_R >> 6) | (SHM_R >> 3) | SHM_R)
92
 
#define MAX_RAND_NUMBER 0x7FFF 
93
 
 
94
 
 
95
 
typedef struct LBUserInfo {
96
 
  LB_MessagePtr lbtable;
97
 
  int shmemid;
98
 
} LBUserInfo, *LBUserInfoPtr;
99
 
 
100
 
typedef struct LBStatus {
101
 
  int   index;
102
 
  float status;
103
 
  int   skip;
104
 
} LBStatus, *LBStatusPtr;
105
 
 
106
 
 
107
 
static LBUserInfo theinfo;
108
 
 
109
 
static float LBCalculateStatus(LB_MessagePtr msgp)
110
 
{
111
 
    float status;
112
 
    int cpuload;
113
 
 
114
 
    /* Penalize machine if load[0]/256 > load[1] */
115
 
 
116
 
    cpuload = msgp->load[0];
117
 
 
118
 
    if(msgp->load[0] > (msgp->load[1]<<8))
119
 
        cpuload *= exp(msgp->load[0] / (256.0*msgp->load[1]) - 1.0);
120
 
    
121
 
    status = 0.01 + 256000*msgp->load[1] / (float)(cpuload*msgp->load[2] + 1);
122
 
    
123
 
    status = status * msgp->load[3];
124
 
    
125
 
    return status;
126
 
}
127
 
 
128
 
static int LBClientInit(void)
129
 
{
130
 
  /* setting it completely random */
131
 
  srand(time(NULL));
132
 
 
133
 
  if ((theinfo.shmemid = shmget(LB_SHARED_KEY, 
134
 
                                sizeof(LB_Message) * MAX_NUM_HOSTS, 
135
 
                                SHM_FLAGS)) < 0)
136
 
    return -1;
137
 
    
138
 
  if ((theinfo.lbtable = (LB_MessagePtr)
139
 
      shmat(theinfo.shmemid, (void *)0, SHM_RDONLY)) == (LB_MessagePtr)-1)
140
 
    return -1;
141
 
    
142
 
  return 0;
143
 
}
144
 
 
145
 
 
146
 
extern int LBPrintTable(void)
147
 
{
148
 
    int i, j;
149
 
    struct sockaddr_in sin;
150
 
    struct hostent    *hp;
151
 
    float status;
152
 
    LB_MessagePtr lbtable;
153
 
    
154
 
    if((lbtable = theinfo.lbtable) == NULL) {
155
 
        if(LBClientInit() < 0)
156
 
            return -1;
157
 
        lbtable = theinfo.lbtable;
158
 
    }
159
 
    
160
 
  for(j = 0; j < MAX_NUM_HOSTS; j++) {
161
 
      if(lbtable[j].address != 0) {
162
 
          sin.sin_addr.s_addr = lbtable[j].address;
163
 
                    
164
 
          hp = gethostbyaddr((char *)&sin.sin_addr, 
165
 
                             sizeof (sin.sin_addr), AF_INET);
166
 
          printf("%-15s: ", 
167
 
                 hp == NULL? inet_ntoa(sin.sin_addr) : hp->h_name);
168
 
          
169
 
          status = LBCalculateStatus(&lbtable[j]);
170
 
          printf("%-10.2f ", status);
171
 
          
172
 
          for(i = 0; i < NUM_LOAD_PARAMETERS; i++)
173
 
              printf("%5d ", lbtable[j].load[i]);
174
 
          
175
 
          for(i = 0; i < MAX_NUM_SERVICES; i++) {
176
 
              if(*lbtable[j].service[i] != '\0')
177
 
                  printf("%s ", lbtable[j].service[i]);
178
 
          }
179
 
          printf("\n");
180
 
          fflush(stdout);
181
 
      }
182
 
  }
183
 
  printf("----\n");
184
 
  
185
 
  return 0;
186
 
}
187
 
 
188
 
 
189
 
extern unsigned LBGetIPAddress(const char *service, unsigned int pref_ip,
190
 
                               unsigned *skip_ip, size_t n_skip)
191
 
{
192
 
  int i, j, k;
193
 
  LBStatus trace[MAX_NUM_HOSTS];
194
 
  int count;
195
 
  float status, all_status, point;
196
 
  LB_MessagePtr lbtable;
197
 
 
198
 
  if (!theinfo.lbtable  &&  LBClientInit() < 0)
199
 
    return 0;
200
 
 
201
 
  lbtable = theinfo.lbtable;
202
 
 
203
 
  memset(trace, '\0', sizeof(trace));
204
 
 
205
 
  /* the hosts to be skipped */
206
 
  for (j = 0;  j < MAX_NUM_HOSTS;  j++) {
207
 
    size_t m;
208
 
    for (m = 0;  m < n_skip;  m++)
209
 
      if (lbtable[j].address == skip_ip[m]) {
210
 
        trace[j].skip = 1;
211
 
        break;
212
 
      }
213
 
  }
214
 
 
215
 
  /* first try to find the preferred address */
216
 
  if ( pref_ip ) {
217
 
    for (j = 0, i = 0;  j < MAX_NUM_HOSTS;  j++) {
218
 
      if (pref_ip == lbtable[j].address) {
219
 
        if ( trace[j].skip )
220
 
          break;
221
 
        for (k = 0;  k < MAX_NUM_SERVICES;  k++) {
222
 
          if ( !strcmp(lbtable[j].service[k], service) )
223
 
            return pref_ip;
224
 
        }
225
 
        break;
226
 
      }
227
 
    }
228
 
  }
229
 
    
230
 
  all_status = 0;
231
 
  for (j = 0, i = 0;  j < MAX_NUM_HOSTS;  j++) {
232
 
    if ( trace[j].skip )
233
 
      continue;
234
 
 
235
 
    for (k = 0;  k < MAX_NUM_SERVICES;  k++) {
236
 
      if(!strcmp(lbtable[j].service[k], service)) {
237
 
        status = LBCalculateStatus(&lbtable[j]);
238
 
        all_status += status;
239
 
        trace[i].status = all_status;
240
 
        trace[i].index = j;
241
 
        i++;
242
 
        break;
243
 
      }
244
 
    }
245
 
  }
246
 
  if ( !i )
247
 
    return 0;
248
 
 
249
 
  count = i;
250
 
  point = (float)(trace[count-1].status * rand()) / (float)MAX_RAND_NUMBER;
251
 
    
252
 
  for (i = 0;  i < count;  i++) {
253
 
    if (point < trace[i].status)
254
 
      break;
255
 
  }
256
 
 
257
 
  return lbtable[trace[i].index].address;
258
 
}
259
 
 
260
 
#endif /* LB_DIRECT */