Control: tag -1 patch

On Mon, Jul 29, 2019 at 06:55:54PM +0200, Guillem Jover wrote:
> Control: reassign -1 aptitude
> Control: severity -1 important
> Control: retitle -1 aptitude: Please add support for dpkg frontend lock
> 
> Hi!
> 
> On Mon, 2019-07-29 at 13:47:05 +0200, Vincent Lefevre wrote:
> > Package: dpkg
> > Version: 1.19.7
> > Severity: serious
> 
> > I wanted to upgrade with aptitude, but it failed with the error
> > "dpkg: error: dpkg frontend lock is locked by another process".
> 

Please find attached a patch for aptitude that reworks the locking
logic to keep the frontend lock once acquired and only release the
inner lock; adjusting the manual dpkg --set-selections call as well
to adhere to the protocol of passing DPKG_FRONTEND_LOCKED as needed.

I've done some testing with the remove command in text mode and
curses UI, and it seems to do the right thing, but please do some
more testing.

Thanks!

-- 
debian developer - deb.li/jak | jak-linux.org - free software dev
ubuntu core developer                              i speak de, en
>From 9c059705f153135fef1d4585561ce9297583a18d Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <[email protected]>
Date: Sun, 28 Dec 2025 17:33:30 +0100
Subject: [PATCH] Implement frontend locking

Change the aptitude locking to never release the frontend lock
but only the inner lock and change internal calls to dpkg to
tell it when we hold the frontend lock.

Bug-Debian: https://bugs.debian.org/933335
---
 src/generic/apt/aptcache.cc        | 36 ++++++++++++++++++++----------
 src/generic/apt/aptcache.h         |  5 +++--
 src/generic/apt/dpkg_selections.cc |  5 +++++
 3 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/src/generic/apt/aptcache.cc b/src/generic/apt/aptcache.cc
index ea176c13..1bc80c86 100644
--- a/src/generic/apt/aptcache.cc
+++ b/src/generic/apt/aptcache.cc
@@ -2512,7 +2512,7 @@ void aptitudeDepCache::apply_solution(const generic_solution<aptitude_universe>
 }
 
 aptitudeCacheFile::aptitudeCacheFile()
-  :Map(NULL), Cache(NULL), DCache(NULL), have_system_lock(false), Policy(NULL)
+  :Map(NULL), Cache(NULL), DCache(NULL), have_frontend_lock(false), have_inner_lock(false), Policy(NULL)
 {
 }
 
@@ -2537,7 +2537,8 @@ bool aptitudeCacheFile::Open(OpProgress* Progress,
       if(!_system->Lock())
 	return false;
 
-      have_system_lock=true;
+      have_frontend_lock=true;
+      have_inner_lock=true;
     }
 
   if(_error->PendingError())
@@ -2590,24 +2591,35 @@ bool aptitudeCacheFile::Open(OpProgress* Progress,
   return true;
 }
 
+// Release the inner lock. Does not release the frontend lock.
 void aptitudeCacheFile::ReleaseLock()
 {
-  if(have_system_lock)
-    {
-      _system->UnLock();
-      have_system_lock=false;
-    }
+  assert(have_frontend_lock >= have_inner_lock);
+  if (have_inner_lock)
+    _system->UnLockInner();
+  have_inner_lock=false;
 }
 
+// Gains the frontend lock and inner lock
+// The frontend lock is never released again.
 bool aptitudeCacheFile::GainLock()
 {
-  if(have_system_lock)
-    return true;
+  assert(have_frontend_lock >= have_inner_lock);
 
-  if(!_system->Lock())
-    return false;
+  if (!have_frontend_lock)
+    {
+      if(!_system->Lock())
+        return false;
+      have_frontend_lock=true;
+      have_inner_lock=true;
+    }
+  else if (!have_inner_lock)
+    {
+      if(!_system->LockInner())
+        return false;
+      have_inner_lock=true;
+    }
 
-  have_system_lock=true;
   return true;
 }
 
diff --git a/src/generic/apt/aptcache.h b/src/generic/apt/aptcache.h
index 3fe3e301..3322ab36 100644
--- a/src/generic/apt/aptcache.h
+++ b/src/generic/apt/aptcache.h
@@ -560,7 +560,8 @@ class aptitudeCacheFile
   pkgCache *Cache;
   aptitudeDepCache *DCache;
 
-  bool have_system_lock;
+  bool have_frontend_lock;
+  bool have_inner_lock;
   // hm, used to make it look like the old stuff?
 public:
 
@@ -581,7 +582,7 @@ public:
 	    bool WithLock,
 	    const char* status_fname,
 	    bool reset_reinstall);
-  bool is_locked() {return have_system_lock;} // EWW (also not quite right)
+  bool is_locked() {return have_frontend_lock;} // EWW (also not quite right)
 
   void ReleaseLock();
   bool GainLock();
diff --git a/src/generic/apt/dpkg_selections.cc b/src/generic/apt/dpkg_selections.cc
index 34cb3341..5d75780b 100644
--- a/src/generic/apt/dpkg_selections.cc
+++ b/src/generic/apt/dpkg_selections.cc
@@ -23,6 +23,7 @@
 #include "aptitude.h"
 
 #include <apt-pkg/configuration.h>
+#include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/error.h>
 
 #include <cstdlib>
@@ -98,6 +99,10 @@ bool DpkgSelections::save_to_dpkg(const std::string& selections)
       signal(SIGBUS,  SIG_DFL);
       signal(SIGABRT, SIG_DFL);
 
+      // Tell dpkg whether we hold the frontend lock
+      if (_system->IsLocked() == true)
+        setenv("DPKG_FRONTEND_LOCKED", "true", 1);
+
       // set input and output for this process
       dup2(dpkg_pipe[0], STDIN_FILENO);
       int fd_null = open("/dev/null", O_RDONLY);
-- 
2.51.0

Reply via email to