Browse Source

angel: add support for setting RLIMIT_CORE / RLIMIT_NOFILE

personal/stbuehler/wip
Stefan Bühler 12 years ago
parent
commit
e3393ce2f5
  1. 2
      include/lighttpd/angel_proc.h
  2. 4
      include/lighttpd/angel_server.h
  3. 8
      src/angel/angel_plugin_core.c
  4. 23
      src/angel/angel_proc.c
  5. 6
      src/angel/angel_server.c

2
include/lighttpd/angel_proc.h

@ -39,7 +39,7 @@ LI_API void li_error_pipe_use(liErrorPipe *epipe, int dest_fd);
/** read remaining data from in-fd */
LI_API void li_error_pipe_flush(liErrorPipe *epipe);
LI_API liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t gid, gchar *username, liProcSetupCB cb, gpointer ctx);
LI_API liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t gid, gchar *username, gint64 rlim_core, gint64 rlim_nofile, liProcSetupCB cb, gpointer ctx);
LI_API void li_proc_free(liProc *proc);
#endif

4
include/lighttpd/angel_server.h

@ -26,6 +26,8 @@ struct liInstanceConf {
GString *username;
uid_t uid;
gid_t gid;
gint64 rlim_core, rlim_nofile; /* < 0: don't change, G_MAXINT64: unlimited */
};
struct liInstance {
@ -68,7 +70,7 @@ LI_API void li_instance_replace(liInstance *oldi, liInstance *newi);
LI_API void li_instance_set_state(liInstance *i, liInstanceState s);
LI_API void li_instance_state_reached(liInstance *i, liInstanceState s);
LI_API liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username, uid_t uid, gid_t gid);
LI_API liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username, uid_t uid, gid_t gid, gint64 rlim_core, gint64 rlim_nofile);
LI_API void li_instance_conf_release(liInstanceConf *ic);
LI_API void li_instance_conf_acquire(liInstanceConf *ic);

8
src/angel/angel_plugin_core.c

@ -12,6 +12,7 @@ static void core_instance_parse(liServer *srv, liPlugin *p, liValue **options) {
uid_t uid = -1;
gid_t gid = -1;
GString *user = NULL;
gint64 rlim_core = -1, rlim_nofile = -1;
if (config->load_instconf) {
ERROR(srv, "%s", "Already configure the instance");
@ -160,10 +161,13 @@ static void core_instance_parse(liServer *srv, liPlugin *p, liValue **options) {
g_ptr_array_add(cmd, g_strndup(CONST_STR_LEN("/usr/lib/lighttpd2/")));
}
if (options[9]) rlim_core = options[9]->data.number;
if (options[10]) rlim_nofile = options[10]->data.number;
g_ptr_array_add(cmd, NULL);
cmdarr = (gchar**) g_ptr_array_free(cmd, FALSE);
envarr = (gchar**) g_ptr_array_free(env, FALSE);
config->load_instconf = li_instance_conf_new(cmdarr, envarr, user, uid, gid);
config->load_instconf = li_instance_conf_new(cmdarr, envarr, user, uid, gid, -1, -1);
}
static const liPluginItemOption core_instance_options[] = {
@ -176,6 +180,8 @@ static const liPluginItemOption core_instance_options[] = {
/* 6 */ { "wrapper", LI_VALUE_LIST, 0 },
/* 7 */ { "env", LI_VALUE_LIST, 0 },
/* 8 */ { "copy-env", LI_VALUE_LIST, 0 },
/* 9 */ { "max-core-file-size", LI_VALUE_NUMBER, 0 },
/* 10 */ { "max-open-files", LI_VALUE_NUMBER, 0 },
{ NULL, 0, 0 }
};

23
src/angel/angel_proc.c

@ -3,6 +3,10 @@
#include <grp.h>
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif
static void read_pipe(liServer *srv, liErrorPipe *epipe, gboolean flush) {
const ssize_t max_read = 8192;
ssize_t r, toread;
@ -137,7 +141,7 @@ static void proc_epipe_cb(liServer *srv, liErrorPipe *epipe, GString *msg) {
BACKEND_LINES(srv, msg->str, "%s[%i]: ", proc->appname, proc->child_pid);
}
liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t gid, gchar *username, liProcSetupCB cb, gpointer ctx) {
liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t gid, gchar *username, gint64 rlim_core, gint64 rlim_nofile, liProcSetupCB cb, gpointer ctx) {
liProc *proc;
pid_t pid;
@ -179,6 +183,23 @@ liProc* li_proc_new(liServer *srv, gchar **args, gchar **env, uid_t uid, gid_t g
li_proc_free(proc);
return NULL;
default:
#ifdef HAVE_GETRLIMIT
{
struct rlimit rlim;
if (rlim_core >= 0) {
rlim.rlim_cur = rlim.rlim_max = ((guint64) rlim_core >= RLIM_INFINITY) ? RLIM_INFINITY : (guint64) rlim_core;
if (0 != setrlimit(RLIMIT_CORE, &rlim)) {
ERROR(srv, "couldn't set 'max core file size': %s", g_strerror(errno));
}
}
if (rlim_nofile >= 0) {
rlim.rlim_cur = rlim.rlim_max = ((guint64) rlim_nofile >= RLIM_INFINITY) ? RLIM_INFINITY : (guint64) rlim_nofile;
if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
ERROR(srv, "couldn't set 'max filedescriptors': %s", g_strerror(errno));
}
}
}
#endif
proc->child_pid = pid;
li_error_pipe_activate(proc->epipe);
break;

6
src/angel/angel_server.c

@ -177,7 +177,7 @@ static void instance_spawn(liInstance *i) {
li_fd_no_block(confd[1]);
i->acon = li_angel_connection_new(i->srv->loop, confd[0], i, instance_angel_call_cb, instance_angel_close_cb);
i->proc = li_proc_new(i->srv, i->ic->cmd, i->ic->env, i->ic->uid, i->ic->gid, i->ic->username->str, instance_spawn_setup, confd);
i->proc = li_proc_new(i->srv, i->ic->cmd, i->ic->env, i->ic->uid, i->ic->gid, i->ic->username->str, i->ic->rlim_core, i->ic->rlim_nofile, instance_spawn_setup, confd);
if (!i->proc) return;
@ -350,7 +350,7 @@ void li_instance_acquire(liInstance *i) {
g_atomic_int_inc(&i->refcount);
}
liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username, uid_t uid, gid_t gid) {
liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username, uid_t uid, gid_t gid, gint64 rlim_core, gint64 rlim_nofile) {
liInstanceConf *ic = g_slice_new0(liInstanceConf);
ic->refcount = 1;
ic->cmd = cmd;
@ -360,6 +360,8 @@ liInstanceConf* li_instance_conf_new(gchar **cmd, gchar **env, GString *username
}
ic->uid = uid;
ic->gid = gid;
ic->rlim_core = rlim_core;
ic->rlim_nofile = rlim_nofile;
return ic;
}

Loading…
Cancel
Save