NCBI C++ ToolKit
ncbi_lbsmd.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_lbsmd.c 99910 2023-05-19 15:27:14Z lavr $
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  * Please cite the author in any work or product based on this material.
22  *
23  * ===========================================================================
24  *
25  * Author: Anton Lavrentiev
26  *
27  * File Description:
28  * Low-level API to resolve NCBI service name to the server meta-address
29  * with the use of NCBI Load-Balancing Service Mapper (LBSMD).
30  *
31  */
32 
33 #include "ncbi_lbsm.h"
34 #include "ncbi_lbsmd.h"
35 #include "ncbi_priv.h"
36 
37 
38 #ifdef NCBI_OS_UNIX
39 
40 #include "ncbi_ansi_ext.h"
41 #include "ncbi_lb.h"
42 #include "ncbi_lbsm_ipc.h"
43 #include "ncbi_version.h"
44 #include <errno.h>
45 #include <stdlib.h>
46 #include <time.h>
47 
48 #define NCBI_USE_ERRCODE_X Connect_LBSM
49 
50 
51 #define MAX_IP_ADDR_LEN 16 /* sizeof("255.255.255.255") */
52 
53 /* Default rate increase 10% if svc runs locally */
54 #define LBSMD_LOCAL_BONUS 1.1
55 
56 
57 #ifdef __cplusplus
58 extern "C" {
59 #endif /*__cplusplus*/
60 
62 static int/*bool*/ s_Feedback (SERV_ITER, double, TNCBI_Time);
63 static void s_Close (SERV_ITER);
64 
65 static const SSERV_VTable kLbsmdOp = {
66  s_GetNextInfo, s_Feedback, 0/*Update*/, 0/*Reset*/, s_Close, "LBSMD"
67 };
68 
69 #ifdef __cplusplus
70 } /* extern "C" */
71 #endif /*__cplusplus*/
72 
73 
74 volatile HEAP g_LBSM_Heap = 0; /* make it accessible from the daemon code */
75 
76 
78 
79 
80 typedef enum {
81  eHOST_BestMatch, /* arg matches the provided environment */
85  eHOST_NoMatch, /* arg does not match the environment */
86  eHOST_BadMatch, /* the entry must be skipped */
87  eHOST_InitMatch /* no information */
89 
90 
91 #if 0
92 static unsigned int x_HeapRevup(const SLBSM_Version* v)
93 {
97  return v->start;
98  }
99  return v->entry.head.size > 32 ? v->start: 0;
100 }
101 #endif
102 
103 
104 #ifdef __GNUC__
105 inline
106 #endif /*__GNUC__*/
107 static const char* s_HostEnv(const SLBSM_Host* h)
108 {
109  return h->env ? (const char*) h + h->env : 0;
110 }
111 
112 
113 static unsigned int s_Localhost(const SLBSM_Version* v)
114 {
115  if (v->entry.head.size >= 32/*FIXME: remove this condition*/
116  && v->local && v->local != (unsigned int)(-1)) {
117  return v->local;
118  }
119  return 0;
120 }
121 
122 
123 unsigned int LBSMD_GetLocalHostAddress(const void* p)
124 {
125  unsigned int localhost;
126  const SLBSM_Version* v = (const SLBSM_Version*) p;
127  if (!v || !(v->entry.head.flag & 1)
128  || v->entry.head.size != sizeof(*v)
129  || !(v->entry.type != eLBSM_Version)
130  || !(localhost = s_Localhost(v))) {
131  localhost = SOCK_GetLocalHostAddress(eDefault);
132  }
133  return localhost;
134 }
135 
136 
137 static unsigned int s_GetLocalHostAddress(HEAP heap)
138 {
139  const SLBSM_Version* v = (const SLBSM_Version*) HEAP_Base(heap);
141  return LBSMD_GetLocalHostAddress(v);
142 }
143 
144 
145 static EHOST_Match s_Match(const char* env,
146  const char* arg, size_t arglen,
147  const char* val, size_t vallen,
148  const char** a, char** v)
149 {
150  int/*bool*/ wildcard = 0/*false*/;
151  int/*bool*/ noval = 0/*false*/;
152  int/*bool*/ only = 0/*false*/;
153  const char* c = env;
154 
155  assert(arg && arglen);
156  assert(a && !*a && v && !*v);
157  /* Note 1: val == NULL implies vallen == 0, and means there was
158  * no argument in the query;
159  * Note 2: val != NULL does not imply vallen != 0, but means there
160  * was (perhaps, empty [if vallen == 0]) argument in the query.
161  */
162  while (c) {
163  const char* p = strchr(c == env ? c : ++c, '=');
164  const char* q = c;
165  if (!p)
166  break;
167  c = strchr(q, '\n');
168  if ((size_t)(p - q) != arglen || strncasecmp(q, arg, arglen) != 0)
169  continue;
170  /* arg matches */
171  *a = arg;
172  if (memchr(p + 1, '!', (c ? (size_t)(c - p) : strlen(p)) - 1))
173  only = 1/*true*/;
174  for (q = p+1/*=*/ + strspn(p+1, " \t!"); ; q = p + strspn(p, " \t!")) {
175  int/*bool*/ no = 0/*false*/;
176  size_t len;
177  if (*q != '\0' && *q != '\n')
178  len = strcspn(q, " \t!\n");
179  else if (*p == '=')
180  len = 0;
181  else
182  break;
183  if (len && *q == '~') {
184  no = 1/*true*/;
185  len--;
186  q++;
187  }
188  if (len == 1 && *q == '*') {
189  if (!no)
190  wildcard = 1/*true*/;
191  } else if (len == 1 && *q == '-') {
192  if (!val) {
193  if (no)
194  return eHOST_BadMatch;
195  *v = strndup("-", 1);
196  return eHOST_BestMatch;
197  }
198  if (no)
199  wildcard = 1/*true*/;
200  else
201  noval = 1/*true*/;
202  } else {
203  size_t vlen = len;
204  if (vlen == 2 && q[0] == '"' && q[1] == '"')
205  vlen = 0;
206  if (val && vlen == vallen && !strncasecmp(q, val, vlen)) {
207  if (no)
208  return eHOST_BadMatch;
209  *v = strndup(q, vlen);
210  return eHOST_BestMatch;
211  }
212  if (no)
213  wildcard = 1/*true*/;
214  }
215  p = q + len;
216  }
217  }
218  /* Neither best match nor mismatch found */
219  if (val) {
220  if (wildcard) {
221  *v = strndup("*", 1);
222  return eHOST_GoodMatch;
223  }
224  if (only)
225  return eHOST_BadMatch;
226  if (!*a)
227  return eHOST_FairMatch;
228  if (noval) {
229  *v = strndup("", 0);
230  return eHOST_PoorMatch;
231  }
232  return eHOST_NoMatch;
233  }
234  if (!*a)
235  return eHOST_GoodMatch;
236  if (only)
237  return eHOST_BadMatch;
238  if (wildcard) {
239  *v = strndup("*", 1);
240  return eHOST_FairMatch;
241  }
242  assert(!noval);
243  return eHOST_PoorMatch;
244 }
245 
246 
249  const SLBSM_Host* host;
251  const char* arg;
252  const char* val;
253 };
254 
255 
256 #ifdef __cplusplus
257 extern "C" {
258 #endif /*__cplusplus*/
259  static int s_SortStandbys(const void* p1, const void* p2);
260 #ifdef __cplusplus
261 }
262 #endif /*__cplusplus*/
263 
264 static int s_SortStandbys(const void* p1, const void* p2)
265 {
266  const struct SLBSM_Candidate* c1 = (const struct SLBSM_Candidate*) p1;
267  const struct SLBSM_Candidate* c2 = (const struct SLBSM_Candidate*) p2;
268  if (!c1->cand.status || !c2->cand.status) {
269  if (c1->cand.status)
270  return -1;
271  if (c2->cand.status)
272  return 1;
273  }
274  if (c1->cand.status < 0.0 || c2->cand.status < 0.0) {
275  if (c1->cand.status > 0.0)
276  return -1;
277  if (c2->cand.status > 0.0)
278  return 1;
279  }
280  assert(c1->svc->info.rate * c2->svc->info.rate >= 0.0); /* same sign */
281  /* randomization is done by allocation of services on the heap */
282  return (int) copysign(1.0,
283  fabs(c2->svc->info.rate) - fabs(c1->svc->info.rate));
284 }
285 
286 
287 struct SLBSM_Data {
289  size_t n_cand;
290 };
291 
292 
293 static SLB_Candidate* s_GetCandidate(void* user_data, size_t n)
294 {
295  struct SLBSM_Data* data = (struct SLBSM_Data*) user_data;
296  return n < data->n_cand ? &data->cand[n].cand : 0;
297 }
298 
299 
301  HOST_INFO* host_info,
302  int/*tristate*/ sign,
303  TNCBI_Time time)
304 {
305  SSERV_Info* info;
306 
307  if (iter->last || iter->n_skip)
308  return 0;
309 
310  if ((info = SERV_CreateDnsInfo(0/*host*/)) != 0) {
311  info->time = time != NCBI_TIME_INFINITE ? time + iter->time : time;
312  info->rate = sign ? copysign(LBSM_DEFAULT_RATE, sign) : 0.0;
313  if (host_info)
314  *host_info = 0;
315  }
316  return info;
317 }
318 
319 
320 static int/*bool*/ s_VerifyChecksum(const HEAP heap,
321  unsigned int count,
322  unsigned int cksum)
323 {
324  const char* base = (const char*) HEAP_Base(heap);
325  const SLBSM_Version* v = (const SLBSM_Version*) base;
326  if (v->count == count && v->cksum == cksum) {
327 #if defined(_DEBUG) && !defined(NDEBUG)
328  static const unsigned char kZero[sizeof(v->cksum)] = { 0 };
329  const char* stop = (const char*) &v->cksum;
330  size_t len = (size_t)(stop - base);
331  unsigned int (*update)(unsigned int sum, const void* ptr, size_t len);
332 
333  assert(v == LBSM_GetVersion(heap));
337  update = UTIL_CRC32_Update;
338  cksum = 0;
339  } else {
340  update = UTIL_Adler32_Update;
341  cksum = 1;
342  }
343  cksum = (*update)(cksum, base, len);
344  cksum = (*update)(cksum, kZero, sizeof(kZero));
345  len = HEAP_Size(heap) - len - sizeof(kZero);
346  cksum = (*update)(cksum, stop + sizeof(kZero), len);
347  return v->cksum == cksum ? 1/*success*/ : 0/*failure*/;
348 #else
349  return 1/*success*/;
350 #endif /*_DEBUG && !NDEBUG*/
351  }
352  return 0/*failure*/;
353 }
354 
355 
356 #ifdef __GNUC__
357 inline
358 #endif /*__GNUC__*/
359 static int/*bool*/ s_IfDaemon(void)
360 {
361  if (g_LBSM_Heap) {
364  CORE_UNLOCK;
365  return 1/*true*/;
366  }
367  CORE_UNLOCK;
368  }
369  return 0/*false*/;
370 }
371 
372 
373 /*
374  * HEAP caching protocol (client side only).
375  *
376  * In order to make heap accesses as efficient as possible:
377  *
378  * If s_LBSM_FastHeapAccess is non-zero, each iterator has its own (cached)
379  * copy of the LBSM heap, and keeps re-using it (w/o expiration checks) until
380  * closed.
381  *
382  * If s_LBSM_FastHeapAccess is zero, g_LBSM_Heap (which then may expire and get
383  * renewed in-between searches) is a cached copy and is used for service
384  * look-ups.
385  *
386  * Serial numbers of original (attached) heaps are positive, while those of
387  * copied heaps (including the global g_LBSM_Heap) are negative (negated
388  * original).
389  *
390  * If the serial number of g_LBSM_Heap is 0, it means that the heap is
391  * controlled by and used from within the daemon (LBSMD), and the heap caching
392  * is not performed.
393  */
394 
396 {
397  enum {
398  eNone = 0,
399  eAgain = 1,
400  eFallback = 2
401  } retry = eNone;
402  HEAP heap = 0;
403  HEAP lbsm;
404 
405  if (s_IfDaemon())
406  return g_LBSM_Heap;
407 
408  for (;;) {
409  const volatile SLBSM_Version *v;
410  unsigned int count, cksum;
411  const SLBSM_Version *c;
412  void* base;
413  int serial;
414 
416 
417  if (g_LBSM_Heap) {
419  assert((void*) c == HEAP_Base(g_LBSM_Heap));
420  if (c->entry.good < now) {
421 #ifdef LBSM_DEBUG
423  ("Cached LBSM heap[%p, %p, %d] expired", g_LBSM_Heap,
425 #endif /*LBSM_DEBUG*/
427  g_LBSM_Heap = 0;
428  }
429 #ifdef LBSM_DEBUG
430  else {
432  ("Cached LBSM heap[%p, %p, %d] valid", g_LBSM_Heap,
434  }
435 #endif /*LBSM_DEBUG*/
436  } else
437  c = 0/*dummy for compiler not to complain*/;
438 
439  if (!(lbsm = LBSM_Shmem_Attach(retry == eFallback ? 1/*T*/ : 0/*F*/))){
440  /* an error has already been posted */
441  break;
442  }
443  if ((serial = HEAP_Serial(lbsm)) <= 0) {
445  ("Bad serial (%d) from LBSM heap attach", serial));
446  break;
447  }
448  base = HEAP_Base(lbsm);
449 
450  if (!(v = LBSM_GetVersion(lbsm)) || (void*) v != base
452  || (v->major == LBSM_HEAP_VERSION_MAJ
453  && v->minor < LBSM_HEAP_VERSION_MIN))) {
454  if (v && (void*) v == base) {
456  ("LBSM heap[%d] version mismatch"
457  " (current=%hu.%hu, expected=%u.%u+)",
458  serial, v->major, v->minor,
460  } else {
462  ("LBSM heap[%d] version information %s",
463  serial, v ? "misplaced" : "missing"));
464  }
465  break;
466  }
467  if (v->entry.good < now) {
468  int/*bool*/ again = !retry && serial > 1? 1/*true*/ : 0/*false*/;
469  CORE_LOGF_X(29, again ? eLOG_Warning : eLOG_Error,
470  ("LBSM heap[%d] out-of-date"
471  " (current=%lu, expiry=%lu, age=%lu, #%u)%s", serial,
472  (unsigned long) now, (unsigned long) v->entry.good,
473  (unsigned long) now -(unsigned long) v->entry.good,
474  v->count, again ? ", re-trying" : ""));
475  if (again) {
476  LBSM_Shmem_Detach(lbsm);
477  retry = eFallback;
478  CORE_UNLOCK;
479  continue;
480  }
481  if (g_LBSM_Heap) {
482 #ifdef LBSM_DEBUG
484  ("Cached LBSM heap[%p, %p, %d] dropped", g_LBSM_Heap,
486 #endif /*LBSM_DEBUG*/
488  g_LBSM_Heap = 0;
489  }
490  break;
491  }
492 
493  if (g_LBSM_Heap) {
494  assert(c);
495  if (c->count == v->count && c->cksum == v->cksum) {
496 #ifdef LBSM_DEBUG
498  ("Cached LBSM heap[%p, %p, %d] used", g_LBSM_Heap,
500 #endif /*LBSM_DEBUG*/
501  heap = g_LBSM_Heap;
502  break;
503  }
504 #ifdef LBSM_DEBUG
506  ("Cached LBSM heap[%p, %p, %d] stale", g_LBSM_Heap,
508 #endif /*LBSM_DEBUG*/
510  g_LBSM_Heap = 0;
511  }
512 
513  if (!(heap = HEAP_Copy(lbsm, 0, -serial))) {
514  CORE_LOGF_ERRNO_X(3, eLOG_Error, errno,
515  ("Unable to copy LBSM heap[%d]", serial));
516  break;
517  }
518 
519  count = v->count;
520  cksum = v->cksum;
521  LBSM_Shmem_Detach(lbsm);
522 
523  if (s_VerifyChecksum(heap, count, cksum)) {
524 #ifdef LBSM_DEBUG
526  ("Cached LBSM heap[%p, %p, %d] renewed",
528 #endif /*LBSM_DEBUG*/
529  g_LBSM_Heap = heap;
530  lbsm = 0;
531  break;
532  }
533 
534  CORE_LOGF_X(4, retry ? eLOG_Error : eLOG_Warning,
535  ("LBSM heap[%p, %p, %d]%s checksum failure%s",
536  (void*) heap, HEAP_Base(heap), HEAP_Serial(heap),
537  retry == eAgain ? " persistent" : "",
538  retry ? "" : ", re-trying"));
539  verify(HEAP_Destroy(heap) == 0);
540  heap = 0;
541  if (retry) {
542  lbsm = 0;
543  break;
544  }
545 
546  retry = eAgain;
547  CORE_UNLOCK;
548  }
549 
550  if (lbsm) {
551  assert(heap != lbsm);
552  LBSM_Shmem_Detach(lbsm);
553  }
554  if (heap) {
555  assert(heap == g_LBSM_Heap);
557  }
558 
559  CORE_UNLOCK;
560 
561  return heap;
562 }
563 
564 
565 static const SLBSM_Host* s_LookupHost(HEAP heap, const SERV_ITER iter,
566  const SLBSM_Service* svc)
567 {
568  unsigned int addr =
569  svc->info.host ? svc->info.host : s_GetLocalHostAddress(heap);
570  const SLBSM_Host* host = LBSM_LookupHost(heap, addr, &svc->entry);
571  if (!host || host->entry.good < iter->time) {
572  if (svc->info.rate > 0.0) {
573  char buf[40];
574  if (SOCK_ntoa(addr, buf, sizeof(buf)) != 0)
575  strcpy(buf, "(unknown)");
577  ("Dynamic %s server `%s' on [%s] w/%s host entry",
578  SERV_TypeStr(svc->info.type),
579  (const char*) svc + svc->name,
580  buf, host ? "outdated" : "o"));
581  }
582  return 0;
583  }
584  return host;
585 }
586 
587 
588 /*
589  * Entries as stored in LBSMD heap:
590  * R==0 T==0 Off (Entry inaccessible and *must* be ignored)
591  * R!=0 T >0 Active (Standby: 0<|R|<LBSM_STANDBY_THRESHOLD)
592  * R!=0 T==0 Reserved
593  * R==0 T!=0 Down
594  * Suppressed have their "fine" field at 100%.
595  * The sign on R for non-down services denotes if the service is "static"
596  * (when < 0) or "dynamic" (when > 0).
597  */
598 static SSERV_Info* s_GetNextInfo(SERV_ITER iter, HOST_INFO* host_info)
599 {
600  const TSERV_TypeOnly types
602  size_t i, n, idx[eHOST_NoMatch], n_cand, a_cand;
603  EHOST_Match best_match, match;
604  struct SLBSM_Candidate* cand;
605  const SLBSM_Service* svc;
606  TNCBI_Time dns_info_time;
607  const SLBSM_Host* host;
608  const char* env, *a;
609  SSERV_Info* info;
610  const char* name;
611  double status;
612  int standby;
613  HEAP heap;
614  char* v;
615 
616  heap = (HEAP)(iter->data != iter ? iter->data : 0);
617  if (heap) {
618 #ifdef LBSM_DEBUG
620  ("LBSM heap[%p, %p, %d] for \"%s\" detected",
621  heap, HEAP_Base(heap), HEAP_Serial(heap), iter->name));
622 #endif /*LBSM_DEBUG*/
623  /*noop*/;
624  } else if (!(heap = s_GetHeapCopy(iter->time))) {
625  return iter->external || iter->data == iter || !(types & fSERV_Dns)
626  ? 0 : s_FakeDnsReturn(iter, host_info, 0, NCBI_TIME_INFINITE);
627  }
628 
629  best_match = eHOST_InitMatch;
630  memset(idx, 0, sizeof(idx));
631  standby = -1/*unassigned*/;
632  dns_info_time = 0/*none*/;
633  n = n_cand = a_cand = 0;
634  a = v = 0;
635  cand = 0;
636  svc = 0;
637 
638  name = *iter->name ? iter->name : 0;
639  assert(name || iter->ismask); /*NB: ismask ignored for NULL*/
640  while ((svc = LBSM_LookupService(heap, name, iter->ismask, svc))) {
642  if (svc->entry.good < iter->time)
643  continue; /* expired entry */
644 
645  if (!svc->info.rate && !svc->info.time)
646  continue; /* off */
647 
648  if (types != fSERV_Any && !(types & svc->info.type))
649  continue; /* type doesn't match */
650 
651  if (iter->external
652  && (svc->info.site & (fSERV_Local | fSERV_Private))) {
653  continue; /* external mapping requested; local/private server */
654  }
655 
656  if (!iter->ok_private && (svc->info.site & fSERV_Private)) {
658  if (svc->info.host &&
660  continue;
661  }
662  }
663 
664  if ((iter->types & fSERV_Stateless)&&(svc->info.mode & fSERV_Stateful))
665  continue;
666 
667  if (svc->info.type == fSERV_Dns) {
668  if (types == fSERV_Any)
669  continue; /* DNS entries have to be requested explicitly */
670  if (!iter->ismask) {
671  if (dns_info_time < svc->info.time)
672  dns_info_time = svc->info.time;
673  }
674  } else {
675  if (!iter->ismask && iter->reverse_dns) {
676  if (dns_info_time < svc->info.time)
677  dns_info_time = svc->info.time;
678  }
679  }
680 
681  if (svc->info.rate > 0.0 || host_info) {
682  if (!(host = s_LookupHost(heap, iter, svc))
683  && svc->info.rate > 0.0) {
684  continue; /* no host information for non-static server */
685  }
686  } else
687  host = 0;
688 
689  for (n = 0; n < iter->n_skip; ++n) {
690  const SSERV_Info* skip = iter->skip[n];
691  const char* s = SERV_NameOfInfo(skip);
692  if (*s) {
693  assert(iter->ismask || iter->reverse_dns);
694  if (strcasecmp(s, (const char*) svc + svc->name) == 0
695  && ((skip->type == fSERV_Dns && !skip->host)
696  || SERV_EqualInfo(skip, &svc->info))) {
697  break;
698  }
699  } else if (SERV_EqualInfo(skip, &svc->info))
700  break;
701  if (skip->type == fSERV_Firewall
702  && skip->u.firewall.type == svc->info.type) {
703  break;
704  }
705  if (iter->reverse_dns && skip->type == fSERV_Dns
706  && skip->host == svc->info.host
707  && (!skip->port || skip->port == svc->info.port)) {
708  break;
709  }
710  }
711  /*FIXME*//*CORE_LOG(eLOG_Note, (char*) svc + svc->name);*/
712  if (n >= iter->n_skip) {
714  (ESERV_Algo) svc->info.algo,
715  &host->sys.load);
716  if (status <= 0.0) {
717  if (!svc->info.rate) {
718  if (!iter->ok_down)
719  continue; /* not operational */
720  status = 0.0;
721  } else
722  status = copysign(svc->info.rate, -1.0);
723  }
724  } else
725  status = 0.0; /* dummy assignment to keep no-init warning off */
726 
727  if (v) {
728  free(v);
729  v = 0;
730  }
731  a = env = 0;
732  if (iter->pref < 0.0 && iter->host
733  && (iter->host != svc->info.host
734  || (iter->port && iter->port != svc->info.port))) {
735  /* not a suitable fixed latching */
737  } else if (iter->arglen) {
738  assert(iter->arg);
739  if (!host)
740  host = s_LookupHost(heap, iter, svc);
741  env = host ? s_HostEnv(host) : 0;
742  match = s_Match(env,
743  iter->arg, iter->arglen,
744  iter->val, iter->vallen, &a, &v);
745  assert(!a || a == iter->arg);
746  } else
748 
749  if (best_match > match)
750  best_match = match;
751 
752  if (match > eHOST_NoMatch) {
753  assert(!v);
754  continue;
755  }
756 
757  if (svc->info.rate) {
758  /* NB: server is _not_ down, but it may have been suppressed */
760  if (!standby) {
761  if (!iter->ok_suppressed)
762  continue;
763  /* this has to be given out as a suppressed one */
764  status = copysign(svc->info.rate, -1.0);
765  } else if (standby < 0)
766  standby = 1;
767  } else if (standby) {
768  standby = 0/*cancel*/;
769  if (!iter->ok_suppressed) {
770  memset(idx, 0, sizeof(idx));
771  for (i = 0; i < n_cand; ++i) {
772  if (cand[i].val)
773  free((void*) cand[i].val);
774  }
775  n_cand = 0;
776  } else for (i = 0; i < n_cand; ++i)
777  cand[i].cand.status = copysign(cand[i].svc->info.rate,-1.);
778  }
779  }
780 
781  if (n < iter->n_skip)
782  continue; /* excluded/seen; NB: dummy assignment goes off here */
783 
784  if (!iter->ok_suppressed && status < 0.0)
785  continue;
786 
787 #ifdef NCBI_LB_DEBUG
788  if (iter->arglen) {
789  char* s = SERV_WriteInfo(&svc->info);
790  const char* m;
791  assert(s);
792  switch (match) {
793  case eHOST_BestMatch:
794  m = "Best match";
795  break;
796  case eHOST_GoodMatch:
797  m = "Good match";
798  break;
799  case eHOST_FairMatch:
800  m = "Fair match";
801  break;
802  case eHOST_PoorMatch:
803  m = "Poor match";
804  break;
805  case eHOST_NoMatch:
806  m = "No match";
807  break;
808  default:
809  assert(0);
810  m = "?";
811  break;
812  }
813  assert(!a || *a);
814  assert(!v || a);
815  CORE_LOGF(eLOG_Note, ("%s%s%s%s: %s%s%s%s%s%s", s,
816  env ? " <" : "", env ? env : "",
817  env ? ">" : "", m,
818  a ? ", arg=" : "",
819  a ? a : "",
820  v ? ", val=" : "",
821  v ? (*v ? v : "\"\"") : "",
822  standby > 0 ? ", standby" : ""));
823  free(s);
824  }
825 #endif /*NCBI_LB_DEBUG*/
826 
827  /* This server should be taken into consideration */
828  if (n_cand == a_cand) {
829  struct SLBSM_Candidate* temp;
830  n = a_cand + 10;
831  temp = (struct SLBSM_Candidate*)
832  (cand
833  ? realloc(cand, n * sizeof(*temp))
834  : malloc ( n * sizeof(*temp)));
835  if (!temp)
836  break;
837  cand = temp;
838  a_cand = n;
839  }
840 
841  if (match < eHOST_NoMatch) {
842  assert((size_t) match < sizeof(idx)/sizeof(idx[0]));
843  n = idx[match];
844  if (n < n_cand)
845  memmove(&cand[n + 1], &cand[n], sizeof(cand[0])*(n_cand - n));
846  for (i = match; i < sizeof(idx)/sizeof(idx[0]); ++i)
847  idx[i]++;
848  } else
849  n = n_cand;
850  cand[n].cand.info = &svc->info;
851  cand[n].cand.status = status;
852  cand[n].host = host;
853  cand[n].svc = svc;
854  cand[n].arg = a;
855  cand[n].val = v;
856  a = v = 0;
857  n_cand++;
858  }
859  if (v)
860  free(v);
861 
862  if (best_match < eHOST_NoMatch) {
863  assert(!best_match || !idx[best_match - 1]);
864  for (n = idx[best_match]; n < n_cand; ++n) {
865  if (cand[n].val)
866  free((void*) cand[n].val);
867  }
868  n_cand = idx[best_match];
869  }
870  if (n_cand) {
871  assert(cand);
872  do {
873  if (standby <= 0) {
874  struct SLBSM_Data data;
875  data.cand = cand;
876  data.n_cand = n_cand;
877  n = LB_Select(iter, &data, s_GetCandidate, LBSMD_LOCAL_BONUS);
878  } else {
879  qsort(cand, n_cand, sizeof(*cand), s_SortStandbys);
880  status = cand[0].cand.status;
881  for (n = 1; n < n_cand; ++n) {
882  if (status != cand[n].cand.status)
883  break;
884  }
885  n = (size_t) rand() % n;
886  }
887  svc = cand[n].svc;
888  /* FIXME: Do not convert secure services because DNS entry
889  * (if found) cannot correctly reflect that property! */
890  if (iter->reverse_dns && svc->info.type != fSERV_Dns) {
891  svc = 0;
892  dns_info_time = 0/*none*/;
893  while ((svc = LBSM_LookupService(heap, 0/*all*/, 0, svc)) !=0){
894  if (svc->info.type != fSERV_Dns || !svc->info.time ||
895  svc->info.host != cand[n].svc->info.host ||
896  svc->info.port != cand[n].svc->info.port) {
897  continue;
898  }
899  if (!iter->ismask) {
900  if (dns_info_time < svc->info.time)
901  dns_info_time = svc->info.time;
902  }
903  if (iter->external
904  && (svc->info.site & (fSERV_Local | fSERV_Private))) {
905  continue;/* external mapping requested; local server */
906  }
907  status = LBSM_CalculateStatus(!svc->info.rate ? 0.0
909  svc->fine, eSERV_Regular,
910  NULL);
911  if (status > 0.0)
912  break;
913  if ((!svc->info.rate && iter->ok_down) ||
914  ( svc->info.rate && iter->ok_suppressed)) {
915  cand[n].cand.status = !svc->info.rate ? 0.0
916  : copysign(svc->info.rate, -1.0);
917  break;
918  }
919  }
920  if (!svc && !dns_info_time)
921  svc = cand[n].svc;
922  }
923  if (svc)
924  break;
925  if (cand[n].val)
926  free((void*) cand[n].val);
927  if (n < --n_cand)
928  memmove(cand + n, cand + n + 1, (n_cand - n) * sizeof(*cand));
929  } while (n_cand);
930  } else
931  svc = 0;
932 
933  if (svc) {
934  /* FIXME: do not return |rate| less that LBSM_STANDBY_THRESHOLD for
935  * non-standby, return standbys with their natural values */
936  name = (iter->ismask || iter->reverse_dns ?
937  (const char*) svc + svc->name : "");
938  if ((info = SERV_CopyInfoEx(&svc->info, name)) != 0) {
939  info->rate = cand[n].cand.status;
940  if (info->time != NCBI_TIME_INFINITE)
941  info->time = cand[n].svc->entry.good;
942  if (host_info) {
943  if ((host = cand[n].host) != 0) {
944  *host_info =
945  HINFO_Create(host->addr, &host->sys, sizeof(host->sys),
946  s_HostEnv(host), cand[n].arg,cand[n].val);
947  } else
948  *host_info = 0;
949  }
950  }
951  } else {
952  info = !n_cand && dns_info_time
953  ? s_FakeDnsReturn(iter, host_info,
954  best_match == eHOST_InitMatch ? 0/*down*/ :
955  best_match != eHOST_BadMatch ? -1/*busy*/ : 1,
956  dns_info_time)
957  : 0;
958  }
959 
960  for (n = 0; n < n_cand; ++n) {
961  if (cand[n].val)
962  free((void*) cand[n].val);
963  }
964  if (cand)
965  free(cand);
966 
967  if (HEAP_Serial(heap)) {
968  if (!s_LBSM_FastHeapAccess) {
969 #ifdef LBSM_DEBUG
971  ("LBSM heap[%p, %p, %d] for \"%s\" released", heap,
972  HEAP_Base(heap), HEAP_Serial(heap), iter->name));
973 #endif /*LBSM_DEBUG*/
975  HEAP_Detach(heap);
976  CORE_UNLOCK;
977  heap = 0;
978  }
979 #ifdef LBSM_DEBUG
980  else {
982  ("LBSM heap[%p, %p, %d] for \"%s\" retained", heap,
983  HEAP_Base(heap), HEAP_Serial(heap), iter->name));
984  }
985 #endif /*LBSM_DEBUG*/
986  } else
987  heap = 0;
988  iter->data = heap;
989 
990  return info;
991 }
992 
993 
994 static int/*bool*/ s_Feedback(SERV_ITER iter, double rate, TNCBI_Time fine)
995 {
996  SSERV_InfoCPtr last = iter->last;
997  assert(last);
999  rate, fine, last->host, last->port, 0);
1000 }
1001 
1002 
1003 static void s_Close(SERV_ITER iter)
1004 {
1005  if (iter->data) {
1006 #ifdef LBSM_DEBUG
1008  ("LBSM heap[%p, %p, %d] for \"%s\" discarded",
1009  iter->data, HEAP_Base((HEAP) iter->data),
1010  HEAP_Serial((HEAP) iter->data), iter->name));
1011 #endif /*LBSM_DEBUG*/
1013  HEAP_Detach((HEAP) iter->data);
1014  CORE_UNLOCK;
1015  iter->data = 0;
1016  }
1017  if (!s_LBSM_FastHeapAccess)
1018  LBSM_UnLBSMD(-1);
1019 }
1020 
1021 
1022 #ifdef __cplusplus
1023 extern "C" {
1024 #endif /*__cplusplus*/
1025  static void s_Fini(void);
1026 #ifdef __cplusplus
1027 }
1028 #endif /*__cplusplus*/
1029 
1030 
1031 static void s_Fini(void)
1032 {
1033  if (g_LBSM_Heap) {
1035  if (g_LBSM_Heap) {
1036 #ifdef LBSM_DEBUG
1038  ("Cached LBSM heap[%p, %p, %d] destroyed", g_LBSM_Heap,
1040 #endif /*LBSM_DEBUG*/
1042  g_LBSM_Heap = 0;
1043  }
1044  CORE_UNLOCK;
1045  }
1046  LBSM_UnLBSMD(-1);
1047 }
1048 
1049 
1050 static int s_LBSMD(void)
1051 {
1052  static volatile int s_Inited = 0;
1053  /* Daemon is running if LBSM_LBSMD() returns 1: lock exists but read
1054  * operation failed with errno == EAGAIN: the lock is taken (!=0). */
1055  if (LBSM_LBSMD(0) <= 0 || errno != EAGAIN)
1056  return 0/*false*/;
1057  if (!s_Inited) {
1059  if (!s_Inited && atexit(s_Fini) == 0)
1060  s_Inited = 1;
1061  CORE_UNLOCK;
1062  }
1063  return 1/*true*/;
1064 }
1065 
1066 
1067 
1068 /***********************************************************************
1069  * EXTERNAL
1070  ***********************************************************************/
1071 
1073  SSERV_Info** info,
1074  HOST_INFO* host_info,
1075  int/*bool*/ no_dispd_follows)
1076 {
1077  SSERV_Info* tmp;
1078 
1079  if (!s_IfDaemon() && !s_LBSMD())
1080  return 0;
1081 
1082  if (g_NCBI_ConnectRandomSeed == 0) {
1084  srand(g_NCBI_ConnectRandomSeed);
1085  }
1086  if (!no_dispd_follows)
1087  iter->data = iter;
1088  tmp = s_GetNextInfo(iter, host_info);
1089  if (iter->data == iter)
1090  iter->data = 0;
1091  if (!no_dispd_follows && !tmp) {
1092  s_Close(iter);
1093  return 0;
1094  }
1095  if (info)
1096  *info = tmp ? tmp : (SSERV_Info*)(-1L);
1097  else if (tmp)
1098  free(tmp);
1099  return &kLbsmdOp;
1100 }
1101 
1102 
1104 {
1106  if (OnOff != eDefault)
1107  s_LBSM_FastHeapAccess = OnOff;
1108  return old;
1109 }
1110 
1111 
1112 /*NB: May not be used from within the daemon!*/
1114 {
1115  return s_GetHeapCopy(now);
1116 }
1117 
1118 
1119 /*NB: May not be used from within the daemon!*/
1120 const char* LBSMD_GetConfig(void)
1121 {
1122  const char* s = 0;
1123  HEAP heap;
1124 
1125  if (s_LBSMD()) {
1126  if ((heap = s_GetHeapCopy((TNCBI_Time) time(0))) != 0) {
1127  if ((s = LBSM_GetConfig(heap)) != 0)
1128  s = strdup(s);
1129 #ifdef LBSM_DEBUG
1131  ("LBSM heap[%p, %p, %d] released",
1133 #endif /*LBSM_DEBUG*/
1135  HEAP_Detach(heap);
1136  CORE_UNLOCK;
1137  }
1138  }
1139  if (!s_LBSM_FastHeapAccess) {
1140  /* As a documented side effect, clean up cached copy of LBSM heap */
1141  s_Fini();
1142  }
1143  return s;
1144 }
1145 
1146 
1147 /*NB: May not be used from within the daemon!*/
1148 const char* LBSMD_GetHostParameter(unsigned int addr,
1149  const char* name)
1150 {
1151  size_t namelen = name && *name ? strlen(name) : 0;
1152  const SLBSM_Host* host;
1153  const char* env;
1154  HEAP heap;
1155 
1156  if (!namelen || !s_LBSMD())
1157  return 0;
1158  if (!(heap = s_GetHeapCopy((TNCBI_Time) time(0))))
1159  return 0;
1160  if (addr == SERV_ANYHOST || addr == SERV_LOCALHOST)
1161  addr = s_GetLocalHostAddress(heap);
1162  if ((host = LBSM_LookupHost(heap, addr, 0)) != 0
1163  && (env = s_HostEnv(host)) != 0) {
1164  const char* e;
1165  for (e = env; *e; e = env) {
1166  const char* p;
1167  size_t len;
1168  if (!(env = strchr(e, '\n'))) {
1169  len = strlen(e);
1170  env = e + len;
1171  } else
1172  len = (size_t)(env++ - e);
1173  if (!(p = (const char*) memchr(e, '=', len)))
1174  continue;
1175  len = (size_t)(p - e);
1176  if (len != namelen)
1177  continue;
1178  if (strncasecmp(e, name, namelen) != 0)
1179  continue;
1180  len = (size_t)(env - ++p);
1181  return strndup(p, len);
1182  }
1183  }
1184 #ifdef LBSM_DEBUG
1186  ("LBSM heap[%p, %p, %d] released",
1188 #endif /*LBSM_DEBUG*/
1190  HEAP_Detach(heap);
1191  CORE_UNLOCK;
1192  return 0;
1193 }
1194 
1195 
1196 /*ARGSUSED*/
1197 static const SLBSM_Sysinfo* s_GetSysinfo(const HOST_INFO hinfo,
1198  int/*bool*/ warn)
1199 {
1200  const SLBSM_Sysinfo* si =
1201  (const SLBSM_Sysinfo*)((const char*) hinfo + sizeof(*hinfo));
1202  assert(hinfo);
1203 #if defined(_DEBUG) && !defined(NDEBUG) && defined(NETDAEMONS_VERSION_INT)
1204  if (si->data.version < NETDAEMONS_VERSION_INT && warn) {
1205  static int s_Warn = 0;
1206  if (s_Warn < 20) {
1207  char addr[40];
1208  if (SOCK_ntoa(hinfo->addr, addr, sizeof(addr)) != 0)
1209  strcpy(addr, "(unknown)");
1210  CORE_LOGF(s_Warn++ < 5 ? eLOG_Warning : eLOG_Trace,
1211  ("HINFO may be incorrect for obsolete LBSMD at %s"
1212  " (detected=%hu.%hu.%hu, expected=%s+)", addr,
1213  NETDAEMONS_MAJOR_OF(si->data.version),
1214  NETDAEMONS_MINOR_OF(si->data.version),
1215  NETDAEMONS_PATCH_OF(si->data.version),
1217  }
1218  }
1219 #endif /*_DEBUG && !NDEBUG && NETDAEMONS_VERSION_INT*/
1220  return si;
1221 }
1222 
1223 
1225 {
1226  const SLBSM_Sysinfo* si = s_GetSysinfo(hinfo, 1/*warn*/);
1227  return si->data.nrproc & 0xFF;
1228 }
1229 
1230 
1232 {
1233  const SLBSM_Sysinfo* si = s_GetSysinfo(hinfo, 1/*warn*/);
1234  return si->data.nrproc >> 8;
1235 }
1236 
1237 
1238 double LBSM_HINFO_CpuClock(const HOST_INFO hinfo)
1239 {
1240  const SLBSM_Sysinfo* si = s_GetSysinfo(hinfo, 1/*warn*/);
1241  assert(si->data.hzfreq >= 0.0);
1242  return si->data.hzfreq / 0.128;
1243 }
1244 
1245 
1247 {
1248  const SLBSM_Sysinfo* si = s_GetSysinfo(hinfo, 1/*warn*/);
1249  return (int) si->load.nrtask;
1250 }
1251 
1252 
1253 int/*bool*/ LBSM_HINFO_Memusage(const HOST_INFO hinfo,
1254  double memusage[5])
1255 {
1256  const SLBSM_Sysinfo* si = s_GetSysinfo(hinfo, 1/*warn*/);
1257  double pgsizemb = si->data.pgsize / 1024.0;
1258  memusage[0] = si->load.ram_total * pgsizemb;
1259  memusage[1] = si->load.ram_cache * pgsizemb;
1260  memusage[2] = si->load.ram_free * pgsizemb;
1261  memusage[3] = si->load.swap_total * pgsizemb;
1262  memusage[4] = si->load.swap_free * pgsizemb;
1263  return 1/*success*/;
1264 }
1265 
1266 
1267 int/*bool*/ LBSM_HINFO_MachineParams(const HOST_INFO hinfo,
1268  SHINFO_Params* p)
1269 {
1270  const SLBSM_Sysinfo* si = s_GetSysinfo(hinfo, 1/*warn*/);
1271  unsigned short div = (si->data.kernel & LBSM_KERNELID_SVPKBIT
1272  ? LBSM_KERNELID_SVPKDIV : 1);
1273  unsigned short major = (unsigned short)((si->data.kernel >> 24) & 0xFF);
1274  unsigned short minor = (unsigned short)((si->data.kernel >> 16) & 0xFF);
1275  p->kernel.patch = si->data.kernel & 0x7FFF;
1276  p->bits = si->data.machine >> 14;
1277  p->arch = (si->data.machine >> 8) & 0x3F;
1278  p->ostype = si->data.machine & 0xFF;
1279  p->pgsize = (size_t) si->data.pgsize << 10;
1280  p->bootup = si->data.sys_uptime;
1281  p->startup = si->data.start_time;
1282  p->daemon.major = NETDAEMONS_MAJOR_OF(si->data.version);
1283  p->daemon.minor = NETDAEMONS_MINOR_OF(si->data.version);
1284  p->daemon.patch = NETDAEMONS_PATCH_OF(si->data.version);
1285  p->kernel.major = major / div;
1286  p->kernel.minor = minor / div;
1287  p->svcpack = (unsigned short)(((major % div) << 8) |
1288  (minor % div));
1289  return 1/*success*/;
1290 }
1291 
1292 
1294  SHINFO_PortUsage ports[], size_t count)
1295 {
1296  size_t n;
1297  const SLBSM_Sysinfo* si = s_GetSysinfo(hinfo, 1/*warn*/);
1298  for (n = 0; n < sizeof(si->load.port)/sizeof(si->load.port[0]); ++n) {
1299  if (!si->load.port[n])
1300  break;
1301  if (n < count) {
1302  ports[n].port = si->load.port[n];
1303  ports[n].used = si->load.used[n] / 2.0;
1304  }
1305  }
1306  return (int) n;
1307 }
1308 
1309 
1310 
1311 int/*bool*/ LBSM_HINFO_LoadAverage(const HOST_INFO hinfo,
1312  double lavg[2])
1313 {
1314  const SLBSM_Sysinfo* si = s_GetSysinfo(hinfo, 1/*warn*/);
1315  lavg[0] = si->load.avg;
1316  lavg[1] = si->load.avgBLAST;
1317  return 1/*success*/;
1318 }
1319 
1320 
1321 int/*bool*/ LBSM_HINFO_Status(const HOST_INFO hinfo,
1322  double status[2])
1323 {
1324  const SLBSM_Sysinfo* si = s_GetSysinfo(hinfo, 0/*nowarn*/);
1325  status[0] = si->load.status;
1326  status[1] = si->load.statusBLAST;
1327  return 1/*success*/;
1328 }
1329 
1330 
1331 #else
1332 
1333 
1334 /*ARGSUSED*/
1335 int LBSM_LBSMD(int/*bool*/ check_n_lock)
1336 {
1337  return -1/*failure*/;
1338 }
1339 
1340 
1341 /*ARGSUSED*/
1343  SSERV_Info** info,
1344  HOST_INFO* host_info,
1345  int/*bool*/ dispd_to_follow)
1346 {
1347  return 0/*failure*/;
1348 }
1349 
1350 
1351 extern const char* LBSMD_GetConfig(void)
1352 {
1353  return 0/*no info*/;
1354 }
1355 
1356 
1357 /*ARGSUSED*/
1359 {
1360  return eDefault/*not implemented*/;
1361 }
1362 
1363 
1364 /*ARGSUSED*/
1365 extern HEAP LBSMD_GetHeapCopy(TNCBI_Time time)
1366 {
1367  return 0/*no heap*/;
1368 }
1369 
1370 
1371 /*ARGSUSED*/
1372 extern const char* LBSMD_GetHostParameter(unsigned int host,
1373  const char* name)
1374 {
1375  return 0/*no info*/;
1376 }
1377 
1378 
1379 /*ARGSUSED*/
1380 unsigned int LBSMD_GetLocalHostAddress(const void* v)
1381 {
1383 }
1384 
1385 
1386 /*ARGSUSED*/
1387 int LBSM_HINFO_CpuCount(const HOST_INFO hinfo)
1388 {
1389  return 0/*no info*/;
1390 }
1391 
1392 
1393 /*ARGSUSED*/
1394 int LBSM_HINFO_CpuUnits(const HOST_INFO hinfo)
1395 {
1396  return 0/*no info*/;
1397 }
1398 
1399 
1400 /*ARGSUSED*/
1401 double LBSM_HINFO_CpuClock(const HOST_INFO hinfo)
1402 {
1403  return 0.0/*no info*/;
1404 }
1405 
1406 
1407 /*ARGSUSED*/
1408 int LBSM_HINFO_TaskCount(const HOST_INFO hinfo)
1409 {
1410  return 0/*no info*/;
1411 }
1412 
1413 
1414 /*ARGSUSED*/
1415 int/*bool*/ LBSM_HINFO_Memusage(const HOST_INFO hinfo,
1416  double memusage[5])
1417 {
1418  return 0/*no info*/;
1419 }
1420 
1421 
1422 /*ARGSUSED*/
1423 int/*bool*/ LBSM_HINFO_MachineParams(const HOST_INFO hinfo,
1424  SHINFO_Params* p)
1425 {
1426  return 0/*no info*/;
1427 }
1428 
1429 
1430 /*ARGSUSED*/
1431 int LBSM_HINFO_PortUsage(const HOST_INFO hinfo,
1432  SHINFO_PortUsage ports[], size_t count)
1433 {
1434  return 0/*no ports*/;
1435 }
1436 
1437 
1438 /*ARGSUSED*/
1439 int/*bool*/ LBSM_HINFO_LoadAverage(const HOST_INFO hinfo,
1440  double lavg[2])
1441 {
1442  return 0/*no info*/;
1443 }
1444 
1445 
1446 /*ARGSUSED*/
1447 int/*bool*/ LBSM_HINFO_Status(const HOST_INFO hinfo,
1448  double status[2])
1449 {
1450  return 0/*no info*/;
1451 }
1452 
1453 
1454 #endif /*!NCBI_OS_UNIX*/
1455 
1456 
1457 double LBSM_CalculateStatus(double rate, double fine, ESERV_Algo algo,
1458  const SLBSM_HostLoad* load)
1459 {
1460  double status;
1461 
1462  if (!rate)
1463  return 0.0;
1464  if (unlikely(rate < LBSM_STANDBY_THRESHOLD))
1465  status = rate < 0.0 ? -LBSM_DEFAULT_RATE : LBSM_DEFAULT_RATE;
1466  else
1467  status = algo & eSERV_Blast ? load->statusBLAST : load->status;
1468  status *= rate / LBSM_DEFAULT_RATE;
1469  /* accurately apply fine: avoid imperfections with 100% */
1470  status *= (100. - (fine < 0. ? 0. : fine > 100. ? 100. : fine)) / 100.0;
1471  return fabs(status); /*paranoid but safe*/
1472 }
@ eNone
None specified.
Definition: blast_def.h:326
static int heap[2 *(256+1+29)+1]
static const char si[8][64]
Definition: des.c:146
static DLIST_TYPE *DLIST_NAME() last(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:51
@ eOff
Definition: ncbi_types.h:110
@ eDefault
Definition: ncbi_types.h:112
#define NULL
Definition: ncbistd.hpp:225
struct SHINFO_Params::@85 kernel
Kernel/OS version #, if available.
unsigned short port
Port number, host byte order.
TNCBI_Time bootup
System boot time, time_t-compatible.
TNCBI_Time startup
LBSMD start time, time_t-compatible.
void * HEAP_Base(const HEAP heap)
TNCBI_Time time
HEAP HEAP_Copy(const HEAP orig, size_t extra, int serial)
#define SERV_ANYHOST
Definition: ncbi_service.h:55
SSERV_Info * SERV_CreateDnsInfo(unsigned int host)
unsigned int HEAP_Destroy(HEAP heap)
TNcbiCapacity bits
Platform bitness, 32/64/32+64/0=unknown.
unsigned short svcpack
Kernel service pack (Hi=major, Lo=minor)
int HEAP_Serial(const HEAP heap)
SSERV_FirewallInfo firewall
struct SHINFO_Params::@86 daemon
LBSMD daemon version.
TNCBI_Size size
Definition: ncbi_heapmgr.h:61
double used
Port usage as percentage, [0..100].
TSERV_Site site
TNcbiOSType ostype
OS type ID, see enum, 0=unknown.
TSERV_Mode mode
struct SHEAP_tag * HEAP
Definition: ncbi_heapmgr.h:53
unsigned int flag
Definition: ncbi_heapmgr.h:59
unsigned short major
const char * SERV_TypeStr(ESERV_Type type)
TSERV_Algo algo
unsigned int HEAP_AddRef(HEAP heap)
char * SERV_WriteInfo(const SSERV_Info *info)
ESERV_Algo
unsigned short TSERV_TypeOnly
Server type only, w/o specials.
Definition: ncbi_service.h:95
unsigned int host
unsigned short patch
unsigned int HEAP_Detach(HEAP heap)
unsigned short minor
unsigned short port
TNcbiArch arch
Architecture ID, see enum, 0=unknown.
USERV_Info u
TNCBI_Size HEAP_Size(const HEAP heap)
#define SERV_LOCALHOST
Special values for the "preferred_host" parameter.
Definition: ncbi_service.h:54
int SERV_EqualInfo(const SSERV_Info *info1, const SSERV_Info *info2)
ESERV_Type type
size_t pgsize
Hardware page size in bytes, if known.
@ fSERV_Firewall
@ fSERV_Dns
@ fSERV_Stateless
Stateless servers only.
Definition: ncbi_service.h:81
@ fSERV_Any
Definition: ncbi_service.h:79
@ fSERV_Stateful
@ eSERV_Blast
@ eSERV_Regular
@ fSERV_Local
@ fSERV_Private
int SOCK_ntoa(unsigned int addr, char *buf, size_t bufsize)
Convert IP address to a string in dotted notation.
Definition: ncbi_socket.c:8665
unsigned int SOCK_GetLocalHostAddress(ESwitch reget)
Get (and cache for faster follow-up retrievals) IPv4 address of local host.
Definition: ncbi_socket.c:8831
unsigned int UTIL_Adler32_Update(unsigned int checksum, const void *ptr, size_t len)
Calculate/Update Adler-32 checksum NB: Initial checksum is "1".
Definition: ncbi_util.c:1174
enum ENcbiSwitch ESwitch
Aux.
unsigned int TNCBI_Time
Definition: ncbi_types.h:145
#define NCBI_TIME_INFINITE
Definition: ncbi_types.h:147
unsigned int UTIL_CRC32_Update(unsigned int checksum, const void *ptr, size_t len)
Calculate/Update CRC-32 checksum NB: Initial checksum is "0".
Definition: ncbi_util.c:1149
@ eLOG_Error
Definition: ncbi_core.h:297
@ eLOG_Note
Definition: ncbi_core.h:294
@ eLOG_Warning
Definition: ncbi_core.h:296
@ eLOG_Trace
Definition: ncbi_core.h:293
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
static CStopWatch sw
char * buf
int i
yy_size_t n
int len
static MDB_envinfo info
Definition: mdb_load.c:37
#define strdup
Definition: ncbi_ansi_ext.h:70
#define strncasecmp
#define strcasecmp
#define strndup
Definition: ncbi_ansi_ext.h:89
#define verify(expr)
Definition: ncbi_assert.h:51
#define LBSM_DEFAULT_RATE
Definition: ncbi_comm.h:46
#define LBSM_STANDBY_THRESHOLD
Definition: ncbi_comm.h:47
#define fabs(v)
Definition: ncbi_dispd.c:46
HOST_INFO HINFO_Create(unsigned int addr, const void *hinfo, size_t hinfo_size, const char *env, const char *arg, const char *val)
size_t LB_Select(SERV_ITER iter, void *data, FGetCandidate get_candidate, double bonus)
Definition: ncbi_lb.c:62
const SLBSM_Host * LBSM_LookupHost(HEAP heap, unsigned int addr, const SLBSM_Entry *hint)
Definition: ncbi_lbsm.c:134
int LBSM_SubmitPenaltyOrRerate(const char *name, ESERV_Type type, double rate, TNCBI_Time fine, unsigned int host, unsigned short port, const char *path)
Definition: ncbi_lbsm.c:159
const char * LBSM_GetConfig(HEAP heap)
Definition: ncbi_lbsm.c:68
const SLBSM_Version * LBSM_GetVersion(HEAP heap)
Definition: ncbi_lbsm.c:58
const SLBSM_Service * LBSM_LookupService(HEAP heap, const char *name, int mask, const SLBSM_Service *hint)
Definition: ncbi_lbsm.c:112
#define LBSM_HEAP_VERSION_MIN_CRC32
Definition: ncbi_lbsm.h:62
#define LBSM_KERNELID_SVPKBIT
Definition: ncbi_lbsm.h:72
#define LBSM_HEAP_VERSION_MAJ_CRC32
Definition: ncbi_lbsm.h:61
#define LBSM_HEAP_VERSION_MAJ
Definition: ncbi_lbsm.h:57
#define LBSM_HEAP_VERSION_MIN
Definition: ncbi_lbsm.h:58
#define LBSM_KERNELID_SVPKDIV
Definition: ncbi_lbsm.h:73
@ eLBSM_Service
Definition: ncbi_lbsm.h:142
@ eLBSM_Version
Definition: ncbi_lbsm.h:143
pid_t LBSM_UnLBSMD(int undaemon)
int LBSM_LBSMD(int check_n_lock)
void LBSM_Shmem_Detach(HEAP heap)
HEAP LBSM_Shmem_Attach(int fallback)
static HEAP s_GetHeapCopy(TNCBI_Time now)
Definition: ncbi_lbsmd.c:395
static int s_VerifyChecksum(const HEAP heap, unsigned int count, unsigned int cksum)
Definition: ncbi_lbsmd.c:320
static const SSERV_VTable kLbsmdOp
Definition: ncbi_lbsmd.c:65
static SLB_Candidate * s_GetCandidate(void *user_data, size_t n)
Definition: ncbi_lbsmd.c:293
static int s_SortStandbys(const void *p1, const void *p2)
Definition: ncbi_lbsmd.c:264
static const SLBSM_Sysinfo * s_GetSysinfo(const HOST_INFO hinfo, int warn)
Definition: ncbi_lbsmd.c:1197
static const char * s_HostEnv(const SLBSM_Host *h)
Definition: ncbi_lbsmd.c:107
static SSERV_Info * s_FakeDnsReturn(SERV_ITER iter, HOST_INFO *host_info, int sign, TNCBI_Time time)
Definition: ncbi_lbsmd.c:300
static void s_Close(SERV_ITER)
Definition: ncbi_lbsmd.c:1003
static int s_IfDaemon(void)
Definition: ncbi_lbsmd.c:359
static unsigned int s_GetLocalHostAddress(HEAP heap)
Definition: ncbi_lbsmd.c:137
static int s_Feedback(SERV_ITER, double, TNCBI_Time)
Definition: ncbi_lbsmd.c:994
int LBSM_HINFO_Status(const HOST_INFO hinfo, double status[2])
Definition: ncbi_lbsmd.c:1321
double LBSM_HINFO_CpuClock(const HOST_INFO hinfo)
Definition: ncbi_lbsmd.c:1238
int LBSM_HINFO_PortUsage(const HOST_INFO hinfo, SHINFO_PortUsage ports[], size_t count)
Definition: ncbi_lbsmd.c:1293
const char * LBSMD_GetConfig(void)
Definition: ncbi_lbsmd.c:1120
int LBSM_HINFO_Memusage(const HOST_INFO hinfo, double memusage[5])
Definition: ncbi_lbsmd.c:1253
static void s_Fini(void)
Definition: ncbi_lbsmd.c:1031
static EHOST_Match s_Match(const char *env, const char *arg, size_t arglen, const char *val, size_t vallen, const char **a, char **v)
Definition: ncbi_lbsmd.c:145
HEAP LBSMD_GetHeapCopy(TNCBI_Time now)
Definition: ncbi_lbsmd.c:1113
static int s_LBSMD(void)
Definition: ncbi_lbsmd.c:1050
EHOST_Match
Definition: ncbi_lbsmd.c:80
@ eHOST_FairMatch
Definition: ncbi_lbsmd.c:83
@ eHOST_InitMatch
Definition: ncbi_lbsmd.c:87
@ eHOST_BadMatch
Definition: ncbi_lbsmd.c:86
@ eHOST_BestMatch
Definition: ncbi_lbsmd.c:81
@ eHOST_GoodMatch
Definition: ncbi_lbsmd.c:82
@ eHOST_NoMatch
Definition: ncbi_lbsmd.c:85
@ eHOST_PoorMatch
Definition: ncbi_lbsmd.c:84
double LBSM_CalculateStatus(double rate, double fine, ESERV_Algo algo, const SLBSM_HostLoad *load)
Definition: ncbi_lbsmd.c:1457
unsigned int LBSMD_GetLocalHostAddress(const void *p)
Definition: ncbi_lbsmd.c:123
int LBSM_HINFO_TaskCount(const HOST_INFO hinfo)
Definition: ncbi_lbsmd.c:1246
int LBSM_HINFO_LoadAverage(const HOST_INFO hinfo, double lavg[2])
Definition: ncbi_lbsmd.c:1311
volatile HEAP g_LBSM_Heap
Definition: ncbi_lbsmd.c:74
const char * LBSMD_GetHostParameter(unsigned int addr, const char *name)
Definition: ncbi_lbsmd.c:1148
static unsigned int s_Localhost(const SLBSM_Version *v)
Definition: ncbi_lbsmd.c:113
ESwitch LBSMD_FastHeapAccess(ESwitch OnOff)
Definition: ncbi_lbsmd.c:1103
static const SLBSM_Host * s_LookupHost(HEAP heap, const SERV_ITER iter, const SLBSM_Service *svc)
Definition: ncbi_lbsmd.c:565
static SSERV_Info * s_GetNextInfo(SERV_ITER, HOST_INFO *)
Definition: ncbi_lbsmd.c:598
int LBSM_HINFO_CpuCount(const HOST_INFO hinfo)
Definition: ncbi_lbsmd.c:1224
static ESwitch s_LBSM_FastHeapAccess
Definition: ncbi_lbsmd.c:77
int LBSM_HINFO_CpuUnits(const HOST_INFO hinfo)
Definition: ncbi_lbsmd.c:1231
#define LBSMD_LOCAL_BONUS
Definition: ncbi_lbsmd.c:54
const SSERV_VTable * SERV_LBSMD_Open(SERV_ITER iter, SSERV_Info **info, HOST_INFO *host_info, int no_dispd_follows)
Definition: ncbi_lbsmd.c:1072
int LBSM_HINFO_MachineParams(const HOST_INFO hinfo, SHINFO_Params *p)
Definition: ncbi_lbsmd.c:1267
unsigned int a
Definition: ncbi_localip.c:102
static int s_Inited
Definition: ncbi_localip.c:94
unsigned int g_NCBI_ConnectRandomSeed
Definition: ncbi_priv.c:51
#define CORE_LOGF_X(subcode, level, fmt_args)
Definition: ncbi_priv.h:150
#define CORE_LOCK_WRITE
Definition: ncbi_priv.h:269
#define CORE_LOGF_ERRNO_X(subcode, level, error, fmt_args)
Definition: ncbi_priv.h:166
#define NCBI_CONNECT_SRAND_ADDEND
Definition: ncbi_priv.h:343
#define CORE_UNLOCK
Definition: ncbi_priv.h:273
#define unlikely(x)
Definition: ncbi_priv.h:389
#define CORE_LOGF(level, fmt_args)
Definition: ncbi_priv.h:158
#define CORE_LOCK_READ
Definition: ncbi_priv.h:271
SSERV_Info * SERV_CopyInfoEx(const SSERV_Info *orig, const char *name)
const char * SERV_NameOfInfo(const SSERV_Info *info)
ESERV_Algo algo
const char * SERV_CurrentName(SERV_ITER iter)
Definition: ncbi_service.c:950
#define NETDAEMONS_VERSION_INT
Definition: ncbi_version.h:87
#define NETDAEMONS_MAJOR_OF(ver)
Definition: ncbi_version.h:83
#define NETDAEMONS_MINOR_OF(ver)
Definition: ncbi_version.h:84
#define NETDAEMONS_PATCH_OF(ver)
Definition: ncbi_version.h:85
#define NETDAEMONS_VERSION_STR
Definition: ncbi_version.h:59
static char tmp[2048]
Definition: utf8.c:42
static int match(register const pcre_uchar *eptr, register const pcre_uchar *ecode, const pcre_uchar *mstart, int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth)
Definition: pcre_exec.c:513
#define memmove(a, b, c)
#define assert(x)
Definition: srv_diag.hpp:58
Host parameters.
unsigned int addr
SLB_Candidate cand
Definition: ncbi_lbsmd.c:248
const SLBSM_Host * host
Definition: ncbi_lbsmd.c:249
const char * val
Definition: ncbi_lbsmd.c:252
const char * arg
Definition: ncbi_lbsmd.c:251
const SLBSM_Service * svc
Definition: ncbi_lbsmd.c:250
struct SLBSM_Candidate * cand
Definition: ncbi_lbsmd.c:288
size_t n_cand
Definition: ncbi_lbsmd.c:289
TNCBI_Time good
Definition: ncbi_lbsm.h:154
ELBSM_Type type
Definition: ncbi_lbsm.h:153
SHEAP_Block head
Definition: ncbi_lbsm.h:152
double status
Definition: ncbi_lbsm.h:106
double statusBLAST
Definition: ncbi_lbsm.h:107
SLBSM_Sysinfo sys
Definition: ncbi_lbsm.h:190
SLBSM_Entry entry
Definition: ncbi_lbsm.h:185
TNCBI_Size env
Definition: ncbi_lbsm.h:191
double fine
Definition: ncbi_lbsm.h:204
SSERV_Info info
Definition: ncbi_lbsm.h:209
SLBSM_Entry entry
Definition: ncbi_lbsm.h:199
TNCBI_Size name
Definition: ncbi_lbsm.h:200
SLBSM_HostLoad load
Definition: ncbi_lbsm.h:177
unsigned int count
Definition: ncbi_lbsm.h:164
TNCBI_Time start
Definition: ncbi_lbsm.h:167
unsigned short minor
Definition: ncbi_lbsm.h:163
SLBSM_Entry entry
Definition: ncbi_lbsm.h:161
unsigned int local
Definition: ncbi_lbsm.h:166
unsigned int cksum
Definition: ncbi_lbsm.h:165
unsigned short major
Definition: ncbi_lbsm.h:162
const SSERV_Info * info
Definition: ncbi_lb.h:48
double status
Definition: ncbi_lb.h:49
unsigned ok_suppressed
Definition: ncbi_servicep.h:99
unsigned external
unsigned ok_down
Definition: ncbi_servicep.h:96
unsigned short port
Definition: ncbi_servicep.h:93
const char * arg
const char * name
Definition: ncbi_servicep.h:89
SSERV_InfoCPtr * skip
unsigned ismask
Definition: ncbi_servicep.h:95
const char * val
unsigned int host
Definition: ncbi_servicep.h:92
SSERV_InfoCPtr last
unsigned ok_private
unsigned reverse_dns
TSERV_TypeOnly types
Definition: ncbi_servicep.h:94
TNCBI_Time time
Definition: ncbi_servicep.h:91
static HENV env
Definition: transaction2.c:38
static const struct type types[]
Definition: type.c:22
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Tue Dec 05 02:21:38 2023 by modify_doxy.py rev. 669887