Browse Source

Move forking of worker to worker_util.

tags/1.0.5
Vsevolod Stakhov 8 years ago
parent
commit
f1a8608981
2 changed files with 156 additions and 0 deletions
  1. 133
    0
      src/libserver/worker_util.c
  2. 23
    0
      src/libserver/worker_util.h

+ 133
- 0
src/libserver/worker_util.c View File

@@ -28,6 +28,7 @@
#include "worker_util.h"
#include "unix-std.h"
#include "utlist.h"
#include "ottery.h"

#ifdef WITH_GPERF_TOOLS
#include <google/profiler.h>
@@ -362,3 +363,135 @@ rspamd_controller_send_ucl (struct rspamd_http_connection_entry *entry,
entry->rt->ev_base);
entry->is_reply = TRUE;
}

static void
rspamd_worker_drop_priv (struct rspamd_main *rspamd_main)
{
if (rspamd_main->is_privilleged) {
if (setgid (rspamd_main->workers_gid) == -1) {
msg_err_main ("cannot setgid to %d (%s), aborting",
(gint) rspamd_main->workers_gid,
strerror (errno));
exit (-errno);
}
if (rspamd_main->cfg->rspamd_user &&
initgroups (rspamd_main->cfg->rspamd_user, rspamd_main->workers_gid) ==
-1) {
msg_err_main ("initgroups failed (%s), aborting", strerror (errno));
exit (-errno);
}
if (setuid (rspamd_main->workers_uid) == -1) {
msg_err_main ("cannot setuid to %d (%s), aborting",
(gint) rspamd_main->workers_uid,
strerror (errno));
exit (-errno);
}
}
}

static void
rspamd_worker_set_limits (struct rspamd_main *rspamd_main,
struct rspamd_worker_conf *cf)
{
struct rlimit rlmt;

if (cf->rlimit_nofile != 0) {
rlmt.rlim_cur = (rlim_t) cf->rlimit_nofile;
rlmt.rlim_max = (rlim_t) cf->rlimit_nofile;

if (setrlimit (RLIMIT_NOFILE, &rlmt) == -1) {
msg_warn_main ("cannot set files rlimit: %d, %s",
cf->rlimit_nofile,
strerror (errno));
}
}

if (cf->rlimit_maxcore != 0) {
rlmt.rlim_cur = (rlim_t) cf->rlimit_maxcore;
rlmt.rlim_max = (rlim_t) cf->rlimit_maxcore;

if (setrlimit (RLIMIT_CORE, &rlmt) == -1) {
msg_warn_main ("cannot set max core rlimit: %d, %s",
cf->rlimit_maxcore,
strerror (errno));
}
}
}

struct rspamd_worker *
rspamd_fork_worker (struct rspamd_main *rspamd_main,
struct rspamd_worker_conf *cf,
guint index)
{
struct rspamd_worker *cur;
/* Starting worker process */
cur = (struct rspamd_worker *) g_malloc0 (sizeof (struct rspamd_worker));

if (!rspamd_socketpair (cur->control_pipe)) {
msg_err ("socketpair failure: %s", strerror (errno));
exit (-errno);
}

cur->srv = rspamd_main;
cur->type = cf->type;
cur->cf = g_malloc (sizeof (struct rspamd_worker_conf));
memcpy (cur->cf, cf, sizeof (struct rspamd_worker_conf));
cur->index = index;
cur->ctx = cf->ctx;

cur->pid = fork ();

switch (cur->pid) {
case 0:
/* Update pid for logging */
rspamd_log_update_pid (cf->type, rspamd_main->logger);
/* Lock statfile pool if possible XXX */
/* Init PRNG after fork */
ottery_init (NULL);
g_random_set_seed (ottery_rand_uint32 ());
/* Drop privilleges */
rspamd_worker_drop_priv (rspamd_main);
/* Set limits */
rspamd_worker_set_limits (rspamd_main, cf);
setproctitle ("%s process", cf->worker->name);
rspamd_pidfile_close (rspamd_main->pfh);
/* Do silent log reopen to avoid collisions */
rspamd_log_close (rspamd_main->logger);
rspamd_log_open (rspamd_main->logger);

#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
# if (GLIB_MINOR_VERSION > 20)
/* Ugly hack for old glib */
if (!g_thread_get_initialized ()) {
g_thread_init (NULL);
}
# else
g_thread_init (NULL);
# endif
#endif
msg_info_main ("starting %s process %P", cf->worker->name, getpid ());
/* Close parent part of socketpair */
close (cur->control_pipe[0]);
/* Set non-blocking on the worker part of socketpair */
rspamd_socket_nonblocking (cur->control_pipe[1]);
/* Execute worker */
cf->worker->worker_start_func (cur);
break;
case -1:
msg_err_main ("cannot fork main process. %s", strerror (errno));
rspamd_pidfile_remove (rspamd_main->pfh);
exit (-errno);
break;
default:
/* Close worker part of socketpair */
close (cur->control_pipe[1]);
/* Set blocking on the main part of socketpair */
rspamd_socket_nonblocking (cur->control_pipe[0]);
/* Insert worker into worker's table, pid is index */
g_hash_table_insert (rspamd_main->workers, GSIZE_TO_POINTER (
cur->pid), cur);
break;
}

return cur;
}

+ 23
- 0
src/libserver/worker_util.h View File

@@ -111,4 +111,27 @@ worker_t * rspamd_get_worker_by_type (struct rspamd_config *cfg, GQuark type);

void rspamd_worker_stop_accept (struct rspamd_worker *worker);

/**
* Fork new worker with the specified configuration
*/
struct rspamd_worker *rspamd_fork_worker (struct rspamd_main *,
struct rspamd_worker_conf *, guint);

#define msg_err_main(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \
rspamd_main->server_pool->tag.tagname, rspamd_main->server_pool->tag.uid, \
G_STRFUNC, \
__VA_ARGS__)
#define msg_warn_main(...) rspamd_default_log_function (G_LOG_LEVEL_WARNING, \
rspamd_main->server_pool->tag.tagname, rspamd_main->server_pool->tag.uid, \
G_STRFUNC, \
__VA_ARGS__)
#define msg_info_main(...) rspamd_default_log_function (G_LOG_LEVEL_INFO, \
rspamd_main->server_pool->tag.tagname, rspamd_main->server_pool->tag.uid, \
G_STRFUNC, \
__VA_ARGS__)
#define msg_debug_main(...) rspamd_default_log_function (G_LOG_LEVEL_DEBUG, \
rspamd_main->server_pool->tag.tagname, rspamd_main->server_pool->tag.uid, \
G_STRFUNC, \
__VA_ARGS__)

#endif /* WORKER_UTIL_H_ */

Loading…
Cancel
Save