]> git.proxmox.com Git - proxmox-backup.git/commitdiff
fix inserting of worker tasks
authorDominik Csapak <d.csapak@proxmox.com>
Wed, 27 May 2020 14:42:22 +0000 (16:42 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 28 May 2020 04:24:42 +0000 (06:24 +0200)
when starting a new task, we do two things to keep track of tasks
(in that order):
* updating the 'active' file with a list of tasks with
  'update_active_workers'
* updating the WORKER_TASK_LIST

the second also updates the status of running tasks in the file by
checking if it is still running by checking the WORKER_TASK_LIST

since those two things are not locked, it can happend that
we update the file, and before updating the WORKER_TASK_LIST,
another thread calls update_active_workers and tries to
get the status from the task log, which won't have any data yet
so the status is 'unknown'

(we do not update that status ever, likely for performance reasons,
so we have to fix this here)

by switching the order of the two operations, we make sure that only
tasks reach the 'active' file which are inserted in the WORKER_TASK_LIST

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
src/server/worker_task.rs

index 202422e6c873c48c8fc2d57d6bc366b68c4e4cc4..c9ca8f525b8594e1d8f8b8fa6b97179d75340473 100644 (file)
@@ -418,10 +418,8 @@ impl WorkerTask {
         let logger = FileLogger::new(&path, to_stdout)?;
         nix::unistd::chown(&path, Some(backup_user.uid), Some(backup_user.gid))?;
 
-        update_active_workers(Some(&upid))?;
-
         let worker = Arc::new(Self {
-            upid,
+            upid: upid.clone(),
             abort_requested: AtomicBool::new(false),
             data: Mutex::new(WorkerTaskData {
                 logger,
@@ -430,10 +428,14 @@ impl WorkerTask {
             }),
         });
 
-        let mut hash = WORKER_TASK_LIST.lock().unwrap();
+        // scope to drop the lock again after inserting
+        {
+            let mut hash = WORKER_TASK_LIST.lock().unwrap();
+            hash.insert(task_id, worker.clone());
+            super::set_worker_count(hash.len());
+        }
 
-        hash.insert(task_id, worker.clone());
-        super::set_worker_count(hash.len());
+        update_active_workers(Some(&upid))?;
 
         Ok(worker)
     }