--- packaging/source-trees/gt2-cvs/gatekeeper/source/globus_gatekeeper.c.orig Fri Jul 16 10:13:21 2004
+++ packaging/source-trees/gt2-cvs/gatekeeper/source/globus_gatekeeper.c Fri Jul 16 10:13:29 2004
@@ -38,6 +38,7 @@
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
+#include <sys/select.h>
#include <syslog.h>
#include <netdb.h>
#include <netinet/in.h>
@@ -188,6 +189,7 @@
#define notice2(i,a,b) {sprintf(tmpbuf, a,b); notice(i,tmpbuf);}
#define notice3(i,a,b,c) {sprintf(tmpbuf, a,b,c); notice(i,tmpbuf);}
#define notice4(i,a,b,c,d) {sprintf(tmpbuf, a,b,c,d); notice(i,tmpbuf);}
+#define notice5(i,a,b,c,d,e) {sprintf(tmpbuf, a,b,c,d,e); notice(i,tmpbuf);}
#define failure2(t,a,b) {sprintf(tmpbuf, a,b); failure(t,tmpbuf);}
#define failure3(t,a,b,c) {sprintf(tmpbuf, a,b,c); failure(t,tmpbuf);}
#define failure4(t,a,b,c,d) {sprintf(tmpbuf, a,b,c,d); failure(t,tmpbuf);}
@@ -199,6 +201,10 @@
static FILE * usrlog_fp;
static char * logfile = LOGFILE;
+static char * acctfile;
+static volatile int logrotate;
+static pid_t gatekeeper_pid;
+static unsigned reqnr;
static char test_dat_file[1024];
static int gatekeeper_test;
static int gatekeeper_uid;
@@ -346,6 +352,105 @@
} /* reaper() */
/******************************************************************************
+Function: rotatelog()
+Description: Handle a SIGUSR1: set a flag indicating the logfile should be
+ rotated by the main loop.
+Parameters:
+Returns:
+******************************************************************************/
+static void
+rotatelog(int s)
+{
+ logrotate = 1;
+}
+
+/******************************************************************************
+Function: new_acct_file()
+Description: Rotate old and open new job accounting file.
+Parameters:
+Returns:
+******************************************************************************/
+static void
+new_acct_file(void)
+{
+ static int acct_fd = -1;
+
+ if (acct_fd >= 0)
+ {
+ if (strcmp(acctfile, logfile) != 0)
+ {
+ static int seqnr;
+ char *acctpath = genfilename(gatekeeperhome, acctfile, NULL);
+ char *oldpath = malloc(strlen(acctpath) + 64);
+ time_t clock = time((time_t *) 0);
+ struct tm *tmp = localtime(&clock);
+ int ret;
+
+ sprintf(oldpath, "%s.%04d%02d%02d%02d%02d%02d.%d", acctpath,
+ tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec, seqnr++);
+
+ if ((ret = rename(acctpath, oldpath)) != 0)
+ {
+ notice4(LOG_ERR, "ERROR: cannot rename %s to %s: %s",
+ acctpath, oldpath, strerror(errno));
+ }
+ else
+ {
+ notice2(0, "renamed accounting file %s", oldpath);
+ }
+
+ free(acctpath);
+ free(oldpath);
+
+ if (ret) {
+ return;
+ }
+ }
+
+ close(acct_fd);
+ acct_fd = -1;
+ }
+
+ if (!acctfile)
+ {
+ acctfile = logfile;
+ }
+
+ if (acctfile && *acctfile)
+ {
+ const char *acct_fd_var = "GATEKEEPER_ACCT_FD";
+ char *acctpath = genfilename(gatekeeperhome, acctfile, NULL);
+
+ acct_fd = open(acctpath, O_WRONLY | O_APPEND | O_CREAT, 0644);
+
+ if (acct_fd < 0)
+ {
+ notice3(LOG_ERR, "ERROR: cannot open accounting file '%s': %s",
+ acctpath, strerror(errno));
+
+ unsetenv(acct_fd_var);
+ }
+ else
+ {
+ /*
+ * Now inform JM via environment.
+ */
+
+ char buf[32];
+
+ sprintf(buf, "%d", acct_fd);
+
+ setenv(acct_fd_var, buf, 1);
+
+ notice4(0, "%s=%s (%s)", acct_fd_var, buf, acctpath);
+ }
+
+ free(acctpath);
+ }
+}
+
+/******************************************************************************
Function: genfilename()
Description: generate an absolute file name given a starting prefix,
a relative or absolute path, and a sufix
@@ -439,6 +544,8 @@
exit (1);
}
+ gatekeeper_pid = getpid();
+
gatekeeper_uid = getuid();
if (gatekeeper_uid == 0)
{
@@ -603,6 +710,12 @@
logfile = argv[i+1];
i++;
}
+ else if ((strcmp(argv[i], "-acctfile") == 0)
+ && (i + 1 < argc))
+ {
+ acctfile = argv[i+1];
+ i++;
+ }
else if ((strcmp(argv[i], "-home") == 0)
&& (i + 1 < argc))
{
@@ -749,7 +862,7 @@
fprintf(stderr, "Usage: %s %s %s %s %s %s %s %s %s %s\n ",
argv[0],
"{-conf parmfile [-test]} | {[-d[ebug] [-inetd | -f] [-p[ort] port] ",
- "[-home path] [-l[ogfile] logfile] [-e path] ",
+ "[-home path] [-l[ogfile] logfile] [-acctfile acctfile] [-e path] ",
"[-grid_services file] ",
"[-globusid globusid] [-gridmap file] [-globuspwd file]",
"[-x509_cert_dir path] [-x509_cert_file file]",
@@ -880,15 +993,25 @@
act.sa_flags = 0;
sigaction(SIGTERM, &act, NULL);
}
+ act.sa_handler = rotatelog;
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, SIGUSR1);
+ act.sa_flags = 0;
+ sigaction(SIGUSR1, &act, NULL);
}
if (run_from_inetd)
{
logging_phase2();
dup2(2,1); /* point stdout at log as well */
- setbuf(stdout,NULL);
}
+ /*
+ * Always make stdout unbuffered: otherwise the fclose(stdout)
+ * in doit() will flush any buffered output again and again!
+ */
+ setbuf(stdout,NULL);
+
/* Get the GSS credential for the accepter
* If not run_from_inetd we can prompt here.
* If we are running as a deamon, and should not
@@ -982,6 +1105,7 @@
free(globusid);
}
+ new_acct_file();
if (run_from_inetd)
{
@@ -999,10 +1123,12 @@
if (fork())
exit(0);
+ gatekeeper_pid = getpid();
+
if (!logging_usrlog)
{
(void) close(2); /* close stderr as well */
- (void) open ("/dev/null",0);
+ (void) open("/dev/null",O_WRONLY);
}
(void) close(0);
@@ -1059,6 +1185,7 @@
while (1)
{
connection_fd = net_accept(listener_fd);
+ reqnr++;
pid = fork();
@@ -1855,6 +1982,31 @@
setenv("GRID_AUTH_METHOD","TO_FILLED_IN_LATER",1);
/*
+ * Cook up a unique ID such that we can link the GSI info logged by
+ * the Gatekeeper to the batch system info logged by the Job Manager.
+ */
+ {
+ time_t clock;
+ struct tm * tmp;
+ const char * gk_jm_id_var = "GATEKEEPER_JM_ID";
+ char gatekeeper_jm_id[64];
+
+ time(&clock);
+ tmp = localtime(&clock);
+
+ sprintf(gatekeeper_jm_id, "%04d-%02d-%02d.%02d:%02d:%02d.%010u.%010u",
+ tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec,
+ gatekeeper_pid & 0xFFFFFFFF, reqnr & 0xFFFFFFFF);
+
+ setenv(gk_jm_id_var, gatekeeper_jm_id, 1);
+ setenv("GATEKEEPER_PEER", peernum, 1);
+
+ notice5(0, "%s %s for %s on %s", gk_jm_id_var, gatekeeper_jm_id,
+ client_name, peernum);
+ }
+
+ /*
* Become the appropriate user
*/
if (gatekeeper_uid == 0)
@@ -2083,18 +2235,87 @@
fromlen = sizeof(from);
gotit = 0;
+
while (!gotit)
{
- skt2 = accept(skt, (struct sockaddr *) &from, &fromlen);
- if (skt2 == -1)
- {
- if (errno == EINTR)
- continue;
- else
- error_check(skt2, "net_accept accept");
- }
- else
- gotit = 1;
+ fd_set fdset;
+ struct timeval timeout;
+ int n;
+
+ FD_ZERO(&fdset);
+ FD_SET(skt, &fdset);
+ timeout.tv_sec = 60;
+ timeout.tv_usec = 0;
+
+ n = select(skt + 1, &fdset, (fd_set *) 0, &fdset, &timeout);
+
+ if (n < 0 && errno != EINTR)
+ {
+ error_check(n, "net_accept select");
+ }
+ else if (n > 0)
+ {
+ skt2 = accept(skt, (struct sockaddr *) &from, &fromlen);
+
+ if (skt2 == -1)
+ {
+ if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK)
+ {
+ error_check(skt2, "net_accept accept");
+ }
+ }
+ else
+ gotit = 1;
+ }
+
+ if (logrotate)
+ {
+ time_t clock = time((time_t *) 0);
+ struct tm *tmp = localtime(&clock);
+ char buf[128];
+
+ sprintf(buf, "logfile rotating at %04d-%02d-%02d %02d:%02d:%02d",
+ tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+ notice2(LOG_INFO, "%s", buf);
+
+ if (logging_usrlog)
+ {
+ static int seqnr;
+ char *logpath = genfilename(gatekeeperhome, logfile, NULL);
+ char *oldpath = malloc(strlen(logpath) + 64);
+
+ sprintf(oldpath, "%s.%04d%02d%02d%02d%02d%02d.%d", logpath,
+ tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec, seqnr++);
+
+ if (rename(logpath, oldpath) != 0)
+ {
+ notice4(LOG_ERR, "ERROR: cannot rename %s to %s: %s",
+ logpath, oldpath, strerror(errno));
+ }
+ else if (logging_startup() != 0)
+ {
+ failure(FAILED_SERVER, "Logging restart failure");
+ }
+ else
+ {
+ logging_phase2();
+ fclose(stdout);
+ (void) dup2(2, 1); /* point stdout to stderr */
+ *stdout = *fdopen(1, "w");
+ notice2(LOG_INFO, "Continuing from %s", oldpath);
+ }
+
+ free(logpath);
+ free(oldpath);
+ }
+
+ new_acct_file();
+
+ logrotate = 0;
+ }
}
return(skt2);
@@ -2114,11 +2335,16 @@
{
netlen_t sinlen;
struct sockaddr_in sin;
+ long flags;
int one=1;
*skt = socket(AF_INET, SOCK_STREAM, 0);
error_check(*skt,"net_setup_anon_listener socket");
+ flags = fcntl(*skt, F_GETFL, 0);
+ flags |= O_NONBLOCK;
+ fcntl(*skt, F_SETFL, flags);
+
error_check(setsockopt(*skt, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)),
"net_setup_anon_listener setsockopt");
@@ -2157,13 +2383,16 @@
}
else
{
- /*
- * By default open syslogfile.
- * All messages will have GRAM gatekeeper and include the PID.
- * The messages will be treated like any other system daemon.
- */
- logging_syslog = 1;
- openlog("GRAM gatekeeper", LOG_PID, LOG_DAEMON);
+ if (!logging_syslog)
+ {
+ /*
+ * By default open syslogfile if it is not open already.
+ * All messages will have GRAM gatekeeper and include the PID.
+ * The messages will be treated like any other system daemon.
+ */
+ logging_syslog = 1;
+ openlog("GRAM gatekeeper", LOG_PID, LOG_DAEMON);
+ }
if (strlen(logfile) > 0)
{
@@ -2172,7 +2401,20 @@
* Open the user specified logfile
*/
+ if (logging_usrlog)
+ {
+ /* close previous logfile, if any */
+
+ if (usrlog_fp)
+ {
+ fclose(usrlog_fp);
+ }
+
+ logging_usrlog = 0;
+ }
+
logfilename = genfilename(gatekeeperhome, logfile, NULL);
+
if ((usrlog_fp = fopen(logfilename, "a")) == NULL)
{
fprintf(stderr, "Cannot open logfile %s: %s\n",
@@ -2181,6 +2423,7 @@
return(1);
}
+
free(logfilename);
logging_usrlog = 1;
}
@@ -2199,25 +2442,37 @@
{
if (logging_usrlog)
-{
- /*
- * set stderr to the log file, to catch all fprintf(stderr,...
- * and catch some from gram_k5, and job_manager
- * But if testing gatekeeper, write to stderr instead.
- */
-
- if (!gatekeeper_test) {
- (void) fflush(usrlog_fp);
- (void) dup2(fileno(usrlog_fp),2);
- (void) fclose(usrlog_fp);
+ {
+ /*
+ * set stderr to the log file, to catch all fprintf(stderr,...
+ * and catch some from gram_k5, and job_manager
+ * But if testing gatekeeper, write to stderr instead.
+ */
+
+ if (!gatekeeper_test && usrlog_fp) {
+ int tmpfd = dup(fileno(usrlog_fp)); /* save copy of logfile fd */
+
+ fflush(stderr);
+
+ if (usrlog_fp != stderr)
+ {
+ fclose(usrlog_fp); /* this may still close fd 2! */
+ }
+
+ fclose(stderr);
+
+ dup2(tmpfd, 2); /* reconnect fd 2 to logfile */
+ close(tmpfd);
+
+ *stderr = *fdopen(2, "w"); /* reinitialize stderr */
+ }
+ usrlog_fp = stderr;
+
+ /*
+ * Set output to non-buffered mode
+ */
+ setbuf(stderr, NULL);
}
- usrlog_fp = stderr;
-
- /*
- * Set output to non-buffered mode
- */
- setbuf(stderr, NULL);
-}
return(0);
} /* logging_phase2() */