diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index f1b7626e..5129fadb 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -2859,12 +2859,15 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) { uwsgi_error("fork()"); goto clear; } + // now i am a grunt, avoid it making mess else if (grunt_pid == 0) { + // it will no more accepts requests uwsgi_close_all_sockets(); // create a new session setsid(); // exit on SIGPIPE signal(SIGPIPE, (void *) &end_me); + // here we create a new worker. Each grunt will race on this datas, so do not rely on them uwsgi.mywid = uwsgi.numproc + 1; uwsgi.mypid = getpid(); memset(&uwsgi.workers[uwsgi.mywid], 0, sizeof(struct uwsgi_worker)); @@ -2881,7 +2884,7 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) { return Py_True; } - // close connection on the worker + // close connection on the original worker if (PyTuple_Size(args) == 0) { if (wsgi_req->socket) { wsgi_req->socket->proto_close(wsgi_req); diff --git a/uwsgi.c b/uwsgi.c index 943131e8..23a028fc 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -179,6 +179,12 @@ static struct uwsgi_option uwsgi_base_options[] = { {"disable-logging", no_argument, 'L', "disable request logging", uwsgi_opt_dyn_false, (void *) UWSGI_OPTION_LOGGING, 0}, + {"flock", required_argument, 0, "lock the specified file before starting, exit if locked", uwsgi_opt_flock, NULL, UWSGI_OPT_IMMEDIATE}, + {"flock-wait", required_argument, 0, "lock the specified file before starting, wait if locked", uwsgi_opt_flock_wait, NULL, UWSGI_OPT_IMMEDIATE}, + + {"flock2", required_argument, 0, "lock the specified file after logging/daemon setup, exit if locked", uwsgi_opt_set_str, &uwsgi.flock2, UWSGI_OPT_IMMEDIATE}, + {"flock-wait2", required_argument, 0, "lock the specified file after logging/daemon setup, wait if locked", uwsgi_opt_set_str, &uwsgi.flock_wait2, UWSGI_OPT_IMMEDIATE}, + {"pidfile", required_argument, 0, "create pidfile (before privileges drop)", uwsgi_opt_set_str, &uwsgi.pidfile,0}, {"pidfile2", required_argument, 0, "create pidfile (after privileges drop)", uwsgi_opt_set_str, &uwsgi.pidfile2,0}, {"chroot", required_argument, 0, "chroot() to the specified directory", uwsgi_opt_set_str, &uwsgi.chroot,0}, @@ -1537,6 +1543,14 @@ int main(int argc, char *argv[], char *envp[]) { } } + if (uwsgi.flock2) { + uwsgi_opt_flock(NULL, uwsgi.flock2, NULL); + } + + if (uwsgi.flock_wait2) { + uwsgi_opt_flock(NULL, uwsgi.flock_wait2, NULL); + } + // setup master logging if (uwsgi.log_master) { @@ -3849,3 +3863,32 @@ void uwsgi_opt_load_json(char *opt, char *filename, void *none) { uwsgi_json_config(filename, uwsgi.magic_table); } #endif + +void uwsgi_opt_flock(char *opt, char *filename, void *none) { + + int fd = open(filename, O_RDWR); + if (fd < 0) { + uwsgi_error_open(filename); + exit(1); + } + + if (uwsgi_fcntl_is_locked(fd)) { + uwsgi_log("uWSGI ERROR: %s is locked by another instance\n", filename); + exit(1); + } + +} + +void uwsgi_opt_flock_wait(char *opt, char *filename, void *none) { + + int fd = open(filename, O_RDWR); + if (fd < 0) { + uwsgi_error_open(filename); + exit(1); + } + + if (uwsgi_fcntl_lock(fd)) { + exit(1); + } + +} diff --git a/uwsgi.h b/uwsgi.h index cb3f8c48..5192f7bd 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1363,6 +1363,9 @@ struct uwsgi_server { char *pidfile; char *pidfile2; + char *flock2; + char *flock_wait2; + int backtrace_depth; int harakiri_verbose; @@ -2632,6 +2635,9 @@ void uwsgi_opt_load_plugin(char *, char *, void *); void uwsgi_opt_load(char *, char *, void *); void uwsgi_opt_cluster_log(char *, char *, void *); void uwsgi_opt_cluster_reload(char *, char *, void *); + +void uwsgi_opt_flock(char *, char *, void *); +void uwsgi_opt_flock_wait(char *, char *, void *); #ifdef UWSGI_INI void uwsgi_opt_load_ini(char *, char *, void *); #endif