-
-
Save oskapt/055d474d7bfef32c49469c1b53e8225f to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# 1. Install this as `/usr/local/etc/rc.d/rc.netdata` | |
# 2. Create the directory `/volume1/netdata` | |
# 3. Symlink `/opt/netdata` to `/volume1/netdata` | |
# 4. Create a triggered task with Task Scheduler to call `/usr/local/etc/rc.d/rc.netdata start` at boot. | |
# - (You may have to turn on Advanced Mode in the Control Panel to see Task Scheduler) | |
# 5. Either reboot or run `sudo /usr/local/etc/rc.d/rc.netdata start` | |
# If you get an error about "Connection Failed," then you've already run Netdata and filled `/`. | |
# Stop netdata and move `/opt/netdata` to `/volume1/netdata` before continuing with step 3 above. | |
NETDATA_DIR=/opt/netdata | |
DAEMON=$NETDATA_DIR/bin/srv/netdata | |
TIMEOUT=30 # seconds to wait for netdata to exit | |
[ -x $DAEMON ] || exit 0 | |
function get_pid() { | |
pid=$( ps ax | grep -v grep | grep -m 1 $DAEMON | awk '{ print $1 }' ) | |
} | |
function check_netdata() { | |
count=1 | |
while [ $count -lt $TIMEOUT ]; do | |
get_pid | |
if [ -z $pid ]; then | |
break | |
else | |
sleep 1 | |
count=$(( $count + 1)) | |
fi | |
done | |
if [ $count -eq $TIMEOUT ]; then | |
echo "Timeout exceeded waiting for netdata to exit." | |
echo "Use '$0 kill' to force netdata to exit." | |
exit 1 | |
fi | |
} | |
function stop_netdata() { | |
get_pid | |
if [ "x$pid" != "x" ]; then | |
if [ "x$1" = "xforce" ]; then | |
kill -9 $pid | |
else | |
kill $pid | |
fi | |
else | |
echo "No running netdata found." | |
fi | |
} | |
function start_netdata() { | |
get_pid | |
if [ "x$pid" = "x" ]; then | |
echo "Starting Netdata." | |
$DAEMON | |
else | |
echo "Netdata already running with pid $pid" | |
fi | |
} | |
case "$1" in | |
start) | |
start_netdata | |
;; | |
stop) | |
echo "Shutting down Netdata." | |
stop_netdata | |
;; | |
restart) | |
echo "Shutting down Netdata." | |
stop_netdata | |
if [ "x$pid" != "x" ]; then | |
echo "Waiting maximum of $TIMEOUT seconds for netdata to exit." | |
fi | |
check_netdata | |
start_netdata | |
;; | |
kill) | |
echo "Killing netdata." | |
stop_netdata force | |
;; | |
status) | |
get_pid | |
if [ "x$pid" != "x" ]; then | |
echo "Netdata running with PID $pid" | |
else | |
echo "No running netdata found." | |
fi | |
;; | |
*) | |
echo "Usage: $0 {start|stop|kill|restart|status}" | |
exit 1 | |
esac | |
exit 0 |
Updated. Thanks for reaching out!
I believe that the modification suggested above can result in the issued command ps ax...
being the only result passed to grep -v grep. I've swapped this:
ps ax | grep -m 1 $DAEMON | grep -v grep | awk '{ print $1 }'
with
ps ax | grep -v grep | grep -m 1 $DAEMON | awk '{ print $1 }'
Thoughts?
It's possible, but only if grep -v $DAEMON
is earlier in the process list than "$DAEMON" itself. The only way that can happen is if this script is run before netdata is started, in which case netdata isn't running and will be started by the script. Your change doesn't hurt anything, and is probably cleaner from a logical flow. I'll make the adjustment. Thanks for posting it.
I am not sure I follow this part
ps ax | grep -v grep
I am not sure I follow this part
ps ax | grep -v grep
This is standard when grepping for something because the grep command also includes the thing you're grepping for. For example (from something unrelated but that I already had open in my terminal):
root@axigen-0:/axigen/var/log# ps ax | grep entrypoint.sh
1 pts/0 Ss+ 0:00 /bin/bash /axigen/bin/entrypoint.sh
348 pts/1 S+ 0:00 grep --color=auto entrypoint.sh
If I was only looking for lines with entrypoint.sh
to find the PID, I need to exclude the grep command that also matches.
Using grep -v grep
means, "exclude any line that has grep
in it," which assures you that you're only processing the lines you're looking for.
Yeah, I mean the order - ps ax | grep -v grep
. Why grep
after ps
? It does nothing.
On a side note: I usually do the following (first letter in square brackets)
ps ax | grep [e]ntrypoint.sh
ps ax
shows all processes running on the host.grep -v grep
excludes the grep commandgrep -m 1 $DAEMON
returns the first match of whatever is in the variable$DAEMON
awk '{ print $1 }'
returns the first field (which is the pid)
The two grep lines were in the opposite order, which could, in an unusual circumstance, cause the grep line to be matched before $DAEMON
and then excluded, resulting in no matches. Flipping it around ensures that only $DAEMON
lines are included.
Doing it with square brackets is another way, but it's dependent on the shell. Using grep -v
is consistent across any shell I might be working in, or any scripts that I write.
Can you explain why you think that "grep
after ps
does nothing?"
Ah, you were fixing this
It's possible, but only if grep -v $DAEMON is earlier in the process list than "$DAEMON" itself. The only way that can happen is if this script is run before netdata is started, in which case netdata isn't running and will be started by the script.
I guess I didn't read or understand. So grep -v grep
is supposed to filter other grep $DAEMON
command that is running at the same time but also started before Netdata. I am not sure this can happen. But thanks for your detailed explanation.
I agree that it's not likely to ever happen, since it would require that the grep
command had a pid lower than the running netdata process. However, placing grep -v grep
first in the chain changes "unlikely to happen" to "will never happen," and that seemed reasonable.
Synology DSM >= 6.1 no longer calls rc.local
, so I've updated the script with new instructions.
First, don't let Netdata write to /opt/netdata
because the DSM root partition is only ~2GB in size. Symlink /opt/netdata
to /volume1/netdata
.
Second, use Task Scheduler to create a Triggered Task that fires at boot and calls /usr/local/etc/rc.d/rc.netdata start
. I'm not sure if /etc
gets overwritten during DSM updates, but allegedly /usr/local/etc/rc.d
is safe. I haven't tried an upgrade yet. Alternatively you can put it in /volume1/netdata
and call it from there.
Hi, @oskapt. We have a link to this file in our documentation. And there is a bug report:
The problem is
get_pid()
func returns 2 PIDs:I think adding
-m 1
option to the first grep will fix the issue.Thanks!