int init_trqauth_log(const char *server_port) { const char *path_home = PBS_SERVER_HOME; int eventclass = PBS_EVENTCLASS_TRQAUTHD; char path_log[MAXPATHLEN + 1]; char *log_file=NULL; char error_buf[MAX_BUF]; int rc; rc = log_init(NULL, NULL); if (rc != PBSE_NONE) return(rc); log_get_set_eventclass(&eventclass, SETV); initialize_globals_for_log(server_port); sprintf(path_log, "%s/%s", path_home, TRQ_LOGFILES); if ((mkdir(path_log, 0755) == -1) && (errno != EEXIST)) { openlog("daemonize_trqauthd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); syslog(LOG_ALERT, "Failed to create client_logs directory: %s errno: %d error message: %s", path_log, errno, strerror(errno)); sprintf(error_buf,"Failed to create client_logs directory: %s, error message: %s",path_log,strerror(errno)); log_err(errno,__func__,error_buf); closelog(); return(PBSE_SYSTEM); } pthread_mutex_lock(&log_mutex); rc = log_open(log_file, path_log); pthread_mutex_unlock(&log_mutex); return(rc); }
void log_record( int eventtype, /* I */ int objclass, /* I */ const char *objname, /* I */ const char *text) /* I */ { int tryagain = 2; time_t now; pid_t thr_id = -1; struct tm *ptm; struct tm tmpPtm; struct timeval mytime; int rc = 0; FILE *savlog; char *start = NULL, *end = NULL; size_t nchars; int eventclass = 0; char time_formatted_str[64]; thr_id = syscall(SYS_gettid); pthread_mutex_lock(&log_mutex); #if SYSLOG if (eventtype & PBSEVENT_SYSLOG) { if (syslogopen == 0) { openlog(msg_daemonname, LOG_NOWAIT, LOG_DAEMON); syslogopen = 1; } syslog(LOG_ERR | LOG_DAEMON,"%s",text); } #endif /* SYSLOG */ if (log_opened < 1) { pthread_mutex_unlock(&log_mutex); return; } now = time((time_t *)0); /* get time for message */ ptm = localtime_r(&now,&tmpPtm); /* mytime used to calculate milliseconds */ gettimeofday(&mytime, NULL); int milliseconds = mytime.tv_usec/1000; /* Do we need to switch the log? */ if (log_auto_switch && (ptm->tm_yday != log_open_day)) { log_close(1); log_open(NULL, log_directory); if (log_opened < 1) { pthread_mutex_unlock(&log_mutex); return; } } time_formatted_str[0] = 0; log_get_set_eventclass(&eventclass, GETV); if (eventclass == PBS_EVENTCLASS_TRQAUTHD) { log_format_trq_timestamp(time_formatted_str, sizeof(time_formatted_str)); } /* * Looking for the newline characters and splitting the output message * on them. Sequence "\r\n" is mapped to the single newline. */ start = (char *)text; while (1) { for (end = start; *end != '\n' && *end != '\r' && *end != '\0'; end++) ; nchars = end - start; if (*end == '\r' && *(end + 1) == '\n') end++; while (tryagain) { if (eventclass != PBS_EVENTCLASS_TRQAUTHD) { rc = fprintf(logfile, "%02d/%02d/%04d %02d:%02d:%02d.%03d;%02d;%10.10s.%d;%s;%s;%s%.*s\n", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_year + 1900, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, milliseconds, (eventtype & ~PBSEVENT_FORCE), msg_daemonname, thr_id, class_names[objclass], objname, (text == start ? "" : "[continued]"), (int)nchars, start); } else { rc = fprintf(logfile, "%s %s%.*s\n", time_formatted_str, (text == start ? "" : "[continued]"), (int)nchars, start); } if ((rc < 0) && (errno == EPIPE) && (tryagain == 2)) { /* the log file descriptor has been changed--it now points to a socket! * reopen log and leave the previous file descriptor alone--do not close it */ log_opened = 0; log_open(NULL, log_directory); tryagain--; } else { tryagain = 0; } } if (rc < 0) break; if (*end == '\0') break; start = end + 1; } /* END while (1) */ fflush(logfile); if (rc < 0) { rc = errno; clearerr(logfile); savlog = logfile; logfile = fopen("/dev/console", "w"); /* we need to add this check to make sure the disk isn't full so we don't segfault * if we can't open this then we're going to have a nice surprise failure */ if (logfile != NULL) { pthread_mutex_unlock(&log_mutex); log_err(rc, __func__, "PBS cannot write to its log"); fclose(logfile); pthread_mutex_lock(&log_mutex); } logfile = savlog; } pthread_mutex_unlock(&log_mutex); return; } /* END log_record() */
/* Note, in extremely high load cases, the alloc value in /proc/net/sockstat can exceed the max value. This will substantially slow down throughput and generate connection failures (accept gets a EMFILE error). As the client is designed to run on each submit host, that issue shouldn't occur. The client must be restarted to clear out this issue. */ int start_listener( const char *server_ip, int server_port, void *(*process_meth)(void *)) { struct sockaddr_in adr_svr; struct sockaddr_in adr_client; int rc = PBSE_NONE; int sockoptval = 1; int len_inet = sizeof(struct sockaddr_in); int *new_conn_port = NULL; int listen_socket = 0; int total_cntr = 0; pthread_t tid; pthread_attr_t t_attr; int objclass = 0; char msg_started[1024]; memset(&adr_svr, 0, sizeof(adr_svr)); adr_svr.sin_family = AF_INET; if (!(adr_svr.sin_port = htons(server_port))) { } else if ((adr_svr.sin_addr.s_addr = inet_addr(server_ip)) == INADDR_NONE) { rc = PBSE_SOCKET_FAULT; } else if ((listen_socket = socket_get_tcp()) < 0) { /* Can not get socket for listening */ rc = PBSE_SOCKET_FAULT; } else if (bind(listen_socket, (struct sockaddr *)&adr_svr, sizeof(struct sockaddr_in)) == -1) { /* Can not bind local socket */ rc = PBSE_SOCKET_FAULT; } else if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&sockoptval, sizeof(sockoptval)) == -1) { rc = PBSE_SOCKET_FAULT; } else if (listen(listen_socket, 128) == -1) { /* Can not listener on local socket */ rc = PBSE_SOCKET_LISTEN; } else if ((rc = pthread_attr_init(&t_attr)) != 0) { /* Can not init thread attribute structure */ rc = PBSE_THREADATTR; } else if ((rc = pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED)) != 0) { /* Can not set thread initial state as detached */ pthread_attr_destroy(&t_attr); } else { log_get_set_eventclass(&objclass, GETV); if (objclass == PBS_EVENTCLASS_TRQAUTHD) { snprintf(msg_started, sizeof(msg_started), "TORQUE authd daemon started and listening on IP:port %s:%d", server_ip, server_port); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, msg_daemonname, msg_started); } while (1) { if ((new_conn_port = (int *)calloc(1, sizeof(int))) == NULL) { printf("Error allocating new connection handle on accept.\n"); break; } if ((*new_conn_port = accept(listen_socket, (struct sockaddr *)&adr_client, (socklen_t *)&len_inet)) == -1) { if (errno == EMFILE) { sleep(1); printf("Temporary pause\n"); } else { printf("error in accept %s\n", strerror(errno)); break; } errno = 0; free(new_conn_port); new_conn_port = NULL; } else { if (debug_mode == TRUE) { process_meth((void *)new_conn_port); } else { pthread_create(&tid, &t_attr, process_meth, (void *)new_conn_port); } } if (debug_mode == TRUE) { if (total_cntr % 1000 == 0) { printf("Total requests: %d\n", total_cntr); } total_cntr++; } } if (new_conn_port != NULL) { free(new_conn_port); } pthread_attr_destroy(&t_attr); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, "net_srvr", "Socket close of network listener requested"); } if (listen_socket != -1) close(listen_socket); return(rc); } /* END start_listener() */
/* start_domainsocket_listener * Starts a listen thread on a UNIX domain socket connection */ int start_domainsocket_listener( const char *socket_name, void *(*process_meth)(void *)) { struct sockaddr_un addr; int rc = PBSE_NONE; char log_buf[LOCAL_LOG_BUF_SIZE]; int *new_conn_port = NULL; int listen_socket = 0; int total_cntr = 0; pthread_t tid; pthread_attr_t t_attr; int objclass = 0; char authd_host_port[1024]; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path)-1); /* socket_name is a file in the file system. It must be gone before we can bind to it. Unlink it */ unlink(socket_name); /* Ignore SIGPIPE so a rougue client won't cause us to abort */ signal(SIGPIPE, SIG_IGN); if ( (listen_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { snprintf(log_buf, sizeof(log_buf), "socket failed: %d %s", errno, strerror(errno)); log_event(PBSEVENT_ADMIN | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, __func__, log_buf); rc = PBSE_SOCKET_FAULT; } else if ( bind(listen_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { snprintf(log_buf, sizeof(log_buf), "failed to bind socket %s: %d %s", socket_name, errno, strerror(errno)); log_event(PBSEVENT_ADMIN | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, __func__, log_buf); rc = PBSE_SOCKET_FAULT; } else if (chmod(socket_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) < 0) { snprintf(log_buf, sizeof(log_buf), "failed to change file permissions on %s: %d %s", socket_name, errno, strerror(errno)); log_event(PBSEVENT_ADMIN | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, __func__, log_buf); rc = PBSE_SOCKET_FAULT; } else if ( listen(listen_socket, 64) < 0) { snprintf(log_buf, sizeof(log_buf), "listen failed %s: %d %s", socket_name, errno, strerror(errno)); log_event(PBSEVENT_ADMIN | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, __func__, log_buf); rc = PBSE_SOCKET_LISTEN; } else if ((rc = pthread_attr_init(&t_attr)) != 0) { /* Can not init thread attribute structure */ rc = PBSE_THREADATTR; } else if ((rc = pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED)) != 0) { /* Can not set thread initial state as detached */ pthread_attr_destroy(&t_attr); } else { log_get_set_eventclass(&objclass, GETV); if (objclass == PBS_EVENTCLASS_TRQAUTHD) { log_get_host_port(authd_host_port, sizeof(authd_host_port)); if (authd_host_port[0]) snprintf(log_buf, sizeof(log_buf), "TORQUE authd daemon started and listening on %s (unix socket %s)", authd_host_port, socket_name); else snprintf(log_buf, sizeof(log_buf), "TORQUE authd daemon started and listening unix socket %s", socket_name); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, msg_daemonname, log_buf); } while (trqauthd_up == true) { if((new_conn_port = (int *)calloc(1, sizeof(int))) == NULL) { printf("Error allocating new connection handle on accept.\n"); break; } if ((*new_conn_port = accept(listen_socket, NULL, NULL)) == -1) { if (errno == EMFILE) { sleep(1); printf("Temporary pause\n"); } else { printf("error in accept %s\n", strerror(errno)); break; } errno = 0; free(new_conn_port); new_conn_port = NULL; } else { if (debug_mode == TRUE) { process_meth((void *)new_conn_port); } else { pthread_create(&tid, &t_attr, process_meth, (void *)new_conn_port); } } if (debug_mode == TRUE) { if (total_cntr % 1000 == 0) { printf("Total requests: %d\n", total_cntr); } total_cntr++; } } /* Do not free the new_conn_port here. It will be freed in process_svr_conn */ pthread_attr_destroy(&t_attr); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, "net_srvr", "Socket close of network listener requested"); } if (listen_socket != -1) close(listen_socket); unlink(socket_name); log_close(1); return(rc); } /* END start_domainsocket_listener() */
int daemonize_trqauthd(const char *server_ip, int server_port, void *(*process_meth)(void *)) { int gid; pid_t pid; int rc; char error_buf[MAX_BUF]; char msg_trqauthddown[MAX_BUF]; char path_log[MAXPATHLEN + 1]; char unix_socket_name[MAXPATHLEN + 1]; char *log_file=NULL; int eventclass = PBS_EVENTCLASS_TRQAUTHD; const char *path_home = PBS_SERVER_HOME; umask(022); gid = getgid(); /* secure supplemental groups */ if(setgroups(1, (gid_t *)&gid) != 0) { fprintf(stderr, "Unable to drop secondary groups. Some MAC framework is active?\n"); snprintf(error_buf, sizeof(error_buf), "setgroups(group = %lu) failed: %s\n", (unsigned long)gid, strerror(errno)); fprintf(stderr, "%s\n", error_buf); return(1); } if (getenv("PBSDEBUG") != NULL) debug_mode = TRUE; if (debug_mode == FALSE) { pid = fork(); if(pid > 0) { /* parent. We are done */ return(0); } else if (pid < 0) { /* something went wrong */ fprintf(stderr, "fork failed. errno = %d\n", errno); return(PBSE_RMSYSTEM); } else { fprintf(stderr, "trqauthd daemonized - port %d\n", server_port); /* If I made it here I am the child */ fclose(stdin); fclose(stdout); fclose(stderr); /* We closed 0 (stdin), 1 (stdout), and 2 (stderr). fopen should give us 0, 1 and 2 in that order. this is a UNIX practice */ if (fopen("/dev/null", "r") == NULL) perror(__func__); if (fopen("/dev/null", "r") == NULL) perror(__func__); if (fopen("/dev/null", "r") == NULL) perror(__func__); } } else { fprintf(stderr, "trqauthd port: %d\n", server_port); } log_init(NULL, NULL); log_get_set_eventclass(&eventclass, SETV); initialize_globals_for_log(server_port); sprintf(path_log, "%s/%s", path_home, TRQ_LOGFILES); if ((mkdir(path_log, 0755) == -1) && (errno != EEXIST)) { openlog("daemonize_trqauthd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); syslog(LOG_ALERT, "Failed to create client_logs directory: errno: %d", errno); log_err(errno,"daemonize_trqauthd", "Failed to create client_logs directory"); closelog(); } pthread_mutex_lock(log_mutex); log_open(log_file, path_log); pthread_mutex_unlock(log_mutex); /* start the listener */ snprintf(unix_socket_name, sizeof(unix_socket_name), "%s/%s", TRQAUTHD_SOCK_DIR, TRQAUTHD_SOCK_NAME); rc = start_domainsocket_listener(unix_socket_name, process_meth); if(rc != PBSE_NONE) { openlog("daemonize_trqauthd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); syslog(LOG_ALERT, "trqauthd could not start: %d\n", rc); log_err(rc, "daemonize_trqauthd", (char *)"trqauthd could not start"); pthread_mutex_lock(log_mutex); log_close(1); pthread_mutex_unlock(log_mutex); if (changed_msg_daem && msg_daemonname) { free(msg_daemonname); } clean_log_init_mutex(); exit(-1); } snprintf(msg_trqauthddown, sizeof(msg_trqauthddown), "TORQUE authd daemon shut down and no longer listening on IP:port %s:%d", server_ip, server_port); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, msg_daemonname, msg_trqauthddown); pthread_mutex_lock(log_mutex); log_close(1); pthread_mutex_unlock(log_mutex); if (changed_msg_daem && msg_daemonname) { free(msg_daemonname); } clean_log_init_mutex(); exit(0); }