X-Git-Url: https://git.octo.it/?p=rrdtool.git;a=blobdiff_plain;f=src%2Frrd_daemon.c;h=c6211a6f97f9190058a1b6391c435d266ee47708;hp=9fbbc1133af5a79869a53e84657086b91d4f0b60;hb=7da79af65016ae22b7d46abead4b2717ae722937;hpb=607eea59c2ba85c63e2de1b665b37a6093e1575c diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c index 9fbbc11..c6211a6 100644 --- a/src/rrd_daemon.c +++ b/src/rrd_daemon.c @@ -62,7 +62,16 @@ /* * Now for some includes.. */ -#include "rrd.h" /* {{{ */ +/* {{{ */ +#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) && !defined(HAVE_CONFIG_H) +#include "../win32/config.h" +#else +#ifdef HAVE_CONFIG_H +#include "../rrd_config.h" +#endif +#endif + +#include "rrd.h" #include "rrd_client.h" #include @@ -564,6 +573,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 +635,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 +690,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 +1459,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); @@ -1525,6 +1535,9 @@ static int handle_request_update (listen_socket_t *sock, /* {{{ */ if (values_num < 1) { + /* journal replay mode */ + if (sock == NULL) return RESP_ERR; + /* if we had only one update attempt, then return the full error message... try to get the most information out of the limited error space allowed by the protocol @@ -2028,7 +2041,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; @@ -2037,7 +2050,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); } @@ -2045,19 +2059,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); @@ -2103,8 +2124,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; @@ -2116,8 +2136,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 = ']') */ @@ -2136,8 +2155,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); } @@ -2151,7 +2170,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; @@ -2160,7 +2180,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; } @@ -2169,7 +2190,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; } @@ -2177,7 +2199,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); } @@ -2228,21 +2251,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); } @@ -2355,7 +2366,6 @@ static void *listen_thread_main (void *args __attribute__((unused))) /* {{{ */ static int daemonize (void) /* {{{ */ { - int status; int pid_fd; char *base_dir; @@ -2367,6 +2377,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; @@ -2375,12 +2405,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 (); @@ -2399,11 +2427,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(); @@ -2415,11 +2443,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) /* {{{ */ @@ -2694,19 +2725,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); }