diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rwxr-xr-x | netdata-installer.sh | 4 | ||||
-rw-r--r-- | src/daemon.c | 59 | ||||
-rw-r--r-- | src/daemon.h | 5 | ||||
-rw-r--r-- | src/main.c | 22 | ||||
-rwxr-xr-x | system/netdata-openrc.in | 2 | ||||
-rw-r--r-- | system/netdata.service.in | 2 |
7 files changed, 60 insertions, 35 deletions
diff --git a/.gitignore b/.gitignore index e6f03c7ad5..78a63f72c2 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ web/control.html web/datasource.css web/gadget.xml web/index_new.html +system/netdata-openrc diff --git a/netdata-installer.sh b/netdata-installer.sh index 88333478d9..2b316ff784 100755 --- a/netdata-installer.sh +++ b/netdata-installer.sh @@ -314,7 +314,7 @@ do count=$((count + 1)) - pid=$(cat /var/run/netdata/netdata.pid 2>/dev/null) + pid=$(cat /var/run/netdata/netdata.pid 2>/dev/null || cat /var/run/netdata.pid 2>/dev/null) isnetdata $pid || pid= if [ ! -z "${pid}" ] then @@ -334,7 +334,7 @@ echo >&2 # run netdata echo >&2 "Starting netdata..." -run ${NETDATA_PREFIX}/usr/sbin/netdata "${@}" +run ${NETDATA_PREFIX}/usr/sbin/netdata -pidfile /var/run/netdata.pid "${@}" if [ $? -ne 0 ] then diff --git a/src/daemon.c b/src/daemon.c index 1428a6153f..2dd7b09c85 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -24,6 +24,9 @@ #include "main.h" #include "daemon.h" +char pidfile[FILENAME_MAX + 1] = ""; +int pidfd = -1; + void sig_handler(int signo) { switch(signo) { @@ -71,23 +74,6 @@ void sig_handler(int signo) } } -char rundir[FILENAME_MAX + 1] = RUN_DIR; -char pidfile[FILENAME_MAX + 1] = ""; -void prepare_rundir() { - if(getuid() != 0) { - mkdir("/run/user", 0775); - snprintf(rundir, FILENAME_MAX, "/run/user/%d", getuid()); - mkdir(rundir, 0775); - snprintf(rundir, FILENAME_MAX, "/run/user/%d/netdata", getuid()); - } - - snprintf(pidfile, FILENAME_MAX, "%s/netdata.pid", rundir); - - if(mkdir(rundir, 0775) != 0) { - if(errno != EEXIST) error("Cannot create directory '%s'.", rundir); - } -} - int become_user(const char *username) { struct passwd *pw = getpwnam(username); @@ -96,9 +82,21 @@ int become_user(const char *username) return -1; } - if(chown(rundir, pw->pw_uid, pw->pw_gid) != 0) { - error("Cannot chown directory '%s' to user %s.", rundir, username); - return -1; + if(pidfile[0] && getuid() != pw->pw_uid) { + // we are dropping privileges + if(chown(pidfile, pw->pw_uid, pw->pw_gid) != 0) + error("Cannot chown pidfile '%s' to user '%s'", pidfile, username); + + else if(pidfd != -1) { + // not need to keep it open + close(pidfd); + pidfd = -1; + } + } + else if(pidfd != -1) { + // not need to keep it open + close(pidfd); + pidfd = -1; } if(setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { @@ -293,15 +291,20 @@ int become_daemon(int dont_fork, int close_all_files, const char *user, const ch close(dev_null); // generate our pid file - { - unlink(pidfile); - int fd = open(pidfile, O_RDWR | O_CREAT, 0666); - if(fd >= 0) { + if(pidfile[0]) { + pidfd = open(pidfile, O_RDWR | O_CREAT, 0644); + if(pidfd >= 0) { + if(ftruncate(pidfd, 0) != 0) + error("Cannot truncate pidfile '%s'.", pidfile); + char b[100]; sprintf(b, "%d\n", getpid()); - ssize_t i = write(fd, b, strlen(b)); - if(i <= 0) perror("Cannot write pid to file."); - close(fd); + ssize_t i = write(pidfd, b, strlen(b)); + if(i <= 0) + error("Cannot write pidfile '%s'.", pidfile); + + // don't close it, we might need it at exit + // close(pidfd); } } @@ -311,6 +314,8 @@ int become_daemon(int dont_fork, int close_all_files, const char *user, const ch } else info("Successfully became user '%s'.", user); } + else if(pidfd != -1) + close(pidfd); return(0); } diff --git a/src/daemon.h b/src/daemon.h index 77186daae2..0642be3c0f 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -3,12 +3,13 @@ extern void sig_handler(int signo); -extern void prepare_rundir(); - extern int become_user(const char *username); extern int become_daemon(int dont_fork, int close_all_files, const char *user, const char *input, const char *output, const char *error, const char *access, int *access_fd, FILE **access_fp); extern void netdata_cleanup_and_exit(int i); +extern char pidfile[]; +extern int pidfd; + #endif /* NETDATA_DAEMON_H */ diff --git a/src/main.c b/src/main.c index 3d8edcfe90..1ba8e461e4 100644 --- a/src/main.c +++ b/src/main.c @@ -44,7 +44,20 @@ void netdata_cleanup_and_exit(int ret) netdata_exit = 1; rrdset_save_all(); // kill_childs(); - unlink(RUN_DIR "/netdata.pid"); + + if(pidfd != -1) { + if(ftruncate(pidfd, 0) != 0) + error("Cannot truncate pidfile '%s'.", pidfile); + + close(pidfd); + pidfd = -1; + } + + if(pidfile[0]) { + if(unlink(pidfile) != 0) + error("Cannot unlink pidfile '%s'.", pidfile); + } + info("NetData exiting. Bye bye..."); exit(ret); } @@ -220,6 +233,11 @@ int main(int argc, char **argv) else if(strcmp(argv[i], "-ch") == 0 && (i+1) < argc) { config_set("global", "host access prefix", argv[i+1]); i++; } else if(strcmp(argv[i], "-stacksize") == 0 && (i+1) < argc) { config_set("global", "pthread stack size", argv[i+1]); i++; } else if(strcmp(argv[i], "-nodaemon") == 0 || strcmp(argv[i], "-nd") == 0) dont_fork = 1; + else if(strcmp(argv[i], "-pidfile") == 0 && (i+1) < argc) { + i++; + strncpy(pidfile, argv[i], FILENAME_MAX); + pidfile[FILENAME_MAX] = '\0'; + } else if(strcmp(argv[i], "--unittest") == 0) { rrd_update_every = 1; if(run_all_mockup_tests()) exit(1); @@ -239,6 +257,7 @@ int main(int argc, char **argv) fprintf(stderr, " -nd or -nodeamon to disable forking in the background. Default: unset.\n"); fprintf(stderr, " -df FLAGS debug options. Default: 0x%08llx.\n", debug_flags); fprintf(stderr, " -stacksize BYTES to overwrite the pthread stack size.\n"); + fprintf(stderr, " -pidfile FILENAME to save a pid while running.\n"); exit(1); } } @@ -401,7 +420,6 @@ int main(int argc, char **argv) // -------------------------------------------------------------------- - prepare_rundir(); user = config_get("global", "run as user" , (getuid() == 0)?NETDATA_USER:""); web_files_uid(); diff --git a/system/netdata-openrc.in b/system/netdata-openrc.in index 8ac87f869e..06bb7ffb20 100755 --- a/system/netdata-openrc.in +++ b/system/netdata-openrc.in @@ -25,7 +25,7 @@ extra_started_commands="getconf" pidfile="/run/netdata/netdata.pid" command="${NETDATA_INSTALL_PATH}/usr/sbin/netdata" command_background="yes" -command_args="${NETDATA_EXTRA_ARGS}" +command_args="-pidfile ${pidfile} ${NETDATA_EXTRA_ARGS}" start_stop_daemon_args="-u ${NETDATA_OWNER}" depend() { diff --git a/system/netdata.service.in b/system/netdata.service.in index 266bc65b1c..e828707ab6 100644 --- a/system/netdata.service.in +++ b/system/netdata.service.in @@ -8,7 +8,7 @@ WorkingDirectory=/tmp User=root Group=root PIDFile=@localstatedir_POST@/run/netdata/netdata.pid -ExecStart=@sbindir_POST@/netdata +ExecStart=@sbindir_POST@/netdata -pidfile $PIDFile ExecStop=/bin/kill -SIGTERM $MAINPID TimeoutStopSec=30 |