implement external solver calling for upgrade and dist-upgrade, too
authorDavid Kalnischkies <kalnischkies@gmail.com>
Tue, 3 May 2011 08:50:25 +0000 (10:50 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Tue, 3 May 2011 08:50:25 +0000 (10:50 +0200)
apt-pkg/algorithms.cc
apt-pkg/algorithms.h
apt-pkg/edsp.cc
apt-pkg/edsp.h

index fea9e92..5d9fefa 100644 (file)
@@ -332,6 +332,10 @@ bool pkgFixBroken(pkgDepCache &Cache)
  */
 bool pkgDistUpgrade(pkgDepCache &Cache)
 {
+   std::string const solver = _config->Find("APT::Solver::Name", "internal");
+   if (solver != "internal")
+      return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false);
+
    pkgDepCache::ActionGroup group(Cache);
 
    /* Upgrade all installed packages first without autoinst to help the resolver
@@ -384,6 +388,10 @@ bool pkgDistUpgrade(pkgDepCache &Cache)
    to install packages not marked for install */
 bool pkgAllUpgrade(pkgDepCache &Cache)
 {
+   std::string const solver = _config->Find("APT::Solver::Name", "internal");
+   if (solver != "internal")
+      return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false);
+
    pkgDepCache::ActionGroup group(Cache);
 
    pkgProblemResolver Fix(&Cache);
@@ -740,25 +748,8 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
 bool pkgProblemResolver::Resolve(bool BrokenFix)
 {
    std::string const solver = _config->Find("APT::Solver::Name", "internal");
-
    if (solver != "internal")
-   {
-      int solver_in, solver_out;
-      if (EDSP::ExecuteSolver(solver.c_str(), &solver_in, &solver_out) == false)
-        return false;
-
-      FILE* output = fdopen(solver_in, "w");
-      if (output == NULL)
-         return _error->Errno("Resolve", "fdopen on solver stdin failed");
-      EDSP::WriteRequest(Cache, output);
-      EDSP::WriteScenario(Cache, output);
-      fclose(output);
-
-      if (EDSP::ReadResponse(solver_out, Cache) == false)
-        return _error->Error("Reading solver response failed");
-
-      return true;
-   }
+      return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false);
    return ResolveInternal(BrokenFix);
 }
                                                                        /*}}}*/
@@ -1230,6 +1221,19 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
    in that it does not install or remove any packages. It is assumed that the
    system was non-broken previously. */
 bool pkgProblemResolver::ResolveByKeep()
+{
+   std::string const solver = _config->Find("APT::Solver::Name", "internal");
+   if (solver != "internal")
+      return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false);
+   return ResolveByKeepInternal();
+}
+                                                                       /*}}}*/
+// ProblemResolver::ResolveByKeepInternal - Resolve problems using keep        /*{{{*/
+// ---------------------------------------------------------------------
+/* This is the work horse of the soft upgrade routine. It is very gental
+   in that it does not install or remove any packages. It is assumed that the
+   system was non-broken previously. */
+bool pkgProblemResolver::ResolveByKeepInternal()
 {
    pkgDepCache::ActionGroup group(Cache);
 
index 0778ec7..582cbc5 100644 (file)
@@ -107,6 +107,7 @@ class pkgProblemResolver                                            /*{{{*/
    bool DoUpgrade(pkgCache::PkgIterator Pkg);
 
    bool ResolveInternal(bool const BrokenFix = false);
+   bool ResolveByKeepInternal();
    
    public:
    
index f35570c..d723703 100644 (file)
@@ -197,7 +197,7 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
         continue;
       req->append(" ").append(Pkg.FullName());
    }
-   fprintf(output, "Request: EDSP 0.2\n");
+   fprintf(output, "Request: EDSP 0.4\n");
    if (del.empty() == false)
       fprintf(output, "Remove: %s\n", del.c_str()+1);
    if (inst.empty() == false)
@@ -460,42 +460,62 @@ bool EDSP::WriteError(std::string const &message, FILE* output) { return false;
 
 // EDSP::ExecuteSolver - fork requested solver and setup ipc pipes     {{{*/
 bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_out) {
-      std::vector<std::string> const solverDirs = _config->FindVector("Dir::Bin::Solvers");
-      std::string file;
-      for (std::vector<std::string>::const_iterator dir = solverDirs.begin();
-          dir != solverDirs.end(); ++dir) {
-        file = flCombine(*dir, solver);
-        if (RealFileExists(file.c_str()) == true)
-           break;
-        file.clear();
-      }
+       std::vector<std::string> const solverDirs = _config->FindVector("Dir::Bin::Solvers");
+       std::string file;
+       for (std::vector<std::string>::const_iterator dir = solverDirs.begin();
+            dir != solverDirs.end(); ++dir) {
+               file = flCombine(*dir, solver);
+               if (RealFileExists(file.c_str()) == true)
+                       break;
+               file.clear();
+       }
 
-      if (file.empty() == true)
-        return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver);
-      int external[4] = {-1, -1, -1, -1};
-      if (pipe(external) != 0 || pipe(external + 2) != 0)
-        return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP");
-      for (int i = 0; i < 4; ++i)
-        SetCloseExec(external[i], true);
+       if (file.empty() == true)
+               return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver);
+       int external[4] = {-1, -1, -1, -1};
+       if (pipe(external) != 0 || pipe(external + 2) != 0)
+               return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP");
+       for (int i = 0; i < 4; ++i)
+               SetCloseExec(external[i], true);
 
-      pid_t Solver = ExecFork();
-      if (Solver == 0)
-      {
-        dup2(external[0], STDIN_FILENO);
-        dup2(external[3], STDOUT_FILENO);
-        const char* calling[2] = { file.c_str(), 0 };
-        execv(calling[0], (char**) calling);
-        std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl;
-        _exit(100);
-      }
-      close(external[0]);
-      close(external[3]);
+       pid_t Solver = ExecFork();
+       if (Solver == 0) {
+               dup2(external[0], STDIN_FILENO);
+               dup2(external[3], STDOUT_FILENO);
+               const char* calling[2] = { file.c_str(), 0 };
+               execv(calling[0], (char**) calling);
+               std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl;
+               _exit(100);
+       }
+       close(external[0]);
+       close(external[3]);
 
-      if (WaitFd(external[1], true, 5) == false)
-         return _error->Errno("Resolve", "Timed out while Waiting on availability of solver stdin");
+       if (WaitFd(external[1], true, 5) == false)
+               return _error->Errno("Resolve", "Timed out while Waiting on availability of solver stdin");
 
-      *solver_in = external[1];
-      *solver_out = external[2];
-      return true;
+       *solver_in = external[1];
+       *solver_out = external[2];
+       return true;
+}
+                                                                       /*}}}*/
+// EDSP::ResolveExternal - resolve problems by asking external for help        {{{*/
+bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache,
+                        bool const upgrade, bool const distUpgrade,
+                        bool const autoRemove) {
+       int solver_in, solver_out;
+       if (EDSP::ExecuteSolver(solver, &solver_in, &solver_out) == false)
+               return false;
+
+       FILE* output = fdopen(solver_in, "w");
+       if (output == NULL)
+               return _error->Errno("Resolve", "fdopen on solver stdin failed");
+       EDSP::WriteRequest(Cache, output, upgrade, distUpgrade, autoRemove);
+       EDSP::WriteScenario(Cache, output);
+       fclose(output);
+
+       if (EDSP::ReadResponse(solver_out, Cache) == false)
+               return _error->Error("Reading solver response failed");
+
+       return true;
 }
                                                                        /*}}}*/
index df6e1d2..95132eb 100644 (file)
@@ -53,6 +53,9 @@ public:
        bool static WriteError(std::string const &message, FILE* output);
 
        bool static ExecuteSolver(const char* const solver, int *solver_in, int *solver_out);
+       bool static ResolveExternal(const char* const solver, pkgDepCache &Cache,
+                                   bool const upgrade, bool const distUpgrade,
+                                   bool const autoRemove);
 };
                                                                        /*}}}*/
 #endif