What are the advantages and disadvantages of running via systemd
/upstart
versus a user-specific @reboot
crontab daemon entry?
Basically with systemd / upstart
, it’s easier to define more options (start, stop, restart, get status, define dependance (need working internet connection for instance), priority of the process at load [start after every disks are mounted and X display manager is running], user, log, make pidfile, etc.).
jasonwryan thanks for the init.d script. I think the status command is not completely correct. It won’t set a non-zero return when one or more of the syncthing instances for each of the users is not running. This screws up with things like puppet that will check the status output to see if they need to restart the service.
I had the same issue on Debian.
I seem to have solved it by adding:
PATH=${PATH}
Otherwise, it does not know where to find start-stop-daemon.
Under:
END INIT INFO
When using systemd I found that I needed to create the config file in the users scripts directory. In fedora 20 that was
/etc/systemd/users/syncthing.service
and to control the script you then need to use
systemctl --user start syncthing
If you want to use the built in upgrade capabilities you will need to stop the service
systemctl --user stop syncthing
and then run syncthing as root
sudo syncthing
Then perform the upgrade, shut it down and restart the service.
At least this was the only way I could do it as I ran into permission issues as the service obviously runs under your account and by default may not have access to update the binaries.
This is my version of init script for debian. As you can see it runs only one instance and reduces the priority of the process. Also need to add the update block, but that’s for later.
(Git)
#!/bin/sh
### BEGIN INIT INFO
# Provides: syncthing
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Syncthing Daemon
# Description: Syncthing replaces proprietary sync and cloud services with something open,
# trustworthy and decentralized.
# Your data is your data alone and you deserve to choose where it is stored,
# if it is shared with some third party and how it's transmitted over the Internet.
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Syncthing"
NAME=syncthing
# DIR should be the path to the folder where the binary resides
DIR=/usr/bin
DAEMON=$DIR/$NAME
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Arguments that should be forwarded to the binary (e.g.: "-home=/etc/syncthing")
DAEMON_ARGS=""
# Permissions
USER=www-data
GROUP=www-data
[ -x "$DAEMON" ] || exit 0
. /lib/init/vars.sh
. /lib/lsb/init-functions
do_start() {
if [ -e $PIDFILE ]; then
PID=`cat $PIDFILE`
if ( ps -p $PID > /dev/null ); then
log_failure_msg "$DESC '$NAME' is already running."
return 1
else
rm -f $PIDFILE
start-stop-daemon --start --background --chdir $DIR --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --quiet --iosched idle --nicelevel 19 --exec $DAEMON --test > /dev/null || return 1
start-stop-daemon --start --background --chdir $DIR --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --quiet --iosched idle --nicelevel 19 --exec $DAEMON -- $DAEMON_ARGS || return 2
fi
else
start-stop-daemon --start --background --chdir $DIR --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --quiet --iosched idle --nicelevel 19 --exec $DAEMON --test > /dev/null || return 1
start-stop-daemon --start --background --chdir $DIR --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --quiet --iosched idle --nicelevel 19 --exec $DAEMON -- $DAEMON_ARGS || return 2
fi
}
do_stop() {
if [ -e $PIDFILE ]; then
PID=`cat $PIDFILE`
if ( ps -p $PID > /dev/null ); then
start-stop-daemon --stop --retry 1 --signal 2 --quiet --pidfile $PIDFILE
[ "$?" = 2 ] && return 2
else
log_failure_msg "$DESC '$NAME' is not running."
rm -f $PIDFILE
return 1
fi
else
log_failure_msg "$DESC '$NAME' is not running."
return 1
fi
}
case "$1" in
start)
log_daemon_msg "Starting $DESC..." "$NAME"
do_start
case "$?" in
0|1) log_end_msg 0 ;;
1) log_end_msg 1 ;;
esac
;;
stop)
log_daemon_msg "Stopping $DESC..." "$NAME"
do_stop
case "$?" in
0|1) log_end_msg 0 ;;
2) log_end_msg 1 ;;
esac
;;
restart)
log_daemon_msg "Restarting $DESC..." "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
*) log_end_msg 1 ;;
esac
;;
*)
log_end_msg 1
;;
esac
;;
status)
if [ -e $PIDFILE ]; then
PID=`cat $PIDFILE`
if ( ps -p $PID > /dev/null ); then
log_success_msg "$DESC '$NAME' is running (pid $PID)."
exit 0
else
log_failure_msg "$DESC '$NAME' is not running."
rm -f $PIDFILE
exit 1
fi
else
log_failure_msg "$DESC '$NAME' is not running."
exit 1
fi
;;
*)
log_action_msg "Usage: $SCRIPTNAME {start|stop|restart|status}"
exit 0
;;
esac
Hi,
I am using syncthing as systemd user service via systemctl --user
in arch linux. The user service file is the one from the 1st post. The service fails after syncthing tries to restart itself, e.g. after config update or suspend. Here is the systemd journal:
Okt 16 14:15:14 t-laptop syncthing[7515]: [GZKC7] 14:15:14 INFO: Paused state detected, possibly woke up from standby. Restarting in 1m0s. Okt 16 14:16:14 t-laptop syncthing[7515]: [GZKC7] 14:16:14 INFO: Restarting Okt 16 14:16:14 t-laptop syncthing[7515]: [GZKC7] 14:16:14 OK: Exiting Okt 16 14:16:14 t-laptop systemd[5885]: syncthing.service: main process exited, code=exited, status=3/NOTIMPLEMENTED Okt 16 14:16:14 t-laptop systemd[5885]: Unit syncthing.service entered failed state.
Does anyone have similiar issues? If I just run syncthing from the console, a restart via the web interface works.
Could anyone tell if the systemd user service works if installed in $XDG_CONFIG_HOME/systemd/user
?
Thanks
I just looked a little bit closer and the service file works like this: if pulse/syncthing exists with exit code 0 then systemd will restart it, because it sets environment variable STNORESTART=yes
so that pulse/syncthing will not restart but just exit. In my case pulse/syncthing exists with exit code 3, meaning program not running, therefore systemd will not restart it. I fixed it for me by adding SuccessExitStatus=3
to the [Service]
of the systemd service file.
I looked at the source code, but I my knowledge of Go ends there My question would be: What are possible exit codes and why it is not
0
in my case ?
Yeah sure, but you have to start it with: systemctl --user start MYSERVICE
. If you want to have it started automatically, use systemctl --user enable MYSERVICE
. Read more about it here: https://wiki.archlinux.org/index.php/Systemd/User
It works well for enabling the service and starting it, but upon stopping it enters a failed state. Starting again seems to work well (GUI is OK), but apparently I did something wrong and systemd doesn’t know exactly how to stop the service.
➜ ~ systemctl --user start syncthing
➜ ~ systemctl --user status syncthing
syncthing.service - Syncthing service for
Loaded: loaded (/home/steko/.config/systemd/user/syncthing.service; enabled)
Active: active (running) since ven 2014-10-17 17:36:41 CEST; 1s ago
Main PID: 3289 (syncthing)
CGroup: /user.slice/user-1000.slice/user@1000.service/syncthing.service
└─3289 /home/steko/Scaricati/syncthing/syncthing
ott 17 17:36:41 ogma systemd[2003]: Starting Syncthing service for ...
ott 17 17:36:41 ogma systemd[2003]: Started Syncthing service for .
➜ ~ systemctl --user is-enabled syncthing
enabled
➜ ~ systemctl --user stop syncthing
➜ ~ systemctl --user status syncthing
syncthing.service - Syncthing service for
Loaded: loaded (/home/steko/.config/systemd/user/syncthing.service; enabled)
Active: failed (Result: exit-code) since ven 2014-10-17 17:38:14 CEST; 2s ago
Process: 3289 ExecStart=/home/steko/Scaricati/syncthing/syncthing (code=exited, status=2)
Main PID: 3289 (code=exited, status=2)
ott 17 17:36:41 ogma systemd[2003]: Starting Syncthing service for ...
ott 17 17:36:41 ogma systemd[2003]: Started Syncthing service for .
ott 17 17:38:14 ogma systemd[2003]: Stopping Syncthing service for ...
ott 17 17:38:14 ogma systemd[2003]: syncthing.service: main process exited,...NT
ott 17 17:38:14 ogma systemd[2003]: Stopped Syncthing service for .
ott 17 17:38:14 ogma systemd[2003]: Unit syncthing.service entered failed state.
This means syncthing has stopped with exit code 2. I don’t know what happened, but it says here that there was a Misuse of shell builtins (according to Bash documentation). Maybe a permission problem?
Exit codes are a bit further up the file
Thanks, I should have searched for exit
When STNORESTART=yes
is set, Syncthing/Pulse returns 3 as an exit code and Systemd will not restart it unless you add SuccessExitStatus=3
to the service file. A restart from the web gui would not work otherwise.
[Unit]
Description=Syncthing service for %i
After=network.target
[Service]
User=%i
Environment=STNORESTART=yes
ExecStart=/usr/bin/syncthing
Restart=on-success
SuccessExitStatus=3
[Install]
WantedBy=multi-user.target
I am running OpenSuse 13.1 and I have no experience in systemd services and would like to explain the problems I had when I tried this guide.
Tried multiple different options including copying syncthing.service to systemd/user folder and so on.
$systemctl start syncthing Failed to issue method call
$systemctl --user start syncthing Failed to get D-Bus connection: Did not receive a reply
The solutions to my problem was provided here in proper order:
- Copy the systemd service from first post and save as syncthing@.service in folder: /etc/systemd/system/multi-user.target.wants/
- $systemctl enable syncthing@$USER.service
- $systemctl start syncthing@$USER.service
Now everything seems to be working fine.
Stopping/restarting would be a PITA. Especially the latter.
You’re supposed to run it as sudo systemctl start syncthing@USERNAME
, not systemctl --user
.
What I just said above applies. Also, the ArchLinux package actually displays a message post-installation telling you exactly this.
I did not miss the install message. Do you know why this is? I would like it better, when this service is controlled by the user itself, that is why I tried to get it working with systemctl --user
.
Is there any reason why you can’t just sudo systemctl
? The service runs as the user anyway. And it can restart itself once it’s started. (or you can kill it and have systemd restart it for you).
Like I said, as a user space process it should be controlled by the user. The user can not stop or start any services of this type, because the service was set by the super user. Correct if I am wrong but I think that the service is started at system start and therefore can affect the overall performance depending on the number of users using syncthing, repositories and so on. The user service manager (systemctl --user
) is started on the first log in of the according user and its logs can only be viewed by the according user (privacy). I know for a single user system there is no difference but for multi user systems it makes sense to use the user service manager and I am always glad to keep my activities in user space