3
A brief file description
5
@section license License
7
Licensed to the Apache Software Foundation (ASF) under one
8
or more contributor license agreements. See the NOTICE file
9
distributed with this work for additional information
10
regarding copyright ownership. The ASF licenses this file
11
to you under the Apache License, Version 2.0 (the
12
"License"); you may not use this file except in compliance
13
with the License. You may obtain a copy of the License at
15
http://www.apache.org/licenses/LICENSE-2.0
17
Unless required by applicable law or agreed to in writing, software
18
distributed under the License is distributed on an "AS IS" BASIS,
19
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
See the License for the specific language governing permissions and
21
limitations under the License.
24
/**************************************
27
* Some utility and support functions for the management module.
32
#include "ink_unused.h" /* MAGIC_EDITING_TAG */
35
#include "MgmtUtils.h"
39
#include "mgmt2/Main.h"
41
#include "mgmt2/../Main.h"
44
extern int diags_init;
47
#define syslog(_X, _Y, _Z)
49
static int use_syslog = 0;
53
* Called to indicate that the syslog should be used and
54
* the log has been opened
64
* Simple, inefficient, read line function. Takes a socket to read
65
* from, a char * to write into, and a max len to read. The newline
68
* Returns: num bytes read
72
mgmt_readline(int soc, char *buf, int maxlen)
77
for (n = 1; n < maxlen; n++) {
79
if ((rc = read_socket(soc, &c, 1)) == 1) {
85
if (*(buf - 1) == '\r') {
93
if (n == 1) { /* EOF */
103
} /* End mgmt_readline */
107
* mgmt_writeline(...)
108
* Simple, inefficient, write line function. Takes a soc to write to,
109
* a char * containing the data, and the number of bytes to write.
110
* It sends nbytes + 1 bytes worth of data, the + 1 being the newline
113
* Returns: num bytes not written
117
mgmt_writeline(int soc, const char *data, int nbytes)
119
int nleft, nwritten, n;
120
const char *tmp = data;
124
nwritten = write_socket(soc, tmp, nleft);
125
if (nwritten <= 0) { /* Error or nothing written */
132
if ((n = write_socket(soc, "\n", 1)) <= 0) { /* Terminating newline */
136
return (nbytes - nleft);
140
return (nleft); /* Paranoia */
141
} /* End mgmt_writeline */
147
* - Reads from a pipe
149
* Returns: bytes read
155
mgmt_read_pipe(int fd, char *buf, int bytes_to_read)
160
while (bytes_to_read > 0) {
161
err = read_socket(fd, p, bytes_to_read);
164
} else if (err < 0) {
177
bytes_to_read -= err;
191
* Returns: bytes written
197
mgmt_write_pipe(int fd, char *buf, int bytes_to_write)
201
int bytes_written = 0;
202
while (bytes_to_write > 0) {
203
err = write_socket(fd, p, bytes_to_write);
206
} else if (err < 0) {
219
bytes_to_write -= err;
220
bytes_written += err;
226
return bytes_written;
233
* - Reads from a message type named pipe.
236
* Returns: num bytes read
240
mgmt_read_pipe(HANDLE hpipe, char *buf, int maxlen)
245
ov.Internal = ov.InternalHigh = ov.Offset = ov.OffsetHigh = 0;
246
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
247
if (ReadFile(hpipe, (LPVOID) buf, maxlen, NULL, &ov) == 0) {
248
if (GetLastError() != ERROR_IO_PENDING) {
249
CloseHandle(ov.hEvent);
253
if (WaitForSingleObject(ov.hEvent, INFINITE) == WAIT_FAILED) {
254
CloseHandle(ov.hEvent);
257
if (GetOverlappedResult(hpipe, &ov, &bytesRead, FALSE) == 0) {
258
CloseHandle(ov.hEvent);
262
CloseHandle(ov.hEvent);
269
* - Writes to a message type named pipe.
272
* Returns: num bytes not written
276
mgmt_write_pipe(HANDLE hpipe, char *data, int nbytes)
278
DWORD bytesWritten = 0;
281
ov.Internal = ov.InternalHigh = ov.Offset = ov.OffsetHigh = 0;
282
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
283
if (WriteFile(hpipe, (LPCVOID) data, nbytes, NULL, &ov) == 0) {
284
if (GetLastError() != ERROR_IO_PENDING) {
285
CloseHandle(ov.hEvent);
289
if (WaitForSingleObject(ov.hEvent, INFINITE) == WAIT_FAILED) {
290
CloseHandle(ov.hEvent);
293
if (GetOverlappedResult(hpipe, &ov, &bytesWritten, FALSE) == 0) {
294
CloseHandle(ov.hEvent);
298
CloseHandle(ov.hEvent);
299
return (nbytes - bytesWritten);
307
#if !defined(linux) && !defined(_WIN32)
308
// Start by blocking all signals
309
sigset_t allSigs; // Set of all signals
310
sigfillset(&allSigs);
311
if (ink_thread_sigsetmask(SIG_SETMASK, &allSigs, NULL) < 0) {
312
perror("ink_thread_sigsetmask");
319
* Really just a print wrapper, function takes a string and outputs the
320
* result to log. Written so that we could turn off all output or at least
324
mgmt_log(FILE * log, const char *message_format, ...)
327
char extended_format[4096], message[4096];
329
va_start(ap, message_format);
331
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
333
diags->print_va(NULL, DL_Note, "NOTE", NULL, message_format, ap);
338
snprintf(extended_format, sizeof(extended_format), "log ==> %s", message_format);
339
vsprintf(message, extended_format, ap);
340
syslog(LOG_WARNING, "%s", message);
342
snprintf(extended_format, sizeof(extended_format), "[E. Mgmt] log ==> %s", message_format);
343
vsprintf(message, extended_format, ap);
344
ink_assert(fwrite(message, strlen(message), 1, log) == 1);
346
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
355
mgmt_log(const char *message_format, ...)
358
char extended_format[4096], message[4096];
360
va_start(ap, message_format);
361
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
363
diags->print_va(NULL, DL_Note, "NOTE", NULL, message_format, ap);
368
snprintf(extended_format, sizeof(extended_format), "log ==> %s", message_format);
369
vsprintf(message, extended_format, ap);
370
syslog(LOG_WARNING, "%s", message);
372
snprintf(extended_format, sizeof(extended_format), "[E. Mgmt] log ==> %s", message_format);
373
vsprintf(message, extended_format, ap);
374
ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
376
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
387
* Same as above, but intended for errors.
390
mgmt_elog(FILE * log, const char *message_format, ...)
393
char extended_format[4096], message[4096];
395
va_start(ap, message_format);
397
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
400
diags->print_va(NULL, DL_Error, "ERROR", NULL, message_format, ap);
401
snprintf(message, sizeof(message), " (last system error %d: %s)\n", lerrno, strerror(lerrno));
402
diags->print(NULL, DL_Error, "ERROR", NULL, message);
406
snprintf(extended_format, sizeof(extended_format), "ERROR ==> %s", message_format);
407
vsprintf(message, extended_format, ap);
408
#if !defined (_WIN32)
409
syslog(LOG_ERR, "%s", message);
410
syslog(LOG_ERR, " (last system error %d: %s)", errno, strerror(errno));
413
snprintf(extended_format, sizeof(extended_format), "[E. Mgmt] ERROR ==> %s", message_format);
414
vsprintf(message, extended_format, ap);
415
ink_assert(fwrite(message, strlen(message), 1, log) == 1);
416
snprintf(message, sizeof(message), "(last system error %d: %s)", errno, strerror(errno));
417
ink_assert(fwrite(message, strlen(message), 1, log) == 1);
419
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
425
} /* End mgmt_elog */
429
mgmt_elog(const char *message_format, ...)
432
char extended_format[4096], message[4096];
434
va_start(ap, message_format);
436
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
439
diags->print_va(NULL, DL_Error, "ERROR", NULL, message_format, ap);
440
snprintf(message, sizeof(message), " (last system error %d: %s)\n", lerrno, strerror(lerrno));
441
diags->print(NULL, DL_Error, "ERROR", NULL, message);
446
snprintf(extended_format, sizeof(extended_format), "ERROR ==> %s", message_format);
447
vsprintf(message, extended_format, ap);
448
syslog(LOG_ERR, "%s", message);
449
#if !defined (_WIN32)
450
syslog(LOG_ERR, " (last system error %d: %s)", errno, strerror(errno));
453
snprintf(extended_format, sizeof(extended_format), "Manager ERROR: %s", message_format);
454
vsprintf(message, extended_format, ap);
455
ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
456
snprintf(message, sizeof(message), "(last system error %d: %s)", errno, strerror(errno));
457
ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
459
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
464
} /* End mgmt_elog */
469
* Same as above, but for fatal errors. Logs error, calls perror, and
473
mgmt_fatal(FILE * log, const char *message_format, ...)
476
char extended_format[4096], message[4096];
478
va_start(ap, message_format);
481
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
484
diags->print_va(NULL, DL_Fatal, "FATAL", NULL, message_format, ap);
485
snprintf(message, sizeof(message), " (last system error %d: %s)\n", lerrno, strerror(lerrno));
486
diags->print(NULL, DL_Fatal, "FATAL", NULL, message);
490
snprintf(extended_format, sizeof(extended_format), "FATAL ==> %s", message_format);
491
vsprintf(message, extended_format, ap);
493
ink_assert(fwrite(message, strlen(message), 1, log) == 1);
496
syslog(LOG_ERR, "%s", message);
501
perror("[E. Mgmt] ");
504
#if !defined (_WIN32)
505
syslog(LOG_ERR, " (last system error %d: %s)", errno, strerror(errno));
508
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
516
} /* End mgmt_fatal */
521
mgmt_fatal(const char *message_format, ...)
524
char extended_format[4096], message[4096];
526
va_start(ap, message_format);
528
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
531
diags->print_va(NULL, DL_Fatal, "FATAL", NULL, message_format, ap);
532
snprintf(message, sizeof(message), " (last system error %d: %s)\n", lerrno, strerror(lerrno));
533
diags->print(NULL, DL_Fatal, "FATAL", NULL, message);
537
snprintf(extended_format, sizeof(extended_format), "FATAL ==> %s", message_format);
538
vsprintf(message, extended_format, ap);
540
ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
543
syslog(LOG_ERR, "%s", message);
548
perror("[E. Mgmt] ");
551
#if !defined (_WIN32)
552
syslog(LOG_ERR, " (last system error %d: %s)", errno, strerror(errno));
555
#if defined(LOCAL_MANAGER) || defined(PROCESS_MANAGER)
563
} /* End mgmt_fatal */
568
#if defined(LOCAL_MANAGER)
570
lmgmt->mgmtShutdown(1, true);
577
get_interface_mtu(int sock_fd, struct ifreq *ifr)
579
if (ioctl(sock_fd, SIOCGIFMTU, ifr) < 0) {
580
mgmt_log(stderr, "[getAddrForIntr] Unable to obtain MTU for " "interface '%s'", ifr->ifr_name);
583
#if defined(solaris) || defined(hpux)
584
return ifr->ifr_metric;
592
mgmt_getAddrForIntr(char *intrName, struct in_addr * addr, int *mtu)
596
if (intrName == NULL) {
601
int fakeSocket; // a temporary socket to pass to ioctl
602
struct sockaddr_in *tmp; // a tmp ptr for addresses
603
struct ifconf ifc; // ifconf information
604
char *ifbuf; // ifconf buffer
605
struct ifreq *ifr, *ifend; // pointer to individual inferface info
610
memset(addr, 0, sizeof(struct in_addr));
612
if ((fakeSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
613
mgmt_fatal(stderr, "[getAddrForIntr] Unable to create socket\n");
616
// Fetch the list of network interfaces
617
// . from Stevens, Unix Network Prog., pg 434-435
620
len = 128 * sizeof(struct ifreq); // initial buffer size guess
622
ifbuf = (char *) xmalloc(len);
623
memset(ifbuf, 0, len); // prevent UMRs
626
if (ioctl(fakeSocket, SIOCGIFCONF, &ifc) < 0) {
627
if (errno != EINVAL || lastlen != 0) {
628
mgmt_fatal(stderr, "[getAddrForIntr] Unable to read network interface configuration\n");
631
if (ifc.ifc_len == lastlen) {
634
lastlen = ifc.ifc_len;
642
// Loop through the list of interfaces
643
ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
644
for (ifr = ifc.ifc_req; ifr < ifend;) {
645
if (ifr->ifr_addr.sa_family == AF_INET && strcmp(ifr->ifr_name, intrName) == 0) {
646
// Get the address of the interface
647
if (ioctl(fakeSocket, SIOCGIFADDR, (char *) ifr) < 0) {
648
mgmt_log(stderr, "[getAddrForIntr] Unable obtain address for network interface %s\n", intrName);
650
// Only look at the address if it an internet address
651
if (ifr->ifr_ifru.ifru_addr.sa_family == AF_INET) {
652
tmp = (struct sockaddr_in *) &ifr->ifr_ifru.ifru_addr;
653
*addr = tmp->sin_addr;
657
*mtu = get_interface_mtu(fakeSocket, ifr);
661
mgmt_log(stderr, "[getAddrForIntr] Interface %s is not configured for IP.\n", intrName);
665
#if defined(freebsd) || defined(darwin)
666
ifr = (struct ifreq *) ((char *) &ifr->ifr_addr + ifr->ifr_addr.sa_len);
668
ifr = (struct ifreq *) (((char *) ifr) + sizeof(*ifr));
676
// There is no notion of network interface names on NT.
677
// So we use a winnt_intr.config file to give each of
678
// the interface a name.
680
char intr_file[PATH_MAX + 1];
684
snprintf(intr_file, sizeof(intr_file), "%s%sconfig%s%s", ts_base_dir, DIR_SEP, DIR_SEP, "winnt_intr.config");
686
snprintf(intr_file, sizeof(intr_file), "%s%sconfig%s%s", system_base_install, DIR_SEP, DIR_SEP, "winnt_intr.config");
689
if ((fp = fopen(intr_file, "r")) == NULL) {
690
mgmt_log(stderr, "[getAddrForIntr] Unable to open %s\n", intr_file);
697
if (!fgets(buffer, 1024, fp)) {
700
// replace newline with null termination
701
p = strchr(buffer, '\n');
705
// skip beginning line spaces
707
while (*p != '\0' && isspace(*p)) {
711
// skip blank or comment lines
712
if (*p == '#' || *p == '\0') {
716
if (p = strstr(p, intrName)) {
717
p = p + strlen(intrName) + 1;
718
in_addr_t cluster_ip = inet_addr(p);
720
if (cluster_ip != INADDR_NONE) {
721
addr->s_addr = cluster_ip;
734
} /* End mgmt_getAddrForIntr */
737
* mgmt_sortipaddrs(...)
738
* Routine to sort and pick smallest ip addr.
741
mgmt_sortipaddrs(int num, struct in_addr **list)
745
struct in_addr *entry, *tmp;
747
min = (list[0])->s_addr;
749
while (i < num && (tmp = (struct in_addr *) list[i]) != NULL) {
751
if (min > tmp->s_addr) {
757
} /* End mgmt_sortipaddrs */
762
#if defined(LOCAL_MANAGER)
766
int rec_err = RecGetRecordString_Xmalloc("proxy.node.hostname_FQ", &hostname);
767
found = (rec_err == REC_ERR_OKAY);
768
if (found && hostname) {
769
ip = host_to_ip(hostname);
770
if (ip != INADDR_ANY) {
771
return inet_ntoa(*(struct in_addr *) &ip);
780
mgmt_sleep_sec(int seconds)
786
mgmt_sleep_msec(int msec)
792
mgmt_sleep_sec(int seconds)
794
Sleep(1000 * seconds);
798
mgmt_sleep_msec(int msec)