mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-08 09:58:53 +00:00
Compare commits
39
Commits
0.9.7-beta1
...
0.9.7-rc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a068a7eb5b | ||
|
|
aa004c1893 | ||
|
|
9a9c149370 | ||
|
|
9e6e226e4b | ||
|
|
06c2aed0e0 | ||
|
|
df4f610cfc | ||
|
|
64249abae1 | ||
|
|
94f4be58bd | ||
|
|
35987d3741 | ||
|
|
be73e00dde | ||
|
|
a5f272f337 | ||
|
|
406691aa69 | ||
|
|
6827b3bf15 | ||
|
|
2055a1472f | ||
|
|
f4f9018068 | ||
|
|
3e82b5cd33 | ||
|
|
07036bce20 | ||
|
|
a4a7a75f29 | ||
|
|
02d6006b2f | ||
|
|
e8e5f11c66 | ||
|
|
e53a6fa4c0 | ||
|
|
c478b0a0c8 | ||
|
|
5f207e6978 | ||
|
|
a2b74d0afd | ||
|
|
b867b11de3 | ||
|
|
806765d1d3 | ||
|
|
62d2b97e17 | ||
|
|
c04e339034 | ||
|
|
927b495646 | ||
|
|
57b5392590 | ||
|
|
463030108f | ||
|
|
46dd754264 | ||
|
|
12d9641b66 | ||
|
|
6cb1203d26 | ||
|
|
23d0ec333e | ||
|
|
da579fd308 | ||
|
|
14152bc999 | ||
|
|
6c32e5f2e2 | ||
|
|
62f74f2b60 |
@@ -9,3 +9,6 @@ b8f67c6cd0d62f864db9b2b265b4e260ad7d873c 0.9.6-rc2
|
||||
35918dd4b3771158b2b57410613ef029e08bbd60 0.9.6
|
||||
5f25d1f97f9dde3e391a668c1c610a52a5db8244 0.9.6.1
|
||||
ef31fc61ac48018c464f28ebfdf865b96bf83f18 0.9.6.2
|
||||
9e100c1f085034396cec586f0c76ad3f9800d1a5 0.9.7-beta1
|
||||
ff4111eb8f55b958ec91c70163e10f3372a9b94d 0.9.7-rc1
|
||||
eb8aff2926230bb114fb90f67203440a2c534bf1 0.9.7-rc2
|
||||
|
||||
@@ -1,8 +1,37 @@
|
||||
*** march 2011 ***
|
||||
|
||||
* 0.9.7-rc2 [20010309]
|
||||
|
||||
- added cron-like interface to signal framework
|
||||
- improved Linux namespaces support
|
||||
- fixed multithreading + --max-requests
|
||||
- added support for reference in configuration files
|
||||
|
||||
* 0.9.7-rc1 [20110307]
|
||||
|
||||
- export %v in emperor mode
|
||||
- fixed signal race condition in server reload
|
||||
- fixed http router post handling bug
|
||||
- added uwsgi.erlang_register_process in pyerl plugin
|
||||
- fixed unix socket inherit
|
||||
- fixed linux namespace support in recent kernel/gcc
|
||||
- ported threading to python 3.2
|
||||
- add build date to uWSGI startup info
|
||||
- do not allow clustering without defining a socket
|
||||
- kill all the gateways/daemons on startup errors
|
||||
- fixed vacuum after chdir()
|
||||
- fixed gateways reload
|
||||
- re-added support for OpenBSD and NetBSD
|
||||
- fixed post-buffering in python
|
||||
- use erlang binary for python string
|
||||
- fixed memory leak in pyerl plugin
|
||||
- removed broken log rotation (post-poned)
|
||||
- fixed no_argument options in ini and yaml parsing
|
||||
|
||||
* 0.9.7-beta1 [20110301]
|
||||
|
||||
- fully modular re-design
|
||||
- advanced build system with presets
|
||||
- threading support
|
||||
- emperor mode for massive auto-hosting
|
||||
- caching subsystem
|
||||
|
||||
@@ -13,9 +13,8 @@ sendfile = true
|
||||
minterpreters = true
|
||||
async = true
|
||||
evdis = false
|
||||
ldap = false
|
||||
ldap = auto
|
||||
pcre = auto
|
||||
stackless = false
|
||||
debug = false
|
||||
unbit = false
|
||||
xml_implementation = libxml2
|
||||
|
||||
@@ -330,6 +330,27 @@ int uwsgi_cache_del(char *key, uint16_t keylen) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void uwsgi_cache_fix() {
|
||||
|
||||
uint64_t i;
|
||||
|
||||
for(i=0;i< uwsgi.cache_max_items;i++) {
|
||||
// valid record ?
|
||||
if (uwsgi.cache_items[i].keysize) {
|
||||
if (!uwsgi.cache_items[i].prev) {
|
||||
// put value in hash_table
|
||||
uwsgi.cache_hashtable[ uwsgi.cache_items[i].djbhash % 0xffff] = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// put this record in unused stack
|
||||
uwsgi.shared->cache_first_available_item = i;
|
||||
uwsgi.shared->cache_unused_stack_ptr++;
|
||||
uwsgi.cache_unused_stack[uwsgi.shared->cache_unused_stack_ptr] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint64_t expires, uint16_t flags) {
|
||||
|
||||
uint64_t index = 0, last_index = 0 ;
|
||||
@@ -476,7 +497,7 @@ void cache_command(char *key, uint16_t keylen, char *val, uint16_t vallen, void
|
||||
if (!uwsgi_strncmp(key, keylen, "key", 3)) {
|
||||
val = uwsgi_cache_get(val, vallen, &tmp_vallen);
|
||||
if (val && tmp_vallen > 0) {
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, val, vallen);
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, val, tmp_vallen);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -528,6 +549,7 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_cache_del(wsgi_req->buffer, wsgi_req->uh.pktsize);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
// dict
|
||||
if (wsgi_req->uh.pktsize > 0) {
|
||||
|
||||
@@ -121,6 +121,9 @@ void emperor_add(char *name, time_t born) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
unsetenv("UWSGI_RELOADS");
|
||||
|
||||
uef = uwsgi_num2str(n_ui->pipe[1]);
|
||||
if (setenv("UWSGI_EMPEROR_FD", uef, 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
@@ -219,10 +222,7 @@ void emperor_loop() {
|
||||
|
||||
if (!i_am_alone) {
|
||||
diedpid = waitpid(uwsgi.emperor_pid, &waitpid_status, WNOHANG);
|
||||
if (diedpid < 0) {
|
||||
uwsgi_error("waitpid()");
|
||||
}
|
||||
else if (diedpid > 0) {
|
||||
if (diedpid < 0 || diedpid > 0) {
|
||||
i_am_alone = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,11 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop)(void)) {
|
||||
|
||||
if (!uwsgi.master_process) {
|
||||
if (gw_pid > 0) {
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0,0,0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
loop();
|
||||
// never here !!! (i hope)
|
||||
exit(1);
|
||||
@@ -101,6 +106,11 @@ void gateway_respawn(int id) {
|
||||
|
||||
if (gw_pid == 0) {
|
||||
if (uwsgi.master_as_root) uwsgi_as_root();
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0,0,0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
ug->loop();
|
||||
// never here !!! (i hope)
|
||||
exit(1);
|
||||
|
||||
@@ -84,7 +84,6 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
|
||||
int lines = 1;
|
||||
|
||||
struct option *lopt, *aopt;
|
||||
char *section_asked = "uwsgi";
|
||||
char *colon;
|
||||
|
||||
@@ -126,26 +125,7 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
ini_rstrip(key);
|
||||
val = ini_lstrip(val);
|
||||
ini_rstrip(val);
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp(key, aopt->name)) {
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
add_exported_option(0, (char *)key);
|
||||
}
|
||||
else {
|
||||
if (aopt->has_arg == optional_argument) {
|
||||
if (!strcmp("true", val)) {
|
||||
val = NULL;
|
||||
}
|
||||
}
|
||||
manage_opt(aopt->val, val);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
add_exported_option((char *)key, val, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,71 +37,162 @@ int calc_ldap_name(char *name) {
|
||||
return strlen(name) + counter;
|
||||
}
|
||||
|
||||
void uwsgi_ldap_schema_dump_ldif() {
|
||||
struct option *aopt, *lopt;
|
||||
struct uwsgi_ldap_entry {
|
||||
int num;
|
||||
char names[1024];
|
||||
int has_arg;
|
||||
};
|
||||
|
||||
|
||||
void uwsgi_name_to_ldap(char *src, char *dst) {
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
int i;
|
||||
int counter = 30000;
|
||||
char *ptr = dst;
|
||||
|
||||
memset(dst, 0, 1024);
|
||||
|
||||
strcat(dst, " 'uWSGI");
|
||||
|
||||
ptr+= 7;
|
||||
|
||||
for(i=0;i< (int)strlen(src);i++) {
|
||||
if (src[i] == '-') {
|
||||
i++;
|
||||
*ptr++= toupper( (int) src[i]);
|
||||
}
|
||||
else {
|
||||
*ptr++= src[i];
|
||||
}
|
||||
}
|
||||
|
||||
strcat(dst, "'");
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_ldap_entry *get_ldap_by_num(struct uwsgi_ldap_entry *root, int num, int count) {
|
||||
|
||||
int i;
|
||||
struct uwsgi_ldap_entry *ule;
|
||||
|
||||
for(i=0;i<count;i++) {
|
||||
ule = &root[i];
|
||||
if (ule->num == num) {
|
||||
return ule;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct uwsgi_ldap_entry *search_ldap_cache(struct uwsgi_ldap_entry *root, char *name, int count) {
|
||||
int i;
|
||||
struct uwsgi_ldap_entry *ule;
|
||||
|
||||
for(i=0;i<count;i++) {
|
||||
ule = &root[i];
|
||||
if (uwsgi_list_has_str(ule->names, name+1)) {
|
||||
return ule;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct uwsgi_ldap_entry *get_ldap_names(int *count) {
|
||||
|
||||
struct option *aopt, *lopt;
|
||||
struct uwsgi_ldap_entry *ule, *entry;
|
||||
char ldap_name[1024];
|
||||
static int counter = 30000000;
|
||||
|
||||
*count = 0;
|
||||
lopt = uwsgi.long_options;
|
||||
|
||||
ule = uwsgi_malloc(sizeof(struct uwsgi_ldap_entry)*count_options(lopt));
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
|
||||
uwsgi_name_to_ldap((char *)aopt->name, ldap_name);
|
||||
|
||||
entry = search_ldap_cache(ule, ldap_name, *count);
|
||||
|
||||
if (entry) goto next;
|
||||
|
||||
if (aopt->flag) {
|
||||
entry = &ule[*count] ;
|
||||
entry->num = counter;
|
||||
strcpy(entry->names, ldap_name);
|
||||
counter++;
|
||||
*count = *count+1;
|
||||
}
|
||||
else {
|
||||
entry = get_ldap_by_num(ule, aopt->val, *count);
|
||||
if (entry) {
|
||||
strcat(entry->names, ldap_name);
|
||||
}
|
||||
else {
|
||||
entry = &ule[*count] ;
|
||||
entry->num = aopt->val;
|
||||
strcpy(entry->names, ldap_name);
|
||||
*count = *count+1;
|
||||
}
|
||||
}
|
||||
|
||||
entry->has_arg = aopt->has_arg;
|
||||
|
||||
next:
|
||||
lopt++;
|
||||
}
|
||||
|
||||
return ule;
|
||||
}
|
||||
|
||||
void uwsgi_ldap_schema_dump_ldif() {
|
||||
|
||||
int i;
|
||||
int items;
|
||||
|
||||
uwsgi_log("\n");
|
||||
uwsgi_log("dn: cn=uwsgi,cn=schema,cn=config\n");
|
||||
uwsgi_log("objectClass: olcSchemaConfig\n");
|
||||
uwsgi_log("cn: uwsgi\n");
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
|
||||
|
||||
if (aopt->flag) {
|
||||
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME 'uWSGI", counter);
|
||||
counter++;
|
||||
for(i=0;i<items;i++) {
|
||||
|
||||
entry = &ule[i];
|
||||
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
|
||||
|
||||
if (entry->has_arg) {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME 'uWSGI", aopt->val);
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
for(i=0;i< (int)strlen(aopt->name);i++) {
|
||||
if (aopt->name[i] == '-') {
|
||||
i++;
|
||||
uwsgi_log("%c", toupper( (int) aopt->name[i]));
|
||||
}
|
||||
else {
|
||||
uwsgi_log("%c", aopt->name[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (aopt->has_arg) {
|
||||
uwsgi_log("' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
|
||||
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
|
||||
uwsgi_log("olcObjectClasses: ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
|
||||
for(i=0;i<items;i++) {
|
||||
|
||||
uwsgi_log("uWSGI");
|
||||
entry = &ule[i];
|
||||
|
||||
char *list2 = uwsgi_concat2(entry->names+1, "");
|
||||
char *p = strtok(list2, " ");
|
||||
while (p != NULL) {
|
||||
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
|
||||
for(i=0;i< (int)strlen(aopt->name);i++) {
|
||||
if (aopt->name[i] == '-') {
|
||||
i++;
|
||||
uwsgi_log("%c", toupper( (int) aopt->name[i]));
|
||||
}
|
||||
else {
|
||||
uwsgi_log("%c", aopt->name[i]);
|
||||
}
|
||||
}
|
||||
uwsgi_log(" $ ");
|
||||
lopt++;
|
||||
}
|
||||
|
||||
uwsgi_log("uWSGInull ))\n");
|
||||
@@ -112,67 +203,47 @@ void uwsgi_ldap_schema_dump_ldif() {
|
||||
}
|
||||
|
||||
void uwsgi_ldap_schema_dump() {
|
||||
struct option *aopt, *lopt;
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
int i;
|
||||
int counter = 30000;
|
||||
int items;
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
|
||||
|
||||
for(i=0;i<items;i++) {
|
||||
|
||||
if (aopt->flag) {
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME 'uWSGI", counter);
|
||||
counter++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME 'uWSGI", aopt->val);
|
||||
}
|
||||
for(i=0;i< (int)strlen(aopt->name);i++) {
|
||||
if (aopt->name[i] == '-') {
|
||||
i++;
|
||||
uwsgi_log("%c", toupper( (int) aopt->name[i]));
|
||||
}
|
||||
else {
|
||||
uwsgi_log("%c", aopt->name[i]);
|
||||
}
|
||||
}
|
||||
entry = &ule[i];
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
|
||||
|
||||
if (entry->has_arg) {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (aopt->has_arg) {
|
||||
uwsgi_log("' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
|
||||
uwsgi_log("objectclass ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
for(i=0;i<items;i++) {
|
||||
|
||||
entry = &ule[i];
|
||||
|
||||
char *list2 = uwsgi_concat2(entry->names+1, "");
|
||||
char *p = strtok(list2, " ");
|
||||
while (p != NULL) {
|
||||
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log("uWSGI");
|
||||
|
||||
for(i=0;i< (int)strlen(aopt->name);i++) {
|
||||
if (aopt->name[i] == '-') {
|
||||
i++;
|
||||
uwsgi_log("%c", toupper( (int) aopt->name[i]));
|
||||
}
|
||||
else {
|
||||
uwsgi_log("%c", aopt->name[i]);
|
||||
}
|
||||
}
|
||||
uwsgi_log(" $ ");
|
||||
lopt++;
|
||||
}
|
||||
|
||||
uwsgi_log("uWSGInull ))\n");
|
||||
|
||||
@@ -194,8 +265,6 @@ void uwsgi_ldap_config() {
|
||||
int desired_version = LDAP_VERSION3;
|
||||
int ret;
|
||||
|
||||
struct option *aopt, *lopt;
|
||||
|
||||
LDAPURLDesc *ldap_url;
|
||||
|
||||
if (uwsgi.ldap) {
|
||||
@@ -211,6 +280,8 @@ void uwsgi_ldap_config() {
|
||||
uwsgi_log("unable to parse LDAP url.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log("[uWSGI] getting LDAP configuration from %s\n", url);
|
||||
|
||||
url_slash = strchr(url, '/');
|
||||
url_slash = strchr(url_slash + 1, '/');
|
||||
@@ -255,9 +326,11 @@ void uwsgi_ldap_config() {
|
||||
|
||||
entry = ldap_first_entry(ldp, results);
|
||||
|
||||
int found = 0;
|
||||
for( attr = ldap_first_attribute(ldp, entry, &ber); attr != NULL; attr = ldap_next_attribute(ldp, entry, ber)) {
|
||||
if (!strncmp(attr,"uWSGI",5)) {
|
||||
|
||||
found = 1;
|
||||
uwsgi_attr = malloc( calc_ldap_name(attr) + 1 );
|
||||
if (!uwsgi_attr) {
|
||||
uwsgi_error("malloc()");
|
||||
@@ -271,7 +344,7 @@ void uwsgi_ldap_config() {
|
||||
#endif
|
||||
bervalues = ldap_get_values_len(ldp, entry, attr);
|
||||
if (bervalues) {
|
||||
// do not free uwsgi_val;
|
||||
// do not free uwsgi_attr/uwsgi_val;
|
||||
char *uwsgi_val = malloc( bervalues[0]->bv_len + 1 );
|
||||
if (!uwsgi_val) {
|
||||
uwsgi_error("malloc()");
|
||||
@@ -281,29 +354,21 @@ void uwsgi_ldap_config() {
|
||||
memcpy(uwsgi_val, bervalues[0]->bv_val, bervalues[0]->bv_len);
|
||||
uwsgi_val[bervalues[0]->bv_len] = 0;
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp(uwsgi_attr, aopt->name)) {
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
add_exported_option(0, (char*) uwsgi_attr);
|
||||
}
|
||||
else {
|
||||
manage_opt(aopt->val, uwsgi_val);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
add_exported_option((char*) uwsgi_attr, uwsgi_val, 0);
|
||||
free(bervalues);
|
||||
}
|
||||
else {
|
||||
free(uwsgi_attr);
|
||||
}
|
||||
|
||||
free(bervalues);
|
||||
free(uwsgi_attr);
|
||||
}
|
||||
free(attr);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
uwsgi_log("no uWSGI LDAP entry found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
free(ber);
|
||||
free(results);
|
||||
|
||||
|
||||
@@ -134,14 +134,36 @@ void uwsgi_rwunlock(void *lock) { uwsgi_unlock(lock); }
|
||||
#define UWSGI_LOCK_SIZE 8
|
||||
#define UWSGI_RWLOCK_SIZE 8
|
||||
|
||||
void uwsgi_lock_init(void *lock) {}
|
||||
static int lock_counter = 0;
|
||||
|
||||
void uwsgi_lock_init(void *lock) {
|
||||
|
||||
char filename[17];
|
||||
|
||||
if (snprintf(filename, 17, ".uwsgiflock%d", lock_counter) < 0) {
|
||||
uwsgi_log("unable to create lock %d\n", lock_counter);
|
||||
}
|
||||
|
||||
int fd = open(filename, O_CREAT|O_RDWR|O_TRUNC);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(lock, &fd, sizeof(int));
|
||||
}
|
||||
|
||||
void uwsgi_lock(void *lock) {
|
||||
//if (flock((int) *lock, LOCK_EX)) { uwsgi_error("flock()"); }
|
||||
|
||||
int fd;
|
||||
memcpy(&fd, lock, sizeof(int));
|
||||
if (flock(fd, LOCK_EX)) { uwsgi_error("flock()"); }
|
||||
}
|
||||
|
||||
void uwsgi_unlock(void *lock) {
|
||||
//if (flock((int) *lock, LOCK_UN)) { uwsgi_error("flock()"); }
|
||||
int fd;
|
||||
memcpy(&fd, lock, sizeof(int));
|
||||
if (flock(fd, LOCK_UN)) { uwsgi_error("flock()"); }
|
||||
}
|
||||
|
||||
void uwsgi_rwlock_init(void *lock) { uwsgi_lock_init(lock) ;}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define _NO_UWSGI_RB
|
||||
#include "uwsgi.h"
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
|
||||
|
||||
@@ -125,7 +125,7 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
char log_buf[4096];
|
||||
|
||||
uint64_t current_time = time(NULL);
|
||||
time_t current_time = time(NULL);
|
||||
|
||||
struct timeval last_respawn;
|
||||
|
||||
@@ -146,8 +146,6 @@ void master_loop(char **argv, char **environ) {
|
||||
uint8_t uwsgi_signal;
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
struct pollfd uwsgi_poll[2];
|
||||
int uwsgi_poll_size = 0;
|
||||
struct sockaddr_in udp_client;
|
||||
socklen_t udp_len;
|
||||
char udp_client_addr[16];
|
||||
@@ -165,6 +163,10 @@ void master_loop(char **argv, char **environ) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
int snmp_fd = -1;
|
||||
#endif
|
||||
|
||||
int i=0,j;
|
||||
int rlen;
|
||||
|
||||
@@ -172,21 +174,19 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
struct uwsgi_rb_timer *min_timeout;
|
||||
struct rb_root *rb_timers = uwsgi_init_rb_timer();
|
||||
struct tm *uwsgi_cron_delta;
|
||||
|
||||
// release the GIL
|
||||
//UWSGI_RELEASE_GIL
|
||||
|
||||
/* route signals to workers... */
|
||||
signal(SIGHUP, (void *) &grace_them_all);
|
||||
signal(SIGTERM, (void *) &reap_them_all);
|
||||
signal(SIGINT, (void *) &kill_them_all);
|
||||
signal(SIGQUIT, (void *) &kill_them_all);
|
||||
/* used only to avoid human-errors */
|
||||
uwsgi_unix_signal(SIGHUP, grace_them_all);
|
||||
uwsgi_unix_signal(SIGTERM, reap_them_all);
|
||||
uwsgi_unix_signal(SIGINT, kill_them_all);
|
||||
uwsgi_unix_signal(SIGQUIT, kill_them_all);
|
||||
uwsgi_unix_signal(SIGUSR1, stats);
|
||||
|
||||
signal(SIGUSR1, (void *) &stats);
|
||||
|
||||
uwsgi.master_queue = event_queue_init();
|
||||
|
||||
/* route signals to workers... */
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("adding %d to signal poll\n", uwsgi.shared->worker_signal_pipe[0]);
|
||||
#endif
|
||||
@@ -208,21 +208,16 @@ void master_loop(char **argv, char **environ) {
|
||||
#ifdef UWSGI_UDP
|
||||
if (uwsgi.udp_socket) {
|
||||
udp_fd = bind_to_udp(uwsgi.udp_socket, 0, 0);
|
||||
uwsgi_poll[uwsgi_poll_size].fd = udp_fd;
|
||||
if (uwsgi_poll[uwsgi_poll_size].fd < 0) {
|
||||
if (udp_fd < 0) {
|
||||
uwsgi_log( "unable to bind to udp socket. SNMP and cluster management services will be disabled.\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "UDP server enabled.\n");
|
||||
uwsgi_poll[uwsgi_poll_size].events = POLLIN;
|
||||
uwsgi_poll_size++;
|
||||
event_queue_add_fd_read(uwsgi.master_queue, udp_fd);
|
||||
}
|
||||
}
|
||||
#ifdef UWSGI_MULTICAST
|
||||
if (uwsgi.cluster) {
|
||||
uwsgi_poll[uwsgi_poll_size].fd = uwsgi.cluster_fd;
|
||||
uwsgi_poll[uwsgi_poll_size].events = POLLIN;
|
||||
uwsgi_poll_size++;
|
||||
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.cluster_fd);
|
||||
|
||||
@@ -245,6 +240,10 @@ void master_loop(char **argv, char **environ) {
|
||||
uh->modifier1 = 99;
|
||||
uh->pktsize = cluster_opt_size - 4;
|
||||
uh->modifier2 = 1;
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uh->pktsize = uwsgi_swap16(uh->pktsize);
|
||||
#endif
|
||||
|
||||
cptrbuf = cluster_opt_buf+4;
|
||||
|
||||
@@ -286,12 +285,28 @@ void master_loop(char **argv, char **environ) {
|
||||
memcpy(uwsgi.shared->snmp_community, uwsgi.snmp_community, strlen(uwsgi.snmp_community) + 1);
|
||||
}
|
||||
}
|
||||
uwsgi_log( "filling SNMP table...");
|
||||
|
||||
uwsgi.shared->snmp_gvalue[0].type = SNMP_COUNTER64;
|
||||
uwsgi.shared->snmp_gvalue[0].val = &uwsgi.workers[0].requests;
|
||||
|
||||
uwsgi_log( "done\n");
|
||||
for(i=0;i<uwsgi.numproc;i++) {
|
||||
uwsgi.shared->snmp_gvalue[30+i].type = SNMP_COUNTER64;
|
||||
uwsgi.shared->snmp_gvalue[30+i].val = &uwsgi.workers[i+1].requests;
|
||||
}
|
||||
|
||||
if (uwsgi.snmp_addr) {
|
||||
snmp_fd = bind_to_udp(uwsgi.snmp_addr, 0, 0);
|
||||
if (snmp_fd < 0) {
|
||||
uwsgi_log( "unable to bind to udp socket. SNMP service will be disabled.\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "SNMP server enabled on %s\n", uwsgi.snmp_addr);
|
||||
event_queue_add_fd_read(uwsgi.master_queue, snmp_fd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "SNMP agent enabled.\n");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -315,6 +330,13 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_subscribe(uwsgi.subscriptions[i]);
|
||||
}
|
||||
|
||||
// sync the cache store if needed
|
||||
if (uwsgi.cache_store && uwsgi.cache_filesize) {
|
||||
if (msync(uwsgi.cache_items, uwsgi.cache_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
//uwsgi_log("ready_to_reload %d %d\n", ready_to_reload, uwsgi.numproc);
|
||||
|
||||
@@ -361,6 +383,11 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
|
||||
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
|
||||
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
|
||||
}
|
||||
|
||||
uwsgi_log( "binary reloading uWSGI...\n");
|
||||
if (chdir(uwsgi.cwd)) {
|
||||
uwsgi_error("chdir()");
|
||||
@@ -407,12 +434,6 @@ void master_loop(char **argv, char **environ) {
|
||||
master_has_children = 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_PROXY
|
||||
if (uwsgi.proxy_socket_name && uwsgi.shared->proxy_pid > 0) {
|
||||
master_has_children = 1;
|
||||
}
|
||||
// TODO if gateways > 0 master_has_children == 1
|
||||
#endif
|
||||
|
||||
if (!master_has_children) {
|
||||
diedpid = 0;
|
||||
@@ -423,7 +444,7 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_error("waitpid()");
|
||||
/* here is better to reload all the uWSGI stack */
|
||||
uwsgi_log( "something horrible happened...\n");
|
||||
reap_them_all();
|
||||
reap_them_all(0);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -497,6 +518,75 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check uwsgi-cron table
|
||||
if (ushared->cron_cnt) {
|
||||
current_time = time(NULL);
|
||||
uwsgi_cron_delta = localtime( ¤t_time );
|
||||
|
||||
if (uwsgi_cron_delta) {
|
||||
|
||||
// fix month
|
||||
uwsgi_cron_delta->tm_mon++;
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
for(i=0;i<ushared->cron_cnt;i++) {
|
||||
|
||||
struct uwsgi_cron *ucron = &ushared->cron[i];
|
||||
int uc_minute, uc_hour, uc_day, uc_month, uc_week;
|
||||
|
||||
uc_minute = ucron->minute;
|
||||
uc_hour = ucron->hour;
|
||||
uc_day = ucron->day;
|
||||
uc_month = ucron->month;
|
||||
uc_week = ucron->week;
|
||||
|
||||
if (ucron->minute == -1) uc_minute = uwsgi_cron_delta->tm_min;
|
||||
if (ucron->hour == -1) uc_hour = uwsgi_cron_delta->tm_hour;
|
||||
if (ucron->month == -1) uc_month = uwsgi_cron_delta->tm_mon;
|
||||
|
||||
// mday and wday are ORed
|
||||
if (ucron->day == -1 && ucron->week == -1) {
|
||||
if (ucron->day == -1) uc_day = uwsgi_cron_delta->tm_mday;
|
||||
if (ucron->week == -1) uc_week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (ucron->day == -1) {
|
||||
ucron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
else if (ucron->week == -1) {
|
||||
ucron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else {
|
||||
if (ucron->day == uwsgi_cron_delta->tm_mday) {
|
||||
ucron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (ucron->week == uwsgi_cron_delta->tm_wday) {
|
||||
ucron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute &&
|
||||
uwsgi_cron_delta->tm_hour == uc_hour &&
|
||||
uwsgi_cron_delta->tm_mon == uc_month &&
|
||||
uwsgi_cron_delta->tm_mday == uc_day &&
|
||||
uwsgi_cron_delta->tm_wday == uc_week) {
|
||||
|
||||
|
||||
// date match, signal it ?
|
||||
if (current_time - ucron->last_job > 60) {
|
||||
uwsgi_route_signal(ucron->sig);
|
||||
ucron->last_job = current_time;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("localtime()");
|
||||
}
|
||||
}
|
||||
|
||||
if (rlen > 0) {
|
||||
|
||||
if (uwsgi.log_master) {
|
||||
@@ -521,21 +611,35 @@ void master_loop(char **argv, char **environ) {
|
||||
if (byte == 0) {
|
||||
close(uwsgi.emperor_fd);
|
||||
uwsgi.has_emperor = 0;
|
||||
kill_them_all();
|
||||
kill_them_all(0);
|
||||
}
|
||||
// reload me
|
||||
else if (byte == 1) {
|
||||
grace_them_all();
|
||||
grace_them_all(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("lost connection with my emperor !!!\n");
|
||||
close(uwsgi.emperor_fd);
|
||||
uwsgi.has_emperor = 0;
|
||||
kill_them_all();
|
||||
kill_them_all(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef UWSGI_SNMP
|
||||
if (uwsgi.snmp_addr && interesting_fd == snmp_fd) {
|
||||
udp_len = sizeof(udp_client);
|
||||
rlen = recvfrom(snmp_fd, uwsgi.wsgi_req->buffer, uwsgi.buffer_size, 0, (struct sockaddr *) &udp_client, &udp_len);
|
||||
|
||||
if (rlen < 0) {
|
||||
uwsgi_error("recvfrom()");
|
||||
}
|
||||
else if (rlen > 0) {
|
||||
manage_snmp(snmp_fd, (uint8_t *) uwsgi.wsgi_req->buffer, rlen, &udp_client);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
if (uwsgi.udp_socket && interesting_fd == udp_fd) {
|
||||
@@ -593,12 +697,19 @@ void master_loop(char **argv, char **environ) {
|
||||
switch(uwsgi.wsgi_requests[0]->uh.modifier1) {
|
||||
case 95:
|
||||
memset(&nucn, 0, sizeof(struct uwsgi_cluster_node));
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uwsgi.wsgi_requests[0]->uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize);
|
||||
#endif
|
||||
uwsgi_hooked_parse(uwsgi.wsgi_requests[0]->buffer, uwsgi.wsgi_requests[0]->uh.pktsize, manage_cluster_announce, &nucn);
|
||||
if (nucn.name[0] != 0) {
|
||||
uwsgi_cluster_add_node(&nucn, CLUSTER_NODE_DYNAMIC);
|
||||
}
|
||||
break;
|
||||
case 96:
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uwsgi.wsgi_requests[0]->uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize);
|
||||
#endif
|
||||
uwsgi_log_verbose("%.*s\n", uwsgi.wsgi_requests[0]->uh.pktsize, uwsgi.wsgi_requests[0]->buffer);
|
||||
break;
|
||||
case 98:
|
||||
@@ -614,6 +725,9 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
break;
|
||||
case 73:
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uwsgi.wsgi_requests[0]->uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize);
|
||||
#endif
|
||||
uwsgi_log_verbose("[uWSGI cluster %s] new node available: %.*s\n", uwsgi.cluster, uwsgi.wsgi_requests[0]->uh.pktsize, uwsgi.wsgi_requests[0]->buffer);
|
||||
break;
|
||||
}
|
||||
@@ -629,7 +743,6 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_lock(uwsgi.fmon_table_lock);
|
||||
for(i=0;i<ushared->files_monitored_cnt;i++) {
|
||||
if (ushared->files_monitored[i].registered) {
|
||||
uwsgi_log("fmon check %d == %d\n", interesting_fd, ushared->files_monitored[i].fd) ;
|
||||
if (interesting_fd == ushared->files_monitored[i].fd) {
|
||||
struct uwsgi_fmon *uf = event_queue_ack_file_monitor(uwsgi.master_queue, interesting_fd);
|
||||
// now call the file_monitor handler
|
||||
@@ -679,6 +792,7 @@ void master_loop(char **argv, char **environ) {
|
||||
// checking logsize
|
||||
if (uwsgi.logfile) {
|
||||
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
|
||||
/*
|
||||
if (uwsgi.shared->logsize > 8192) {
|
||||
//uwsgi_log("logsize: %d\n", uwsgi.shared->logsize);
|
||||
char *new_logfile = uwsgi_malloc(strlen(uwsgi.logfile) + 14 + 1);
|
||||
@@ -688,6 +802,7 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
free(new_logfile);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -698,16 +813,6 @@ void master_loop(char **argv, char **environ) {
|
||||
// recalculate requests counter on race conditions risky configurations
|
||||
// a bit of inaccuracy is better than locking;)
|
||||
|
||||
if (uwsgi.cores > 1) {
|
||||
for(i=1;i<uwsgi.numproc+1;i++) {
|
||||
tmp_counter = 0;
|
||||
for(j=0;j<uwsgi.cores;j++) {
|
||||
tmp_counter += uwsgi.core[j]->requests;
|
||||
}
|
||||
uwsgi.workers[i].requests = tmp_counter;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.numproc > 1) {
|
||||
tmp_counter = 0;
|
||||
for(i=1;i<uwsgi.numproc+1;i++) {
|
||||
@@ -716,12 +821,12 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi.workers[0].requests = tmp_counter;
|
||||
}
|
||||
|
||||
// remove expired cache items
|
||||
// remove expired cache items TODO use rb_tree timeouts
|
||||
if (uwsgi.cache_max_items > 0) {
|
||||
for(i=0;i< (int)uwsgi.cache_max_items;i++) {
|
||||
uwsgi_wlock(uwsgi.cache_lock);
|
||||
if (uwsgi.cache_items[i].expires) {
|
||||
if (uwsgi.cache_items[i].expires < current_time) {
|
||||
if (uwsgi.cache_items[i].expires < (uint64_t) current_time) {
|
||||
uwsgi_cache_del(uwsgi.cache_items[i].key, uwsgi.cache_items[i].keysize);
|
||||
}
|
||||
}
|
||||
@@ -839,6 +944,12 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.cache_store && uwsgi.cache_filesize && uwsgi.cache_store_sync && ((master_cycles % uwsgi.cache_store_sync) == 0)) {
|
||||
if (msync(uwsgi.cache_items, uwsgi.cache_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+20
-1
@@ -247,6 +247,7 @@ void erlang_loop() {
|
||||
int fd;
|
||||
|
||||
int eversion;
|
||||
int i;
|
||||
|
||||
ei_x_buff x, xr;
|
||||
|
||||
@@ -291,13 +292,31 @@ void erlang_loop() {
|
||||
|
||||
x.index = 0;
|
||||
ei_decode_version(x.buff, &x.index, &eversion);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("eversion: %d\n", eversion);
|
||||
#endif
|
||||
|
||||
if (!strcmp(em.toname, "rex")) {
|
||||
uwsgi_erlang_rpc(fd, &em.from, &x);
|
||||
}
|
||||
else {
|
||||
dump_eterm(&x);
|
||||
int uep = -1;
|
||||
for(i=0;i<uerl.uep_cnt;i++) {
|
||||
if (!strcmp(uerl.uep[i].name, em.toname)) {
|
||||
uep = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uep > -1) {
|
||||
if (uerl.uep[uep].plugin) {
|
||||
uerl.uep[uep].plugin( uerl.uep[uep].func, &x );
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("!!! unregistered erlang process requested, dumping it !!!\n");
|
||||
dump_eterm(&x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+13
-1
@@ -1,9 +1,19 @@
|
||||
#include <ei.h>
|
||||
|
||||
#define MAX_UWSGI_ERLANG_PROCESSES 64
|
||||
|
||||
#define LONG_ARGS_ERLANG 17012
|
||||
#define LONG_ARGS_ERLANG_COOKIE 17013
|
||||
|
||||
|
||||
|
||||
struct uwsgi_erlang_process {
|
||||
|
||||
char name[0xff];
|
||||
void (*plugin)(void *, ei_x_buff *);
|
||||
void *func;
|
||||
};
|
||||
|
||||
struct uwsgi_erlang {
|
||||
|
||||
ei_cnode cnode;
|
||||
@@ -13,6 +23,8 @@ struct uwsgi_erlang {
|
||||
int fd;
|
||||
|
||||
void *lock;
|
||||
|
||||
struct uwsgi_erlang_process uep[MAX_UWSGI_ERLANG_PROCESSES];
|
||||
int uep_cnt;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+8
-3
@@ -209,7 +209,7 @@ uint16_t http_add_uwsgi_header(struct http_session *h_session, struct iovec *iov
|
||||
|
||||
for(i=0;i<hhlen;i++) {
|
||||
if (!status) {
|
||||
hh[i] = toupper(hh[i]);
|
||||
hh[i] = toupper((int)hh[i]);
|
||||
if (hh[i] == '-') hh[i] = '_';
|
||||
if (hh[i] == ':') {
|
||||
status = 1;
|
||||
@@ -548,9 +548,10 @@ void http_loop() {
|
||||
continue;
|
||||
}
|
||||
|
||||
uhttp_session->timeout = reset_timeout(uhttp_session);
|
||||
|
||||
switch(uhttp_session->status) {
|
||||
|
||||
uhttp_session->timeout = reset_timeout(uhttp_session);
|
||||
|
||||
case HTTP_STATUS_RECV:
|
||||
len = recv(uhttp_session->fd, uhttp_session->buffer + uhttp_session->h_pos, UMAX16-uhttp_session->h_pos, 0);
|
||||
@@ -681,6 +682,10 @@ void http_loop() {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uhttp_session->uh.pktsize = uwsgi_swap16(uhttp_session->uh.pktsize);
|
||||
#endif
|
||||
|
||||
uhttp_session->iov[0].iov_base = &uhttp_session->uh;
|
||||
uhttp_session->iov[0].iov_len = 4;
|
||||
|
||||
@@ -691,7 +696,7 @@ void http_loop() {
|
||||
}
|
||||
|
||||
// fd passing: PERFORMANCE EXTREME BOOST !!!
|
||||
if (uhttp_session->pass_fd) {
|
||||
if (uhttp_session->pass_fd && !uhttp_session->remains) {
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_iov = uhttp_session->iov;
|
||||
|
||||
+51
-6
@@ -72,6 +72,7 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
ei_decode_string(x->buff, &x->index, atom);
|
||||
pobj = PyString_FromString(atom);
|
||||
free(atom);
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_ATOM_EXT:
|
||||
atom = uwsgi_malloc(esize+1);
|
||||
@@ -84,6 +85,7 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
pobj = PyUnicode_FromString(atom);
|
||||
#endif
|
||||
free(atom);
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_SMALL_TUPLE_EXT:
|
||||
case ERL_LARGE_TUPLE_EXT:
|
||||
@@ -94,6 +96,7 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
PyTuple_SetItem(pobj, i, zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_LIST_EXT:
|
||||
case ERL_NIL_EXT:
|
||||
@@ -108,12 +111,14 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
PyList_Append(pobj, zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_BINARY_EXT:
|
||||
binary = uwsgi_malloc(esize);
|
||||
ei_decode_binary(x->buff, &x->index, binary, &bin_size);
|
||||
pobj = PyString_FromStringAndSize(binary, bin_size);
|
||||
free(binary);
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_PID_EXT:
|
||||
ei_decode_pid(x->buff, &x->index, &epid);
|
||||
@@ -121,6 +126,7 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
PyTuple_SetItem(pobj, 0, PyInt_FromLong(epid.num));
|
||||
PyTuple_SetItem(pobj, 1, PyInt_FromLong(epid.serial));
|
||||
PyTuple_SetItem(pobj, 2, PyInt_FromLong(epid.creation));
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
default:
|
||||
ei_skip_term(x->buff, &x->index);
|
||||
@@ -292,6 +298,42 @@ recv:
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
void pyerl_call_registered(void *func, ei_x_buff *x) {
|
||||
|
||||
PyObject *pyargs = PyTuple_New(1);
|
||||
PyObject *ret;
|
||||
|
||||
PyTuple_SetItem(pyargs, 0, erl_to_py(x));
|
||||
|
||||
ret = python_call((PyObject *) func, pyargs, 0);
|
||||
}
|
||||
|
||||
PyObject *pyerl_register_process(PyObject * self, PyObject * args) {
|
||||
|
||||
char *name;
|
||||
PyObject *callable;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sO:erlang_register_process", &name, &callable)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uerl.uep_cnt >= MAX_UWSGI_ERLANG_PROCESSES)
|
||||
return PyErr_Format(PyExc_ValueError, "You can define max %d erlang registered processes", MAX_UWSGI_ERLANG_PROCESSES);
|
||||
|
||||
if (strlen(name) > 0xff-1)
|
||||
return PyErr_Format(PyExc_ValueError, "Invalid erlang process name");
|
||||
|
||||
strcpy(uerl.uep[uerl.uep_cnt].name, name);
|
||||
uerl.uep[uerl.uep_cnt].plugin = pyerl_call_registered;
|
||||
uerl.uep[uerl.uep_cnt].func = callable;
|
||||
|
||||
uerl.uep_cnt++;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
}
|
||||
|
||||
PyObject *pyerl_recv(PyObject * self, PyObject * args) {
|
||||
|
||||
ei_x_buff x;
|
||||
@@ -401,6 +443,7 @@ static PyMethodDef uwsgi_pyerl_methods[] = {
|
||||
{"erlang_rpc", pyerl_rpc, METH_VARARGS, ""},
|
||||
{"erlang_lock", pyerl_lock, METH_VARARGS, ""},
|
||||
{"erlang_unlock", pyerl_unlock, METH_VARARGS, ""},
|
||||
{"erlang_register_process", pyerl_register_process, METH_VARARGS, ""},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -426,7 +469,7 @@ int py_to_erl(PyObject *pobj, ei_x_buff *x) {
|
||||
ei_x_encode_empty_list(x);
|
||||
}
|
||||
else if (PyString_Check(pobj)) {
|
||||
ei_x_encode_string(x, PyString_AsString(pobj));
|
||||
ei_x_encode_binary(x, PyString_AsString(pobj), PyString_Size(pobj));
|
||||
}
|
||||
else if (PyUnicode_Check(pobj)) {
|
||||
ei_x_encode_atom(x, PyString_AsString(pobj));
|
||||
@@ -435,11 +478,13 @@ int py_to_erl(PyObject *pobj, ei_x_buff *x) {
|
||||
ei_x_encode_long(x, PyInt_AsLong(pobj));
|
||||
}
|
||||
else if (PyList_Check(pobj)) {
|
||||
ei_x_encode_list_header(x, PyList_Size(pobj));
|
||||
for (i = 0; i < PyList_Size(pobj); i++) {
|
||||
pobj2 = PyList_GetItem(pobj, i);
|
||||
if (py_to_erl(pobj2, x) < 0) return -1;
|
||||
}
|
||||
if (PyList_Size(pobj) > 0) {
|
||||
ei_x_encode_list_header(x, PyList_Size(pobj));
|
||||
for (i = 0; i < PyList_Size(pobj); i++) {
|
||||
pobj2 = PyList_GetItem(pobj, i);
|
||||
if (py_to_erl(pobj2, x) < 0) return -1;
|
||||
}
|
||||
}
|
||||
ei_x_encode_empty_list(x);
|
||||
}
|
||||
else if (PyTuple_Check(pobj)) {
|
||||
|
||||
+10
-1
@@ -4,13 +4,22 @@ extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
|
||||
void gil_real_get() {
|
||||
#ifndef PYTHREE
|
||||
PyEval_AcquireLock();
|
||||
PyThreadState_Swap((PyThreadState *) pthread_getspecific(up.upt_gil_key));
|
||||
#else
|
||||
PyEval_RestoreThread((PyThreadState *) pthread_getspecific(up.upt_gil_key));
|
||||
#endif
|
||||
}
|
||||
|
||||
void gil_real_release() {
|
||||
#ifndef PYTHREE
|
||||
pthread_setspecific(up.upt_gil_key, (void *) PyThreadState_Swap(NULL));
|
||||
PyEval_ReleaseLock();
|
||||
PyEval_ReleaseLock();
|
||||
#else
|
||||
pthread_setspecific(up.upt_gil_key, (void *) PyThreadState_Get());
|
||||
PyEval_SaveThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
void gil_fake_get() {}
|
||||
|
||||
@@ -13,6 +13,9 @@ struct option uwsgi_python_options[] = {
|
||||
{"callable", required_argument, 0, LONG_ARGS_CALLABLE},
|
||||
{"test", required_argument, 0, 'j'},
|
||||
{"home", required_argument, 0, 'H'},
|
||||
{"virtualenv", required_argument, 0, 'H'},
|
||||
{"venv", required_argument, 0, 'H'},
|
||||
{"pyhome", required_argument, 0, 'H'},
|
||||
{"pythonpath", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"python-path", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"pymodule-alias", required_argument, 0, LONG_ARGS_PYMODULE_ALIAS},
|
||||
@@ -795,6 +798,9 @@ int uwsgi_python_xml(char *node, char *content) {
|
||||
uwsgi.wsgi_req->module_len = strlen(uwsgi.wsgi_req->module);
|
||||
return init_uwsgi_app(LOADER_DYN, uwsgi.wsgi_req, uwsgi.wsgi_req, interpreter);
|
||||
}
|
||||
else {
|
||||
return init_uwsgi_app(LOADER_UWSGI, content, uwsgi.wsgi_req, interpreter);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp("pyhome", node)) {
|
||||
@@ -829,6 +835,9 @@ int uwsgi_python_signal_handler(uint8_t sig, void *handler) {
|
||||
if (!args)
|
||||
return -1;
|
||||
|
||||
if (!handler) return -1;
|
||||
|
||||
|
||||
PyTuple_SetItem(args, 0, PyInt_FromLong(sig));
|
||||
|
||||
ret = python_call(handler, args, 0);
|
||||
|
||||
@@ -181,6 +181,25 @@ PyObject *py_uwsgi_close(PyObject * self, PyObject * args) {
|
||||
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_add_cron(PyObject * self, PyObject * args) {
|
||||
|
||||
uint8_t uwsgi_signal;
|
||||
int minute, hour, day, month, week;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "Biiiii:add_cron", &uwsgi_signal, &minute, &hour, &day, &month, &week)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uwsgi_signal_add_cron(uwsgi_signal, minute, hour, day, month, week)) {
|
||||
return PyErr_Format(PyExc_ValueError, "unable to add cron");
|
||||
}
|
||||
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject *py_uwsgi_add_timer(PyObject * self, PyObject * args) {
|
||||
|
||||
uint8_t uwsgi_signal;
|
||||
@@ -2343,6 +2362,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"add_file_monitor", py_uwsgi_add_file_monitor, METH_VARARGS, ""},
|
||||
{"add_timer", py_uwsgi_add_timer, METH_VARARGS, ""},
|
||||
{"add_rb_timer", py_uwsgi_add_rb_timer, METH_VARARGS, ""},
|
||||
{"add_cron", py_uwsgi_add_cron, METH_VARARGS, ""},
|
||||
|
||||
{"register_rpc", py_uwsgi_register_rpc, METH_VARARGS, ""},
|
||||
{"rpc", py_uwsgi_rpc, METH_VARARGS, ""},
|
||||
|
||||
@@ -398,8 +398,8 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
|
||||
#endif
|
||||
#ifdef PYTHREE
|
||||
pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, "ignore");
|
||||
pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, "ignore");
|
||||
pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL);
|
||||
pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL);
|
||||
#else
|
||||
pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
|
||||
pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
|
||||
@@ -428,15 +428,26 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
if (uwsgi.post_buffering > 0) {
|
||||
UWSGI_RELEASE_GIL
|
||||
// read to disk
|
||||
if (wsgi_req->post_cl <= (size_t) uwsgi.post_buffering) {
|
||||
if (!uwsgi_read_whole_body(wsgi_req, wsgi_req->post_buffering_buf, uwsgi.post_buffering_bufsize)) {
|
||||
goto clear;
|
||||
// read to disk if post_cl > post_buffering
|
||||
if (!up.pep3333_input) {
|
||||
if (wsgi_req->post_cl >= (size_t) uwsgi.post_buffering) {
|
||||
if (!uwsgi_read_whole_body(wsgi_req, wsgi_req->post_buffering_buf, uwsgi.post_buffering_bufsize)) {
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!uwsgi_read_whole_body_in_mem(wsgi_req, wsgi_req->post_buffering_buf)) {
|
||||
goto clear;
|
||||
// read to disk if post_cl > post_buffering
|
||||
if (wsgi_req->post_cl >= (size_t) uwsgi.post_buffering) {
|
||||
if (!uwsgi_read_whole_body(wsgi_req, wsgi_req->post_buffering_buf, uwsgi.post_buffering_bufsize)) {
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
// on tiny post use memory
|
||||
else {
|
||||
if (!uwsgi_read_whole_body_in_mem(wsgi_req, wsgi_req->post_buffering_buf)) {
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
}
|
||||
UWSGI_GET_GIL
|
||||
|
||||
@@ -893,6 +893,9 @@ int uwsgi_string_sendto(int fd, uint8_t modifier1, uint8_t modifier2, struct soc
|
||||
|
||||
uh->modifier1 = modifier1;
|
||||
uh->pktsize = len;
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uh->pktsize = uwsgi_swap16(uh->pktsize);
|
||||
#endif
|
||||
uh->modifier2 = modifier2;
|
||||
|
||||
memcpy(upkt+4, message, len);
|
||||
|
||||
@@ -91,6 +91,31 @@ int uwsgi_add_timer(uint8_t sig, int secs) {
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_signal_add_cron(uint8_t sig, int minute, int hour, int day, int month, int week) {
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
|
||||
if (ushared->cron_cnt < MAX_CRONS) {
|
||||
|
||||
ushared->cron[ushared->cron_cnt].sig = sig;
|
||||
ushared->cron[ushared->cron_cnt].minute = minute;
|
||||
ushared->cron[ushared->cron_cnt].hour = hour;
|
||||
ushared->cron[ushared->cron_cnt].day = day;
|
||||
ushared->cron[ushared->cron_cnt].month = month;
|
||||
ushared->cron[ushared->cron_cnt].week = week;
|
||||
ushared->cron_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max %d cron !!!\n", MAX_CRONS);
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_signal_add_rb_timer(uint8_t sig, int secs, int iterations) {
|
||||
|
||||
uwsgi_lock(uwsgi.rb_timer_table_lock);
|
||||
|
||||
@@ -10,20 +10,20 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
// leave 1 byte for abstract namespace (108 linux -> 104 bsd/mac)
|
||||
if (strlen(socket_name) > 102) {
|
||||
uwsgi_log( "invalid socket name\n");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
uws_addr = malloc(sizeof(struct sockaddr_un));
|
||||
if (uws_addr == NULL) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
memset(uws_addr, 0, sizeof(struct sockaddr_un));
|
||||
serverfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (serverfd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
if (abstract_socket == 0) {
|
||||
if (unlink(socket_name) != 0 && errno != ENOENT) {
|
||||
@@ -44,13 +44,13 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
if (bind(serverfd, (struct sockaddr *) uws_addr, strlen(socket_name) + abstract_socket + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) {
|
||||
#endif
|
||||
uwsgi_error("bind()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
|
||||
if (listen(serverfd, listen_queue) != 0) {
|
||||
uwsgi_error("listen()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
// chmod unix socket for lazy users
|
||||
@@ -104,7 +104,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
|
||||
if (serverfd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
uwsgi_log( "binding on %d SCTP interfaces on port: %d\n", num_ip, ntohs(uws_addr[0].sin_port));
|
||||
@@ -112,7 +112,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
|
||||
if (sctp_bindx(serverfd, (struct sockaddr *) uws_addr, num_ip, SCTP_BINDX_ADD_ADDR) != 0) {
|
||||
uwsgi_error("sctp_bindx()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
sctp_im.sinit_max_instreams = 0xFFFF;
|
||||
@@ -124,7 +124,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
|
||||
if (listen(serverfd, listen_queue) != 0) {
|
||||
uwsgi_error("listen()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
return serverfd;
|
||||
@@ -328,7 +328,7 @@ char *generate_socket_name(char *socket_name) {
|
||||
struct ifaddrs *ifap = NULL, *ifa, *ifaf;
|
||||
if (getifaddrs(&ifap)) {
|
||||
uwsgi_error("getifaddrs()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
// here socket_name will be truncated
|
||||
@@ -359,7 +359,7 @@ char *generate_socket_name(char *socket_name) {
|
||||
}
|
||||
|
||||
uwsgi_log("unable to find avalid socket address\n");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
return socket_name ;
|
||||
}
|
||||
@@ -381,7 +381,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
serverfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (serverfd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
if (socket_name[0] == 0) {
|
||||
@@ -394,7 +394,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
|
||||
uwsgi_error("setsockopt()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
if (!uwsgi.no_defer_accept) {
|
||||
@@ -421,12 +421,12 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
uwsgi_log("probably another instance of uWSGI is running on the same address.\n");
|
||||
}
|
||||
uwsgi_error("bind()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
if (listen(serverfd, listen_queue) != 0) {
|
||||
uwsgi_error("listen()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
def application(env, start_response):
|
||||
while 1:
|
||||
pass
|
||||
@@ -394,10 +394,6 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi.workers[0].requests++;
|
||||
uwsgi.workers[uwsgi.mywid].requests++;
|
||||
|
||||
if (uwsgi.cores > 1) {
|
||||
uwsgi.core[wsgi_req->async_id]->requests++;
|
||||
}
|
||||
|
||||
// after_request hook
|
||||
if (uwsgi.p[wsgi_req->uh.modifier1]->after_request) uwsgi.p[wsgi_req->uh.modifier1]->after_request(wsgi_req);
|
||||
|
||||
@@ -504,7 +500,7 @@ polling:
|
||||
if (read(uwsgi.sockets_poll[uwsgi.sockets_cnt].fd, &uwsgi_signal, 1) <= 0) {
|
||||
if (uwsgi.no_orphans) {
|
||||
uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid);
|
||||
end_me();
|
||||
end_me(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -614,13 +610,11 @@ void env_to_arg(char *src, char *dst) {
|
||||
|
||||
void parse_sys_envs(char **envs) {
|
||||
|
||||
struct option *lopt, *aopt;
|
||||
|
||||
char **uenvs = envs;
|
||||
char *earg, *eq_pos;
|
||||
|
||||
while(*uenvs) {
|
||||
if (!strncmp(*uenvs, "UWSGI_", 6)) {
|
||||
if (!strncmp(*uenvs, "UWSGI_", 6) && strncmp(*uenvs, "UWSGI_RELOADS=",14)) {
|
||||
earg = uwsgi_malloc(strlen(*uenvs+6)+1);
|
||||
env_to_arg(*uenvs+6, earg);
|
||||
eq_pos = strchr(earg, '=');
|
||||
@@ -629,27 +623,7 @@ void parse_sys_envs(char **envs) {
|
||||
}
|
||||
eq_pos[0] = 0;
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp(earg, aopt->name)) {
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
}
|
||||
else {
|
||||
if (eq_pos[1] != 0) {
|
||||
manage_opt(aopt->val, eq_pos+1);
|
||||
}
|
||||
else {
|
||||
manage_opt(aopt->val, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
|
||||
add_exported_option(earg, eq_pos+1, 0);
|
||||
}
|
||||
uenvs++;
|
||||
}
|
||||
@@ -1173,37 +1147,7 @@ end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void add_exported_option(int i, char *value) {
|
||||
|
||||
char *key = NULL;
|
||||
struct option *lopt, *aopt;
|
||||
|
||||
if (i == 0) {
|
||||
key = value;
|
||||
value = NULL;
|
||||
}
|
||||
else {
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (aopt->val == 0 && *aopt->flag == i) {
|
||||
key = (char *) aopt->name;
|
||||
break;
|
||||
}
|
||||
if (aopt->val == i) {
|
||||
key = (char *) aopt->name;
|
||||
break;
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
}
|
||||
|
||||
//uwsgi_log("%s = %s\n", key, value);
|
||||
|
||||
if (!key) return;
|
||||
|
||||
|
||||
void add_exported_option(char *key, char *value, int configured) {
|
||||
|
||||
if (!uwsgi.exported_opts) {
|
||||
uwsgi.exported_opts = uwsgi_malloc(sizeof(struct uwsgi_opt*));
|
||||
@@ -1216,10 +1160,10 @@ void add_exported_option(int i, char *value) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uwsgi.exported_opts[uwsgi.exported_opts_cnt] = uwsgi_malloc(sizeof(struct uwsgi_opt));
|
||||
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->key = key;
|
||||
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->value = value;
|
||||
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->configured = configured;
|
||||
uwsgi.exported_opts_cnt++;
|
||||
|
||||
}
|
||||
@@ -1489,6 +1433,7 @@ void init_magic_table(char *magic_table[]) {
|
||||
}
|
||||
|
||||
magic_table['%'] = "%";
|
||||
magic_table['('] = "%(";
|
||||
}
|
||||
|
||||
char *uwsgi_get_last_char(char *what, char c) {
|
||||
@@ -1634,8 +1579,86 @@ int is_a_number(char *what) {
|
||||
int i;
|
||||
|
||||
for(i=0;i<(int)strlen(what);i++) {
|
||||
if (!isdigit(what[i])) return 0;
|
||||
if (!isdigit((int)what[i])) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uwsgi_unix_signal(int signum, void (*func)(int)) {
|
||||
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof(struct sigaction));
|
||||
|
||||
sa.sa_handler = func;
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
|
||||
if (sigaction(signum, &sa, NULL) < 0) {
|
||||
uwsgi_error("sigaction()");
|
||||
}
|
||||
}
|
||||
|
||||
char *uwsgi_get_exported_opt(char *key) {
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
if (!strcmp(uwsgi.exported_opts[i]->key, key)) {
|
||||
return uwsgi.exported_opts[i]->value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *uwsgi_get_optname_by_index(int index) {
|
||||
|
||||
struct option *aopt;
|
||||
struct option *lopt = uwsgi.long_options;
|
||||
|
||||
while ( (aopt = lopt) ) {
|
||||
if (!aopt->name) break;
|
||||
if (aopt->val == index) {
|
||||
return (char *) aopt->name;
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int uwsgi_list_has_num(char *list, int num) {
|
||||
|
||||
char *list2 = uwsgi_concat2(list, "");
|
||||
|
||||
char *p = strtok(list2, ",");
|
||||
while (p != NULL) {
|
||||
if (atoi(p) == num) {
|
||||
free(list2);
|
||||
return 1;
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_list_has_str(char *list, char *str) {
|
||||
|
||||
char *list2 = uwsgi_concat2(list+1, "");
|
||||
|
||||
char *p = strtok(list2, " ");
|
||||
while (p != NULL) {
|
||||
if (!strcasecmp(p, str)) {
|
||||
free(list2);
|
||||
return 1;
|
||||
}
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ static struct option long_base_options[] = {
|
||||
{"sharedarea", required_argument, 0, 'A'},
|
||||
{"cache", required_argument, 0, LONG_ARGS_CACHE},
|
||||
{"cache-blocksize", required_argument, 0, LONG_ARGS_CACHE_BLOCKSIZE},
|
||||
{"cache-store", required_argument, 0, LONG_ARGS_CACHE_STORE},
|
||||
{"cache-store-sync", required_argument, 0, LONG_ARGS_CACHE_STORE_SYNC},
|
||||
{"queue", required_argument, 0, LONG_ARGS_QUEUE},
|
||||
{"queue-blocksize", required_argument, 0, LONG_ARGS_QUEUE_BLOCKSIZE},
|
||||
#ifdef UWSGI_SPOOLER
|
||||
@@ -95,6 +97,7 @@ static struct option long_base_options[] = {
|
||||
{"limit-post", required_argument, 0, LONG_ARGS_LIMIT_POST},
|
||||
{"no-orphans", no_argument, &uwsgi.no_orphans, 1},
|
||||
{"prio", required_argument, 0, LONG_ARGS_PRIO},
|
||||
{"cpu-affinity", required_argument, 0, LONG_ARGS_CPU_AFFINITY},
|
||||
{"post-buffering", required_argument, 0, LONG_ARGS_POST_BUFFERING},
|
||||
{"post-buffering-bufsize", required_argument, 0, LONG_ARGS_POST_BUFFERING_SIZE},
|
||||
{"upload-progress", required_argument, 0, LONG_ARGS_UPLOAD_PROGRESS},
|
||||
@@ -112,7 +115,7 @@ static struct option long_base_options[] = {
|
||||
{"cluster-log", required_argument, 0, LONG_ARGS_CLUSTER_LOG},
|
||||
{"subscribe-to", required_argument, 0, LONG_ARGS_SUBSCRIBE_TO},
|
||||
#ifdef UWSGI_SNMP
|
||||
{"snmp", no_argument, 0, LONG_ARGS_SNMP},
|
||||
{"snmp", optional_argument, 0, LONG_ARGS_SNMP},
|
||||
{"snmp-community", required_argument, 0, LONG_ARGS_SNMP_COMMUNITY},
|
||||
#endif
|
||||
{"check-interval", required_argument, 0, LONG_ARGS_CHECK_INTERVAL},
|
||||
@@ -153,13 +156,17 @@ static struct option long_base_options[] = {
|
||||
{"cgroup-opt", required_argument, 0, LONG_ARGS_CGROUP_OPT},
|
||||
{"namespace", required_argument, 0, LONG_ARGS_LINUX_NS},
|
||||
{"ns", required_argument, 0, LONG_ARGS_LINUX_NS},
|
||||
{"namespace-net", required_argument, 0, LONG_ARGS_LINUX_NS_NET},
|
||||
{"ns-net", required_argument, 0, LONG_ARGS_LINUX_NS_NET},
|
||||
#endif
|
||||
{"loop", required_argument, 0, LONG_ARGS_LOOP},
|
||||
{"worker-exec", required_argument, 0, LONG_ARGS_WORKER_EXEC},
|
||||
{"attach-daemon", required_argument, 0, LONG_ARGS_ATTACH_DAEMON},
|
||||
{"plugins", required_argument, 0, LONG_ARGS_PLUGINS},
|
||||
{"allowed-modifiers", required_argument, 0, LONG_ARGS_ALLOWED_MODIFIERS},
|
||||
{"remap-modifier", required_argument, 0, LONG_ARGS_REMAP_MODIFIER},
|
||||
{"dump-options", no_argument, &uwsgi.dump_options, 1},
|
||||
{"show-config", no_argument, &uwsgi.show_config, 1},
|
||||
{"print", required_argument, 0, LONG_ARGS_PRINT},
|
||||
{"version", no_argument, 0, LONG_ARGS_VERSION},
|
||||
{0, 0, 0, 0}
|
||||
@@ -188,22 +195,22 @@ void warn_pipe()
|
||||
}
|
||||
}
|
||||
|
||||
void gracefully_kill()
|
||||
void gracefully_kill(int signum)
|
||||
{
|
||||
uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
|
||||
if (UWSGI_IS_IN_REQUEST) {
|
||||
uwsgi.workers[uwsgi.mywid].manage_next_request = 0;
|
||||
} else {
|
||||
reload_me();
|
||||
reload_me(0);
|
||||
}
|
||||
}
|
||||
|
||||
void reload_me()
|
||||
void reload_me(int signum)
|
||||
{
|
||||
exit(UWSGI_RELOAD_CODE);
|
||||
}
|
||||
|
||||
void end_me()
|
||||
void end_me(int signum)
|
||||
{
|
||||
exit(UWSGI_END_CODE);
|
||||
}
|
||||
@@ -214,7 +221,7 @@ void goodbye_cruel_world()
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void kill_them_all()
|
||||
void kill_them_all(int signum)
|
||||
{
|
||||
int i;
|
||||
uwsgi.to_hell = 1;
|
||||
@@ -224,16 +231,18 @@ void kill_them_all()
|
||||
kill(uwsgi.workers[i].pid, SIGINT);
|
||||
}
|
||||
|
||||
for (i = 0; i <= uwsgi.gateways_cnt; i++) {
|
||||
kill(uwsgi.gateways[i].pid, SIGKILL);
|
||||
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
|
||||
if (uwsgi.shared->daemons[i].pid > 0)
|
||||
kill(uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
}
|
||||
|
||||
for (i = 0; i <= uwsgi.shared->daemons_cnt; i++) {
|
||||
kill(uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
for (i = 0; i < uwsgi.gateways_cnt; i++) {
|
||||
if (uwsgi.gateways[i].pid > 0)
|
||||
kill(uwsgi.gateways[i].pid, SIGKILL);
|
||||
}
|
||||
}
|
||||
|
||||
void grace_them_all()
|
||||
void grace_them_all(int signum)
|
||||
{
|
||||
int i;
|
||||
uwsgi.to_heaven = 1;
|
||||
@@ -243,9 +252,16 @@ void grace_them_all()
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
|
||||
if (uwsgi.shared->daemons[i].pid > 0)
|
||||
kill(uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gateways_cnt; i++) {
|
||||
if (uwsgi.gateways[i].pid > 0)
|
||||
kill(uwsgi.gateways[i].pid, SIGKILL);
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log("...gracefully killing workers...\n");
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].pid > 0)
|
||||
@@ -254,15 +270,37 @@ void grace_them_all()
|
||||
|
||||
}
|
||||
|
||||
void reap_them_all()
|
||||
void uwsgi_nuclear_blast() {
|
||||
|
||||
if (!uwsgi.workers) {
|
||||
reap_them_all(0);
|
||||
}
|
||||
else if (uwsgi.master_process) {
|
||||
if (getpid() == uwsgi.workers[0].pid) {
|
||||
reap_them_all(0);
|
||||
}
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void reap_them_all(int signum)
|
||||
{
|
||||
int i;
|
||||
uwsgi.to_heaven = 1;
|
||||
|
||||
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
|
||||
if (uwsgi.shared->daemons[i].pid > 0)
|
||||
kill(uwsgi.shared->daemons[i].pid, SIGKILL);
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gateways_cnt; i++) {
|
||||
if (uwsgi.gateways[i].pid > 0)
|
||||
kill(uwsgi.gateways[i].pid, SIGKILL);
|
||||
}
|
||||
|
||||
if (!uwsgi.workers) return;
|
||||
|
||||
uwsgi_log("...brutally killing workers...\n");
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
if (uwsgi.workers[i].pid > 0)
|
||||
@@ -281,7 +319,7 @@ void harakiri()
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void stats()
|
||||
void stats(int signum)
|
||||
{
|
||||
//fix this for better logging(this cause races)
|
||||
struct uwsgi_app *ua = NULL;
|
||||
@@ -366,6 +404,18 @@ static void vacuum(void)
|
||||
if (chdir(uwsgi.cwd)) {
|
||||
uwsgi_error("chdir()");
|
||||
}
|
||||
if (uwsgi.pidfile && !uwsgi.uid) {
|
||||
if (unlink(uwsgi.pidfile)) {
|
||||
uwsgi_error("unlink()");
|
||||
} else {
|
||||
uwsgi_log("VACUUM: pidfile removed.\n");
|
||||
}
|
||||
}
|
||||
if (uwsgi.chdir) {
|
||||
if (chdir(uwsgi.chdir)) {
|
||||
uwsgi_error("chdir()");
|
||||
}
|
||||
}
|
||||
for (i = 0; i < uwsgi.sockets_cnt; i++) {
|
||||
if (uwsgi.sockets[i].family == AF_UNIX) {
|
||||
if (unlink(uwsgi.sockets[i].name)) {
|
||||
@@ -375,13 +425,6 @@ static void vacuum(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uwsgi.pidfile && !uwsgi.uid) {
|
||||
if (unlink(uwsgi.pidfile)) {
|
||||
uwsgi_error("unlink()");
|
||||
} else {
|
||||
uwsgi_log("VACUUM: pidfile removed.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,7 +432,7 @@ static void vacuum(void)
|
||||
int main(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
|
||||
int i;
|
||||
int i, j;
|
||||
int rlen;
|
||||
|
||||
FILE *pidfile;
|
||||
@@ -411,6 +454,7 @@ int main(int argc, char *argv[], char *envp[])
|
||||
|
||||
char *emperor_env;
|
||||
char *magic_table[0xff];
|
||||
char *optname;
|
||||
|
||||
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
@@ -546,24 +590,26 @@ int main(int argc, char *argv[], char *envp[])
|
||||
}
|
||||
build_options();
|
||||
|
||||
uwsgi.option_index = -1;
|
||||
while ((i = getopt_long(argc, argv, short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
|
||||
if (i == 0) {
|
||||
add_exported_option(0, (char *)uwsgi.long_options[uwsgi.option_index].name);
|
||||
|
||||
if (uwsgi.option_index > -1) {
|
||||
optname = (char *)uwsgi.long_options[uwsgi.option_index].name;
|
||||
}
|
||||
else {
|
||||
optname = uwsgi_get_optname_by_index(i);
|
||||
}
|
||||
// is this a flagged option ?
|
||||
if (i == 0) {
|
||||
add_exported_option(optname, "1", 0);
|
||||
}
|
||||
else {
|
||||
add_exported_option(optname, optarg, 1);
|
||||
manage_opt(i, optarg);
|
||||
}
|
||||
uwsgi.option_index = -1;
|
||||
}
|
||||
|
||||
if (uwsgi.dump_options) {
|
||||
struct option *lopt = uwsgi.long_options;
|
||||
while(lopt->name) {
|
||||
uwsgi_log("--%s\n", lopt->name);
|
||||
lopt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (optind < argc) {
|
||||
char *lazy = argv[optind];
|
||||
if (lazy[0] != '[') {
|
||||
@@ -611,6 +657,15 @@ int main(int argc, char *argv[], char *envp[])
|
||||
}
|
||||
}
|
||||
|
||||
if (gethostname(uwsgi.hostname, 255)) {
|
||||
uwsgi_error("gethostname()");
|
||||
}
|
||||
uwsgi.hostname_len = strlen(uwsgi.hostname);
|
||||
|
||||
|
||||
magic_table['v'] = uwsgi.cwd;
|
||||
magic_table['h'] = uwsgi.hostname;
|
||||
|
||||
#ifdef UWSGI_XML
|
||||
if (uwsgi.xml_config != NULL) {
|
||||
magic_table['o'] = uwsgi.xml_config;
|
||||
@@ -625,6 +680,7 @@ int main(int argc, char *argv[], char *envp[])
|
||||
if (uwsgi_get_last_char(uwsgi.xml_config, '.')) magic_table['e'] = uwsgi_get_last_char(uwsgi.xml_config, '.')+1;
|
||||
if (uwsgi_get_last_char(magic_table['s'], '.')) magic_table['n'] = uwsgi_concat2n(magic_table['s'], uwsgi_get_last_char(magic_table['s'], '.')-magic_table['s'], "", 0) ;
|
||||
uwsgi_xml_config(uwsgi.wsgi_req, 0, magic_table);
|
||||
uwsgi.xml_config = magic_table['p'];
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_INI
|
||||
@@ -669,12 +725,121 @@ int main(int argc, char *argv[], char *envp[])
|
||||
//parse environ
|
||||
parse_sys_envs(environ);
|
||||
|
||||
if (gethostname(uwsgi.hostname, 255)) {
|
||||
uwsgi_error("gethostname()");
|
||||
|
||||
// second pass
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
int has_percent = 0;
|
||||
char *magic_key = NULL;
|
||||
char *magic_val = NULL;
|
||||
if (uwsgi.exported_opts[i]->value && !uwsgi.exported_opts[i]->configured) {
|
||||
for(j=0;j<(int)strlen(uwsgi.exported_opts[i]->value);j++) {
|
||||
if (uwsgi.exported_opts[i]->value[j] == '%') {
|
||||
has_percent = 1;
|
||||
}
|
||||
else if (uwsgi.exported_opts[i]->value[j] == '(' && has_percent == 1) {
|
||||
has_percent = 2;
|
||||
magic_key = uwsgi.exported_opts[i]->value + j + 1;
|
||||
}
|
||||
else if (has_percent > 1) {
|
||||
if (uwsgi.exported_opts[i]->value[j] == ')') {
|
||||
if (has_percent <= 2) {
|
||||
magic_key = NULL;
|
||||
has_percent = 0;
|
||||
continue;
|
||||
}
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("need to interpret the %.*s tag\n", has_percent-2, magic_key);
|
||||
#endif
|
||||
char *tmp_magic_key = uwsgi_concat2n(magic_key, has_percent-2, "", 0);
|
||||
magic_val = uwsgi_get_exported_opt(tmp_magic_key);
|
||||
free(tmp_magic_key);
|
||||
if (!magic_val) {
|
||||
magic_key = NULL;
|
||||
has_percent = 0;
|
||||
continue;
|
||||
}
|
||||
uwsgi.exported_opts[i]->value = uwsgi_concat4n(
|
||||
uwsgi.exported_opts[i]->value, (magic_key-2) - uwsgi.exported_opts[i]->value,
|
||||
magic_val, strlen(magic_val),
|
||||
magic_key + (has_percent-1),
|
||||
strlen(magic_key + (has_percent-1)), "", 0);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("computed new value = %s\n", uwsgi.exported_opts[i]->value);
|
||||
#endif
|
||||
magic_key = NULL;
|
||||
has_percent = 0;
|
||||
}
|
||||
else {
|
||||
has_percent++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
has_percent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
uwsgi.hostname_len = strlen(uwsgi.hostname);
|
||||
|
||||
|
||||
// ok, the options dictionary is available, lets manage it
|
||||
|
||||
struct option *lopt = uwsgi.long_options;
|
||||
struct option *aopt;
|
||||
char *val;
|
||||
|
||||
for(i=0;i<uwsgi.exported_opts_cnt;i++) {
|
||||
|
||||
if (uwsgi.exported_opts[i]->configured) continue;
|
||||
lopt = uwsgi.long_options;;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name) break;
|
||||
|
||||
if (!strcmp(aopt->name, uwsgi.exported_opts[i]->key)) {
|
||||
val = uwsgi.exported_opts[i]->value;
|
||||
|
||||
if (aopt->flag) *aopt->flag = aopt->val;
|
||||
else if (val) {
|
||||
if (aopt->has_arg == optional_argument) {
|
||||
if (!strcasecmp("true", val)) {
|
||||
val = NULL;
|
||||
}
|
||||
}
|
||||
if (aopt->has_arg == no_argument) {
|
||||
if (!strcasecmp("false", val) || val[0] == '0') {
|
||||
lopt++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
manage_opt(aopt->val, val);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* uWSGI IS CONFIGURED !!! */
|
||||
|
||||
if (uwsgi.dump_options) {
|
||||
struct option *lopt = uwsgi.long_options;
|
||||
while(lopt->name) {
|
||||
uwsgi_log("--%s\n", lopt->name);
|
||||
lopt++;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.show_config) {
|
||||
fprintf(stdout, "\n;uWSGI instance configuration\n[uwsgi]\n");
|
||||
for(i=0;i<uwsgi.exported_opts_cnt;i++) {
|
||||
if (uwsgi.exported_opts[i]->value) {
|
||||
fprintf(stdout,"%s = %s\n", uwsgi.exported_opts[i]->key, uwsgi.exported_opts[i]->value);
|
||||
}
|
||||
else {
|
||||
fprintf(stdout,"%s = true\n", uwsgi.exported_opts[i]->key);
|
||||
}
|
||||
}
|
||||
fprintf(stdout, ";end of configuration\n\n");
|
||||
}
|
||||
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
@@ -736,7 +901,7 @@ options_parsed:
|
||||
uwsgi_log("***\n*** You are running a DEBUG version of uWSGI, plese disable DEBUG in uwsgiconfig.py and recompile it ***\n***\n");
|
||||
#endif
|
||||
|
||||
uwsgi_log("compiled with version: %s\n", __VERSION__);
|
||||
uwsgi_log("compiled with version: %s on %s\n", __VERSION__, UWSGI_BUILD_DATE);
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uwsgi_log("*** big endian arch detected ***\n");
|
||||
@@ -771,19 +936,29 @@ options_parsed:
|
||||
#define CLONE_NEWIPC 0x08000000
|
||||
#endif
|
||||
if (uwsgi.ns) {
|
||||
void *linux_clone_stack = alloca(uwsgi.page_size);
|
||||
for(;;) {
|
||||
pid_t pid = clone(uwsgi_start, linux_clone_stack+uwsgi.page_size, SIGCHLD|CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS, (void *)argv);
|
||||
char stack[PTHREAD_STACK_MIN];
|
||||
int waitpid_status;
|
||||
uwsgi_log("*** jailing uWSGI in %s ***\n", uwsgi.ns);
|
||||
int clone_flags = SIGCHLD|CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
|
||||
//clone_flags |= CLONE_NEWNET;
|
||||
pid_t pid = clone(uwsgi_start, stack+PTHREAD_STACK_MIN, clone_flags, (void *)argv);
|
||||
if (pid == -1) {
|
||||
uwsgi_error("clone()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_log("waiting for jailed master dead...\n");
|
||||
pid = waitpid(pid, NULL, 0);
|
||||
uwsgi_log("waiting for jailed master (pid: %d) death...\n", (int) pid);
|
||||
pid = waitpid(pid, &waitpid_status, 0);
|
||||
if (pid < 0) {
|
||||
uwsgi_error("waitpid()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// in Linux this is reliable
|
||||
if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == 1) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log("pid %d ended. Respawning...\n", (int) pid);
|
||||
}
|
||||
}
|
||||
@@ -820,7 +995,7 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
#ifdef __linux__
|
||||
if (uwsgi.ns) {
|
||||
|
||||
|
||||
if (getpid() != 1) {
|
||||
uwsgi_log("your kernel does not support linux pid namespace\n");
|
||||
exit(1);
|
||||
@@ -840,25 +1015,9 @@ int uwsgi_start(void *v_argv) {
|
||||
int unmounted = 1;
|
||||
char *delim0, *delim1;
|
||||
|
||||
while(unmounted) {
|
||||
|
||||
unmounted = 0;
|
||||
procmounts = fopen("/proc/self/mounts", "r");
|
||||
while(fgets(line,1024,procmounts) != NULL) {
|
||||
delim0 = strchr(line, ' ');
|
||||
delim0++;
|
||||
delim1 = strchr(delim0, ' ');
|
||||
*delim1 = 0;
|
||||
if (!umount(delim0)) {
|
||||
unmounted++;
|
||||
}
|
||||
}
|
||||
fclose(procmounts);
|
||||
}
|
||||
|
||||
uwsgi_log("unmounting /proc\n");
|
||||
if (umount("/proc")) {
|
||||
uwsgi_error("umount()");
|
||||
if (chdir(uwsgi.ns)) {
|
||||
uwsgi_error("chdir()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *ns_tmp_mountpoint = uwsgi_concat2(uwsgi.ns, "/.uwsgi_ns_tmp_mountpoint");
|
||||
@@ -873,25 +1032,49 @@ int uwsgi_start(void *v_argv) {
|
||||
if (chdir(ns_tmp_mountpoint)) {
|
||||
uwsgi_error("chdir()");
|
||||
}
|
||||
|
||||
if (pivot_root(".", ns_tmp_mountpoint2)) {
|
||||
uwsgi_error("pivot_root()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (umount("/.uwsgi_ns_tmp_mountpoint")) {
|
||||
uwsgi_error("umount tmp()");
|
||||
if (chdir("/")) {
|
||||
uwsgi_error("chdir()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rmdir("/.uwsgi_ns_tmp_mountpoint/.uwsgi_ns_tmp_mountpoint");
|
||||
rmdir("/.uwsgi_ns_tmp_mountpoint");
|
||||
|
||||
free(ns_tmp_mountpoint2);
|
||||
free(ns_tmp_mountpoint);
|
||||
|
||||
uwsgi_log("remounting /proc\n");
|
||||
if (mount("proc","/proc", "proc", 0, NULL)) {
|
||||
uwsgi_error("mount()");
|
||||
}
|
||||
|
||||
while(unmounted) {
|
||||
|
||||
unmounted = 0;
|
||||
procmounts = fopen("/proc/self/mounts", "r");
|
||||
while(fgets(line,1024,procmounts) != NULL) {
|
||||
delim0 = strchr(line, ' ');
|
||||
delim0++;
|
||||
delim1 = strchr(delim0, ' ');
|
||||
*delim1 = 0;
|
||||
if (!strcmp(delim0,"/") || !strcmp(delim0,"/proc")) continue;
|
||||
if (!umount(delim0)) {
|
||||
unmounted++;
|
||||
}
|
||||
}
|
||||
fclose(procmounts);
|
||||
}
|
||||
|
||||
if (rmdir("/.uwsgi_ns_tmp_mountpoint/.uwsgi_ns_tmp_mountpoint")) {
|
||||
uwsgi_error("rmdir()");
|
||||
}
|
||||
if (rmdir("/.uwsgi_ns_tmp_mountpoint")) {
|
||||
uwsgi_error("rmdir()");
|
||||
}
|
||||
|
||||
free(ns_tmp_mountpoint2);
|
||||
free(ns_tmp_mountpoint);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -973,6 +1156,11 @@ int uwsgi_start(void *v_argv) {
|
||||
// never here
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// do not go on if no socket or gateway is defined
|
||||
if (!uwsgi.sockets_cnt && !uwsgi.gateways_cnt) {
|
||||
exit(0);
|
||||
}
|
||||
close(emperor_pipe[0]);
|
||||
uwsgi.has_emperor = 1;
|
||||
uwsgi.emperor_fd = emperor_pipe[1];
|
||||
@@ -1081,6 +1269,10 @@ int uwsgi_start(void *v_argv) {
|
||||
// daemons table lock
|
||||
uwsgi.daemon_table_lock = uwsgi_mmap_shared_lock();
|
||||
uwsgi_lock_init(uwsgi.daemon_table_lock);
|
||||
|
||||
// cron table lock
|
||||
uwsgi.cron_table_lock = uwsgi_mmap_shared_lock();
|
||||
uwsgi_lock_init(uwsgi.cron_table_lock);
|
||||
}
|
||||
|
||||
if (uwsgi.spool_dir) {
|
||||
@@ -1155,26 +1347,65 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
memset(uwsgi.cache_unused_stack, 0, sizeof(uint64_t) * uwsgi.cache_max_items);
|
||||
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
// the first cache item is always zero
|
||||
uwsgi.shared->cache_first_available_item = 1;
|
||||
uwsgi.shared->cache_unused_stack_ptr = 0;
|
||||
|
||||
//uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (uwsgi.cache_store) {
|
||||
uwsgi.cache_filesize = (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items);
|
||||
int cache_fd;
|
||||
struct stat cst;
|
||||
|
||||
if (stat(uwsgi.cache_store, &cst)) {
|
||||
uwsgi_log("creating a new cache store file: %s\n", uwsgi.cache_store);
|
||||
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR );
|
||||
if (cache_fd >= 0) {
|
||||
// fill the caching store
|
||||
if (ftruncate(cache_fd, uwsgi.cache_filesize)) {
|
||||
uwsgi_log("ftruncate()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (cst.st_size != uwsgi.cache_filesize || !S_ISREG(cst.st_mode)) {
|
||||
uwsgi_log("invalid cache store file. Please remove it or fix cache blocksize/items to match its size\n");
|
||||
exit(1);
|
||||
}
|
||||
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR );
|
||||
uwsgi_log("recovered cache from backing store file: %s\n", uwsgi.cache_store);
|
||||
}
|
||||
|
||||
if (cache_fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, uwsgi.cache_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, cache_fd, 0);
|
||||
uwsgi_cache_fix();
|
||||
|
||||
}
|
||||
else {
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
for(i=0;i< (int) uwsgi.cache_max_items;i++) {
|
||||
memset(&uwsgi.cache_items[i], 0, sizeof(struct uwsgi_cache_item));
|
||||
}
|
||||
}
|
||||
if (!uwsgi.cache_items) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
uwsgi.cache = mmap(NULL, uwsgi.cache_blocksize * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (!uwsgi.cache) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
|
||||
uwsgi.cache = ((void *) uwsgi.cache_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) ;
|
||||
|
||||
for(i=0;i< (int) uwsgi.cache_max_items;i++) {
|
||||
memset(&uwsgi.cache_items[i], 0, sizeof(struct uwsgi_cache_item));
|
||||
}
|
||||
|
||||
// the first cache item is always zero
|
||||
uwsgi.shared->cache_first_available_item = 1;
|
||||
uwsgi.shared->cache_unused_stack_ptr = 0;
|
||||
|
||||
uwsgi.cache_lock = uwsgi_mmap_shared_rwlock();
|
||||
uwsgi_rwlock_init(uwsgi.cache_lock);
|
||||
|
||||
@@ -1212,6 +1443,10 @@ int uwsgi_start(void *v_argv) {
|
||||
socket_type_len = sizeof(struct sockaddr_un);
|
||||
gsa.sa = &usa.sa;
|
||||
if (!getsockname(j, gsa.sa, &socket_type_len)) {
|
||||
if (socket_type_len <= 2) {
|
||||
// unbound socket
|
||||
continue;
|
||||
}
|
||||
if (gsa.sa->sa_family == AF_UNIX) {
|
||||
if (!strcmp(usa.sa_un.sun_path, uwsgi.sockets[i].name)) {
|
||||
uwsgi.sockets[i].fd = j;
|
||||
@@ -1539,12 +1774,6 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
|
||||
uwsgi_rawlog(" ***\n");
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
if (uwsgi.snmp) {
|
||||
//snmp_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
//init apps hook
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->init_apps) {
|
||||
@@ -1598,6 +1827,20 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
uwsgi_log("spawned uWSGI master process (pid: %d)\n", uwsgi.mypid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// security in multiuser environment: allow only a subset of modifiers
|
||||
if (uwsgi.allowed_modifiers) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (!uwsgi_list_has_num(uwsgi.allowed_modifiers, i)) {
|
||||
uwsgi.p[i]->request = unconfigured_hook;
|
||||
uwsgi.p[i]->after_request = unconfigured_after_hook;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir != NULL && uwsgi.sockets_cnt > 0) {
|
||||
uwsgi.shared->spooler_pid = spooler_start();
|
||||
@@ -1658,6 +1901,29 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
//from now on the process is a real worker
|
||||
}
|
||||
|
||||
if (uwsgi.cpu_affinity) {
|
||||
#ifdef __linux__
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
int ncpu = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
int base_cpu = (uwsgi.mywid-1)*uwsgi.cpu_affinity;
|
||||
if (base_cpu >= ncpu) {
|
||||
base_cpu = base_cpu % ncpu;
|
||||
}
|
||||
uwsgi_log("set cpu affinity for worker %d to", uwsgi.mywid);
|
||||
for(i=0;i<uwsgi.cpu_affinity;i++) {
|
||||
if (base_cpu >= ncpu) base_cpu = 0 ;
|
||||
CPU_SET(base_cpu, &cpuset);
|
||||
uwsgi_log(" %d", base_cpu);
|
||||
base_cpu++;
|
||||
}
|
||||
if (sched_setaffinity(0, sizeof(cpu_set_t), &cpuset)) {
|
||||
uwsgi_error("sched_setaffinity()");
|
||||
}
|
||||
uwsgi_log("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (uwsgi.worker_exec) {
|
||||
char *w_argv[2];
|
||||
w_argv[0] = uwsgi.worker_exec;
|
||||
@@ -1715,12 +1981,12 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0 && !uwsgi.master_process) {
|
||||
signal(SIGALRM, (void *) &harakiri);
|
||||
}
|
||||
signal(SIGHUP, (void *) &gracefully_kill);
|
||||
signal(SIGINT, (void *) &end_me);
|
||||
signal(SIGTERM, (void *) &reload_me);
|
||||
uwsgi_unix_signal(SIGHUP, gracefully_kill);
|
||||
uwsgi_unix_signal(SIGINT, end_me);
|
||||
uwsgi_unix_signal(SIGTERM, reload_me);
|
||||
|
||||
|
||||
signal(SIGUSR1, (void *) &stats);
|
||||
uwsgi_unix_signal(SIGUSR1, stats);
|
||||
|
||||
signal(SIGUSR2, (void *) &what_i_am_doing);
|
||||
|
||||
@@ -1822,7 +2088,7 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
|
||||
end:
|
||||
if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) {
|
||||
reload_me();
|
||||
reload_me(0);
|
||||
} else {
|
||||
goodbye_cruel_world();
|
||||
}
|
||||
@@ -1860,6 +2126,9 @@ end:
|
||||
case LONG_ARGS_REMAP_MODIFIER:
|
||||
uwsgi.remap_modifier = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_ALLOWED_MODIFIERS:
|
||||
uwsgi.allowed_modifiers = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_PLUGINS:
|
||||
p = strtok(optarg, ",");
|
||||
while (p != NULL) {
|
||||
@@ -1932,6 +2201,10 @@ end:
|
||||
#ifdef UWSGI_SNMP
|
||||
case LONG_ARGS_SNMP:
|
||||
uwsgi.snmp = 1;
|
||||
if (optarg) {
|
||||
uwsgi.snmp_addr = optarg;
|
||||
uwsgi.master_process = 1;
|
||||
}
|
||||
return 1;
|
||||
case LONG_ARGS_SNMP_COMMUNITY:
|
||||
uwsgi.snmp = 1;
|
||||
@@ -1954,10 +2227,12 @@ end:
|
||||
return 1;
|
||||
case LONG_ARGS_CLUSTER:
|
||||
uwsgi.cluster = optarg;
|
||||
uwsgi.master_process = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_CLUSTER_NODES:
|
||||
uwsgi.cluster = optarg;
|
||||
uwsgi.cluster_nodes = 1;
|
||||
uwsgi.master_process = 1;
|
||||
return 1;
|
||||
#endif
|
||||
case LONG_ARGS_CHROOT:
|
||||
@@ -2032,6 +2307,9 @@ end:
|
||||
case LONG_ARGS_PRIO:
|
||||
uwsgi.prio = (int) strtol(optarg, NULL, 10);
|
||||
return 1;
|
||||
case LONG_ARGS_CPU_AFFINITY:
|
||||
uwsgi.cpu_affinity = (int) strtol(optarg, NULL, 10);
|
||||
return 1;
|
||||
case LONG_ARGS_POST_BUFFERING:
|
||||
uwsgi.post_buffering = atoi(optarg);
|
||||
return 1;
|
||||
@@ -2057,6 +2335,13 @@ end:
|
||||
case LONG_ARGS_CACHE:
|
||||
uwsgi.cache_max_items = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CACHE_STORE:
|
||||
uwsgi.cache_store = optarg;
|
||||
uwsgi.master_process = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_CACHE_STORE_SYNC:
|
||||
uwsgi.cache_store_sync = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CACHE_BLOCKSIZE:
|
||||
uwsgi.cache_blocksize = atoi(optarg);
|
||||
return 1;
|
||||
@@ -2151,7 +2436,11 @@ end:
|
||||
uwsgi.numproc = rl.rlim_max;
|
||||
}
|
||||
else {
|
||||
#ifdef _SC_NPROCESSORS_ONLN
|
||||
uwsgi.numproc = (sysconf(_SC_NPROCESSORS_ONLN))*2;
|
||||
#else
|
||||
uwsgi.numproc = 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2338,14 +2627,12 @@ end:
|
||||
int j;
|
||||
|
||||
if (manage_base_opt(i, optarg)) {
|
||||
add_exported_option( i, optarg );
|
||||
return;
|
||||
}
|
||||
|
||||
for (j = 0; j < 0xFF; j++) {
|
||||
if (uwsgi.p[j]->manage_opt) {
|
||||
if (uwsgi.p[j]->manage_opt(i, optarg)) {
|
||||
add_exported_option( i, optarg );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2354,7 +2641,6 @@ end:
|
||||
for (j = 0; j < uwsgi.gp_cnt; j++) {
|
||||
if (uwsgi.gp[j]->manage_opt) {
|
||||
if (uwsgi.gp[j]->manage_opt(i, optarg)) {
|
||||
add_exported_option( i, optarg );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2606,27 +2892,12 @@ void build_options() {
|
||||
|
||||
void manage_string_opt(char *key, uint16_t keylen, char *val, uint16_t vallen, void *data) {
|
||||
|
||||
struct option *lopt, *aopt;
|
||||
|
||||
// never free this value
|
||||
char *key2 = uwsgi_concat2n(key, keylen, "", 0);
|
||||
char *val2 = uwsgi_concat2n(val, vallen, "", 0);
|
||||
|
||||
uwsgi_log("%s = %s\n", key2, val2);
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name) break;
|
||||
if (!strcmp(key2, aopt->name)) {
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
add_exported_option(0, key2);
|
||||
}
|
||||
else {
|
||||
manage_opt(aopt->val, val2);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
add_exported_option(key2, val2, 0);
|
||||
}
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
@@ -2641,6 +2912,11 @@ int uwsgi_cluster_add_me() {
|
||||
uint16_t ustrlen;
|
||||
char numproc[6];
|
||||
|
||||
if (!uwsgi.sockets[0].name) {
|
||||
uwsgi_log("you need to specify at least a socket to start a uWSGI cluster\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
snprintf(numproc, 6, "%d", uwsgi.numproc);
|
||||
|
||||
size_t len = 2 + strlen(key1) + 2 + strlen(uwsgi.hostname) + 2 + strlen(key2) + 2 + strlen(uwsgi.sockets[0].name) + 2 + strlen(key3) + 2 + strlen(numproc) + 2 + strlen(key4) + 2 + 1;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define MAX_GATEWAYS 64
|
||||
#define MAX_DAEMONS 8
|
||||
#define MAX_SUBSCRIPTIONS 8
|
||||
#define MAX_CRONS 64
|
||||
|
||||
#ifndef UWSGI_LOAD_EMBEDDED_PLUGINS
|
||||
#define UWSGI_LOAD_EMBEDDED_PLUGINS
|
||||
@@ -97,6 +98,8 @@
|
||||
|
||||
|
||||
#ifdef __linux
|
||||
#define __USE_GNU
|
||||
#include <sched.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <sys/mount.h>
|
||||
@@ -273,6 +276,7 @@ struct uwsgi_cache_item {
|
||||
struct uwsgi_opt {
|
||||
char *key;
|
||||
char *value;
|
||||
int configured;
|
||||
};
|
||||
|
||||
#define MAX_CLUSTER_NODES 100
|
||||
@@ -355,7 +359,11 @@ struct uwsgi_opt {
|
||||
#define LONG_ARGS_SUBSCRIBE_TO 17078
|
||||
#define LONG_ARGS_CLUSTER_NODES 17079
|
||||
#define LONG_ARGS_RELOAD_MERCY 17080
|
||||
|
||||
#define LONG_ARGS_ALLOWED_MODIFIERS 17081
|
||||
#define LONG_ARGS_LINUX_NS_NET 17082
|
||||
#define LONG_ARGS_CPU_AFFINITY 17083
|
||||
#define LONG_ARGS_CACHE_STORE 17084
|
||||
#define LONG_ARGS_CACHE_STORE_SYNC 17085
|
||||
|
||||
|
||||
#define UWSGI_OK 0
|
||||
@@ -715,12 +723,15 @@ struct uwsgi_server {
|
||||
|
||||
time_t master_mercy;
|
||||
|
||||
int cpu_affinity;
|
||||
|
||||
int reload_mercy;
|
||||
int option_index;
|
||||
struct option *long_options;
|
||||
struct uwsgi_opt **exported_opts;
|
||||
int exported_opts_cnt;
|
||||
int dump_options;
|
||||
int show_config;
|
||||
//base for all the requests(even on async mode)
|
||||
struct wsgi_request **wsgi_requests;
|
||||
struct wsgi_request *wsgi_req;
|
||||
@@ -791,13 +802,10 @@ struct uwsgi_server {
|
||||
char *spool_dir;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_NAGIOS
|
||||
int nagios;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
int snmp;
|
||||
char *snmp_community;
|
||||
char *snmp_addr;
|
||||
char *snmp_community;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -950,6 +958,8 @@ struct uwsgi_server {
|
||||
struct uwsgi_plugin *p[0xFF];
|
||||
struct uwsgi_plugin *gp[MAX_GENERIC_PLUGINS];
|
||||
int gp_cnt;
|
||||
|
||||
char *allowed_modifiers;
|
||||
|
||||
char *upload_progress;
|
||||
|
||||
@@ -964,6 +974,9 @@ struct uwsgi_server {
|
||||
uint64_t cache_blocksize;
|
||||
struct uwsgi_cache_item *cache_items;
|
||||
void *cache;
|
||||
char *cache_store;
|
||||
size_t cache_filesize;
|
||||
int cache_store_sync;
|
||||
|
||||
uint64_t queue_size;
|
||||
uint64_t queue_blocksize;
|
||||
@@ -976,6 +989,7 @@ struct uwsgi_server {
|
||||
void *fmon_table_lock;
|
||||
void *timer_table_lock;
|
||||
void *rb_timer_table_lock;
|
||||
void *cron_table_lock;
|
||||
void *rpc_table_lock;
|
||||
void *spooler_lock;
|
||||
|
||||
@@ -1061,6 +1075,18 @@ struct uwsgi_snmp_server_value {
|
||||
};
|
||||
#endif
|
||||
|
||||
struct uwsgi_cron {
|
||||
|
||||
int minute;
|
||||
int hour;
|
||||
int day;
|
||||
int month;
|
||||
int week;
|
||||
|
||||
time_t last_job;
|
||||
uint8_t sig;
|
||||
};
|
||||
|
||||
struct uwsgi_shared {
|
||||
|
||||
//vga 80 x25 specific !
|
||||
@@ -1116,6 +1142,9 @@ struct uwsgi_shared {
|
||||
#ifdef __linux__
|
||||
struct tcp_info ti;
|
||||
#endif
|
||||
|
||||
struct uwsgi_cron cron[MAX_CRONS];
|
||||
int cron_cnt;
|
||||
};
|
||||
|
||||
struct uwsgi_core {
|
||||
@@ -1125,7 +1154,7 @@ struct uwsgi_core {
|
||||
|
||||
time_t harakiri;
|
||||
|
||||
uint64_t requests;
|
||||
//uint64_t requests;
|
||||
uint64_t failed_requests;
|
||||
|
||||
//multiple ts per - core are needed only with multiple_interpreter + threads
|
||||
@@ -1163,12 +1192,12 @@ char *uwsgi_get_cwd(void);
|
||||
void warn_pipe(void);
|
||||
void what_i_am_doing(void);
|
||||
void goodbye_cruel_world(void);
|
||||
void gracefully_kill(void);
|
||||
void reap_them_all(void);
|
||||
void kill_them_all(void);
|
||||
void grace_them_all(void);
|
||||
void reload_me(void);
|
||||
void end_me(void);
|
||||
void gracefully_kill(int);
|
||||
void reap_them_all(int);
|
||||
void kill_them_all(int);
|
||||
void grace_them_all(int);
|
||||
void reload_me(int);
|
||||
void end_me(int);
|
||||
int bind_to_unix(char *, int, int, int);
|
||||
int bind_to_tcp(char *, int, char *);
|
||||
int bind_to_udp(char *, int, int);
|
||||
@@ -1188,7 +1217,7 @@ void log_request(struct wsgi_request *);
|
||||
void get_memusage(void);
|
||||
void harakiri(void);
|
||||
|
||||
void stats(void);
|
||||
void stats(int);
|
||||
|
||||
#ifdef UWSGI_XML
|
||||
void uwsgi_xml_config(struct wsgi_request *, int, char *[]);
|
||||
@@ -1367,7 +1396,7 @@ ssize_t uwsgi_sendfile(struct wsgi_request *);
|
||||
void uwsgi_register_loop(char *, void *);
|
||||
void *uwsgi_get_loop(char *);
|
||||
|
||||
void add_exported_option(int, char *);
|
||||
void add_exported_option(char *, char *, int);
|
||||
|
||||
ssize_t uwsgi_send_empty_pkt(int , char *, uint8_t , uint8_t);
|
||||
|
||||
@@ -1566,6 +1595,7 @@ int uwsgi_dict_set(struct uwsgi_dict *, char *, uint16_t, char *, uint64_t);
|
||||
|
||||
struct uwsgi_subscriber_name *uwsgi_get_subscriber(struct uwsgi_dict *, char *, uint16_t);
|
||||
|
||||
#ifndef _NO_UWSGI_RB
|
||||
#include "lib/rbtree.h"
|
||||
|
||||
struct uwsgi_rb_timer {
|
||||
@@ -1579,3 +1609,21 @@ struct uwsgi_rb_timer {
|
||||
struct rb_root *uwsgi_init_rb_timer(void);
|
||||
struct uwsgi_rb_timer *uwsgi_add_rb_timer(struct rb_root *, time_t, void *);
|
||||
struct uwsgi_rb_timer *uwsgi_min_rb_timer(struct rb_root *);
|
||||
|
||||
#endif
|
||||
|
||||
void uwsgi_nuclear_blast();
|
||||
|
||||
void uwsgi_unix_signal(int, void (*)(int));
|
||||
|
||||
char *uwsgi_get_exported_opt(char *);
|
||||
|
||||
int uwsgi_signal_add_cron(uint8_t, int, int, int, int, int);
|
||||
|
||||
char *uwsgi_get_optname_by_index(int);
|
||||
|
||||
int uwsgi_list_has_num(char *, int);
|
||||
|
||||
int uwsgi_list_has_str(char *, char *);
|
||||
|
||||
void uwsgi_cache_fix(void);
|
||||
|
||||
+13
-4
@@ -2,6 +2,7 @@
|
||||
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
uwsgi_os = os.uname()[0]
|
||||
uwsgi_os_k = re.split('[-+]', os.uname()[2])[0]
|
||||
uwsgi_os_v = os.uname()[3]
|
||||
@@ -208,6 +209,8 @@ class uConf(object):
|
||||
sys.exit(1)
|
||||
|
||||
def get_gcll(self):
|
||||
|
||||
self.cflags.append('-DUWSGI_BUILD_DATE="\\"%s\\""' % time.strftime("%d %B %Y %H:%M:%S"))
|
||||
kvm_list = ['FreeBSD', 'OpenBSD', 'NetBSD', 'DragonFly']
|
||||
|
||||
if uwsgi_os == 'SunOS':
|
||||
@@ -256,7 +259,7 @@ class uConf(object):
|
||||
if int(sun_major) >= 5:
|
||||
if int(sun_minor) >= 10:
|
||||
event_mode = 'port'
|
||||
elif uwsgi_os in ('Darwin', 'FreeBSD', 'OpenBSD'):
|
||||
elif uwsgi_os in ('Darwin', 'FreeBSD', 'OpenBSD', 'NetBSD'):
|
||||
event_mode = 'kqueue'
|
||||
|
||||
if event_mode == 'epoll':
|
||||
@@ -374,9 +377,15 @@ class uConf(object):
|
||||
self.gcc_list.append('yaml')
|
||||
|
||||
if self.get('ldap'):
|
||||
self.cflags.append("-DUWSGI_LDAP")
|
||||
self.gcc_list.append('ldap')
|
||||
self.libs.append('-lldap')
|
||||
if self.get('ldap') == 'auto':
|
||||
if os.path.exists('/usr/include/ldap.h'):
|
||||
self.cflags.append("-DUWSGI_LDAP")
|
||||
self.gcc_list.append('ldap')
|
||||
self.libs.append('-lldap')
|
||||
else:
|
||||
self.cflags.append("-DUWSGI_LDAP")
|
||||
self.gcc_list.append('ldap')
|
||||
self.libs.append('-lldap')
|
||||
|
||||
if self.get('evdis'):
|
||||
self.cflags.append("-DUWSGI_EVDIS")
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
[uwsgi]
|
||||
|
||||
trac = trac.web.main
|
||||
id = myapp
|
||||
socket = /tmp/%(id).sock
|
||||
env = TRAC_ENV=/opt/projects/%(id)
|
||||
module = %(trac):dispatch_request
|
||||
processes = 8
|
||||
master = true
|
||||
@@ -0,0 +1,31 @@
|
||||
<uwsgi>
|
||||
|
||||
<id>app001</id>
|
||||
|
||||
<print>starting dir is %v</print>
|
||||
|
||||
<chdir>%v/../</chdir>
|
||||
<localhost>127.0.0.1</localhost>
|
||||
|
||||
<socket>%(localhost):3031</socket>
|
||||
<socket>/tmp/%(id).sock</socket>
|
||||
|
||||
<cpus>4</cpus>
|
||||
<werkzeug>werkzeug.testapp:test_app</werkzeug>
|
||||
|
||||
<master/>
|
||||
|
||||
<vhost/>
|
||||
<vhost-host/>
|
||||
|
||||
<processes>%(cpus)</processes>
|
||||
|
||||
<app domain="sirius001:9090">
|
||||
<script>werkzeug.testapp:test_app</script>
|
||||
</app>
|
||||
|
||||
<app domain="sirius002:9090">
|
||||
<script>uwsgicc</script>
|
||||
</app>
|
||||
|
||||
</uwsgi>
|
||||
@@ -18,12 +18,11 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, int app_tag, char *magic_ta
|
||||
xmlChar *xml_uwsgi_mountpoint = NULL;
|
||||
xmlChar *xml_uwsgi_domain = NULL;
|
||||
xmlChar *node_mode;
|
||||
struct option *lopt, *aopt;
|
||||
|
||||
char *colon;
|
||||
|
||||
char *xml_id;
|
||||
int i;
|
||||
char *xml_id;
|
||||
char *xml_content;
|
||||
int xml_size = 0;
|
||||
|
||||
@@ -105,52 +104,26 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, int app_tag, char *magic_ta
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp((char *) node->name, aopt->name)) {
|
||||
if (!node->children && aopt->has_arg) {
|
||||
uwsgi_log( "[uWSGI] %s option need a value. skip.\n", aopt->name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (node->children) {
|
||||
if (!node->children->content && aopt->has_arg) {
|
||||
uwsgi_log( "[uWSGI] %s option need a value. skip.\n", aopt->name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
node_mode = xmlGetProp(node, (const xmlChar *) "mode");
|
||||
if (uwsgi.mode && node_mode) {
|
||||
if (strcmp(uwsgi.mode, (char *) node_mode)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
node_mode = xmlGetProp(node, (const xmlChar *) "mode");
|
||||
if (uwsgi.mode && node_mode) {
|
||||
if (strcmp(uwsgi.mode, (char *) node_mode)) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
xml_id = (char *) xmlGetProp(node, (const xmlChar *) "id");
|
||||
if (colon && xml_id) {
|
||||
if (strcmp(colon, xml_id)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
xml_id = (char *) xmlGetProp(node, (const xmlChar *) "id");
|
||||
if (colon && xml_id) {
|
||||
if (strcmp(colon, xml_id)) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
add_exported_option(0, (char *) node->name);
|
||||
}
|
||||
else {
|
||||
if (node->children) {
|
||||
manage_opt(aopt->val, (char *) node->children->content);
|
||||
}
|
||||
else {
|
||||
manage_opt(aopt->val, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
next:
|
||||
lopt++;
|
||||
if (node->children) {
|
||||
add_exported_option((char *) node->name, (char *) node->children->content, 0);
|
||||
}
|
||||
else {
|
||||
add_exported_option((char *) node->name, "1", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,6 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
|
||||
int lines = 1;
|
||||
|
||||
struct option *lopt, *aopt;
|
||||
char *section_asked = "uwsgi";
|
||||
char *colon;
|
||||
|
||||
@@ -171,26 +170,7 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
|
||||
//uwsgi_log("YAML: %s = %s\n", key, val);
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp(key, aopt->name)) {
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
add_exported_option(0, (char *)key);
|
||||
}
|
||||
else {
|
||||
if (aopt->has_arg == optional_argument) {
|
||||
if (!strcmp("true", val)) {
|
||||
val = NULL;
|
||||
}
|
||||
}
|
||||
manage_opt(aopt->val, val);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
add_exported_option((char *)key, val, 0);
|
||||
}
|
||||
next:
|
||||
len -= (yaml_line - yaml);
|
||||
|
||||
Reference in New Issue
Block a user