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__*/
39
#include <sys/types.h>
40
#include <sys/socket.h>
41
#include <netinet/in.h>
42
#include <arpa/inet.h>
50
#include "sge_bootstrap.h"
51
#include "sge_hostname.h"
54
#include "sge_language.h"
56
#include "sge_unistd.h"
57
#include "sge_string.h"
59
#include "sge_uidgid.h"
62
#include "msg_utilib.h"
63
#include "sge_mtutil.h"
65
#define ALIAS_DELIMITER "\n\t ,;"
66
#define SGE_MAXNISRETRY 5
72
extern void trace(char *);
75
/* MT-NOTE: hostlist used only in qmaster, commd and some utilities */
76
static host *hostlist = NULL;
78
/* MT-NOTE: localhost used only in commd */
79
static host *localhost = NULL;
81
static pthread_mutex_t get_qmaster_port_mutex = PTHREAD_MUTEX_INITIALIZER;
82
static pthread_mutex_t get_execd_port_mutex = PTHREAD_MUTEX_INITIALIZER;
84
static struct servent *sge_getservbyname_r(struct servent *se_result, const char *service, char *buffer, size_t size)
88
int nisretry = SGE_MAXNISRETRY;
90
/*******************************************************************************
92
* Whoever extends this function to account for other architectures,
93
* DO NOT base the ifdef's on architecture names. Instead, use the format:
94
* GETSERVBYNAM_R<num_args>. For example, instead of "LINUX" below, you
95
* should use "GETSERVBYNAM_R6". For architectures without a reentrant
96
* version of the function, use "GETSERVBYNAM_M" and use locks to make it MT
97
* safe. This will require that you update aimk to include the correct defines
98
* for each architecture.
99
******************************************************************************/
101
if (getservbyname_r(service, "tcp", se_result, buffer, size, &se) != 0)
103
#elif defined(SOLARIS)
104
se = getservbyname_r(service, "tcp", se_result, buffer, size);
106
se = getservbyname(service, "tcp");
118
#define SGE_PORT_CACHE_TIMEOUT 60*10 /* 10 Min. */
119
int sge_get_qmaster_port(bool *from_services) {
124
static long next_timeout = 0;
125
static int cached_port = -1;
126
DENTER(GDI_LAYER, "sge_get_qmaster_port");
128
sge_mutex_lock("get_qmaster_port_mutex", SGE_FUNC, __LINE__, &get_qmaster_port_mutex);
130
/* check for reresolve timeout */
131
gettimeofday(&now,NULL);
133
if (next_timeout > 0 ) {
134
DPRINTF(("reresolve port timeout in "sge_U32CFormat"\n", sge_u32c( next_timeout - now.tv_sec)));
136
if (cached_port >= 0 && next_timeout > now.tv_sec) {
137
int_port = cached_port;
138
DPRINTF(("returning cached port value: "sge_U32CFormat"\n", sge_u32c(int_port)));
139
sge_mutex_unlock("get_qmaster_port_mutex", SGE_FUNC, __LINE__, &get_qmaster_port_mutex);
144
port = getenv("SGE_QMASTER_PORT");
146
int_port = atoi(port);
149
/* get port from services file */
152
struct servent se_result;
153
struct servent* se_help = NULL;
155
se_help = sge_getservbyname_r(&se_result, "sge_qmaster", buffer, sizeof(buffer));
156
if (se_help != NULL) {
157
int_port = ntohs(se_help->s_port);
158
if (int_port > 0 && from_services) {
159
*from_services = true;
164
if (int_port <= 0 ) {
165
ERROR((SGE_EVENT, MSG_UTI_CANT_GET_ENV_OR_PORT_SS, "SGE_QMASTER_PORT", "sge_qmaster"));
166
if ( cached_port > 0 ) {
167
WARNING((SGE_EVENT, MSG_UTI_USING_CACHED_PORT_SU, "sge_qmaster", sge_u32c(cached_port) ));
168
int_port = cached_port;
170
sge_mutex_unlock("get_qmaster_port_mutex", SGE_FUNC, __LINE__, &get_qmaster_port_mutex);
174
DPRINTF(("returning port value: "sge_U32CFormat"\n", sge_u32c(int_port)));
175
/* set new timeout time */
176
gettimeofday(&now,NULL);
177
next_timeout = now.tv_sec + SGE_PORT_CACHE_TIMEOUT;
179
/* set new port value */
180
cached_port = int_port;
183
sge_mutex_unlock("get_qmaster_port_mutex", SGE_FUNC, __LINE__, &get_qmaster_port_mutex);
189
int sge_get_execd_port(void) {
194
static long next_timeout = 0;
195
static int cached_port = -1;
197
DENTER(TOP_LAYER, "sge_get_execd_port");
199
sge_mutex_lock("get_execd_port_mutex", SGE_FUNC, __LINE__, &get_execd_port_mutex);
201
/* check for reresolve timeout */
202
gettimeofday(&now,NULL);
204
if ( next_timeout > 0 ) {
205
DPRINTF(("reresolve port timeout in "sge_U32CFormat"\n", sge_u32c( next_timeout - now.tv_sec)));
207
if ( cached_port >= 0 && next_timeout > now.tv_sec ) {
208
int_port = cached_port;
209
DPRINTF(("returning cached port value: "sge_U32CFormat"\n", sge_u32c(int_port)));
210
sge_mutex_unlock("get_execd_port_mutex", SGE_FUNC, __LINE__, &get_execd_port_mutex);
214
port = getenv("SGE_EXECD_PORT");
216
int_port = atoi(port);
219
/* get port from services file */
222
struct servent se_result;
223
struct servent* se_help = NULL;
225
se_help = sge_getservbyname_r(&se_result, "sge_execd", buffer, sizeof(buffer));
226
if (se_help != NULL) {
227
int_port = ntohs(se_help->s_port);
231
if (int_port <= 0 ) {
232
ERROR((SGE_EVENT, MSG_UTI_CANT_GET_ENV_OR_PORT_SS, "SGE_EXECD_PORT" , "sge_execd"));
233
if ( cached_port > 0 ) {
234
WARNING((SGE_EVENT, MSG_UTI_USING_CACHED_PORT_SU, "sge_execd", sge_u32c(cached_port) ));
235
int_port = cached_port;
237
sge_mutex_unlock("get_execd_port_mutex", SGE_FUNC, __LINE__, &get_execd_port_mutex);
241
DPRINTF(("returning port value: "sge_U32CFormat"\n", sge_u32c(int_port)));
242
/* set new timeout time */
243
gettimeofday(&now,NULL);
244
next_timeout = now.tv_sec + SGE_PORT_CACHE_TIMEOUT;
246
/* set new port value */
247
cached_port = int_port;
250
sge_mutex_unlock("get_execd_port_mutex", SGE_FUNC, __LINE__, &get_execd_port_mutex);
257
static int matches_addr(struct hostent *he, char *addr);
258
static host *sge_host_search_pred_alias(host *h);
260
static int matches_name(struct hostent *he, const char *name);
261
static void sge_host_delete(host *h);
263
/* this globals are used for profiling */
264
unsigned long gethostbyname_calls = 0;
265
unsigned long gethostbyname_sec = 0;
266
unsigned long gethostbyaddr_calls = 0;
267
unsigned long gethostbyaddr_sec = 0;
270
#if 0 /*defined(SOLARIS)*/
271
int gethostname(char *name, int namelen);
274
#ifdef GETHOSTBYNAME_M
275
/* guards access to the non-MT-safe gethostbyname system call */
276
static pthread_mutex_t hostbyname_mutex = PTHREAD_MUTEX_INITIALIZER;
279
#ifdef GETHOSTBYADDR_M
280
/* guards access to the non-MT-safe gethostbyaddr system call */
281
static pthread_mutex_t hostbyaddr_mutex = PTHREAD_MUTEX_INITIALIZER;
285
/****** libs/uti/uti_state_get_localhost() *************************************
287
* uti_state_get_localhost() - read access to uti lib global variables
290
* Provides access to either global variable or per thread global variable.
292
*******************************************************************************/
293
host *uti_state_get_localhost(void)
295
/* so far called only by commd */
299
#define MAX_RESOLVER_BLOCKING 15
301
/****** uti/host/sge_gethostbyname_retry() *************************************
303
* sge_gethostbyname_retry() -- gethostbyname() wrapper
306
* struct hostent *sge_gethostbyname_retry(const char *name)
309
* Wraps sge_gethostbyname() function calls, and retries if the host is not
312
* return value must be released by function caller (don't forget the
313
* char** array lists inside of struct hostent)
315
* If possible (libcomm linked) use getuniquehostname() or
316
* cl_com_cached_gethostbyname() or cl_com_gethostname() from commlib.
318
* This will return an sge aliased hostname.
323
* MT-NOTE: see sge_gethostbyname()
324
*******************************************************************************/
325
struct hostent *sge_gethostbyname_retry(
331
DENTER(TOP_LAYER, "sge_gethostbyname_retry");
333
if (!name || name[0] == '\0') {
334
DPRINTF(("hostname to resolve is NULL or has zero length\n"));
339
he = sge_gethostbyname(name,NULL);
341
for (i = 0; i < MAX_NIS_RETRIES && he == NULL; i++) {
342
DPRINTF(("Couldn't resolve hostname %s\n", name));
344
he = sge_gethostbyname(name,NULL);
352
/****** uti/host/sge_gethostbyname() ****************************************
354
* sge_gethostbyname() -- gethostbyname() wrapper
357
* struct hostent *sge_gethostbyname(const char *name)
360
* Wrapps gethostbyname() function calls, measures time spent
361
* in gethostbyname() and logs when very much time has passed.
363
* return value must be released by function caller (don't forget the
364
* char* array lists inside of struct hostent)
366
* If possible (libcomm linked) use getuniquehostname() or
367
* cl_com_cached_gethostbyname() or cl_com_gethostname() from libcomm.
369
* This will return an sge aliased hostname.
373
* MT-NOTE: sge_gethostbyname() is MT safe
374
* MT-NOTE: sge_gethostbyname() uses a mutex to guard access to the
375
* MT-NOTE: gethostbyname() system call on all platforms other than Solaris,
376
* MT-NOTE: Linux, AIX, Tru64, HP-UX, and MacOS 10.2 and greater. Therefore,
377
* MT-NOTE: except on the aforementioned platforms, MT calls to
378
* MT-NOTE: gethostbyname() must go through sge_gethostbyname() to be MT safe.
379
*******************************************************************************/
380
struct hostent *sge_gethostbyname(const char *name, int* system_error_retval)
382
struct hostent *he = NULL;
387
DENTER(GDI_LAYER, "sge_gethostbyname");
389
/* This method goes to great lengths to slip a reentrant gethostbyname into
390
* the code without making changes to the rest of the source base. That
391
* basically means that we have to make some redundant copies to
392
* return to the caller. This method doesn't appear to be highly utilized,
393
* so that's probably ok. If it's not ok, the interface can be changed
396
now = (time_t)sge_get_gmt();
397
gethostbyname_calls++; /* profiling */
399
#ifdef GETHOSTBYNAME_R6
400
#define SGE_GETHOSTBYNAME_FOUND
401
/* This is for Linux */
402
DPRINTF (("Getting host by name - Linux\n"));
407
/* No need to malloc he because it will end up pointing to re. */
408
gethostbyname_r(name, &re, buffer, 4096, &he, &l_errno);
410
/* Since re contains pointers into buffer, and both re and the buffer go
411
* away when we exit this code block, we make a deep copy to return. */
412
/* Yes, I do mean to check if he is NULL and then copy re! No, he
413
* doesn't need to be freed first. */
415
he = sge_copy_hostent (&re);
419
#ifdef GETHOSTBYNAME_R5
420
#define SGE_GETHOSTBYNAME_FOUND
422
/* This is for Solaris */
423
DPRINTF (("Getting host by name - Solaris\n"));
426
struct hostent *help_he = NULL;
428
he = (struct hostent *)malloc (sizeof (struct hostent));
430
memset(he, 0, sizeof(struct hostent));
431
/* On Solaris, this function returns the pointer to my struct on success
432
* and NULL on failure. */
433
help_he = gethostbyname_r(name, he, buffer, 4096, &l_errno);
435
/* Since he contains pointers into buffer, and buffer goes away when we
436
* exit this code block, we make a deep copy to return. */
437
if (help_he != NULL) {
438
struct hostent *new_he = sge_copy_hostent(he);
447
#ifdef GETHOSTBYNAME_R3
448
#define SGE_GETHOSTBYNAME_FOUND
450
/* This is for AIX < 4.3, HPUX < 11, and Tru64 */
451
DPRINTF (("Getting host by name - 3 arg\n"));
454
struct hostent_data he_data;
456
memset(&he_data, 0, sizeof(he_data));
457
he = (struct hostent *)malloc (sizeof (struct hostent));
459
memset(he, 0, sizeof(struct hostent));
460
if (gethostbyname_r(name, he, &he_data) < 0) {
461
/* If this function fails, free he so that we can test if it's NULL
462
* later in the code. */
465
/* The location of the error code is actually undefined. I'm just
466
* assuming that it's in h_errno since that's where it is in the unsafe
468
* h_errno is, of course, not thread safe, but if there's an error we're
469
* already screwed, so we won't worry to much about it.
470
* An alternative would be to set errno to HOST_NOT_FOUND. */
473
/* Since he contains pointers into he_data, and he_data goes away when we
474
* exit this code block, we make a deep copy to return. */
476
struct hostent *new_he = sge_copy_hostent(he);
484
#define SGE_GETHOSTBYNAME_FOUND
486
/* This is for AIX >= 4.3, HPUX >= 11, and Mac OS X >= 10.2 */
487
DPRINTF (("Getting host by name - Thread safe\n"));
488
he = gethostbyname(name);
489
/* The location of the error code is actually undefined. I'm just
490
* assuming that it's in h_errno since that's where it is in the unsafe
492
* h_errno is, of course, not thread safe, but if there's an error we're
493
* already screwed, so we won't worry too much about it.
494
* An alternative would be to set errno to HOST_NOT_FOUND. */
497
struct hostent *new_he = sge_copy_hostent (he);
498
/* do NOT free he, there was no malloc() */
502
#ifdef GETHOSTBYNAME_M
503
#define SGE_GETHOSTBYNAME_FOUND
505
/* This is for Mac OS < 10.2, IRIX, and everyone else
506
* - Actually, IRIX 6.5.17 supports a reentrant getaddrinfo(), but it's not
507
* worth the effort. */
508
DPRINTF (("Getting host by name - Mutex guarded\n"));
510
sge_mutex_lock("hostbyname", SGE_FUNC, __LINE__, &hostbyname_mutex);
512
he = gethostbyname(name);
516
struct hostent *new_he = sge_copy_hostent (he);
517
/* do NOT free he, there was no malloc() */
520
sge_mutex_unlock("hostbyname", SGE_FUNC, __LINE__, &hostbyname_mutex);
524
#ifndef SGE_GETHOSTBYNAME_FOUND
525
#error "no sge_gethostbyname() definition for this architecture."
528
time = (time_t)sge_get_gmt() - now;
529
gethostbyname_sec += time; /* profiling */
531
/* warn about blocking gethostbyname() calls */
532
if (time > MAX_RESOLVER_BLOCKING) {
533
WARNING((SGE_EVENT, "gethostbyname(%s) took %d seconds and returns %s\n",
534
name, (int)time, he?"success":
535
(l_errno == HOST_NOT_FOUND)?"HOST_NOT_FOUND":
536
(l_errno == TRY_AGAIN)?"TRY_AGAIN":
537
(l_errno == NO_RECOVERY)?"NO_RECOVERY":
538
(l_errno == NO_DATA)?"NO_DATA":
539
(l_errno == NO_ADDRESS)?"NO_ADDRESS":"<unknown error>"));
541
if (system_error_retval != NULL) {
542
*system_error_retval = l_errno;
549
/****** uti/host/sge_copy_hostent() ****************************************
551
* sge_copy_hostent() -- make a deep copy of a struct hostent
554
* struct hostent *sge_copy_hostent (struct hostent *orig)
557
* Makes a deep copy of a struct hostent so that sge_gethostbyname() can
558
* free it's buffer for the gethostbyname_r() calls on Linux and Solaris.
561
* MT-NOTE: sge_copy_hostent() is MT safe
562
*******************************************************************************/
563
struct hostent *sge_copy_hostent(struct hostent *orig)
565
struct hostent *copy = (struct hostent *)malloc(sizeof(struct hostent));
569
DENTER (GDI_LAYER, "sge_copy_hostent");
572
/* reset the malloced memory */
573
memset(copy, 0, sizeof(struct hostent));
575
/* Easy stuff first */
576
copy->h_name = strdup(orig->h_name);
577
copy->h_addrtype = orig->h_addrtype;
578
copy->h_length = orig->h_length;
580
/* Count the number of entries */
582
for (p = orig->h_addr_list; *p != NULL; p++) {
586
DPRINTF (("%d names in h_addr_list\n", count));
588
copy->h_addr_list = (char **) malloc (sizeof (char *) * (count + 1));
590
/* Copy the entries */
592
for (p = orig->h_addr_list; *p != NULL; p++) {
595
int tmp_size = sizeof (uint32_t); /* POSIX definition for AF_INET */
597
int tmp_size = sizeof (in_addr_t);
600
copy->h_addr_list[count] = (char *)malloc (tmp_size);
601
memcpy (copy->h_addr_list[count++], *p, tmp_size);
604
copy->h_addr_list[count] = NULL;
606
/* Count the number of entries */
608
for (p = orig->h_aliases; *p != 0; p++) {
612
DPRINTF (("%d names in h_aliases\n", count));
614
copy->h_aliases = (char **) malloc (sizeof (char *) * (count + 1));
616
/* Copy the entries */
618
for (p = orig->h_aliases; *p != 0; p++) {
619
int tmp_size = (strlen(*p) + 1) * sizeof(char);
621
copy->h_aliases[count] = (char *)malloc(tmp_size);
622
memcpy(copy->h_aliases[count++], *p, tmp_size);
625
copy->h_aliases[count] = NULL;
631
/****** uti/host/sge_gethostbyaddr() ****************************************
633
* sge_gethostbyaddr() -- gethostbyaddr() wrapper
636
* struct hostent *sge_gethostbyaddr(const struct in_addr *addr)
639
* Wrapps gethostbyaddr() function calls, measures time spent
640
* in gethostbyaddr() and logs when very much time has passed.
642
* return value must be released by function caller (don't forget the
643
* char** array lists inside of struct hostent)
645
* If possible (libcomm linked) use cl_com_cached_gethostbyaddr()
646
* from libcomm. This will return an sge aliased hostname.
650
* MT-NOTE: sge_gethostbyaddr() is MT safe
651
* MT-NOTE: sge_gethostbyaddr() uses a mutex to guard access to the
652
* MT-NOTE: gethostbyaddr() system call on all platforms other than Solaris,
653
* MT-NOTE: Linux, and HP-UX. Therefore, except on the aforementioned
654
* MT-NOTE: platforms, MT calls to gethostbyaddr() must go through
655
* MT-NOTE: sge_gethostbyaddr() to be MT safe.
656
*******************************************************************************/
657
struct hostent *sge_gethostbyaddr(const struct in_addr *addr, int* system_error_retval)
659
struct hostent *he = NULL;
664
DENTER(TOP_LAYER, "sge_gethostbyaddr");
666
/* This method goes to great lengths to slip a reentrant gethostbyaddr into
667
* the code without making changes to the rest of the source base. That
668
* basically means that we have to make some redundant copies to
669
* return to the caller. This method doesn't appear to be highly utilized,
670
* so that's probably ok. If it's not ok, the interface can be changed
673
gethostbyaddr_calls++; /* profiling */
674
now = (time_t)sge_get_gmt();
676
#ifdef GETHOSTBYADDR_R8
677
#define SGE_GETHOSTBYADDR_FOUND
678
/* This is for Linux */
679
DPRINTF (("Getting host by addr - Linux\n"));
684
/* No need to malloc he because it will end up pointing to re. */
685
gethostbyaddr_r ((const char *)addr, 4, AF_INET, &re, buffer, 4096, &he, &l_errno);
687
/* Since re contains pointers into buffer, and both re and the buffer go
688
* away when we exit this code block, we make a deep copy to return. */
689
/* Yes, I do mean to check if he is NULL and then copy re! No, he
690
* doesn't need to be freed first. */
692
he = sge_copy_hostent (&re);
696
#ifdef GETHOSTBYADDR_R7
697
#define SGE_GETHOSTBYADDR_FOUND
698
/* This is for Solaris */
699
DPRINTF(("Getting host by addr - Solaris\n"));
702
struct hostent *help_he = NULL;
703
he = (struct hostent *)malloc(sizeof(struct hostent));
705
memset(he, 0, sizeof(struct hostent));
707
/* On Solaris, this function returns the pointer to my struct on success
708
* and NULL on failure. */
709
help_he = gethostbyaddr_r((const char *)addr, 4, AF_INET, he, buffer, 4096, &l_errno);
711
/* Since he contains pointers into buffer, and buffer goes away when we
712
* exit this code block, we make a deep copy to return. */
713
if (help_he != NULL) {
714
struct hostent *new_he = sge_copy_hostent(help_he);
725
#ifdef GETHOSTBYADDR_R5
726
#define SGE_GETHOSTBYADDR_FOUND
727
/* This is for HPUX < 11 */
728
DPRINTF(("Getting host by addr - 3 arg\n"));
731
struct hostent_data he_data;
733
memset(&he_data, 0, sizeof(he_data));
734
he = (struct hostent *)malloc (sizeof (struct hostent));
736
memset(he, 0, sizeof(struct hostent));
737
if (gethostbyaddr_r ((const char *)addr, 4, AF_INET, he, &he_data) < 0) {
738
/* If this function fails, free he so that we can test if it's NULL
739
* later in the code. */
743
/* The location of the error code is actually undefined. I'm just
744
* assuming that it's in h_errno since that's where it is in the unsafe
746
* h_errno is, of course, not thread safe, but if there's an error we're
747
* already screwed, so we won't worry to much about it.
748
* An alternative would be to set errno to HOST_NOT_FOUND. */
751
/* Since he contains pointers into he_data, and he_data goes away when we
752
* exit this code block, we make a deep copy to return. */
754
struct hostent *new_he = sge_copy_hostent (he);
762
#define SGE_GETHOSTBYADDR_FOUND
763
/* This is for HPUX >= 11 */
764
DPRINTF(("Getting host by addr - Thread safe\n"));
765
he = gethostbyaddr((const char *)addr, 4, AF_INET);
767
* JG: TODO: shouldn't it be
768
* he = gethostbyaddr((const char *)addr, sizeof(struct in_addr), AF_INET);
771
/* The location of the error code is actually undefined. I'm just
772
* assuming that it's in h_errno since that's where it is in the unsafe
774
* h_errno is, of course, not thread safe, but if there's an error we're
775
* already screwed, so we won't worry too much about it.
776
* An alternative would be to set errno to HOST_NOT_FOUND. */
779
struct hostent *new_he = sge_copy_hostent(he);
780
/* do not free he, there was no malloc() */
786
#ifdef GETHOSTBYADDR_M
787
#define SGE_GETHOSTBYADDR_FOUND
788
/* This is for everone else. */
789
DPRINTF (("Getting host by addr - Mutex guarded\n"));
791
sge_mutex_lock("hostbyaddr", SGE_FUNC, __LINE__, &hostbyaddr_mutex);
794
he = gethostbyaddr((const char *)addr, sizeof(struct in_addr), AF_INET);
796
/* JG: TODO: shouldn't it always be sizeof(struct in_addr)? */
797
he = gethostbyaddr((const char *)addr, 4, AF_INET);
802
struct hostent *new_he = sge_copy_hostent(he);
803
/* do not free he, there was no malloc() */
806
sge_mutex_unlock("hostbyaddr", SGE_FUNC, __LINE__, &hostbyaddr_mutex);
809
#ifndef SGE_GETHOSTBYADDR_FOUND
810
#error "no sge_gethostbyaddr() definition for this architecture."
812
time = (time_t)sge_get_gmt() - now;
813
gethostbyaddr_sec += time; /* profiling */
815
/* warn about blocking gethostbyaddr() calls */
816
if (time > MAX_RESOLVER_BLOCKING) {
817
WARNING((SGE_EVENT, "gethostbyaddr() took %d seconds and returns %s\n", (int)time, he?"success":
818
(l_errno == HOST_NOT_FOUND)?"HOST_NOT_FOUND":
819
(l_errno == TRY_AGAIN)?"TRY_AGAIN":
820
(l_errno == NO_RECOVERY)?"NO_RECOVERY":
821
(l_errno == NO_DATA)?"NO_DATA":
822
(l_errno == NO_ADDRESS)?"NO_ADDRESS":"<unknown error>"));
824
if (system_error_retval != NULL) {
825
*system_error_retval = l_errno;
833
/****** sge_hostname/sge_host_delete() *****************************************
835
* sge_host_delete() -- delete host in host list with all aliases
838
* static void sge_host_delete(host *h)
841
* host *h - host to be deleted
844
* MT-NOTE: sge_host_delete() is not MT safe due to access to global variable
846
*******************************************************************************/
847
static void sge_host_delete(host *h)
849
host *last = NULL, *hl = hostlist;
850
host *predalias, *nextalias;
855
predalias = sge_host_search_pred_alias(h);
856
nextalias = h->alias;
858
while (hl && hl != h) {
864
last->next = hl->next;
866
hostlist = hostlist->next;
868
sge_strafree(&(h->he.h_aliases));
869
sge_strafree(&(h->he.h_addr_list));
872
sge_host_delete(predalias);
873
sge_host_delete(nextalias);
878
/****** sge_hostname/sge_host_search_pred_alias() ******************************
880
* sge_host_search_pred_alias() -- search host who's aliasptr points to host
883
* static host* sge_host_search_pred_alias(host *h)
886
* host *h - host we search for
889
* static host* - found host if contained in host list
892
* MT-NOTE: sge_host_search_pred_alias() is not MT safe due to access to
893
* MT-NOTE: global variable
900
*******************************************************************************/
901
static host *sge_host_search_pred_alias(host *h)
905
while (hl && hl->alias != h)
912
/****** sge_hostname/matches_name() ********************************************
914
* matches_name() -- ???
917
* static int matches_name(struct hostent *he, const char *name)
920
* struct hostent *he - ???
921
* const char *name - ???
927
* MT-NOTE: matches_name() is MT safe
928
*******************************************************************************/
929
static int matches_name(struct hostent *he, const char *name)
933
if (!strcasecmp(name, he->h_name))
935
if (sge_stracasecmp(name, he->h_aliases))
940
/****** sge_hostname/matches_addr() ********************************************
942
* matches_addr() -- ???
945
* static int matches_addr(hostent *he, char *addr)
948
* struct hostent *he - ???
952
* MT-NOTE: matches_addr() is MT safe
953
*******************************************************************************/
954
static int matches_addr(struct hostent *he, char *addr)
959
if (sge_stramemncpy(addr, he->h_addr_list, he->h_length)) {
965
/****** uti/hostname/sge_host_search() ****************************************
967
* sge_host_search() -- Search for host
970
* host* sge_host_search(const char *name, char *addr)
973
* Search for host. If 'name' is not NULL the returned host has
974
* the given or the alias that matches this name. 'name' is
975
* not case sensitive. 'addr' is in hostorder.
976
* If 'addr' is not NULL the returned host has 'addr' in his
977
* addrlist. If 'addr' is aliased this function returns the
978
* hostname of the first alias (mainname)
981
* const char *name - hostname
982
* char *addr - address
985
* MT-NOTE: sge_host_search() is not MT safe due to access to hostlist
986
* MT-NOTE: global variable
990
******************************************************************************/
991
host *sge_host_search(const char *name, char *addr)
993
host *hl = hostlist, *h1;
999
if (((name && !strcasecmp(hl->mainname, name)) ||
1000
matches_name(he, name)) && matches_addr(he, addr)) {
1001
while ((h1 = sge_host_search_pred_alias(hl))) /* start of alias chain */
1011
/****** uti/hostname/sge_host_print() *****************************************
1013
* sge_host_print() -- Print host entry info file
1016
* void sge_host_print(host *h, FILE *fp)
1019
* Print host entry info file
1022
* host *h - host entry
1026
* MT-NOTE: sge_host_print() is NOT MT safe ( because of inet_ntoa() call)
1027
******************************************************************************/
1028
void sge_host_print(host *h, FILE *fp)
1034
fprintf(fp, "h_name: %s\n", he->h_name);
1035
fprintf(fp, "mainname: %s\n", h->mainname);
1036
fprintf(fp, "h_aliases:\n");
1037
for (cpp = he->h_aliases; *cpp; cpp++) {
1038
fprintf(fp, " %s\n", *cpp);
1040
fprintf(fp, "h_addrtype: %d\n", he->h_addrtype);
1041
fprintf(fp, "h_length: %d\n", he->h_length);
1042
fprintf(fp, "h_addr_list:\n");
1043
for (cpp = he->h_addr_list; *cpp; cpp++) {
1044
fprintf(fp, " %s\n", inet_ntoa(*(struct in_addr *) *cpp)); /* inet_ntoa() is not MT save */
1047
fprintf(fp, "aliased to %s\n", h->alias->he.h_name);
1051
/****** uti/hostname/sge_host_list_print() ************************************
1053
* sge_host_list_print() -- Print hostlist into file
1056
* void sge_host_list_print(FILE *fp)
1059
* Print hostlist into file
1062
* FILE *fp - filename
1065
* MT-NOTE: sge_host_list_print() is not MT safe due to access to hostlist
1066
* MT-NOTE: global variable
1067
******************************************************************************/
1068
void sge_host_list_print(FILE *fp)
1070
host *hl = hostlist;
1073
sge_host_print(hl, fp);
1082
void sge_free_hostent( struct hostent** he_to_del ) {
1083
struct hostent *he = NULL;
1086
/* nothing to free */
1087
if (he_to_del == NULL) {
1091
/* pointer points to NULL, nothing to free */
1092
if (*he_to_del == NULL) {
1098
/* free unique host name */
1102
/* free host aliases */
1103
if (he->h_aliases != NULL) {
1104
help = he->h_aliases;
1108
free(he->h_aliases);
1110
he->h_aliases = NULL;
1112
/* free addr list */
1113
if (he->h_addr_list != NULL) {
1114
help = he->h_addr_list;
1118
free(he->h_addr_list);
1120
he->h_addr_list = NULL;
1122
/* free hostent struct */
1129
/****** uti/hostname/sge_host_get_mainname() **********************************
1131
* sge_host_get_mainname() -- Return mainname considering aliases
1134
* char* sge_host_get_mainname(host *h)
1137
* Return the mainname of a host considering aliases.
1146
* MT-NOTE: sge_host_get_mainname() is not MT safe
1147
******************************************************************************/
1148
char *sge_host_get_mainname(host *h)
1153
while ((h = sge_host_search_pred_alias(h))) /* search start of alias chain */
1156
if (h1->mainname[0])
1157
return h1->mainname;
1159
return (char *) h1->he.h_name;
1164
/****** uti/hostname/sge_hostcpy() ********************************************
1166
* sge_hostcpy() -- strcpy() for hostnames.
1169
* void sge_hostcpy(char *dst, const char *raw)
1172
* strcpy() for hostnames. Honours some configuration values:
1173
* - Domain name may be ignored
1174
* - Domain name may be replaced by a 'default domain'
1175
* - Hostnames may be used as they are.
1176
* - straight strcpy() for hostgroup names
1179
* char *dst - possibly modified hostname
1180
* const char *raw - hostname
1183
* uti/hostname/sge_hostcmp()
1184
* uti/hostname/sge_hostmatch()
1187
* MT-NOTE: sge_hostcpy() is MT safe
1188
******************************************************************************/
1189
void sge_hostcpy(char *dst, const char *raw)
1191
bool ignore_fqdn = bootstrap_get_ignore_fqdn();
1192
bool is_hgrp = is_hgroup_name(raw);
1193
const char *default_domain;
1195
if (dst == NULL || raw == NULL) {
1199
/* hostgroup name: not in FQDN format, copy the entire string*/
1200
sge_strlcpy(dst, raw, CL_MAXHOSTLEN);
1205
/* standard: simply ignore FQDN */
1207
sge_strlcpy(dst, raw, CL_MAXHOSTLEN);
1208
if ((s = strchr(dst, '.'))) {
1213
if ((default_domain = bootstrap_get_default_domain()) != NULL &&
1214
SGE_STRCASECMP(default_domain, "none") != 0) {
1216
/* exotic: honor FQDN but use default_domain */
1217
if (!strchr(raw, '.')) {
1218
snprintf(dst, CL_MAXHOSTLEN, "%s.%s", raw, default_domain);
1220
sge_strlcpy(dst, raw, CL_MAXHOSTLEN);
1223
/* hardcore: honor FQDN, don't use default_domain */
1225
sge_strlcpy(dst, raw, CL_MAXHOSTLEN);
1231
/****** uti/hostname/sge_hostcmp() ********************************************
1233
* sge_hostcmp() -- strcmp() for hostnames
1236
* int sge_hostcmp(const char *h1, const char*h2)
1239
* strcmp() for hostnames. Honours some configuration values:
1240
* - Domain name may be ignored
1241
* - Domain name may be replaced by a 'default domain'
1242
* - Hostnames may be used as they are.
1245
* const char *h1 - 1st hostname
1246
* const char *h2 - 2nd hostname
1252
* uti/hostname/sge_hostmatch()
1253
* uti/hostname/sge_hostcpy()
1256
* MT-NOTE: sge_hostcmp() is MT safe
1257
******************************************************************************/
1258
int sge_hostcmp(const char *h1, const char*h2)
1261
char h1_cpy[CL_MAXHOSTLEN+1], h2_cpy[CL_MAXHOSTLEN+1];
1264
DENTER(BASIS_LAYER, "sge_hostcmp");
1266
if (h1 != NULL && h2 != NULL) {
1267
sge_hostcpy(h1_cpy,h1);
1268
sge_hostcpy(h2_cpy,h2);
1270
cmp = SGE_STRCASECMP(h1_cpy, h2_cpy);
1272
DPRINTF(("sge_hostcmp(%s, %s) = %d\n", h1_cpy, h2_cpy));
1279
/****** uti/hostname/sge_hostmatch() ********************************************
1281
* sge_hostmatch() -- fnmatch() for hostnames
1284
* int sge_hostmatch(const char *h1, const char*h2)
1287
* fnmatch() for hostnames. Honours some configuration values:
1288
* - Domain name may be ignored
1289
* - Domain name may be replaced by a 'default domain'
1290
* - Hostnames may be used as they are.
1293
* const char *h1 - 1st hostname
1294
* const char *h2 - 2nd hostname
1300
* uti/hostname/sge_hostcmp()
1301
* uti/hostname/sge_hostcpy()
1304
* MT-NOTE: sge_hostmatch() is MT safe
1305
******************************************************************************/
1306
int sge_hostmatch(const char *h1, const char*h2)
1309
char h1_cpy[CL_MAXHOSTLEN+1], h2_cpy[CL_MAXHOSTLEN+1];
1312
DENTER(BASIS_LAYER, "sge_hostmatch");
1314
if (h1 != NULL && h2 != NULL) {
1315
sge_hostcpy(h1_cpy,h1);
1316
sge_hostcpy(h2_cpy,h2);
1318
cmp=fnmatch(h1_cpy, h2_cpy, 0);
1320
DPRINTF(("sge_hostmatch(%s, %s) = %d\n", h1_cpy, h2_cpy));
1328
/****** uti/hostname/is_hgroup_name() ****************************************
1330
* is_hgroup_name() -- Is the given name a hostgroup name
1333
* bool is_hgroup_name(const char *name)
1336
* Is the given name a hostgroup name
1339
* This function is also used for usergroup in resource quota sets
1342
* const char *name - hostname or hostgroup name
1345
* bool - true for hostgroupnames otherwise false
1346
******************************************************************************/
1348
is_hgroup_name(const char *name)
1353
ret = (name[0] == HOSTGROUP_INITIAL_CHAR) ? true : false;