web/datasource.css
web/gadget.xml
web/index_new.html
+system/netdata-openrc
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
# 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
#include "main.h"
#include "daemon.h"
+char pidfile[FILENAME_MAX + 1] = "";
+int pidfd = -1;
+
void sig_handler(int signo)
{
switch(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);
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) {
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);
}
}
}
else info("Successfully became user '%s'.", user);
}
+ else if(pidfd != -1)
+ close(pidfd);
return(0);
}
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 */
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);
}
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);
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);
}
}
// --------------------------------------------------------------------
- prepare_rundir();
user = config_get("global", "run as user" , (getuid() == 0)?NETDATA_USER:"");
web_files_uid();
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() {
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