From e30ea48c912be20ddc9c327205d146e46d60535e Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 4 May 2009 16:39:35 +0400 Subject: [PATCH] * Enable support of google perf tools --- CMakeLists.txt | 9 +++++++++ config.h.in | 2 ++ rspamc.pl.in | 3 +++ src/cfg_file.h | 3 +++ src/cfg_file.l | 1 + src/cfg_file.y | 13 ++++++++++++- src/worker.c | 38 +++++++++++++++++++++++++++++++++----- 7 files changed, 63 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 59537af11..1403c0b23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ OPTION(ENABLE_LUA "Enable lua support [default: OFF]" OPTION(SKIP_RELINK_RPATH "Skip relinking and full RPATH for the install tree" OFF) OPTION(ENABLE_REDIRECTOR "Enable redirector install [default: OFF]" OFF) OPTION(ENABLE_PROFILING "Enable profiling [default: OFF]" OFF) +OPTION(ENABLE_GPERF_TOOLS "Enable google perftools [default: OFF]" OFF) # Build optimized code for following CPU (default i386) #SET(CPU_TUNE "i686") @@ -143,6 +144,10 @@ IF(ENABLE_PROFILING MATCHES "ON") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") ENDIF(ENABLE_PROFILING MATCHES "ON") +IF(ENABLE_GPERF_TOOLS MATCHES "ON") + SET(WITH_GPERF_TOOLS 1) +ENDIF(ENABLE_GPERF_TOOLS MATCHES "ON") + FIND_PATH(LIBEVENT_INCLUDE event.h PATHS /opt/include /usr/include @@ -407,6 +412,10 @@ IF(ENABLE_LUA MATCHES "ON") TARGET_LINK_LIBRARIES(rspamd "${LUA_LIBRARY}") ENDIF(ENABLE_LUA MATCHES "ON") +IF(ENABLE_GPERF_TOOLS MATCHES "ON") + TARGET_LINK_LIBRARIES(rspamd profiler) +ENDIF(ENABLE_GPERF_TOOLS MATCHES "ON") + ADD_EXECUTABLE(test/rspamd-test ${TESTDEPENDS} ${CONTRIBSRC} ${TESTSRC}) SET_TARGET_PROPERTIES(test/rspamd-test PROPERTIES LINKER_LANGUAGE C) TARGET_LINK_LIBRARIES(test/rspamd-test m) diff --git a/config.h.in b/config.h.in index 14530362f..61bbc6068 100644 --- a/config.h.in +++ b/config.h.in @@ -101,6 +101,8 @@ #cmakedefine WITH_PROFILER 1 +#cmakedefine WITH_GPERF_TOOLS 1 + #define RVERSION "${RSPAMD_VERSION}" #define RSPAMD_MASTER_SITE_URL "${RSPAMD_MASTER_SITE_URL}" diff --git a/rspamc.pl.in b/rspamc.pl.in index c8d7f07d0..9976794d0 100755 --- a/rspamc.pl.in +++ b/rspamc.pl.in @@ -78,6 +78,9 @@ sub connect_socket { my $proto = getprotobyname('tcp'); my $sin; socket ($sock, PF_INET, SOCK_STREAM, $proto) or die "cannot create tcp socket"; + if ($cfg{'host'} eq '*') { + $cfg{'host'} = '127.0.0.1'; + } if (inet_aton ($cfg{'host'})) { $sin = sockaddr_in ($cfg{'port'}, inet_aton($cfg{'host'})); } diff --git a/src/cfg_file.h b/src/cfg_file.h index 437317ed0..201b46823 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -154,6 +154,9 @@ struct config_file { char *cfg_name; /**< name of config file */ char *pid_file; /**< name of pid file */ char *temp_dir; /**< dir for temp files */ +#ifdef WITH_GPERF_TOOLS + char *profile_path; +#endif char *bind_host; /**< bind line */ struct in_addr bind_addr; /**< bind address in case of TCP socket */ diff --git a/src/cfg_file.l b/src/cfg_file.l index 29ca9aef7..f839c0b45 100644 --- a/src/cfg_file.l +++ b/src/cfg_file.l @@ -84,6 +84,7 @@ WARNING return LOG_LEVEL_WARNING; ERROR return LOG_LEVEL_ERROR; log_facility return LOG_FACILITY; log_file return LOG_FILENAME; +profile_file return PROFILE_FILE; statfile_pool_size return STATFILE_POOL_SIZE; diff --git a/src/cfg_file.y b/src/cfg_file.y index 9ddc5850f..e4e4d8dbe 100644 --- a/src/cfg_file.y +++ b/src/cfg_file.y @@ -48,7 +48,7 @@ struct statfile_section *cur_section = NULL; %token LOGGING LOG_TYPE LOG_TYPE_CONSOLE LOG_TYPE_SYSLOG LOG_TYPE_FILE %token LOG_LEVEL LOG_LEVEL_DEBUG LOG_LEVEL_INFO LOG_LEVEL_WARNING LOG_LEVEL_ERROR LOG_FACILITY LOG_FILENAME %token STATFILE ALIAS PATTERN WEIGHT STATFILE_POOL_SIZE SIZE TOKENIZER CLASSIFIER -%token DELIVERY LMTP ENABLED AGENT SECTION LUACODE RAW_MODE +%token DELIVERY LMTP ENABLED AGENT SECTION LUACODE RAW_MODE PROFILE_FILE %type STRING %type VARIABLE @@ -94,6 +94,7 @@ command : | delivery | luacode | raw_mode + | profile_file ; tempdir : @@ -842,6 +843,16 @@ raw_mode: } ; +profile_file: + PROFILE_FILE EQSIGN QUOTEDSTRING { +#ifdef WITH_GPREF_TOOLS + cfg->profile_path = $3; +#else + yywarn ("yyparse: profile_file directive is ignored as gperf support is not enabled"); +#endif + } + ; + %% /* * vi:ts=4 diff --git a/src/worker.c b/src/worker.c index 270d71f61..5242c0087 100644 --- a/src/worker.c +++ b/src/worker.c @@ -43,6 +43,14 @@ extern PerlInterpreter *perl_interpreter; #endif +#ifdef WITH_GPERF_TOOLS +#include +/* Declare prototypes */ +int ProfilerStart (u_char* fname); +void ProfilerStop (void); +void ProfilerRegisterThread (void); +#endif + static struct timeval io_tv; static void write_socket (void *arg); @@ -53,6 +61,9 @@ void sig_handler (int signo) switch (signo) { case SIGINT: case SIGTERM: +#ifdef WITH_GPERF_TOOLS + ProfilerStop (); +#endif #ifdef WITH_PROFILER exit (0); #else @@ -299,17 +310,34 @@ start_worker (struct rspamd_worker *worker, int listen_sock) { struct sigaction signals; int i; + #ifdef WITH_PROFILER extern void _start (void), etext (void); monstartup ((u_long) &_start, (u_long) &etext); #endif -#if 0 + +#ifdef WITH_GPERF_TOOLS + char prof_path[PATH_MAX]; + + if (getenv("CPUPROFILE")) { + + /* disable inherited Profiler enabled in master process */ + ProfilerStop (); + } /* Try to create temp directory for gmon.out and chdir to it */ - char prof_dir[PATH_MAX]; - snprintf (prof_dir, sizeof (prof_dir), "%s/rspamd-prof-%d", worker->srv->cfg->temp_dir, (int)getpid ()); - if (mkdir (prof_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IXOTH | S_IROTH | S_IXGRP | S_IRGRP) != -1) { - chdir (prof_dir); + if (worker->srv->cfg->profile_path == NULL) { + worker->srv->cfg->profile_path = g_strdup_printf ("%s/rspamd-profile", worker->srv->cfg->temp_dir); + } + + snprintf (prof_path, sizeof (prof_path), "%s.%d", worker->srv->cfg->profile_path, (int)getpid ()); + if (ProfilerStart (prof_path)) { + /* start ITIMER_PROF timer */ + ProfilerRegisterThread(); + } + else { + msg_warn ("start_worker: cannot start google perftools profiler"); } + #endif worker->srv->pid = getpid (); -- 2.39.5