From cbc135ce128c6b3ae44042bb130346ebc7182785 Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Wed, 3 Jun 2020 15:49:06 +0200 Subject: [PATCH] Fix startup race condition --- CHANGELOG.md | 1 + assets/vpncloud@.service | 10 ++++++---- src/main.rs | 5 ++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35654a6..c08a6a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This project follows [semantic versioning](http://semver.org). - [changed] Updated dependencies - [changed] Rewrote argument parsing - [fixed] Fixed problem that could lead to 100% cpu consumption +- [fixed] Fixed startup race condition ### v1.3.0 (2020-01-25) diff --git a/assets/vpncloud@.service b/assets/vpncloud@.service index 0a15153..7067953 100644 --- a/assets/vpncloud@.service +++ b/assets/vpncloud@.service @@ -5,16 +5,18 @@ Wants=network-online.target Documentation=man:vpncloud(1) [Service] -Type=simple -ExecStart=/usr/bin/vpncloud --config /etc/vpncloud/%i.net --log-file /var/log/vpncloud-%i.log --stats-file /var/log/vpncloud-%i.stats +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 --daemon --pid-file /run/vpncloud-%i.pid +PIDFile=/run/vpncloud-%i.pid WorkingDirectory=/etc/vpncloud RestartSec=5s Restart=on-failure -LimitNPROC=10 +TasksMax=10 +MemoryMax=50M PrivateTmp=yes ProtectHome=yes 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 DeviceAllow=/dev/null rw DeviceAllow=/dev/net/tun rw diff --git a/src/main.rs b/src/main.rs index ef51a91..022d638 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,7 +40,8 @@ use std::{ path::Path, process::Command, str::FromStr, - sync::Mutex + sync::Mutex, + thread }; use crate::{ @@ -400,6 +401,8 @@ fn run(config: Config) { } if let Some(pid_file) = config.pid_file { 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: {}"); } else if config.user.is_some() || config.group.is_some() {