/** * Sets up signal handlers */ void seas_sighandler(int signo) { struct as_entry *as; if(is_dispatcher) sig_flag=signo; switch(signo){ case SIGPIPE: if(is_dispatcher) return; LM_INFO("%s exiting\n",whoami); if(my_as->u.as.ac_buffer.s){ pkg_free(my_as->u.as.ac_buffer.s); my_as->u.as.ac_buffer.s=0; } if(my_as->u.as.action_fd!=-1){ close(my_as->u.as.action_fd); my_as->u.as.action_fd=-1; } exit(0); break; case SIGCHLD: LM_INFO("Child stopped or terminated\n"); break; case SIGUSR1: case SIGUSR2: LM_DBG("Memory status (pkg):\n"); #ifdef PKG_MALLOC pkg_status(); #endif break; case SIGINT: case SIGTERM: LM_INFO("INFO: signal %d received\n",signo); #ifdef PKG_MALLOC pkg_status(); #endif if(is_dispatcher){ for (as=as_list;as;as=as->next) { if(as->type==AS_TYPE && as->connected) kill(as->u.as.action_pid,signo); } while(wait(0) > 0); exit(0); }else{ LM_INFO("%s exiting\n",whoami); if(my_as && my_as->u.as.ac_buffer.s) pkg_free(my_as->u.as.ac_buffer.s); if(my_as && my_as->u.as.action_fd!=-1) close(my_as->u.as.action_fd); exit(0); } break; } }
/** * Exit regulary on a specific signal. * This is good for profiling which only works if exited regularly * and not by default signal handlers * \param signo The signal that should be handled */ static void sig_usr(int signo) { int status; pid_t pid; UNUSED(pid); if (is_main){ if (sig_flag==0) sig_flag=signo; else /* previous sig. not processed yet, ignoring? */ return; ; if (dont_fork) /* only one proc, doing everything from the sig handler, unsafe, but this is only for debugging mode*/ handle_sigs(); }else{ /* process the important signals */ switch(signo){ case SIGPIPE: LM_INFO("signal %d received\n", signo); break; case SIGINT: case SIGTERM: LM_INFO("signal %d received\n", signo); /* print memory stats for non-main too */ #ifdef PKG_MALLOC LM_GEN1(memdump, "Memory status (pkg):\n"); pkg_status(); #endif exit(0); break; case SIGUSR1: /* statistics -> show only pkg mem */ #ifdef PKG_MALLOC LM_GEN1(memdump, "Memory status (pkg):\n"); pkg_status(); #endif break; case SIGUSR2: #ifdef PKG_MALLOC set_pkg_stats( get_pkg_status_holder(process_no) ); #endif break; case SIGHUP: /* ignored*/ break; case SIGCHLD: pid = waitpid(-1, &status, WNOHANG); LM_DBG("SIGCHLD received from %ld (status=%d), ignoring\n", (long)pid,status); } } }
/* Dumps pkg memory status. * Per-child process callback that is called * when mem_dump_pkg cfg var is changed. */ void mem_dump_pkg_cb(str *gname, str *name) { int old_memlog; int memlog; if (cfg_get(core, core_cfg, mem_dump_pkg) == my_pid()) { /* set memlog to ALERT level to force printing the log messages */ old_memlog = cfg_get(core, core_cfg, memlog); memlog = L_ALERT; /* ugly hack to temporarily switch memlog to something visible, * possible race with a parallel cfg_set */ ((struct cfg_group_core*)core_cfg)->memlog=memlog; if (cfg_get(core, core_cfg, mem_summary) & 1) { LOG(memlog, "Memory status (pkg) of process %d:\n", my_pid()); pkg_status(); } if (cfg_get(core, core_cfg, mem_summary) & 4) { LOG(memlog, "Memory still-in-use summary (pkg) of process %d:\n", my_pid()); pkg_sums(); } ((struct cfg_group_core*)core_cfg)->memlog=old_memlog; } }
/** initialized the pkg and shm memory */ int init_memory(int show_status) { #ifdef PKG_MALLOC if (init_pkg_mallocs()==-1) goto error; if (show_status){ LOG(memlog, "Memory status (pkg):\n"); pkg_status(); } #endif #ifdef SHM_MEM if (init_shm_mallocs( #ifdef SER_MOD_INTERFACE 1 #endif )==-1) goto error; if (show_status){ LOG(memlog, "Memory status (shm):\n"); shm_status(); } #endif return 1; error: return 0; }
/** * Clean up on exit. This should be called before exiting. * \param show_status set to one to display the mem status */ void cleanup(int show_status) { LM_INFO("cleanup\n"); /*clean-up*/ /* hack: force-unlock the shared memory lock in case some process crashed and let it locked; this will allow an almost gracious shutdown */ if (mem_lock) #ifdef HP_MALLOC { int i; for (i = 0; i < HP_HASH_SIZE; i++) shm_unlock(i); } #else shm_unlock(); #endif handle_ql_shutdown(); destroy_modules(); #ifdef USE_TCP destroy_tcp(); #endif #ifdef USE_TLS destroy_tls(); #endif destroy_timer(); destroy_stats_collector(); destroy_script_cb(); pv_free_extra_list(); destroy_argv_list(); destroy_black_lists(); #ifdef PKG_MALLOC if (show_status){ LM_GEN1(memdump, "Memory status (pkg):\n"); pkg_status(); } #endif #ifdef SHM_MEM cleanup_debug(); if (pt) shm_free(pt); pt=0; if (show_status){ LM_GEN1(memdump, "Memory status (shm):\n"); shm_status(); } /* zero all shmem alloc vars that we still use */ shm_mem_destroy(); #endif if (pid_file) unlink(pid_file); if (pgid_file) unlink(pgid_file); }
/** * Exit regulary on a specific signal. * This is good for profiling which only works if exited regularly * and not by default signal handlers * \param signo The signal that should be handled */ static void sig_usr(int signo) { if (is_main){ if (sig_flag==0) sig_flag=signo; else /* previous sig. not processed yet, ignoring? */ return; ; if (dont_fork) /* only one proc, doing everything from the sig handler, unsafe, but this is only for debugging mode*/ handle_sigs(); }else{ /* process the important signals */ switch(signo){ case SIGPIPE: LM_INFO("signal %d received\n", signo); break; case SIGINT: case SIGTERM: LM_INFO("signal %d received\n", signo); /* print memory stats for non-main too */ #ifdef PKG_MALLOC LOG(memlog, "Memory status (pkg):\n"); pkg_status(); #endif exit(0); break; case SIGUSR1: /* statistics -> show only pkg mem */ #ifdef PKG_MALLOC LOG(memlog, "Memory status (pkg):\n"); pkg_status(); #endif break; /* ignored*/ case SIGUSR2: case SIGHUP: break; case SIGCHLD: LM_DBG("SIGCHLD received: " "we do not worry about grand-children\n"); } } }
/** * Clean up on exit. This should be called before exiting. * \param show_status set to one to display the mem status */ void cleanup(int show_status) { LM_INFO("cleanup\n"); /*clean-up*/ if (mem_lock) shm_unlock(); /* hack: force-unlock the shared memory lock in case some process crashed and let it locked; this will allow an almost gracious shutdown */ handle_ql_shutdown(); destroy_modules(); #ifdef USE_TCP destroy_tcp(); #endif #ifdef USE_TLS destroy_tls(); #endif destroy_timer(); destroy_stats_collector(); destroy_script_cb(); pv_free_extra_list(); destroy_argv_list(); destroy_black_lists(); #ifdef CHANGEABLE_DEBUG_LEVEL if (debug!=&debug_init) { reset_proc_debug_level(); debug_init = *debug; shm_free(debug); debug = &debug_init; } #endif #ifdef PKG_MALLOC if (show_status){ LM_GEN1(memdump, "Memory status (pkg):\n"); pkg_status(); } #endif #ifdef SHM_MEM if (pt) shm_free(pt); pt=0; if (show_status){ LM_GEN1(memdump, "Memory status (shm):\n"); shm_status(); } /* zero all shmem alloc vars that we still use */ shm_mem_destroy(); #endif if (pid_file) unlink(pid_file); if (pgid_file) unlink(pgid_file); }
/* call it before exiting; if show_status==1, mem status is displayed */ void cleanup(show_status) { /*clean-up*/ if (mem_lock) shm_unlock(); /* hack: force-unlock the shared memory lock in case some process crashed and let it locked; this will allow an almost gracious shutdown */ destroy_modules(); #ifdef USE_TCP destroy_tcp(); #endif #ifdef USE_TLS destroy_tls(); #endif destroy_timer(); close_unixsock_server(); destroy_fifo(); destroy_script_cb(); #ifdef PKG_MALLOC if (show_status){ LOG(memlog, "Memory status (pkg):\n"); pkg_status(); } #endif #ifdef SHM_MEM if (pt) shm_free(pt); pt=0; if (show_status){ LOG(memlog, "Memory status (shm):\n"); shm_status(); } /* zero all shmem alloc vars that we still use */ shm_mem_destroy(); #endif if (pid_file) unlink(pid_file); if (pgid_file) unlink(pgid_file); }
static int dbg_pkg_status(struct sip_msg* msg, char* foo, char* bar) { pkg_status(); return 1; }
/** * Signal handler for the server. */ void handle_sigs(void) { pid_t chld; int chld_status; int i; int do_exit; const unsigned int shutdown_time = 60; /* one minute close timeout */ switch(sig_flag){ case 0: break; /* do nothing*/ case SIGPIPE: /* SIGPIPE might be rarely received on use of exec module; simply ignore it */ LM_WARN("SIGPIPE received and ignored\n"); break; case SIGINT: case SIGTERM: /* we end the program in all these cases */ if (sig_flag==SIGINT) LM_DBG("INT received, program terminates\n"); else LM_DBG("SIGTERM received, program terminates\n"); /* first of all, kill the children also */ kill_all_children(SIGTERM); if (signal(SIGALRM, sig_alarm_kill) == SIG_ERR ) { LM_ERR("could not install SIGALARM handler\n"); /* continue, the process will die anyway if no * alarm is installed which is exactly what we want */ } alarm(shutdown_time); while(wait(0) > 0); /* Wait for all the children to terminate */ signal(SIGALRM, sig_alarm_abort); cleanup(1); /* cleanup & show status*/ alarm(0); signal(SIGALRM, SIG_IGN); dprint("Thank you for flying " NAME "\n"); exit(0); break; case SIGUSR1: #ifdef PKG_MALLOC LM_GEN1(memdump, "Memory status (pkg):\n"); pkg_status(); #endif #ifdef SHM_MEM LM_GEN1(memdump, "Memory status (shm):\n"); shm_status(); #endif break; case SIGUSR2: #ifdef PKG_MALLOC set_pkg_stats( get_pkg_status_holder(process_no) ); #endif break; case SIGCHLD: do_exit = 0; while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) { /* is it a process we know about? */ for( i=0 ; i<counted_processes ; i++ ) if (pt[i].pid==chld) break; if (i==counted_processes) { LM_DBG("unkown child process %d ended. Ignoring\n",chld); continue; } do_exit = 1; /* process the signal */ if (WIFEXITED(chld_status)) LM_INFO("child process %d exited normally," " status=%d\n", chld, WEXITSTATUS(chld_status)); else if (WIFSIGNALED(chld_status)) { LM_INFO("child process %d exited by a signal" " %d\n", chld, WTERMSIG(chld_status)); #ifdef WCOREDUMP LM_INFO("core was %sgenerated\n", WCOREDUMP(chld_status) ? "" : "not " ); #endif }else if (WIFSTOPPED(chld_status)) LM_INFO("child process %d stopped by a" " signal %d\n", chld, WSTOPSIG(chld_status)); } if (!do_exit) break; LM_INFO("terminating due to SIGCHLD\n"); /* exit */ kill_all_children(SIGTERM); if (signal(SIGALRM, sig_alarm_kill) == SIG_ERR ) { LM_ERR("could not install SIGALARM handler\n"); /* continue, the process will die anyway if no * alarm is installed which is exactly what we want */ } alarm(shutdown_time); while(wait(0) > 0); /* wait for all the children to terminate*/ signal(SIGALRM, sig_alarm_abort); cleanup(1); /* cleanup & show status*/ alarm(0); signal(SIGALRM, SIG_IGN); LM_DBG("terminating due to SIGCHLD\n"); exit(0); break; case SIGHUP: /* ignoring it*/ LM_DBG("SIGHUP received, ignoring it\n"); break; default: LM_CRIT("unhandled signal %d\n", sig_flag); } sig_flag=0; }
void handle_sigs() { pid_t chld; int chld_status; switch(sig_flag){ case 0: break; /* do nothing*/ case SIGPIPE: /* SIGPIPE might be rarely received on use of exec module; simply ignore it */ LOG(L_WARN, "WARNING: SIGPIPE received and ignored\n"); break; case SIGINT: case SIGTERM: /* we end the program in all these cases */ if (sig_flag==SIGINT) DBG("INT received, program terminates\n"); else DBG("SIGTERM received, program terminates\n"); /* first of all, kill the children also */ kill_all_children(SIGTERM); /* Wait for all the children to die */ while(wait(0) > 0); cleanup(1); /* cleanup & show status*/ dprint("Thank you for flying " NAME "\n"); exit(0); break; case SIGUSR1: #ifdef STATS dump_all_statistic(); #endif #ifdef PKG_MALLOC LOG(memlog, "Memory status (pkg):\n"); pkg_status(); #endif #ifdef SHM_MEM LOG(memlog, "Memory status (shm):\n"); shm_status(); #endif break; case SIGCHLD: while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) { if (WIFEXITED(chld_status)) LOG(L_INFO, "child process %d exited normally," " status=%d\n", chld, WEXITSTATUS(chld_status)); else if (WIFSIGNALED(chld_status)) { LOG(L_INFO, "child process %d exited by a signal" " %d\n", chld, WTERMSIG(chld_status)); #ifdef WCOREDUMP LOG(L_INFO, "core was %sgenerated\n", WCOREDUMP(chld_status) ? "" : "not " ); #endif }else if (WIFSTOPPED(chld_status)) LOG(L_INFO, "child process %d stopped by a" " signal %d\n", chld, WSTOPSIG(chld_status)); } #ifndef STOP_JIRIS_CHANGES if (dont_fork) { LOG(L_INFO, "INFO: dont_fork turned on, living on\n"); break; } LOG(L_INFO, "INFO: terminating due to SIGCHLD\n"); #endif /* exit */ kill_all_children(SIGTERM); if (set_sig_h(SIGALRM, sig_alarm_kill) == SIG_ERR ) { LOG(L_ERR, "ERROR: could not install SIGALARM handler\n"); /* continue, the process will die anyway if no * alarm is installed which is exactly what we want */ } alarm(60); /* 1 minute close timeout */ while(wait(0) > 0); /* wait for all the children to terminate*/ set_sig_h(SIGALRM, sig_alarm_abort); cleanup(1); /* cleanup & show status*/ alarm(0); set_sig_h(SIGALRM, SIG_IGN); DBG("terminating due to SIGCHLD\n"); exit(0); break; case SIGHUP: /* ignoring it*/ DBG("SIGHUP received, ignoring it\n"); break; default: LOG(L_CRIT, "WARNING: unhandled signal %d\n", sig_flag); } sig_flag=0; }
static int ki_pkg_status(sip_msg_t* msg) { pkg_status(); return 1; }
/* --------------------------------------------------------------------- */ int netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags) { DIR *d; struct dirent *dp; struct stat stat_buf; #ifdef HAVE_PKGINFO char *v, *c; #endif char buf[ BUFSIZ ]; unsigned char *cp; time_t install_time; size_t date_len; int i = 1; netsnmp_swinst_entry *entry; #ifdef HAVE_LIBPKG struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; char pkgname[ SNMP_MAXPATH ]; char pkgdate[ BUFSIZ ]; int pkgng = 0; if (pkg_init(NULL, NULL)) { snmp_log( LOG_ERR, "SWInst: error initializing pkgng db\n" ); return 1; } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { snmp_log( LOG_ERR, "SWInst: error opening pkgng db\n" ); return 1; } if (pkg_status(NULL) == PKG_STATUS_ACTIVE) { pkgng = 1; } else { snmp_log( LOG_INFO, "SWInst: not a pkgng system\n" ); } /* if we are using FreeBSD's pkgng */ if (pkgng) { if ((it = pkgdb_query(db, NULL, MATCH_ALL)) == NULL) { snmp_log( LOG_ERR, "SWInst: error querying pkgng db\n" ); return 1; } while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) { pkg_snprintf(pkgname, sizeof(pkgname), "%n-%v", pkg, pkg); pkg_snprintf(pkgdate, sizeof(pkgdate), "%t", pkg); entry = netsnmp_swinst_entry_create( i++ ); if (NULL == entry) continue; /* error already logged by function */ CONTAINER_INSERT(container, entry); entry->swName_len = snprintf( entry->swName, sizeof(entry->swName), "%s", pkgname ); if (entry->swName_len >= sizeof(entry->swName)) entry->swName_len = sizeof(entry->swName)-1; install_time = atoi(pkgdate); cp = date_n_time( &install_time, &date_len ); memcpy( entry->swDate, cp, date_len ); entry->swDate_len = date_len; } pkgdb_it_free(it); pkgdb_close(db); pkg_shutdown(); } else { #endif /* HAVE_LIBPKG */ if ( !pkg_directory[0] ) { return 1; /* Can't report installed packages if there isn't a list of them! */ } d = opendir( pkg_directory ); if (!d) return 1; while ((dp = readdir(d)) != NULL) { if ( '.' == dp->d_name[0] ) continue; snprintf( buf, BUFSIZ, "%s/%s", pkg_directory, dp->d_name ); if (stat( buf, &stat_buf ) < 0) continue; entry = netsnmp_swinst_entry_create( i++ ); if (NULL == entry) continue; /* error already logged by function */ CONTAINER_INSERT(container, entry); #ifdef HAVE_PKGINFO v = pkgparam( dp->d_name, "VERSION" ); c = pkgparam( dp->d_name, "CATEGORY" ); entry->swName_len = snprintf( entry->swName, sizeof(entry->swName), "%s-%s", dp->d_name, v ); if (entry->swName_len >= sizeof(entry->swName)) entry->swName_len = sizeof(entry->swName)-1; entry->swType = (NULL != strstr( c, "system")) ? 2 /* operatingSystem */ : 4; /* application */ /* Do we need to free 'v' & 'c' ??? */ #else entry->swName_len = snprintf( entry->swName, sizeof(entry->swName), "%s", dp->d_name ); if (entry->swName_len >= sizeof(entry->swName)) entry->swName_len = sizeof(entry->swName)-1; /* no information about O/S vs application packages ??? */ #endif install_time = stat_buf.st_mtime; cp = date_n_time( &install_time, &date_len ); memcpy( entry->swDate, cp, date_len ); entry->swDate_len = date_len; } closedir( d ); #ifdef HAVE_LIBPKG } #endif DEBUGMSGTL(("swinst:load:arch"," loaded %d entries\n", (int)CONTAINER_SIZE(container))); return 0; }
static int dbg_pkg_status(struct sip_msg* msg) { pkg_status(); return 1; }