diff --git a/Makefile b/Makefile index 355d75de7..920da1be6 100644 --- a/Makefile +++ b/Makefile @@ -129,10 +129,6 @@ harvest: deps @echo "Building harvest" @GOOS=$(GOOS) GOARCH=$(GOARCH) $(FLAGS) go build -trimpath -o bin -ldflags=$(LD_FLAGS) ./cmd/harvest ./cmd/poller - @# Build the daemonize for the pollers - @echo "Building daemonize" - @cd cmd/tools/daemonize; gcc daemonize.c -o ../../../bin/daemonize - @cp service/contrib/grafana bin; chmod +x bin/grafana ############################################################################### diff --git a/cmd/harvest/harvest.go b/cmd/harvest/harvest.go index a385cbd77..732dabeba 100644 --- a/cmd/harvest/harvest.go +++ b/cmd/harvest/harvest.go @@ -439,7 +439,30 @@ func startPoller(pollerName string, promPort int, opts *options) { os.Exit(0) } - cmd := exec.Command(path.Join(HarvestHomePath, "bin", "daemonize"), argv...) //nolint:gosec + // Set the Setsid attribute to true, which creates a new session for the child process + // This effectively detaches the child process from the parent process + cmd := exec.Command(argv[0], argv[1:]...) //nolint:gosec + cmd.SysProcAttr = &syscall.SysProcAttr{ + Setsid: true, + } + + // Redirect standard file descriptors to /dev/null + devNull, err := os.OpenFile(os.DevNull, os.O_RDWR, 0) + if err != nil { + fmt.Println("Error opening /dev/null:", err) + os.Exit(1) + } + defer func() { + if err := devNull.Close(); err != nil { + fmt.Println("Error closing /dev/null:", err) + } + }() + + cmd.Stdin = devNull + cmd.Stdout = devNull + cmd.Stderr = devNull + + // Start the poller process in the background if err := cmd.Start(); err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/tools/daemonize/daemonize.c b/cmd/tools/daemonize/daemonize.c deleted file mode 100644 index 7a33febdc..000000000 --- a/cmd/tools/daemonize/daemonize.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -/* - Executes command as a daemon process. Unlike what - is done usually (two forks and exit), we perform - execv after second fork, such that the daemon has - it's own (pretty) cmdline identity. This is helpful to - trace status of pollers. - - Script is only intended to daemonize Harvest pollers. - Daemonizing other processes should be ok, as long as - the command line arguments are correct, but no - guarantee. - - The daemonize function is implemented in the quick - and dirty way: some system calls would need better - error-checking for a safer implementation. - - Usage: - ./daemonize [args...] - - Arguments: - - executable path to executable program - - args optional, passed to daemon unchanged -*/ - -int daemonize(char *bin, char *args[]) { - - // open syslog to send messages - openlog("harvest daemonize", LOG_PID, LOG_USER); - - if (fork() != 0) - return 0; // parent exits - // child continues... - - // get new session ID - if (setsid() == -1) { - syslog(LOG_ERR, "setsid: %s", strerror(errno)); - return -1; - } - - // second fork, so we are not session leader - if (fork() != 0) - return 0; - // (grand) child continues - - // clean file permissions - umask(0); - - // close FDs, if can't get max, choose reasonable number - int maxfds, fd; - if ((maxfds = sysconf(_SC_OPEN_MAX)) == -1) - maxfds = 256; - for (fd=0; fd [args...]\n"); - exit(0); - } - - // construct path to executable and arg vector - // this is done here, so errors are detected early on - char* daemon_argv[100]; - char path[100]; - int i; - - strcpy(path, argv[1]); - - daemon_argv[0] = argv[1]; - - for (i=1; i