Просмотр исходного кода

implement external solver calling for upgrade and dist-upgrade, too

David Kalnischkies лет назад: 15
Родитель
Сommit
741b7da9de
4 измененных файлов с 80 добавлено и 52 удалено
  1. 22 18
      apt-pkg/algorithms.cc
  2. 1 0
      apt-pkg/algorithms.h
  3. 54 34
      apt-pkg/edsp.cc
  4. 3 0
      apt-pkg/edsp.h

+ 22 - 18
apt-pkg/algorithms.cc

@@ -332,6 +332,10 @@ bool pkgFixBroken(pkgDepCache &Cache)
  */
  */
 bool pkgDistUpgrade(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);
    pkgDepCache::ActionGroup group(Cache);
 
 
    /* Upgrade all installed packages first without autoinst to help the resolver
    /* 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 */
    to install packages not marked for install */
 bool pkgAllUpgrade(pkgDepCache &Cache)
 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);
    pkgDepCache::ActionGroup group(Cache);
 
 
    pkgProblemResolver Fix(&Cache);
    pkgProblemResolver Fix(&Cache);
@@ -740,25 +748,8 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
 bool pkgProblemResolver::Resolve(bool BrokenFix)
 bool pkgProblemResolver::Resolve(bool BrokenFix)
 {
 {
    std::string const solver = _config->Find("APT::Solver::Name", "internal");
    std::string const solver = _config->Find("APT::Solver::Name", "internal");
-
    if (solver != "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);
    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
    in that it does not install or remove any packages. It is assumed that the
    system was non-broken previously. */
    system was non-broken previously. */
 bool pkgProblemResolver::ResolveByKeep()
 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);
    pkgDepCache::ActionGroup group(Cache);
 
 

+ 1 - 0
apt-pkg/algorithms.h

@@ -107,6 +107,7 @@ class pkgProblemResolver						/*{{{*/
    bool DoUpgrade(pkgCache::PkgIterator Pkg);
    bool DoUpgrade(pkgCache::PkgIterator Pkg);
 
 
    bool ResolveInternal(bool const BrokenFix = false);
    bool ResolveInternal(bool const BrokenFix = false);
+   bool ResolveByKeepInternal();
    
    
    public:
    public:
    
    

+ 54 - 34
apt-pkg/edsp.cc

@@ -197,7 +197,7 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
 	 continue;
 	 continue;
       req->append(" ").append(Pkg.FullName());
       req->append(" ").append(Pkg.FullName());
    }
    }
-   fprintf(output, "Request: EDSP 0.2\n");
+   fprintf(output, "Request: EDSP 0.4\n");
    if (del.empty() == false)
    if (del.empty() == false)
       fprintf(output, "Remove: %s\n", del.c_str()+1);
       fprintf(output, "Remove: %s\n", del.c_str()+1);
    if (inst.empty() == false)
    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	{{{*/
 // EDSP::ExecuteSolver - fork requested solver and setup ipc pipes	{{{*/
 bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_out) {
 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;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 3 - 0
apt-pkg/edsp.h

@@ -53,6 +53,9 @@ public:
 	bool static WriteError(std::string const &message, FILE* output);
 	bool static WriteError(std::string const &message, FILE* output);
 
 
 	bool static ExecuteSolver(const char* const solver, int *solver_in, int *solver_out);
 	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
 #endif