]> git.proxmox.com Git - proxmox-backup.git/commitdiff
daemon: add hack for sd_notify
authorDominik Csapak <d.csapak@proxmox.com>
Wed, 11 Nov 2020 08:27:51 +0000 (09:27 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 11 Nov 2020 08:43:00 +0000 (09:43 +0100)
sd_notify is not synchronous, iow. it only waits until the message
reaches the queue not until it is processed by systemd

when the process that sent such a message exits before systemd could
process it, it cannot be associated to the correct pid

so in case of reloading, we send a message with 'MAINPID=<newpid>'
to signal that it will change. if now the old process exits before
systemd knows this, it will not accept the 'READY=1' message from the
child, since it rejects the MAINPID change

since there is no (AFAICS) library interface to check the unit status,
we use 'systemctl is-active <SERVICE_NAME>' to check the state until
it is not 'reloading' anymore.

on newer systemd versions, there is 'sd_notify_barrier' which would
allow us to wait for systemd to have all messages from the current
pid to be processed before acknowledging to the child, but on buster
the systemd version is to old...

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
src/bin/proxmox-backup-api.rs
src/bin/proxmox-backup-proxy.rs
src/tools/daemon.rs

index 7d59717b9c3b37eea7fe666db8568eaa77cee4d8..70d4cb5d075088b35fb099babef7e0e53491318d 100644 (file)
@@ -76,6 +76,7 @@ async fn run() -> Result<(), Error> {
                 })
             )
         },
+        "proxmox-backup.service",
     );
 
     server::write_pid(buildcfg::PROXMOX_BACKUP_API_PID_FN)?;
index 04c976b537ac9b49303a55436aab5fc17cfa0cf7..259d558a48b0d6674373842c665395921f979971 100644 (file)
@@ -133,6 +133,7 @@ async fn run() -> Result<(), Error> {
                 .map(|_| ())
             )
         },
+        "proxmox-backup-proxy.service",
     );
 
     server::write_pid(buildcfg::PROXMOX_BACKUP_PROXY_PID_FN)?;
index 249ce2ad10ba78c21b460968c27d0cafbeaf29e3..63eb6dee79285e7cd28a12d0985eb7812e8c0323 100644 (file)
@@ -260,6 +260,7 @@ impl Future for NotifyReady {
 pub async fn create_daemon<F, S>(
     address: std::net::SocketAddr,
     create_service: F,
+    service_name: &str,
 ) -> Result<(), Error>
 where
     F: FnOnce(tokio::net::TcpListener, NotifyReady) -> Result<S, Error>,
@@ -301,10 +302,35 @@ where
     if let Some(future) = finish_future {
         future.await;
     }
+
+    // FIXME: this is a hack, replace with sd_notify_barrier when available
+    if server::is_reload_request() {
+        check_service_is_active(service_name).await?;
+    }
+
     log::info!("daemon shut down...");
     Ok(())
 }
 
+pub async fn check_service_is_active(service: &str) -> Result<(), Error> {
+    for _ in 0..5 {
+        tokio::time::delay_for(std::time::Duration::new(5, 0)).await;
+        if let Ok(output) = tokio::process::Command::new("systemctl")
+            .args(&["is-active", service])
+            .output()
+            .await
+        {
+            if let Ok(text) = String::from_utf8(output.stdout) {
+                if text.trim().trim_start() != "reloading" {
+                    return Ok(());
+                }
+            }
+        }
+    }
+
+    Ok(())
+}
+
 #[link(name = "systemd")]
 extern "C" {
     fn sd_notify(unset_environment: c_int, state: *const c_char) -> c_int;