X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrd_daemon.c;h=7201c52c4e12c86429f90240a3b01272d906f501;hb=c05cbd882ff8c3f9bdd1099cf5cb42ac08fae7a6;hp=40785b00778cc19ffc40b3e97bc687f553f5b4a9;hpb=3b19d6c1658787822ebbd71bd397c6da867a0c4c;p=rrdtool.git diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c index 40785b0..7201c52 100644 --- a/src/rrd_daemon.c +++ b/src/rrd_daemon.c @@ -564,6 +564,7 @@ static void wipe_ci_values(cache_item_t *ci, time_t when) static void remove_from_queue(cache_item_t *ci) /* {{{ */ { if (ci == NULL) return; + if ((ci->flags & CI_FLAGS_IN_QUEUE) == 0) return; /* not queued */ if (ci->prev == NULL) cache_queue_head = ci->next; /* reset head */ @@ -625,9 +626,8 @@ static int enqueue_cache_item (cache_item_t *ci, /* {{{ */ if (cache_queue_head == ci) return 0; - /* remove from the double linked list */ - if (ci->flags & CI_FLAGS_IN_QUEUE) - remove_from_queue(ci); + /* remove if further down in queue */ + remove_from_queue(ci); ci->prev = NULL; ci->next = cache_queue_head; @@ -681,20 +681,20 @@ static gboolean tree_callback_flush (gpointer key, gpointer value, /* {{{ */ ci = (cache_item_t *) value; cfd = (callback_flush_data_t *) data; + if (ci->flags & CI_FLAGS_IN_QUEUE) + return FALSE; + if ((ci->last_flush_time <= cfd->abs_timeout) - && ((ci->flags & CI_FLAGS_IN_QUEUE) == 0) && (ci->values_num > 0)) { enqueue_cache_item (ci, TAIL); } else if ((do_shutdown != 0) - && ((ci->flags & CI_FLAGS_IN_QUEUE) == 0) && (ci->values_num > 0)) { enqueue_cache_item (ci, TAIL); } else if (((cfd->now - ci->last_flush_time) >= config_flush_interval) - && ((ci->flags & CI_FLAGS_IN_QUEUE) == 0) && (ci->values_num <= 0)) { char **temp; @@ -1450,6 +1450,7 @@ static int handle_request_update (listen_socket_t *sock, /* {{{ */ wipe_ci_values(ci, now); ci->flags = CI_FLAGS_IN_TREE; + pthread_cond_init(&ci->flushed, NULL); pthread_mutex_lock(&cache_lock); g_tree_insert (cache_tree, (void *) ci->file, (void *) ci); @@ -2031,7 +2032,7 @@ static int open_listen_socket_unix (const listen_socket_t *sock) /* {{{ */ sizeof (listen_fds[0]) * (listen_fds_num + 1)); if (temp == NULL) { - RRDD_LOG (LOG_ERR, "open_listen_socket_unix: realloc failed."); + fprintf (stderr, "rrdcached: open_listen_socket_unix: realloc failed.\n"); return (-1); } listen_fds = temp; @@ -2040,7 +2041,8 @@ static int open_listen_socket_unix (const listen_socket_t *sock) /* {{{ */ fd = socket (PF_UNIX, SOCK_STREAM, /* protocol = */ 0); if (fd < 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket_unix: socket(2) failed."); + fprintf (stderr, "rrdcached: unix socket(2) failed: %s\n", + rrd_strerror(errno)); return (-1); } @@ -2048,19 +2050,26 @@ static int open_listen_socket_unix (const listen_socket_t *sock) /* {{{ */ sa.sun_family = AF_UNIX; strncpy (sa.sun_path, path, sizeof (sa.sun_path) - 1); + /* if we've gotten this far, we own the pid file. any daemon started + * with the same args must not be alive. therefore, ensure that we can + * create the socket... + */ + unlink(path); + status = bind (fd, (struct sockaddr *) &sa, sizeof (sa)); if (status != 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket_unix: bind(2) failed."); + fprintf (stderr, "rrdcached: bind(%s) failed: %s.\n", + path, rrd_strerror(errno)); close (fd); - unlink (path); return (-1); } status = listen (fd, /* backlog = */ 10); if (status != 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket_unix: listen(2) failed."); + fprintf (stderr, "rrdcached: listen(%s) failed: %s.\n", + path, rrd_strerror(errno)); close (fd); unlink (path); return (-1); @@ -2106,8 +2115,7 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ port = strchr (addr, ']'); if (port == NULL) { - RRDD_LOG (LOG_ERR, "open_listen_socket_network: Malformed address: %s", - sock->addr); + fprintf (stderr, "rrdcached: Malformed address: %s\n", sock->addr); return (-1); } *port = 0; @@ -2119,8 +2127,7 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ port = NULL; else { - RRDD_LOG (LOG_ERR, "open_listen_socket_network: Garbage after address: %s", - port); + fprintf (stderr, "rrdcached: Garbage after address: %s\n", port); return (-1); } } /* if (*addr = ']') */ @@ -2139,8 +2146,8 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ &ai_hints, &ai_res); if (status != 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket_network: getaddrinfo(%s) failed: " - "%s", addr, gai_strerror (status)); + fprintf (stderr, "rrdcached: getaddrinfo(%s) failed: %s\n", + addr, gai_strerror (status)); return (-1); } @@ -2154,7 +2161,8 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ sizeof (listen_fds[0]) * (listen_fds_num + 1)); if (temp == NULL) { - RRDD_LOG (LOG_ERR, "open_listen_socket_network: realloc failed."); + fprintf (stderr, + "rrdcached: open_listen_socket_network: realloc failed.\n"); continue; } listen_fds = temp; @@ -2163,7 +2171,8 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); if (fd < 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket_network: socket(2) failed."); + fprintf (stderr, "rrdcached: network socket(2) failed: %s.\n", + rrd_strerror(errno)); continue; } @@ -2172,7 +2181,8 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ status = bind (fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); if (status != 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket_network: bind(2) failed."); + fprintf (stderr, "rrdcached: bind(%s) failed: %s.\n", + sock->addr, rrd_strerror(errno)); close (fd); continue; } @@ -2180,7 +2190,8 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ status = listen (fd, /* backlog = */ 10); if (status != 0) { - RRDD_LOG (LOG_ERR, "open_listen_socket_network: listen(2) failed."); + fprintf (stderr, "rrdcached: listen(%s) failed: %s\n.", + sock->addr, rrd_strerror(errno)); close (fd); return (-1); } @@ -2231,21 +2242,9 @@ static void *listen_thread_main (void *args __attribute__((unused))) /* {{{ */ int status; int i; - for (i = 0; i < config_listen_address_list_len; i++) - open_listen_socket (config_listen_address_list[i]); - - if (config_listen_address_list_len < 1) - { - listen_socket_t sock; - memset(&sock, 0, sizeof(sock)); - strncpy(sock.addr, RRDCACHED_DEFAULT_ADDRESS, sizeof(sock.addr)); - open_listen_socket (&sock); - } - if (listen_fds_num < 1) { - RRDD_LOG (LOG_ERR, "listen_thread_main: No listen sockets " - "could be opened. Sorry."); + RRDD_LOG(LOG_ERR, "listen_thread_main: no listen_fds !"); return (NULL); } @@ -2358,7 +2357,6 @@ static void *listen_thread_main (void *args __attribute__((unused))) /* {{{ */ static int daemonize (void) /* {{{ */ { - int status; int pid_fd; char *base_dir; @@ -2370,6 +2368,26 @@ static int daemonize (void) /* {{{ */ if (pid_fd < 0) return pid_fd; + /* open all the listen sockets */ + if (config_listen_address_list_len > 0) + { + for (int i = 0; i < config_listen_address_list_len; i++) + open_listen_socket (config_listen_address_list[i]); + } + else + { + listen_socket_t sock; + memset(&sock, 0, sizeof(sock)); + strncpy(sock.addr, RRDCACHED_DEFAULT_ADDRESS, sizeof(sock.addr)); + open_listen_socket (&sock); + } + + if (listen_fds_num < 1) + { + fprintf (stderr, "rrdcached: FATAL: cannot open any listen sockets\n"); + goto error; + } + if (!stay_foreground) { pid_t child; @@ -2378,12 +2396,10 @@ static int daemonize (void) /* {{{ */ if (child < 0) { fprintf (stderr, "daemonize: fork(2) failed.\n"); - return (-1); + goto error; } else if (child > 0) - { - return (1); - } + exit(0); /* Become session leader */ setsid (); @@ -2402,11 +2418,11 @@ static int daemonize (void) /* {{{ */ base_dir = (config_base_dir != NULL) ? config_base_dir : "/tmp"; - status = chdir (base_dir); - if (status != 0) + + if (chdir (base_dir) != 0) { fprintf (stderr, "daemonize: chdir (%s) failed.\n", base_dir); - return (-1); + goto error; } install_signal_handlers(); @@ -2418,11 +2434,14 @@ static int daemonize (void) /* {{{ */ if (cache_tree == NULL) { RRDD_LOG (LOG_ERR, "daemonize: g_tree_new failed."); - return (-1); + goto error; } - status = write_pidfile (pid_fd); - return status; + return write_pidfile (pid_fd); + +error: + remove_pidfile(); + return -1; } /* }}} int daemonize */ static int cleanup (void) /* {{{ */ @@ -2697,19 +2716,9 @@ int main (int argc, char **argv) } status = daemonize (); - if (status == 1) - { - struct sigaction sigchld; - - memset (&sigchld, 0, sizeof (sigchld)); - sigchld.sa_handler = SIG_IGN; - sigaction (SIGCHLD, &sigchld, NULL); - - return (0); - } - else if (status != 0) + if (status != 0) { - fprintf (stderr, "daemonize failed, exiting.\n"); + fprintf (stderr, "rrdcached: daemonize failed, exiting.\n"); return (1); }