X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=src%2Fweb_server.c;h=593a82a57f4abfd5a9508130a84cd341d73cee63;hb=9dccc16d3763392f0b13349de18c3a838a667653;hp=cf3687f3e6031779d8b17769730df8ffa739b594;hpb=4573404814de3da6605595bbe0a43837fa48d568;p=netdata.git diff --git a/src/web_server.c b/src/web_server.c index cf3687f3..593a82a5 100644 --- a/src/web_server.c +++ b/src/web_server.c @@ -5,26 +5,47 @@ size_t listen_fds_count = 0; int listen_fds[MAX_LISTEN_FDS] = { [0 ... 99] = -1 }; char *listen_fds_names[MAX_LISTEN_FDS] = { [0 ... 99] = NULL }; int listen_port = LISTEN_PORT; -int web_server_mode = WEB_SERVER_MODE_MULTI_THREADED; + +WEB_SERVER_MODE web_server_mode = WEB_SERVER_MODE_MULTI_THREADED; + +static int shown_server_socket_error = 0; #ifdef NETDATA_INTERNAL_CHECKS static void log_allocations(void) { - static int mem = 0; +#ifdef HAVE_C_MALLINFO + static int heap = 0, used = 0, mmap = 0; struct mallinfo mi; mi = mallinfo(); - if(mi.uordblks > mem) { + if(mi.uordblks > used) { int clients = 0; struct web_client *w; for(w = web_clients; w ; w = w->next) clients++; - info("Allocated memory increased from %d to %d (increased by %d bytes). There are %d web clients connected.", mem, mi.uordblks, mi.uordblks - mem, clients); - mem = mi.uordblks; + info("Allocated memory: used %d KB (+%d B), mmap %d KB (+%d B), heap %d KB (+%d B). %d web clients connected.", + mi.uordblks / 1024, + mi.uordblks - used, + mi.hblkhd / 1024, + mi.hblkhd - mmap, + mi.arena / 1024, + mi.arena - heap, + clients); + + used = mi.uordblks; + heap = mi.arena; + mmap = mi.hblkhd; } -} +#else /* ! HAVE_C_MALLINFO */ + ; +#endif /* ! HAVE_C_MALLINFO */ + +#ifdef has_jemalloc + malloc_stats_print(NULL, NULL, NULL); #endif +} +#endif /* NETDATA_INTERNAL_CHECKS */ #ifndef HAVE_ACCEPT4 int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) { @@ -38,10 +59,14 @@ int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) { flags &= ~SOCK_NONBLOCK; } +#ifdef SOCK_CLOEXEC +#ifdef O_CLOEXEC if (flags & SOCK_CLOEXEC) { newflags |= O_CLOEXEC; flags &= ~SOCK_CLOEXEC; } +#endif +#endif if (flags) { errno = -EINVAL; @@ -59,6 +84,29 @@ int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) { } #endif +WEB_SERVER_MODE web_server_mode_id(const char *mode) { + if(!strcmp(mode, "none")) + return WEB_SERVER_MODE_NONE; + else if(!strcmp(mode, "single") || !strcmp(mode, "single-threaded")) + return WEB_SERVER_MODE_SINGLE_THREADED; + else // if(!strcmp(mode, "multi") || !strcmp(mode, "multi-threaded")) + return WEB_SERVER_MODE_MULTI_THREADED; +} + +const char *web_server_mode_name(WEB_SERVER_MODE id) { + switch(id) { + case WEB_SERVER_MODE_NONE: + return "none"; + + case WEB_SERVER_MODE_SINGLE_THREADED: + return "single-threaded"; + + default: + case WEB_SERVER_MODE_MULTI_THREADED: + return "multi-threaded"; + } +} + int create_listen_socket4(const char *ip, int port, int listen_backlog) { int sock; int sockopt = 1; @@ -68,6 +116,7 @@ int create_listen_socket4(const char *ip, int port, int listen_backlog) { sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { error("IPv4 socket() on ip '%s' port %d failed.", ip, port); + shown_server_socket_error = 1; return -1; } @@ -83,6 +132,7 @@ int create_listen_socket4(const char *ip, int port, int listen_backlog) { int ret = inet_pton(AF_INET, ip, (void *)&name.sin_addr.s_addr); if(ret != 1) { error("Failed to convert IP '%s' to a valid IPv4 address.", ip); + shown_server_socket_error = 1; close(sock); return -1; } @@ -90,12 +140,14 @@ int create_listen_socket4(const char *ip, int port, int listen_backlog) { if(bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) { close(sock); error("IPv4 bind() on ip '%s' port %d failed.", ip, port); + shown_server_socket_error = 1; return -1; } if(listen(sock, listen_backlog) < 0) { close(sock); - fatal("IPv4 listen() on ip '%s' port %d failed.", ip, port); + error("IPv4 listen() on ip '%s' port %d failed.", ip, port); + shown_server_socket_error = 1; return -1; } @@ -113,6 +165,7 @@ int create_listen_socket6(const char *ip, int port, int listen_backlog) { sock = socket(AF_INET6, SOCK_STREAM, 0); if (sock < 0) { error("IPv6 socket() on ip '%s' port %d failed.", ip, port); + shown_server_socket_error = 1; return -1; } @@ -132,6 +185,7 @@ int create_listen_socket6(const char *ip, int port, int listen_backlog) { int ret = inet_pton(AF_INET6, ip, (void *)&name.sin6_addr.s6_addr); if(ret != 1) { error("Failed to convert IP '%s' to a valid IPv6 address.", ip); + shown_server_socket_error = 1; close(sock); return -1; } @@ -141,12 +195,14 @@ int create_listen_socket6(const char *ip, int port, int listen_backlog) { if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) { close(sock); error("IPv6 bind() on ip '%s' port %d failed.", ip, port); + shown_server_socket_error = 1; return -1; } if (listen(sock, listen_backlog) < 0) { close(sock); error("IPv6 listen() on ip '%s' port %d failed.", ip, port); + shown_server_socket_error = 1; return -1; } @@ -157,6 +213,7 @@ int create_listen_socket6(const char *ip, int port, int listen_backlog) { static inline int add_listen_socket(int fd, const char *ip, int port) { if(listen_fds_count >= MAX_LISTEN_FDS) { error("Too many listening sockets. Failed to add listening socket at ip '%s' port %d", ip, port); + shown_server_socket_error = 1; close(fd); return -1; } @@ -268,7 +325,7 @@ static inline int bind_to_one(const char *definition, int default_port, int list } if (fd == -1) - error("Cannot bind to ip '%s', port %d", rip, default_port); + error("Cannot bind to ip '%s', port %d", rip, rport); else { add_listen_socket(fd, rip, rport); added++; @@ -281,22 +338,18 @@ static inline int bind_to_one(const char *definition, int default_port, int list } int create_listen_sockets(void) { - listen_backlog = (int) config_get_number("global", "http port listen backlog", LISTEN_BACKLOG); + shown_server_socket_error = 0; - if(config_exists("global", "bind socket to IP") && !config_exists("global", "bind to")) - config_rename("global", "bind socket to IP", "bind to"); + listen_backlog = (int) config_get_number(CONFIG_SECTION_WEB, "listen backlog", LISTEN_BACKLOG); - if(config_exists("global", "port") && !config_exists("global", "default port")) - config_rename("global", "port", "default port"); - - listen_port = (int) config_get_number("global", "default port", LISTEN_PORT); + listen_port = (int) config_get_number(CONFIG_SECTION_WEB, "default port", LISTEN_PORT); if(listen_port < 1 || listen_port > 65535) { error("Invalid listen port %d given. Defaulting to %d.", listen_port, LISTEN_PORT); - listen_port = (int) config_set_number("global", "default port", LISTEN_PORT); + listen_port = (int) config_set_number(CONFIG_SECTION_WEB, "default port", LISTEN_PORT); } debug(D_OPTIONS, "Default listen port set to %d.", listen_port); - char *s = config_get("global", "bind to", "*"); + char *s = config_get(CONFIG_SECTION_WEB, "bind to", "*"); while(*s) { char *e = s; @@ -318,6 +371,11 @@ int create_listen_sockets(void) { if(!listen_fds_count) fatal("Cannot listen on any socket. Exiting..."); + else if(shown_server_socket_error) { + size_t i; + for(i = 0; i < listen_fds_count ;i++) + info("Listen socket %s opened.", listen_fds_names[i]); + } return (int)listen_fds_count; } @@ -350,7 +408,7 @@ static inline void cleanup_web_clients(void) { #define CLEANUP_EVERY_EVENTS 100 void *socket_listen_main_multi_threaded(void *ptr) { - (void)ptr; + struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr; web_server_mode = WEB_SERVER_MODE_MULTI_THREADED; info("Multi-threaded WEB SERVER thread created with task id %d", gettid()); @@ -430,6 +488,10 @@ void *socket_listen_main_multi_threaded(void *ptr) { debug(D_WEB_CLIENT, "LISTENER: exit!"); close_listen_sockets(); + freez(fds); + + static_thread->enabled = 0; + pthread_exit(NULL); return NULL; } @@ -478,7 +540,7 @@ static inline int single_threaded_unlink_client(struct web_client *w, fd_set *if } void *socket_listen_main_single_threaded(void *ptr) { - (void)ptr; + struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr; web_server_mode = WEB_SERVER_MODE_SINGLE_THREADED; @@ -570,7 +632,7 @@ void *socket_listen_main_single_threaded(void *ptr) { if (w->mode != WEB_CLIENT_MODE_FILECOPY) { debug(D_WEB_CLIENT, "%llu: Processing received data.", w->id); - web_client_process(w); + web_client_process_request(w); } } @@ -597,5 +659,8 @@ void *socket_listen_main_single_threaded(void *ptr) { debug(D_WEB_CLIENT, "LISTENER: exit!"); close_listen_sockets(); + + static_thread->enabled = 0; + pthread_exit(NULL); return NULL; }