Skip to content

Commit cbc127a

Browse files
committed
Changes to collectd.c
1 parent 6e006af commit cbc127a

File tree

5 files changed

+399
-256
lines changed

5 files changed

+399
-256
lines changed

Makefile.am

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,11 @@ collectd_LDFLAGS = -export-dynamic
269269
collectd_LDADD = \
270270
$(COMMON_LIBS) \
271271
libcollectd.la
272+
if BUILD_WIN32
273+
collectd_SOURCES += src/daemon/collectd_windows.c
274+
else
275+
collectd_SOURCES += src/daemon/collectd_linux.c
276+
endif
272277

273278
if BUILD_FEATURE_DAEMON
274279
collectd_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"'

src/daemon/collectd.c

Lines changed: 29 additions & 256 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@
3333

3434
#include <netdb.h>
3535
#include <sys/types.h>
36-
#include <sys/un.h>
36+
37+
#ifdef WIN32
38+
#undef COLLECT_DAEMON
39+
#include <unistd.h>
40+
#undef gethostname
41+
#include <winsock2.h>
42+
#include <locale.h>
43+
#endif
3744

3845
#if HAVE_LOCALE_H
3946
#include <locale.h>
@@ -49,30 +56,16 @@
4956

5057
static int loop = 0;
5158

52-
static void *do_flush(void __attribute__((unused)) * arg) {
53-
INFO("Flushing all data.");
54-
plugin_flush(/* plugin = */ NULL,
55-
/* timeout = */ 0,
56-
/* ident = */ NULL);
57-
INFO("Finished flushing all data.");
58-
pthread_exit(NULL);
59-
return NULL;
60-
}
61-
62-
static void sig_int_handler(int __attribute__((unused)) signal) { loop++; }
63-
64-
static void sig_term_handler(int __attribute__((unused)) signal) { loop++; }
65-
66-
static void sig_usr1_handler(int __attribute__((unused)) signal) {
67-
pthread_t thread;
68-
pthread_attr_t attr;
69-
70-
/* flushing the data might take a while,
71-
* so it should be done asynchronously */
72-
pthread_attr_init(&attr);
73-
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
74-
pthread_create(&thread, &attr, do_flush, NULL);
75-
pthread_attr_destroy(&attr);
59+
static long hostname_len() {
60+
#ifdef WIN32
61+
return NI_MAXHOST;
62+
#else
63+
long hostname_len = sysconf(_SC_HOST_NAME_MAX);
64+
if (hostname_len == -1) {
65+
hostname_len = NI_MAXHOST;
66+
}
67+
return hostname_len;
68+
#endif /* WIN32 */
7669
}
7770

7871
static int init_hostname(void) {
@@ -82,13 +75,9 @@ static int init_hostname(void) {
8275
return 0;
8376
}
8477

85-
long hostname_len = sysconf(_SC_HOST_NAME_MAX);
86-
if (hostname_len == -1) {
87-
hostname_len = NI_MAXHOST;
88-
}
89-
char hostname[hostname_len];
78+
char hostname[hostname_len()];
9079

91-
if (gethostname(hostname, hostname_len) != 0) {
80+
if (gethostname(hostname, hostname_len()) != 0) {
9281
fprintf(stderr, "`gethostname' failed and no "
9382
"hostname was configured.\n");
9483
return -1;
@@ -328,122 +317,6 @@ static int do_shutdown(void) {
328317
return plugin_shutdown_all();
329318
} /* int do_shutdown */
330319

331-
#if COLLECT_DAEMON
332-
static int pidfile_create(void) {
333-
FILE *fh;
334-
const char *file = global_option_get("PIDFile");
335-
336-
if ((fh = fopen(file, "w")) == NULL) {
337-
ERROR("fopen (%s): %s", file, STRERRNO);
338-
return 1;
339-
}
340-
341-
fprintf(fh, "%i\n", (int)getpid());
342-
fclose(fh);
343-
344-
return 0;
345-
} /* static int pidfile_create (const char *file) */
346-
347-
static int pidfile_remove(void) {
348-
const char *file = global_option_get("PIDFile");
349-
if (file == NULL)
350-
return 0;
351-
352-
return unlink(file);
353-
} /* static int pidfile_remove (const char *file) */
354-
#endif /* COLLECT_DAEMON */
355-
356-
#ifdef KERNEL_LINUX
357-
static int notify_upstart(void) {
358-
char const *upstart_job = getenv("UPSTART_JOB");
359-
360-
if (upstart_job == NULL)
361-
return 0;
362-
363-
if (strcmp(upstart_job, "collectd") != 0) {
364-
WARNING("Environment specifies unexpected UPSTART_JOB=\"%s\", expected "
365-
"\"collectd\". Ignoring the variable.",
366-
upstart_job);
367-
return 0;
368-
}
369-
370-
NOTICE("Upstart detected, stopping now to signal readyness.");
371-
raise(SIGSTOP);
372-
unsetenv("UPSTART_JOB");
373-
374-
return 1;
375-
}
376-
377-
static int notify_systemd(void) {
378-
int fd;
379-
const char *notifysocket;
380-
struct sockaddr_un su = {0};
381-
size_t su_size;
382-
char buffer[] = "READY=1\n";
383-
384-
notifysocket = getenv("NOTIFY_SOCKET");
385-
if (notifysocket == NULL)
386-
return 0;
387-
388-
if ((strlen(notifysocket) < 2) ||
389-
((notifysocket[0] != '@') && (notifysocket[0] != '/'))) {
390-
ERROR("invalid notification socket NOTIFY_SOCKET=\"%s\": path must be "
391-
"absolute",
392-
notifysocket);
393-
return 0;
394-
}
395-
NOTICE("Systemd detected, trying to signal readyness.");
396-
397-
unsetenv("NOTIFY_SOCKET");
398-
399-
#if defined(SOCK_CLOEXEC)
400-
fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, /* protocol = */ 0);
401-
#else
402-
fd = socket(AF_UNIX, SOCK_DGRAM, /* protocol = */ 0);
403-
#endif
404-
if (fd < 0) {
405-
ERROR("creating UNIX socket failed: %s", STRERRNO);
406-
return 0;
407-
}
408-
409-
su.sun_family = AF_UNIX;
410-
if (notifysocket[0] != '@') {
411-
/* regular UNIX socket */
412-
sstrncpy(su.sun_path, notifysocket, sizeof(su.sun_path));
413-
su_size = sizeof(su);
414-
} else {
415-
/* Linux abstract namespace socket: specify address as "\0foo", i.e.
416-
* start with a null byte. Since null bytes have no special meaning in
417-
* that case, we have to set su_size correctly to cover only the bytes
418-
* that are part of the address. */
419-
sstrncpy(su.sun_path, notifysocket, sizeof(su.sun_path));
420-
su.sun_path[0] = 0;
421-
su_size = sizeof(sa_family_t) + strlen(notifysocket);
422-
if (su_size > sizeof(su))
423-
su_size = sizeof(su);
424-
}
425-
426-
if (sendto(fd, buffer, strlen(buffer), MSG_NOSIGNAL, (void *)&su,
427-
(socklen_t)su_size) < 0) {
428-
ERROR("sendto(\"%s\") failed: %s", notifysocket, STRERRNO);
429-
close(fd);
430-
return 0;
431-
}
432-
433-
unsetenv("NOTIFY_SOCKET");
434-
close(fd);
435-
return 1;
436-
}
437-
#endif /* KERNEL_LINUX */
438-
439-
struct cmdline_config {
440-
_Bool test_config;
441-
_Bool test_readall;
442-
_Bool create_basedir;
443-
const char *configfile;
444-
_Bool daemonize;
445-
};
446-
447320
void read_cmdline(int argc, char **argv, struct cmdline_config *config) {
448321
/* read options */
449322
while (1) {
@@ -530,20 +403,17 @@ int configure_collectd(struct cmdline_config *config) {
530403
return 0;
531404
}
532405

533-
int main(int argc, char **argv) {
534-
#if COLLECT_DAEMON
535-
pid_t pid;
536-
#endif
537-
int exit_status = 0;
406+
void stop_collectd(void) { loop++; }
538407

408+
struct cmdline_config init_config(int argc, char **argv) {
539409
struct cmdline_config config = {
540410
.daemonize = 1, .create_basedir = 1, .configfile = CONFIGFILE,
541411
};
542412

543413
read_cmdline(argc, argv, &config);
544414

545415
if (config.test_config)
546-
return 0;
416+
exit(EXIT_SUCCESS);
547417

548418
if (optind < argc)
549419
exit_usage(1);
@@ -554,110 +424,18 @@ int main(int argc, char **argv) {
554424
if ((status = configure_collectd(&config)) != 0)
555425
exit(EXIT_FAILURE);
556426

557-
#if COLLECT_DAEMON
558-
/*
559-
* fork off child
560-
*/
561-
struct sigaction sig_chld_action = {.sa_handler = SIG_IGN};
562-
563-
sigaction(SIGCHLD, &sig_chld_action, NULL);
564-
565-
/*
566-
* Only daemonize if we're not being supervised
567-
* by upstart or systemd (when using Linux).
568-
*/
569-
if (config.daemonize
570-
#ifdef KERNEL_LINUX
571-
&& notify_upstart() == 0 && notify_systemd() == 0
572-
#endif
573-
) {
574-
int status;
575-
576-
if ((pid = fork()) == -1) {
577-
/* error */
578-
fprintf(stderr, "fork: %s", STRERRNO);
579-
return 1;
580-
} else if (pid != 0) {
581-
/* parent */
582-
/* printf ("Running (PID %i)\n", pid); */
583-
return 0;
584-
}
585-
586-
/* Detach from session */
587-
setsid();
588-
589-
/* Write pidfile */
590-
if (pidfile_create())
591-
exit(2);
592-
593-
/* close standard descriptors */
594-
close(2);
595-
close(1);
596-
close(0);
597-
598-
status = open("/dev/null", O_RDWR);
599-
if (status != 0) {
600-
ERROR("Error: Could not connect `STDIN' to `/dev/null' (status %d)",
601-
status);
602-
return 1;
603-
}
604-
605-
status = dup(0);
606-
if (status != 1) {
607-
ERROR("Error: Could not connect `STDOUT' to `/dev/null' (status %d)",
608-
status);
609-
return 1;
610-
}
611-
612-
status = dup(0);
613-
if (status != 2) {
614-
ERROR("Error: Could not connect `STDERR' to `/dev/null', (status %d)",
615-
status);
616-
return 1;
617-
}
618-
} /* if (config.daemonize) */
619-
#endif /* COLLECT_DAEMON */
620-
621-
struct sigaction sig_pipe_action = {.sa_handler = SIG_IGN};
622-
623-
sigaction(SIGPIPE, &sig_pipe_action, NULL);
624-
625-
/*
626-
* install signal handlers
627-
*/
628-
struct sigaction sig_int_action = {.sa_handler = sig_int_handler};
629-
630-
if (0 != sigaction(SIGINT, &sig_int_action, NULL)) {
631-
ERROR("Error: Failed to install a signal handler for signal INT: %s",
632-
STRERRNO);
633-
return 1;
634-
}
635-
636-
struct sigaction sig_term_action = {.sa_handler = sig_term_handler};
637-
638-
if (0 != sigaction(SIGTERM, &sig_term_action, NULL)) {
639-
ERROR("Error: Failed to install a signal handler for signal TERM: %s",
640-
STRERRNO);
641-
return 1;
642-
}
643-
644-
struct sigaction sig_usr1_action = {.sa_handler = sig_usr1_handler};
427+
return config;
428+
}
645429

646-
if (0 != sigaction(SIGUSR1, &sig_usr1_action, NULL)) {
647-
ERROR("Error: Failed to install a signal handler for signal USR1: %s",
648-
STRERRNO);
649-
return 1;
650-
}
430+
int run_loop(_Bool test_readall) {
431+
int exit_status = 0;
651432

652-
/*
653-
* run the actual loops
654-
*/
655433
if (do_init() != 0) {
656434
ERROR("Error: one or more plugin init callbacks failed.");
657435
exit_status = 1;
658436
}
659437

660-
if (config.test_readall) {
438+
if (test_readall) {
661439
if (plugin_read_all_once() != 0) {
662440
ERROR("Error: one or more plugin read callbacks failed.");
663441
exit_status = 1;
@@ -675,10 +453,5 @@ int main(int argc, char **argv) {
675453
exit_status = 1;
676454
}
677455

678-
#if COLLECT_DAEMON
679-
if (config.daemonize)
680-
pidfile_remove();
681-
#endif /* COLLECT_DAEMON */
682-
683456
return exit_status;
684-
} /* int main */
457+
} /* int run_loop */

0 commit comments

Comments
 (0)