void run_scripts(void) { LOG_INFO(NULL, "calling update helpers", class_scripts, ""); if (need_update_boot) update_kernel(); if (need_update_bootloader) update_bootloader(); /* Crudely call post-update hooks after every update, must fix with proper conditions and log output */ update_triggers(); }
void* nsca_gateway(void *u) { struct epoll_event ev, events[EPOLL_MAX_FD]; int n, nfds, epfd, connfd; server_t *svr; void *kernel; svr = (server_t*)u; if (!svr) { logger(LOG_CRIT, "NSCA gateway failed: server context was NULL"); return NULL; } int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { logger(LOG_CRIT, "NSCA gateway failed to get a socket descriptor: %s", strerror(errno)); return NULL; } struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(svr->config.nsca_port); addr.sin_addr.s_addr = INADDR_ANY; n = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) != 0) { logger(LOG_WARNING, "NSCA gateway failed to set SO_REUSEADDR on listening socket"); return NULL; } if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) != 0) { logger(LOG_CRIT, "NSCA gateway failed to bind socket to port %u", svr->config.nsca_port); return NULL; } if (listen(sockfd, 64) != 0) { logger(LOG_CRIT, "NSCA gateway failed to listen on port %u", svr->config.nsca_port); return NULL; } if (nonblocking(sockfd) != 0) { logger(LOG_CRIT, "NSCA gateway failed to set bound socket non-blocking (O_NONBLOCK): %s", strerror(errno)); return NULL; } kernel = zmq_socket(svr->zmq, ZMQ_DEALER); if (!kernel) { logger(LOG_CRIT, "NSCA gateway failed to get a DEALER socket"); return NULL; } if (vx_vzmq_connect(kernel, KERNEL_ENDPOINT) != 0) { logger(LOG_CRIT, "NSCA gateway failed to connect to kernel at " KERNEL_ENDPOINT); return NULL; } epfd = epoll_create(256); if (epfd < 0) { logger(LOG_CRIT, "NSCA gateway failed to get an epoll file descriptor: %s", strerror(errno)); return NULL; } memset(&ev, 0, sizeof(ev)); ev.events = EPOLLIN; ev.data.fd = sockfd; if (epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev) != 0) { logger(LOG_CRIT, "Failed to add socket fd to epoll list: %s", strerror(errno)); return NULL; } cache_t *clients = cache_new(CLIENT_MAX, CLIENT_EXPIRE); cache_setopt(clients, VIGOR_CACHE_DESTRUCTOR, client_free); logger(LOG_INFO, "NSCA gateway thread starting up"); for (;;) { nfds = epoll_wait(epfd, events, EPOLL_MAX_FD, -1); if (nfds == -1) { logger(LOG_CRIT, "epoll_wait encountered an error: %s", strerror(errno)); return NULL; } for (n = 0; n < nfds; n++) { if (events[n].data.fd == sockfd) { /* new inbound connection */ connfd = accept(sockfd, NULL, NULL); if (connfd < 0) { logger(LOG_ERR, "listener: inbound connect could not be accepted: %s", strerror(errno)); continue; } if (nonblocking(connfd) != 0) { logger(LOG_CRIT, "NSCA gateway failed to set connecion %i non-blocking (O_NONBLOCK): %s", connfd, connfd); close(connfd); break; } ev.events = EPOLLIN | EPOLLET; ev.data.fd = connfd; if (epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev) != 0) { logger(LOG_CRIT, "NSCA gateway failed to register connection %i with epoll subsystem: %s", connfd, strerror(errno)); return NULL; } /* push new client state into cache */ char *id = string("%04x", connfd); client_t *c = client_new(connfd); if (!cache_set(clients, id, c)) { logger(LOG_ERR, "NSCA gateway has no more room in the connection cache, closing connection %i", connfd); client_free(c); } free(id); } else { char *id = string("%04x", events[n].data.fd); client_t *c = cache_get(clients, id); if (!c) { logger(LOG_CRIT, "NSCA gateway received data for unknown client %s; ignoring", id); free(id); continue; } /* read what's left from the client */ ssize_t n = read(c->fd, &c->packet + c->bytes, NSCA_PACKET_LEN - c->bytes); if (n > 0) { c->bytes += n; if (c->bytes == NSCA_PACKET_LEN) { update_kernel(kernel, c); client_free(cache_unset(clients, id)); } } else { client_free(cache_unset(clients, id)); } free(id); } } } logger(LOG_INFO, "NSCA gateway thread shutting down"); cache_free(clients); return NULL; }