diff options
| author | Emīls Piņķis <emils@mullvad.net> | 2019-07-25 11:07:45 +0100 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2019-07-25 18:05:50 +0100 |
| commit | e4ab045a3fc930b7947e4284933f2253e481260d (patch) | |
| tree | 0ed610e70a542cd76d731c677b7b596633c77b66 | |
| parent | e2e1f468f3f24e34dca70ec9ab644e1fb5d91608 (diff) | |
| download | mullvadvpn-e4ab045a3fc930b7947e4284933f2253e481260d.tar.xz mullvadvpn-e4ab045a3fc930b7947e4284933f2253e481260d.zip | |
Specify recovery actions for daemon on Windows
| -rw-r--r-- | Cargo.lock | 32 | ||||
| -rw-r--r-- | mullvad-daemon/Cargo.toml | 2 | ||||
| -rw-r--r-- | mullvad-daemon/src/system_service.rs | 63 |
3 files changed, 81 insertions, 16 deletions
diff --git a/Cargo.lock b/Cargo.lock index 1caa605063..79ed38fae9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1186,7 +1186,7 @@ dependencies = [ "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "windows-service 0.1.0 (git+https://github.com/mullvad/windows-service-rs.git?rev=aab5b26beae364253802b6e5554c9ecdc6285454)", + "windows-service 0.2.0 (git+https://github.com/mullvad/windows-service-rs.git?rev=a5eb1dcbbcee4ec2c6479256305c64b25640c799)", "winres 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2809,6 +2809,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" version = "0.3.7" +source = "git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082#4bcf5cab87124bbeef8c1a445137494d874f8082" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)", +] + +[[package]] +name = "winapi" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2823,6 +2832,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" +source = "git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082#4bcf5cab87124bbeef8c1a445137494d874f8082" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2836,6 +2850,11 @@ dependencies = [ [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" +source = "git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082#4bcf5cab87124bbeef8c1a445137494d874f8082" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2860,13 +2879,13 @@ dependencies = [ [[package]] name = "windows-service" -version = "0.1.0" -source = "git+https://github.com/mullvad/windows-service-rs.git?rev=aab5b26beae364253802b6e5554c9ecdc6285454#aab5b26beae364253802b6e5554c9ecdc6285454" +version = "0.2.0" +source = "git+https://github.com/mullvad/windows-service-rs.git?rev=a5eb1dcbbcee4ec2c6479256305c64b25640c799#a5eb1dcbbcee4ec2c6479256305c64b25640c799" dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "widestring 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)", ] [[package]] @@ -3185,14 +3204,17 @@ dependencies = [ "checksum widestring 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a212922ea58fbf5044f83663aa4fc6281ff890f1fd7546c0c3f52f5290831781" "checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.7 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)" = "<none>" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)" = "<none>" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (git+https://github.com/mullvad/winapi-rs.git?rev=4bcf5cab87124bbeef8c1a445137494d874f8082)" = "<none>" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" "checksum winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef84b96d10db72dd980056666d7f1e7663ce93d82fa33b63e71c966f4cf5032" -"checksum windows-service 0.1.0 (git+https://github.com/mullvad/windows-service-rs.git?rev=aab5b26beae364253802b6e5554c9ecdc6285454)" = "<none>" +"checksum windows-service 0.2.0 (git+https://github.com/mullvad/windows-service-rs.git?rev=a5eb1dcbbcee4ec2c6479256305c64b25640c799)" = "<none>" "checksum winreg 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "daf67b95d0b1bf421c4f11048d63110ca3719977169eec86396b614c8942b6e0" "checksum winres 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ff4fb510bbfe5b8992ff15f77a2e6fe6cf062878f0eda00c0f44963a807ca5dc" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/mullvad-daemon/Cargo.toml b/mullvad-daemon/Cargo.toml index bbd1de43b2..511e52b060 100644 --- a/mullvad-daemon/Cargo.toml +++ b/mullvad-daemon/Cargo.toml @@ -52,7 +52,7 @@ simple-signal = "1.1" [target.'cfg(windows)'.dependencies] ctrlc = "3.0" -windows-service = { git = "https://github.com/mullvad/windows-service-rs.git", rev = "aab5b26beae364253802b6e5554c9ecdc6285454" } +windows-service = { git = "https://github.com/mullvad/windows-service-rs.git", rev = "a5eb1dcbbcee4ec2c6479256305c64b25640c799" } winapi = "0.3" [target.'cfg(windows)'.build-dependencies] diff --git a/mullvad-daemon/src/system_service.rs b/mullvad-daemon/src/system_service.rs index 62c997022a..c7007ae666 100644 --- a/mullvad-daemon/src/system_service.rs +++ b/mullvad-daemon/src/system_service.rs @@ -4,7 +4,7 @@ use std::{ env, ffi::OsString, sync::{ - atomic::{AtomicUsize, Ordering}, + atomic::{AtomicBool, AtomicUsize, Ordering}, mpsc, Arc, }, thread, @@ -13,9 +13,10 @@ use std::{ use talpid_types::ErrorExt; use windows_service::{ service::{ - ServiceAccess, ServiceControl, ServiceControlAccept, ServiceDependency, - ServiceErrorControl, ServiceExitCode, ServiceInfo, ServiceStartType, ServiceState, - ServiceStatus, ServiceType, + ServiceAccess, ServiceAction, ServiceActionType, ServiceControl, ServiceControlAccept, + ServiceDependency, ServiceErrorControl, ServiceExitCode, ServiceFailureActions, + ServiceFailureResetPeriod, ServiceInfo, ServiceStartType, ServiceState, ServiceStatus, + ServiceType, }, service_control_handler::{self, ServiceControlHandlerResult, ServiceStatusHandle}, service_dispatcher, @@ -69,26 +70,42 @@ fn run_service() -> Result<(), String> { .set_pending_start(Duration::from_secs(1)) .unwrap(); + let clean_shutdown = Arc::new(AtomicBool::new(false)); + let log_dir = crate::get_log_dir(cli::get_config()).expect("Log dir should be available here"); let result = crate::create_daemon(log_dir).and_then(|daemon| { let shutdown_handle = daemon.shutdown_handle(); // Register monitor that translates `ServiceControl` to Daemon events - start_event_monitor(persistent_service_status.clone(), shutdown_handle, event_rx); + start_event_monitor( + persistent_service_status.clone(), + shutdown_handle, + event_rx, + clean_shutdown.clone(), + ); persistent_service_status.set_running().unwrap(); daemon.run().map_err(|e| e.display_chain()) }); + let exit_code = match result { - Ok(()) => ServiceExitCode::default(), + Ok(()) => { + // check if shutdown signal was sent from the system + if clean_shutdown.load(Ordering::Acquire) { + ServiceExitCode::default() + } else { + // otherwise return a non-zero code so that the daemon gets restarted + ServiceExitCode::ServiceSpecific(1) + } + } Err(_) => ServiceExitCode::ServiceSpecific(1), }; persistent_service_status.set_stopped(exit_code).unwrap(); - result + result.map(|_| ()) } /// Start event monitor thread that polls for `ServiceControl` and translates them into calls to @@ -97,6 +114,7 @@ fn start_event_monitor( mut persistent_service_status: PersistentServiceStatus, shutdown_handle: DaemonShutdownHandle, event_rx: mpsc::Receiver<ServiceControl>, + clean_shutdown: Arc<AtomicBool>, ) -> thread::JoinHandle<()> { thread::spawn(move || { for event in event_rx { @@ -106,6 +124,7 @@ fn start_event_monitor( .set_pending_stop(Duration::from_secs(10)) .unwrap(); + clean_shutdown.store(true, Ordering::Release); shutdown_handle.shutdown(); } _ => (), @@ -227,9 +246,33 @@ pub fn install_service() -> Result<(), InstallError> { let manager_access = ServiceManagerAccess::CONNECT | ServiceManagerAccess::CREATE_SERVICE; let service_manager = ServiceManager::local_computer(None::<&str>, manager_access) .map_err(InstallError::ConnectServiceManager)?; - service_manager - .create_service(get_service_info(), ServiceAccess::empty()) - .map(|_| ()) + let service_access = ServiceAccess::QUERY_CONFIG + | ServiceAccess::CHANGE_CONFIG + | ServiceAccess::START + | ServiceAccess::DELETE; + + let service = service_manager + .create_service(get_service_info(), service_access) + .or(service_manager.open_service(SERVICE_NAME, service_access)) + .map_err(InstallError::CreateService)?; + + let recovery_actions = vec![ServiceAction { + action_type: ServiceActionType::Restart, + delay: Duration::from_secs(3), + }]; + + let failure_actions = ServiceFailureActions { + reset_period: ServiceFailureResetPeriod::After(Duration::from_secs(2)), + reboot_msg: None, + command: None, + actions: Some(recovery_actions), + }; + + service + .update_failure_actions(failure_actions) + .map_err(InstallError::CreateService)?; + service + .set_failure_actions_on_non_crash_failures(true) .map_err(InstallError::CreateService) } |
