Fix startup race condition

This commit is contained in:
Dennis Schwerdel 2020-06-03 15:49:06 +02:00
parent cac5af890b
commit cbc135ce12
3 changed files with 11 additions and 5 deletions

View File

@ -11,6 +11,7 @@ This project follows [semantic versioning](http://semver.org).
- [changed] Updated dependencies - [changed] Updated dependencies
- [changed] Rewrote argument parsing - [changed] Rewrote argument parsing
- [fixed] Fixed problem that could lead to 100% cpu consumption - [fixed] Fixed problem that could lead to 100% cpu consumption
- [fixed] Fixed startup race condition
### v1.3.0 (2020-01-25) ### v1.3.0 (2020-01-25)

View File

@ -5,16 +5,18 @@ Wants=network-online.target
Documentation=man:vpncloud(1) Documentation=man:vpncloud(1)
[Service] [Service]
Type=simple Type=forking
ExecStart=/usr/bin/vpncloud --config /etc/vpncloud/%i.net --log-file /var/log/vpncloud-%i.log --stats-file /var/log/vpncloud-%i.stats ExecStart=/usr/bin/vpncloud --config /etc/vpncloud/%i.net --log-file /var/log/vpncloud-%i.log --stats-file /var/log/vpncloud-%i.stats --daemon --pid-file /run/vpncloud-%i.pid
PIDFile=/run/vpncloud-%i.pid
WorkingDirectory=/etc/vpncloud WorkingDirectory=/etc/vpncloud
RestartSec=5s RestartSec=5s
Restart=on-failure Restart=on-failure
LimitNPROC=10 TasksMax=10
MemoryMax=50M
PrivateTmp=yes PrivateTmp=yes
ProtectHome=yes ProtectHome=yes
ProtectSystem=strict ProtectSystem=strict
ReadWritePaths=/var/log ReadWritePaths=/var/log /run
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT
DeviceAllow=/dev/null rw DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw DeviceAllow=/dev/net/tun rw

View File

@ -40,7 +40,8 @@ use std::{
path::Path, path::Path,
process::Command, process::Command,
str::FromStr, str::FromStr,
sync::Mutex sync::Mutex,
thread
}; };
use crate::{ use crate::{
@ -400,6 +401,8 @@ fn run<P: Protocol>(config: Config) {
} }
if let Some(pid_file) = config.pid_file { if let Some(pid_file) = config.pid_file {
daemonize = daemonize.pid_file(pid_file).chown_pid_file(true); daemonize = daemonize.pid_file(pid_file).chown_pid_file(true);
// Give child process some time to write PID file
daemonize = daemonize.exit_action(|| thread::sleep(std::time::Duration::from_millis(10)));
} }
try_fail!(daemonize.start(), "Failed to daemonize: {}"); try_fail!(daemonize.start(), "Failed to daemonize: {}");
} else if config.user.is_some() || config.group.is_some() { } else if config.user.is_some() || config.group.is_some() {