void svc_request( struct service *sp ) { connection_s *cp ; status_e ret_code; cp = conn_new( sp ) ; if ( cp == CONN_NULL ) return ; /* * Output the banner now that the connection is established. The * other banners come later. */ banner_always(sp, cp); if (SVC_NOT_GENERIC(sp)) ret_code = spec_service_handler(sp, cp); else ret_code = svc_generic_handler(sp, cp); if( (SVC_SOCKET_TYPE( sp ) == SOCK_DGRAM) && (SVC_IS_ACTIVE( sp )) ) drain( cp->co_descriptor ) ; /* Prevents looping next time */ if ( ret_code != OK ) { if ( SVC_LOGS_USERID_ON_FAILURE( sp ) ) { if( spec_service_handler( LOG_SERVICE( ps ), cp ) == FAILED ) conn_free( cp, 1 ) ; else if (!SC_WAITS( SVC_CONF( sp ) ) ) { /* The logging service will gen SIGCHLD thus freeing connection */ CONN_CLOSE(cp) ; } return; } if (!SC_WAITS( SVC_CONF( sp ) )) conn_free( cp, 1 ); else { if( (SVC_SOCKET_TYPE( sp ) == SOCK_DGRAM) && (SVC_IS_ACTIVE( sp )) ) drain( cp->co_descriptor ) ; /* Prevents looping next time */ free( cp ); } } else if ((SVC_NOT_GENERIC(sp)) || (!SC_FORKS( SVC_CONF( sp ) ) ) ) free( cp ); }
void dump_internal_state(void) { int dump_fd ; const char *dump_file = DUMP_FILE ; time_t current_time ; int fd ; unsigned u ; const char *func = "dump_internal_state" ; if ( debug.on ) msg( LOG_DEBUG, func, "Dumping State" ) ; dump_fd = open( dump_file, O_WRONLY | O_CREAT | O_APPEND, DUMP_FILE_MODE); if ( dump_fd == -1 ) { msg( LOG_ERR, func, "failed to open %s: %m", dump_file ) ; return ; } if (Sbuftype( dump_fd, SIO_LINEBUF ) == SIO_ERR ) { /* * If the above function failed, Sprint will most likely * fail, too. Output a message for troubleshooting and quit. */ msg( LOG_ERR, func, "failed setting up sio buffering: %m" ) ; return; } /* * Print the program name, version, and timestamp. * Note that the program_version variable contains the program name. */ (void) time( ¤t_time ) ; Sprint( dump_fd, "INTERNAL STATE DUMP: %s\n", program_version ) ; Sprint( dump_fd, "Current time: %s\n", ctime( ¤t_time ) ) ; dump_services( dump_fd ) ; /* * Dump the server table */ Sprint( dump_fd, "Server table dump:\n" ) ; for ( u = 0 ; u < pset_count( SERVERS( ps ) ) ; u++ ) server_dump( SERP( pset_pointer( SERVERS( ps ), u ) ), dump_fd ) ; Sputchar( dump_fd, '\n' ) ; /* * Dump the retry_table */ Sprint( dump_fd, "Retry table dump:\n" ) ; for ( u = 0 ; u < pset_count( RETRIES( ps ) ) ; u++ ) server_dump( SERP( pset_pointer( RETRIES( ps ), u ) ), dump_fd ) ; Sputchar( dump_fd, '\n' ) ; /* * Dump the socket mask */ Sprint( dump_fd, "Socket mask:" ) ; for ( fd = 0 ; fd < ps.ros.max_descriptors ; fd++ ) if ( FD_ISSET( fd, &ps.rws.socket_mask ) ) Sprint( dump_fd, " %d", fd ) ; Sputchar( dump_fd, '\n' ) ; Sprint( dump_fd, "mask_max = %d\n", ps.rws.mask_max ) ; /* * Dump the descriptors that are open and are *not* in the socket mask */ Sprint( dump_fd, "Open descriptors (not in socket mask):" ) ; for ( fd = 0 ; fd < ps.ros.max_descriptors ; fd++ ) { struct stat st ; if ( FD_ISSET( fd, &ps.rws.socket_mask ) ) continue ; if ( fstat( fd, &st ) == -1 ) continue ; Sprint( dump_fd, " %d", fd ) ; } Sputchar( dump_fd, '\n' ) ; Sputchar( dump_fd, '\n' ) ; Sprint( dump_fd, "active_services = %d\n", ps.rws.active_services ) ; Sprint( dump_fd, "available_services = %d\n", ps.rws.available_services ) ; Sprint( dump_fd, "descriptors_free = %d\n", ps.rws.descriptors_free ) ; Sprint( dump_fd, "running_servers = %d\n", pset_count( SERVERS( ps ) ) ) ; Sprint( dump_fd, "Logging service = %s\n", LOG_SERVICE( ps ) != NULL ? "enabled" : "not enabled" ) ; Sputchar( dump_fd, '\n' ) ; Sprint( dump_fd, "max_descriptors = %d\n", (int)ps.ros.max_descriptors ) ; Sprint( dump_fd, "process_limit = %d\n", (int)ps.ros.process_limit ) ; Sprint( dump_fd, "config_file = %s\n", ps.ros.config_file ) ; if ( debug.on ) Sprint( dump_fd, "debug_fd = %d\n", debug.fd ) ; Sputchar( dump_fd, '\n' ) ; Sprint( dump_fd, "END OF DUMP\n\n" ) ; Sclose( dump_fd ); msg( LOG_INFO, func, "generated state dump in file %s", dump_file ) ; }
int main(int argc, char **argv) { /* * Defs for arg-handling code: handles setting of policy-related variables */ int ch; int dont_fork = 0, use_syslog = 0, kdump_only = 0; int ilo_gen = 0; char *transport = "hpilo:"; int i; int do_ahs = 1; int do_ide = 1; int do_host = 1; int do_nic = 1; int do_scsi = 1; int do_pmp = 0; int do_se = 1; int do_fca = 1; int do_mibII = 1; int scale = 1; char *argarg; int prepared_sockets = 0; struct stat st; struct timeval the_time[2]; init_etime(&the_time[0]); if (stat("/sys/module/hpilo", &st) != 0 ) { printf("hp-ams requires that the hpilo kernel module is loaded"); exit(1); } #ifndef NETSNMP_NO_SYSTEMD /* check if systemd has sockets for us and don't close them */ prepared_sockets = netsnmp_sd_listen_fds(0); #endif /* NETSNMP_NO_SYSTEMD */ /* * close all non-standard file descriptors we may have * inherited from the shell. */ if (!prepared_sockets) { for (i = getdtablesize() - 1; i > 2; --i) { (void) close(i); } } snmp_disable_log(); while ((ch = getopt(argc, argv, "D:fG:kLM::OI:P:t:T::x:V:")) != EOF) switch (ch) { case 'D': debug_register_tokens(optarg); snmp_set_do_debugging(1); break; case 'f': dont_fork = 1; break; case 'k': kdump_only = 1; break; case 'h': usage(); exit(0); break; case 'G': GenericData = optarg; break; case 'I': log_interval = atoi(optarg); if ((log_interval <0) || (log_interval > 3)) { usage(); exit(0); } break; case 'P': interval2ping = atoi(optarg); if (interval2ping <0) { usage(); exit(0); } break; case 'L': use_syslog = 0; /* use stderr */ break; case 'M': argarg = optarg; do_ahs = 0; do_ide = 0; do_nic = 0; do_scsi = 0; do_host = 0; do_pmp = 0; do_se = 0; do_fca = 0; do_mibII = 1; while (argarg != 0) { char * mibnum; int mibitem; do_mibII = 0; mibnum = argarg; argarg = index(mibnum, ','); if (argarg != 0) { *argarg = 0; argarg++; } mibitem = atoi(mibnum); switch (mibitem) { case 0: do_ahs = 1; break; case 1: do_se = 1; break; case 5: do_scsi = 1; break; case 11: do_host = 1; break; case 14: do_ide = 1; break; case 16: do_fca = 1; break; case 18: do_nic = 1; break; case 23: do_pmp = 1; break; case 99: do_mibII = 1; break; default: break; } } break; case 'O': gen8_only = 0; /* allow to run on non supported */ break; case 't': if (optarg != (char *) 0) trap_fire = atoi(optarg); else trap_fire = 1; break; case 'T': if (optarg != (char *) 0) { switch (optarg[strlen(optarg)-1]) { case 'd': case 'D': optarg[strlen(optarg)-1] = (char )0; scale = 60*60*24; break; case 'h': case 'H': optarg[strlen(optarg)-1] = (char )0; scale = 60*60; break; case 'm': case 'M': optarg[strlen(optarg)-1] = (char )0; scale = 60; break; case 'S': case 's': optarg[strlen(optarg)-1] = (char )0; default: break; } testtrap_interval = atoi(optarg) * scale; if ((testtrap_interval < 10) || (testtrap_interval > (7*24*60*60))) { usage(); exit(0); } } break; case 'x': if (optarg != NULL) { transport = optarg; } else { usage(); } break; case 'V': if (optarg != NULL) { vendor_tag = optarg; } else { usage(); } break; default: fprintf(stderr, "unknown option %c\n", ch); usage(); exit(1); } /* if the -k option was provided, then also set the dont_fork flag. */ if (kdump_only) { dont_fork = 1; } if (dont_fork) { snmp_enable_stderrlog(); } netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, transport); /* * make us a agentx client. */ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); if (InitSMBIOS() == 0 ) { if (gen8_only == 0) { fprintf(stderr,"SM BIOS initialization failed," " some functionality may not exist\n"); } else { fprintf(stderr,"SM BIOS initialization failed," " unable to determine system type\n"); exit(1); } } else { ilo_gen = GetiLOGen(); if ((gen8_only) && (ilo_gen < 4)) { fprintf(stderr,"This program requires the host to have a HP Integrated Lights Out 4 (iLO 4)" " BMC\n"); exit(1); } } /* * daemonize */ snmp_disable_log(); if (!dont_fork) { snmp_enable_calllog(); int rc = netsnmp_daemonize(1, use_syslog); if (rc) exit(-1); } else snmp_enable_stderrlog(); /* Clear out Status array */ memset(cpqHostMibStatusArray,0,sizeof(cpqHostMibStatusArray)); memset(cpqHoMibHealthStatusArray, 0, sizeof(cpqHoMibHealthStatusArray)); DEBUGMSG(("amsHelper:timer", "interval for StartUp %dms\n", get_etime(&the_time[0]))); if (do_ahs) { LOG_PROCESS_CRASHES(); DEBUGMSG(("amsHelper:timer", "interval for Log Crashes %dms\n", get_etime(&the_time[0]))); if (kdump_only) { return 0; } LOG_OS_BOOT(); DEBUGMSG(("amsHelper:timer", "interval for Log Boot %dms\n", get_etime(&the_time[0]))); } openlog("hp-ams", LOG_CONS | LOG_PID, LOG_DAEMON); /* * initialize the agent library */ init_agent("amsHelper"); netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_HPILODOMAIN_IML, 4); netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_TIMEOUT, 120 * ONE_SEC); /* set ping inetrval to interval2pimn - default is 0 */ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, interval2ping); /* sometime iLO4 can be slow so double the default to 2 sec if necessary*/ netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_TIMEOUT, 3); /* if the ilo starts dropping packets retry a couple of times */ netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_RETRIES, 5); init_snmp("amsHelper"); DEBUGMSG(("amsHelper:timer", "interval for SNMP startup %dms\n", get_etime(&the_time[0]))); if (do_mibII) { init_mib_modules(); DEBUGMSG(("amsHelper:timer", "interval for init MIB-2 %dms\n", get_etime(&the_time[0]))); } if (do_host) { init_cpqHost(); DEBUGMSG(("amsHelper:timer", "interval for cpqHost %dms\n", get_etime(&the_time[0]))); } if (do_ahs) { LOG_OS_INFORMATION(); DEBUGMSG(("amsHelper:timer", "interval for LOG OS %dms\n", get_etime(&the_time[0]))); LOG_DRIVERS(); DEBUGMSG(("amsHelper:timer", "interval for Log drivers %dms\n", get_etime(&the_time[0]))); LOG_SERVICE(); DEBUGMSG(("amsHelper:timer", "interval for Log services %dms\n", get_etime(&the_time[0]))); LOG_PACKAGE(); DEBUGMSG(("amsHelper:timer", "interval for Log packages %dms\n", get_etime(&the_time[0]))); } if (do_se) { init_cpqStdPciTable(); DEBUGMSG(("amsHelper:timer", "interval for cpqSe %dms\n", get_etime(&the_time[0]))); } if (do_scsi) { init_cpqScsi(); DEBUGMSG(("amsHelper:timer", "interval for cpqScsi %dms\n", get_etime(&the_time[0]))); } if (do_ide) { init_cpqIde(); DEBUGMSG(("amsHelper:timer", "interval for cpqIde %dms\n", get_etime(&the_time[0]))); } if (do_fca) { init_cpqFibreArray(); DEBUGMSG(("amsHelper:timer", "interval for cpqFca %dms\n", get_etime(&the_time[0]))); } if (do_nic) { init_cpqNic(); DEBUGMSG(("amsHelper:timer", "interval for cpqNic %dms\n", get_etime(&the_time[0]))); } if (do_pmp) { init_cpqLinOsMgmt(); DEBUGMSG(("amsHelper:timer", "interval for cpqLinOsMgmt %dms\n", get_etime(&the_time[0]))); } /* * Send coldstart trap if possible. */ send_easy_trap(0, 0); syslog(LOG_NOTICE, "amsHelper Started . . "); /* * Let systemd know we're up. */ #ifndef NETSNMP_NO_SYSTEMD netsnmp_sd_notify(1, "READY=1\n"); if (prepared_sockets) /* * Clear the environment variable, we already processed all the sockets * by now. */ netsnmp_sd_listen_fds(1); #endif if (do_ahs) { LOG_OS_USAGE(); DEBUGMSG(("amsHelper:timer", "interval for LOG OS Usage%dms\n", get_etime(&the_time[0]))); LOG_PROCESSOR_USAGE(); DEBUGMSG(("amsHelper:timer", "interval for LOG Processor Usage %dms\n", get_etime(&the_time[0]))); LOG_MEMORY_USAGE(); DEBUGMSG(("amsHelper:timer", "interval for LOG Memory Usage %dms\n", get_etime(&the_time[0]))); } /* * In case we recevie a request to stop (kill -TERM or kill -INT) */ ams_running = 1; signal(SIGTERM, stop_server); signal(SIGINT, stop_server); DEBUGMSGTL(("snmpd/main", "We're up. Starting to process data.\n")); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) receive(); snmp_shutdown("amsHelper"); LOG_OS_SHUTDOWN(); syslog(LOG_NOTICE, "amsHelper Stopped . . "); exit(0); }