libzypp 9.41.1
|
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ 00002 /* SATResolver.cc 00003 * 00004 * Copyright (C) 2000-2002 Ximian, Inc. 00005 * Copyright (C) 2005 SUSE Linux Products GmbH 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License, 00009 * version 2, as published by the Free Software Foundation. 00010 * 00011 * This program is distributed in the hope that it will be useful, but 00012 * WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 00019 * 02111-1307, USA. 00020 */ 00021 extern "C" 00022 { 00023 #include <satsolver/repo_solv.h> 00024 #include <satsolver/poolarch.h> 00025 #include <satsolver/evr.h> 00026 #include <satsolver/poolvendor.h> 00027 #include <satsolver/policy.h> 00028 #include <satsolver/bitmap.h> 00029 #include <satsolver/queue.h> 00030 } 00031 00032 #include "zypp/solver/detail/Helper.h" 00033 #include "zypp/base/String.h" 00034 #include "zypp/Product.h" 00035 #include "zypp/Capability.h" 00036 #include "zypp/ResStatus.h" 00037 #include "zypp/VendorAttr.h" 00038 #include "zypp/base/LogTools.h" 00039 #include "zypp/base/String.h" 00040 #include "zypp/base/Gettext.h" 00041 #include "zypp/base/Algorithm.h" 00042 #include "zypp/ResPool.h" 00043 #include "zypp/ResFilters.h" 00044 #include "zypp/ZConfig.h" 00045 #include "zypp/sat/Pool.h" 00046 #include "zypp/sat/WhatProvides.h" 00047 #include "zypp/sat/WhatObsoletes.h" 00048 #include "zypp/solver/detail/SATResolver.h" 00049 #include "zypp/solver/detail/ProblemSolutionCombi.h" 00050 #include "zypp/solver/detail/ProblemSolutionIgnore.h" 00051 #include "zypp/solver/detail/SolverQueueItemInstall.h" 00052 #include "zypp/solver/detail/SolverQueueItemDelete.h" 00053 #include "zypp/solver/detail/SystemCheck.h" 00054 #include "zypp/sat/Transaction.h" 00055 00057 namespace zypp 00058 { 00059 00060 namespace solver 00061 { 00062 00063 namespace detail 00064 { 00065 00066 using namespace std; 00067 00068 IMPL_PTR_TYPE(SATResolver); 00069 00070 #define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0) 00071 00072 //--------------------------------------------------------------------------- 00073 // Callbacks for SAT policies 00074 //--------------------------------------------------------------------------- 00075 00076 int vendorCheck( Pool *pool, Solvable *solvable1, Solvable *solvable2 ) 00077 { 00078 return VendorAttr::instance().equivalent( IdString(solvable1->vendor), 00079 IdString(solvable2->vendor) ) ? 0 : 1; 00080 } 00081 00082 00083 inline std::string itemToString( const PoolItem & item ) 00084 { 00085 if ( !item ) 00086 return std::string(); 00087 00088 sat::Solvable slv( item.satSolvable() ); 00089 std::string ret( slv.asString() ); // n-v-r.a 00090 if ( ! slv.isSystem() ) 00091 { 00092 ret += "["; 00093 ret += slv.repository().alias(); 00094 ret += "]"; 00095 } 00096 return ret; 00097 } 00098 00099 inline PoolItem getPoolItem( Id id_r ) 00100 { 00101 PoolItem ret( (sat::Solvable( id_r )) ); 00102 if ( !ret && id_r ) 00103 INT << "id " << id_r << " not found in ZYPP pool." << endl; 00104 return ret; 00105 } 00106 00107 //--------------------------------------------------------------------------- 00108 00109 std::ostream & 00110 SATResolver::dumpOn( std::ostream & os ) const 00111 { 00112 os << "<resolver>" << endl; 00113 if (_solv) { 00114 os << " fixsystem = " << _solv->fixsystem << endl; 00115 os << " allowdowngrade = " << _solv->allowdowngrade << endl; 00116 os << " allowarchchange = " << _solv->allowarchchange << endl; 00117 os << " allowvendorchange = " << _solv->allowvendorchange << endl; 00118 os << " allowuninstall = " << _solv->allowuninstall << endl; 00119 os << " updatesystem = " << _solv->updatesystem << endl; 00120 os << " noupdateprovide = " << _solv->noupdateprovide << endl; 00121 os << " dosplitprovides = " << _solv->dosplitprovides << endl; 00122 os << " onlyRequires = " << _solv->dontinstallrecommended << endl; 00123 os << " ignorealreadyrecommended = " << _solv->ignorealreadyrecommended << endl; 00124 os << " distupgrade = " << _distupgrade << endl; 00125 os << " distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl; 00126 os << " solveSrcPackages = " << _solveSrcPackages << endl; 00127 os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl; 00128 } else { 00129 os << "<NULL>"; 00130 } 00131 return os << "<resolver/>" << endl; 00132 } 00133 00134 //--------------------------------------------------------------------------- 00135 00136 SATResolver::SATResolver (const ResPool & pool, Pool *SATPool) 00137 : _pool (pool) 00138 , _SATPool (SATPool) 00139 , _solv(NULL) 00140 , _fixsystem(false) 00141 , _allowdowngrade(false) 00142 , _allowarchchange(false) 00143 , _allowvendorchange(ZConfig::instance().solver_allowVendorChange()) 00144 , _allowuninstall(false) 00145 , _updatesystem(false) 00146 , _noupdateprovide(false) 00147 , _dosplitprovides(false) 00148 , _onlyRequires(ZConfig::instance().solver_onlyRequires()) 00149 , _ignorealreadyrecommended(false) 00150 , _distupgrade(false) 00151 , _distupgrade_removeunsupported(false) 00152 , _solveSrcPackages(false) 00153 , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove()) 00154 { 00155 } 00156 00157 00158 SATResolver::~SATResolver() 00159 { 00160 solverEnd(); 00161 } 00162 00163 //--------------------------------------------------------------------------- 00164 00165 sat::Transaction SATResolver::getTransaction() 00166 { 00167 if ( !_solv ) 00168 return sat::Transaction(); 00169 return sat::Transaction( _solv->trans ); 00170 } 00171 00172 ResPool 00173 SATResolver::pool (void) const 00174 { 00175 return _pool; 00176 } 00177 00178 void 00179 SATResolver::resetItemTransaction (PoolItem item) 00180 { 00181 bool found = false; 00182 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); 00183 iter != _items_to_remove.end(); ++iter) { 00184 if (*iter == item) { 00185 _items_to_remove.remove(*iter); 00186 found = true; 00187 break; 00188 } 00189 } 00190 if (!found) { 00191 for (PoolItemList::const_iterator iter = _items_to_install.begin(); 00192 iter != _items_to_install.end(); ++iter) { 00193 if (*iter == item) { 00194 _items_to_install.remove(*iter); 00195 found = true; 00196 break; 00197 } 00198 } 00199 } 00200 if (!found) { 00201 for (PoolItemList::const_iterator iter = _items_to_keep.begin(); 00202 iter != _items_to_keep.end(); ++iter) { 00203 if (*iter == item) { 00204 _items_to_keep.remove(*iter); 00205 found = true; 00206 break; 00207 } 00208 } 00209 } 00210 if (!found) { 00211 for (PoolItemList::const_iterator iter = _items_to_lock.begin(); 00212 iter != _items_to_lock.end(); ++iter) { 00213 if (*iter == item) { 00214 _items_to_lock.remove(*iter); 00215 found = true; 00216 break; 00217 } 00218 } 00219 } 00220 } 00221 00222 00223 void 00224 SATResolver::addPoolItemToInstall (PoolItem item) 00225 { 00226 resetItemTransaction (item); 00227 _items_to_install.push_back (item); 00228 _items_to_install.unique (); 00229 } 00230 00231 00232 void 00233 SATResolver::addPoolItemsToInstallFromList (PoolItemList & rl) 00234 { 00235 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) { 00236 addPoolItemToInstall (*iter); 00237 } 00238 } 00239 00240 00241 void 00242 SATResolver::addPoolItemToRemove (PoolItem item) 00243 { 00244 resetItemTransaction (item); 00245 _items_to_remove.push_back (item); 00246 _items_to_remove.unique (); 00247 } 00248 00249 00250 void 00251 SATResolver::addPoolItemsToRemoveFromList (PoolItemList & rl) 00252 { 00253 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) { 00254 addPoolItemToRemove (*iter); 00255 } 00256 } 00257 00258 void 00259 SATResolver::addPoolItemToLock (PoolItem item) 00260 { 00261 resetItemTransaction (item); 00262 _items_to_lock.push_back (item); 00263 _items_to_lock.unique (); 00264 } 00265 00266 void 00267 SATResolver::addPoolItemToKeep (PoolItem item) 00268 { 00269 resetItemTransaction (item); 00270 _items_to_keep.push_back (item); 00271 _items_to_keep.unique (); 00272 } 00273 00274 //--------------------------------------------------------------------------- 00275 00276 // copy marked item from solution back to pool 00277 // if data != NULL, set as APPL_LOW (from establishPool()) 00278 00279 static void 00280 SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::TransactByValue causer) 00281 { 00282 // resetting 00283 item.status().resetTransact (causer); 00284 item.status().resetWeak (); 00285 00286 bool r; 00287 00288 // installation/deletion 00289 if (status.isToBeInstalled()) { 00290 r = item.status().setToBeInstalled (causer); 00291 _XDEBUG("SATSolutionToPool install returns " << item << ", " << r); 00292 } 00293 else if (status.isToBeUninstalledDueToUpgrade()) { 00294 r = item.status().setToBeUninstalledDueToUpgrade (causer); 00295 _XDEBUG("SATSolutionToPool upgrade returns " << item << ", " << r); 00296 } 00297 else if (status.isToBeUninstalled()) { 00298 r = item.status().setToBeUninstalled (causer); 00299 _XDEBUG("SATSolutionToPool remove returns " << item << ", " << r); 00300 } 00301 00302 return; 00303 } 00304 00305 //---------------------------------------------------------------------------- 00306 //---------------------------------------------------------------------------- 00307 // resolvePool 00308 //---------------------------------------------------------------------------- 00309 //---------------------------------------------------------------------------- 00310 00311 //---------------------------------------------------------------------------- 00312 // Helper functions for the ZYPP-Pool 00313 //---------------------------------------------------------------------------- 00314 00315 00316 //------------------------------------------------------------------------------------------------------------ 00317 // This function loops over the pool and grabs all items 00318 // It clears all previous bySolver() states also 00319 // 00320 // Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall() 00321 // Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove() 00322 // 00323 // Solver results must be written back to the pool. 00324 //------------------------------------------------------------------------------------------------------------ 00325 00326 00327 struct SATCollectTransact : public resfilter::PoolItemFilterFunctor 00328 { 00329 SATResolver & resolver; 00330 00331 SATCollectTransact (SATResolver & r) 00332 : resolver (r) 00333 { } 00334 00335 bool operator()( PoolItem item ) // only transacts() items go here 00336 { 00337 ResStatus status = item.status(); 00338 bool by_solver = (status.isBySolver() || status.isByApplLow()); 00339 00340 if (by_solver) { 00341 item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions 00342 return true; // back out here, dont re-queue former solver result 00343 } 00344 00345 if ( item.satSolvable().isKind<SrcPackage>() && ! resolver.solveSrcPackages() ) 00346 { 00347 // Later we may continue on a per source package base. 00348 return true; // dont process this source package. 00349 } 00350 00351 if (status.isToBeInstalled()) { 00352 resolver.addPoolItemToInstall(item); // -> install! 00353 } 00354 else if (status.isToBeUninstalled()) { 00355 resolver.addPoolItemToRemove(item); // -> remove ! 00356 } 00357 else if (status.isLocked() 00358 && !by_solver) { 00359 resolver.addPoolItemToLock (item); 00360 } 00361 else if (status.isKept() 00362 && !by_solver) { 00363 resolver.addPoolItemToKeep (item); 00364 } 00365 00366 return true; 00367 } 00368 }; 00369 00370 00371 //---------------------------------------------------------------------------- 00372 //---------------------------------------------------------------------------- 00373 // solving..... 00374 //---------------------------------------------------------------------------- 00375 //---------------------------------------------------------------------------- 00376 00377 00378 class CheckIfUpdate : public resfilter::PoolItemFilterFunctor 00379 { 00380 public: 00381 bool is_updated; 00382 bool multiversion; 00383 sat::Solvable _installed; 00384 00385 CheckIfUpdate( sat::Solvable installed_r ) 00386 : is_updated( false ) 00387 , multiversion( installed_r.multiversionInstall() ) 00388 , _installed( installed_r ) 00389 {} 00390 00391 // check this item will be updated 00392 00393 bool operator()( PoolItem item ) 00394 { 00395 if ( item.status().isToBeInstalled() ) 00396 { 00397 if ( ! multiversion || sameNVRA( _installed, item ) ) 00398 { 00399 is_updated = true; 00400 return false; 00401 } 00402 } 00403 return true; 00404 } 00405 }; 00406 00407 00408 class CollectPseudoInstalled : public resfilter::PoolItemFilterFunctor 00409 { 00410 public: 00411 Queue *solvableQueue; 00412 00413 CollectPseudoInstalled( Queue *queue ) 00414 :solvableQueue (queue) 00415 {} 00416 00417 // collecting PseudoInstalled items 00418 bool operator()( PoolItem item ) 00419 { 00420 if ( traits::isPseudoInstalled( item.satSolvable().kind() ) ) 00421 queue_push( solvableQueue, item.satSolvable().id() ); 00422 return true; 00423 } 00424 }; 00425 00426 bool 00427 SATResolver::solving(const CapabilitySet & requires_caps, 00428 const CapabilitySet & conflict_caps) 00429 { 00430 _solv = solver_create( _SATPool ); 00431 _solv->vendorCheckCb = &vendorCheck; 00432 _solv->fixsystem = _fixsystem; 00433 _solv->ignorealreadyrecommended = _ignorealreadyrecommended; 00434 _solv->updatesystem = _updatesystem; 00435 _solv->allowdowngrade = _allowdowngrade; 00436 _solv->allowuninstall = _allowuninstall; 00437 _solv->allowarchchange = _allowarchchange; 00438 _solv->allowvendorchange = _allowvendorchange; 00439 _solv->dosplitprovides = _dosplitprovides; 00440 _solv->noupdateprovide = _noupdateprovide; 00441 _solv->dontinstallrecommended = _onlyRequires; 00442 _solv->distupgrade = _distupgrade; 00443 _solv->distupgrade_removeunsupported = _distupgrade_removeunsupported; 00444 00445 sat::Pool::instance().prepareForSolving(); 00446 00447 // Solve ! 00448 MIL << "Starting solving...." << endl; 00449 MIL << *this; 00450 solver_solve( _solv, &(_jobQueue) ); 00451 MIL << "....Solver end" << endl; 00452 00453 // copying solution back to zypp pool 00454 //----------------------------------------- 00455 _result_items_to_install.clear(); 00456 _result_items_to_remove.clear(); 00457 00458 /* solvables to be installed */ 00459 for ( int i = 0; i < _solv->decisionq.count; ++i ) 00460 { 00461 sat::Solvable slv( _solv->decisionq.elements[i] ); 00462 if ( !slv || slv.isSystem() ) 00463 continue; 00464 00465 PoolItem poolItem( slv ); 00466 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER); 00467 _result_items_to_install.push_back (poolItem); 00468 } 00469 00470 /* solvables to be erased */ 00471 Repository systemRepo( sat::Pool::instance().findSystemRepo() ); // don't create if it does not exist 00472 if ( systemRepo && ! systemRepo.solvablesEmpty() ) 00473 { 00474 bool mustCheckObsoletes = false; 00475 for_( it, systemRepo.solvablesBegin(), systemRepo.solvablesEnd() ) 00476 { 00477 if (_solv->decisionmap[it->id()] > 0) 00478 continue; 00479 00480 // Check if this is an update 00481 CheckIfUpdate info( *it ); 00482 PoolItem poolItem( *it ); 00483 invokeOnEach( _pool.byIdentBegin( poolItem ), 00484 _pool.byIdentEnd( poolItem ), 00485 resfilter::ByUninstalled(), // ByUninstalled 00486 functor::functorRef<bool,PoolItem> (info) ); 00487 00488 if (info.is_updated) { 00489 SATSolutionToPool( poolItem, ResStatus::toBeUninstalledDueToUpgrade, ResStatus::SOLVER ); 00490 } else { 00491 SATSolutionToPool( poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER ); 00492 if ( ! mustCheckObsoletes ) 00493 mustCheckObsoletes = true; // lazy check for UninstalledDueToObsolete 00494 } 00495 _result_items_to_remove.push_back (poolItem); 00496 } 00497 if ( mustCheckObsoletes ) 00498 { 00499 sat::WhatObsoletes obsoleted( _result_items_to_install.begin(), _result_items_to_install.end() ); 00500 for_( it, obsoleted.poolItemBegin(), obsoleted.poolItemEnd() ) 00501 { 00502 ResStatus & status( it->status() ); 00503 // WhatObsoletes contains installed items only! 00504 if ( status.transacts() && ! status.isToBeUninstalledDueToUpgrade() ) 00505 status.setToBeUninstalledDueToObsolete(); 00506 } 00507 } 00508 } 00509 00510 /* solvables which are recommended */ 00511 for ( int i = 0; i < _solv->recommendations.count; ++i ) 00512 { 00513 PoolItem poolItem( getPoolItem( _solv->recommendations.elements[i] ) ); 00514 poolItem.status().setRecommended( true ); 00515 } 00516 00517 /* solvables which are suggested */ 00518 for ( int i = 0; i < _solv->suggestions.count; ++i ) 00519 { 00520 PoolItem poolItem( getPoolItem( _solv->suggestions.elements[i] ) ); 00521 poolItem.status().setSuggested( true ); 00522 } 00523 00524 _problem_items.clear(); 00525 /* solvables which are orphaned */ 00526 for ( int i = 0; i < _solv->orphaned.count; ++i ) 00527 { 00528 PoolItem poolItem( getPoolItem( _solv->orphaned.elements[i] ) ); 00529 poolItem.status().setOrphaned( true ); 00530 _problem_items.push_back( poolItem ); 00531 } 00532 00533 /* Write validation state back to pool */ 00534 Queue flags, solvableQueue; 00535 00536 queue_init(&flags); 00537 queue_init(&solvableQueue); 00538 00539 CollectPseudoInstalled collectPseudoInstalled(&solvableQueue); 00540 invokeOnEach( _pool.begin(), 00541 _pool.end(), 00542 functor::functorRef<bool,PoolItem> (collectPseudoInstalled) ); 00543 solver_trivial_installable(_solv, &solvableQueue, &flags ); 00544 for (int i = 0; i < solvableQueue.count; i++) { 00545 PoolItem item = _pool.find (sat::Solvable(solvableQueue.elements[i])); 00546 item.status().setUndetermined(); 00547 00548 if (flags.elements[i] == -1) { 00549 item.status().setNonRelevant(); 00550 _XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !"); 00551 } else if (flags.elements[i] == 1) { 00552 item.status().setSatisfied(); 00553 _XDEBUG("SATSolutionToPool(" << item << " ) satisfied !"); 00554 } else if (flags.elements[i] == 0) { 00555 item.status().setBroken(); 00556 _XDEBUG("SATSolutionToPool(" << item << " ) broken !"); 00557 } 00558 } 00559 00560 // Solvables which were selected due requirements which have been made by the user will 00561 // be selected by APPL_LOW. We can't use any higher level, because this setting must 00562 // not serve as a request for the next solver run. APPL_LOW is reset before solving. 00563 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) { 00564 sat::WhatProvides rpmProviders(*iter); 00565 for_( iter2, rpmProviders.begin(), rpmProviders.end() ) { 00566 PoolItem poolItem(*iter2); 00567 if (poolItem.status().isToBeInstalled()) { 00568 MIL << "User requirement " << *iter << " sets " << poolItem << endl; 00569 poolItem.status().setTransactByValue (ResStatus::APPL_LOW); 00570 } 00571 } 00572 } 00573 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) { 00574 sat::WhatProvides rpmProviders(*iter); 00575 for_( iter2, rpmProviders.begin(), rpmProviders.end() ) { 00576 PoolItem poolItem(*iter2); 00577 if (poolItem.status().isToBeUninstalled()) { 00578 MIL << "User conflict " << *iter << " sets " << poolItem << endl; 00579 poolItem.status().setTransactByValue (ResStatus::APPL_LOW); 00580 } 00581 } 00582 } 00583 00584 if (_solv->problems.count > 0 ) 00585 { 00586 ERR << "Solverrun finished with an ERROR" << endl; 00587 return false; 00588 } 00589 00590 queue_free(&(solvableQueue)); 00591 queue_free(&flags); 00592 00593 return true; 00594 } 00595 00596 00597 void 00598 SATResolver::solverInit(const PoolItemList & weakItems) 00599 { 00600 SATCollectTransact info (*this); 00601 00602 MIL << "SATResolver::solverInit()" << endl; 00603 00604 // remove old stuff 00605 solverEnd(); 00606 00607 queue_init( &_jobQueue ); 00608 _items_to_install.clear(); 00609 _items_to_remove.clear(); 00610 _items_to_lock.clear(); 00611 _items_to_keep.clear(); 00612 00613 invokeOnEach ( _pool.begin(), _pool.end(), 00614 functor::functorRef<bool,PoolItem>(info) ); 00615 00616 for (PoolItemList::const_iterator iter = weakItems.begin(); iter != weakItems.end(); iter++) { 00617 Id id = (*iter)->satSolvable().id(); 00618 if (id == ID_NULL) { 00619 ERR << "Weaken: " << *iter << " not found" << endl; 00620 } 00621 MIL << "Weaken dependencies of " << *iter << endl; 00622 queue_push( &(_jobQueue), SOLVER_WEAKENDEPS | SOLVER_SOLVABLE ); 00623 queue_push( &(_jobQueue), id ); 00624 } 00625 00626 // Add rules for parallel installable resolvables with different versions 00627 for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() ) 00628 { 00629 queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE_NAME ); 00630 queue_push( &(_jobQueue), it->id() ); 00631 } 00632 00633 if ( cleandepsOnRemove() ) 00634 { 00635 // Add all items known to be installed by user request (not solver selected). 00636 for_( it, sat::Pool::instance().onSystemByUserBegin(), sat::Pool::instance().onSystemByUserEnd() ) 00637 { 00638 queue_push( &(_jobQueue), SOLVER_USERINSTALLED | SOLVER_SOLVABLE_NAME ); 00639 queue_push( &(_jobQueue), it->id() ); 00640 } 00641 } 00642 00643 if ( _distupgrade ) 00644 { 00645 if ( ZConfig::instance().solverUpgradeRemoveDroppedPackages() ) 00646 { 00647 MIL << "Checking droplists ..." << endl; 00648 // Dropped packages: look for 'weakremover()' provides 00649 // in dup candidates of installed products. 00650 ResPoolProxy proxy( ResPool::instance().proxy() ); 00651 for_( it, proxy.byKindBegin<Product>(), proxy.byKindEnd<Product>() ) 00652 { 00653 if ( (*it)->onSystem() ) // (to install) or (not to delete) 00654 { 00655 Product::constPtr prodCand( (*it)->candidateAsKind<Product>() ); 00656 if ( ! prodCand || (*it)->identicalInstalledCandidate() ) 00657 continue; // product no longer available or unchanged 00658 00659 CapabilitySet droplist( prodCand->droplist() ); 00660 dumpRangeLine( MIL << "Droplist for " << (*it)->candidateObj() << ": " << droplist.size() << " ", droplist.begin(), droplist.end() ) << endl; 00661 for_( cap, droplist.begin(), droplist.end() ) 00662 { 00663 queue_push( &_jobQueue, SOLVER_DROP_ORPHANED | SOLVER_SOLVABLE_NAME ); 00664 queue_push( &_jobQueue, cap->id() ); 00665 } 00666 } 00667 } 00668 } 00669 else 00670 { 00671 MIL << "Droplist processing is disabled." << endl; 00672 } 00673 } 00674 } 00675 00676 void 00677 SATResolver::solverEnd() 00678 { 00679 // cleanup 00680 if ( _solv ) 00681 { 00682 solver_free(_solv); 00683 _solv = NULL; 00684 queue_free( &(_jobQueue) ); 00685 } 00686 } 00687 00688 00689 bool 00690 SATResolver::resolvePool(const CapabilitySet & requires_caps, 00691 const CapabilitySet & conflict_caps, 00692 const PoolItemList & weakItems, 00693 const std::set<Repository> & upgradeRepos) 00694 { 00695 MIL << "SATResolver::resolvePool()" << endl; 00696 00697 // initialize 00698 solverInit(weakItems); 00699 00700 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) { 00701 Id id = (*iter)->satSolvable().id(); 00702 if (id == ID_NULL) { 00703 ERR << "Install: " << *iter << " not found" << endl; 00704 } else { 00705 MIL << "Install " << *iter << endl; 00706 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE ); 00707 queue_push( &(_jobQueue), id ); 00708 } 00709 } 00710 00711 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) { 00712 Id id = (*iter)->satSolvable().id(); 00713 if (id == ID_NULL) { 00714 ERR << "Delete: " << *iter << " not found" << endl; 00715 } else { 00716 MIL << "Delete " << *iter << endl; 00717 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | MAYBE_CLEANDEPS ); 00718 queue_push( &(_jobQueue), id); 00719 } 00720 } 00721 00722 for_( iter, upgradeRepos.begin(), upgradeRepos.end() ) 00723 { 00724 queue_push( &(_jobQueue), SOLVER_DISTUPGRADE | SOLVER_SOLVABLE_REPO ); 00725 queue_push( &(_jobQueue), iter->get()->repoid ); 00726 MIL << "Upgrade repo " << *iter << endl; 00727 } 00728 00729 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) { 00730 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES ); 00731 queue_push( &(_jobQueue), iter->id() ); 00732 MIL << "Requires " << *iter << endl; 00733 } 00734 00735 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) { 00736 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS ); 00737 queue_push( &(_jobQueue), iter->id() ); 00738 MIL << "Conflicts " << *iter << endl; 00739 } 00740 00741 // set requirements for a running system 00742 setSystemRequirements(); 00743 00744 // set locks for the solver 00745 setLocks(); 00746 00747 // solving 00748 bool ret = solving(requires_caps, conflict_caps); 00749 00750 (ret?MIL:WAR) << "SATResolver::resolvePool() done. Ret:" << ret << endl; 00751 return ret; 00752 } 00753 00754 00755 bool 00756 SATResolver::resolveQueue(const SolverQueueItemList &requestQueue, 00757 const PoolItemList & weakItems) 00758 { 00759 MIL << "SATResolver::resolvQueue()" << endl; 00760 00761 // initialize 00762 solverInit(weakItems); 00763 00764 // generate solver queue 00765 for (SolverQueueItemList::const_iterator iter = requestQueue.begin(); iter != requestQueue.end(); iter++) { 00766 (*iter)->addRule(_jobQueue); 00767 } 00768 00769 // Add addition item status to the resolve-queue cause these can be set by problem resolutions 00770 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) { 00771 Id id = (*iter)->satSolvable().id(); 00772 if (id == ID_NULL) { 00773 ERR << "Install: " << *iter << " not found" << endl; 00774 } else { 00775 MIL << "Install " << *iter << endl; 00776 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE ); 00777 queue_push( &(_jobQueue), id ); 00778 } 00779 } 00780 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) { 00781 sat::detail::IdType ident( (*iter)->satSolvable().ident().id() ); 00782 MIL << "Delete " << *iter << ident << endl; 00783 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | MAYBE_CLEANDEPS ); 00784 queue_push( &(_jobQueue), ident); 00785 } 00786 00787 // set requirements for a running system 00788 setSystemRequirements(); 00789 00790 // set locks for the solver 00791 setLocks(); 00792 00793 // solving 00794 bool ret = solving(); 00795 00796 MIL << "SATResolver::resolveQueue() done. Ret:" << ret << endl; 00797 return ret; 00798 } 00799 00801 void SATResolver::doUpdate() 00802 { 00803 MIL << "SATResolver::doUpdate()" << endl; 00804 00805 // initialize 00806 solverInit(PoolItemList()); 00807 00808 // set requirements for a running system 00809 setSystemRequirements(); 00810 00811 // set locks for the solver 00812 setLocks(); 00813 00814 _solv = solver_create( _SATPool ); 00815 _solv->vendorCheckCb = &vendorCheck; 00816 _solv->fixsystem = _fixsystem; 00817 _solv->ignorealreadyrecommended = _ignorealreadyrecommended; 00818 _solv->updatesystem = true; 00819 _solv->allowdowngrade = _allowdowngrade; 00820 _solv->allowuninstall = _allowuninstall; 00821 _solv->allowarchchange = _allowarchchange; 00822 _solv->allowvendorchange = _allowvendorchange; 00823 _solv->dosplitprovides = _dosplitprovides; 00824 _solv->noupdateprovide = _noupdateprovide; 00825 _solv->dontinstallrecommended = _onlyRequires; 00826 _solv->distupgrade = _distupgrade; 00827 _solv->distupgrade_removeunsupported = _distupgrade_removeunsupported; 00828 00829 sat::Pool::instance().prepareForSolving(); 00830 00831 // Solve ! 00832 MIL << "Starting solving for update...." << endl; 00833 MIL << *this; 00834 solver_solve( _solv, &(_jobQueue) ); 00835 MIL << "....Solver end" << endl; 00836 00837 // copying solution back to zypp pool 00838 //----------------------------------------- 00839 00840 /* solvables to be installed */ 00841 for (int i = 0; i < _solv->decisionq.count; i++) 00842 { 00843 Id p; 00844 p = _solv->decisionq.elements[i]; 00845 if (p < 0 || !sat::Solvable(p)) 00846 continue; 00847 if (sat::Solvable(p).repository().get() == _solv->installed) 00848 continue; 00849 00850 PoolItem poolItem = _pool.find (sat::Solvable(p)); 00851 if (poolItem) { 00852 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER); 00853 } else { 00854 ERR << "id " << p << " not found in ZYPP pool." << endl; 00855 } 00856 } 00857 00858 /* solvables to be erased */ 00859 for (int i = _solv->installed->start; i < _solv->installed->start + _solv->installed->nsolvables; i++) 00860 { 00861 if (_solv->decisionmap[i] > 0) 00862 continue; 00863 00864 PoolItem poolItem( _pool.find( sat::Solvable(i) ) ); 00865 if (poolItem) { 00866 // Check if this is an update 00867 CheckIfUpdate info( (sat::Solvable(i)) ); 00868 invokeOnEach( _pool.byIdentBegin( poolItem ), 00869 _pool.byIdentEnd( poolItem ), 00870 resfilter::ByUninstalled(), // ByUninstalled 00871 functor::functorRef<bool,PoolItem> (info) ); 00872 00873 if (info.is_updated) { 00874 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER); 00875 } else { 00876 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER); 00877 } 00878 } else { 00879 ERR << "id " << i << " not found in ZYPP pool." << endl; 00880 } 00881 } 00882 MIL << "SATResolver::doUpdate() done" << endl; 00883 } 00884 00885 00886 00887 //---------------------------------------------------------------------------- 00888 //---------------------------------------------------------------------------- 00889 // error handling 00890 //---------------------------------------------------------------------------- 00891 //---------------------------------------------------------------------------- 00892 00893 //---------------------------------------------------------------------------- 00894 // helper function 00895 //---------------------------------------------------------------------------- 00896 00897 struct FindPackage : public resfilter::ResObjectFilterFunctor 00898 { 00899 ProblemSolutionCombi *problemSolution; 00900 TransactionKind action; 00901 FindPackage (ProblemSolutionCombi *p, const TransactionKind act) 00902 : problemSolution (p) 00903 , action (act) 00904 { 00905 } 00906 00907 bool operator()( PoolItem p) 00908 { 00909 problemSolution->addSingleAction (p, action); 00910 return true; 00911 } 00912 }; 00913 00914 00915 //---------------------------------------------------------------------------- 00916 // Checking if this solvable/item has a buddy which reflect the real 00917 // user visible description of an item 00918 // e.g. The release package has a buddy to the concerning product item. 00919 // This user want's the message "Product foo conflicts with product bar" and 00920 // NOT "package release-foo conflicts with package release-bar" 00921 // (ma: that's why we should map just packages to buddies, not vice versa) 00922 //---------------------------------------------------------------------------- 00923 inline sat::Solvable mapBuddy( const PoolItem & item_r ) 00924 { 00925 if ( item_r.satSolvable().isKind<Package>() ) 00926 { 00927 sat::Solvable buddy = item_r.buddy(); 00928 if ( buddy ) 00929 return buddy; 00930 } 00931 return item_r.satSolvable(); 00932 } 00933 inline sat::Solvable mapBuddy( sat::Solvable item_r ) 00934 { return mapBuddy( PoolItem( item_r ) ); } 00935 00936 PoolItem SATResolver::mapItem ( const PoolItem & item ) 00937 { return PoolItem( mapBuddy( item ) ); } 00938 00939 sat::Solvable SATResolver::mapSolvable ( const Id & id ) 00940 { return mapBuddy( sat::Solvable(id) ); } 00941 00942 string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreId) 00943 { 00944 string ret; 00945 Pool *pool = _solv->pool; 00946 Id probr; 00947 Id dep, source, target; 00948 sat::Solvable s, s2; 00949 00950 ignoreId = 0; 00951 probr = solver_findproblemrule(_solv, problem); 00952 switch (solver_ruleinfo(_solv, probr, &source, &target, &dep)) 00953 { 00954 case SOLVER_RULE_DISTUPGRADE: 00955 s = mapSolvable (source); 00956 ret = str::form (_("%s does not belong to a distupgrade repository"), s.asString().c_str()); 00957 break; 00958 case SOLVER_RULE_INFARCH: 00959 s = mapSolvable (source); 00960 ret = str::form (_("%s has inferior architecture"), s.asString().c_str()); 00961 break; 00962 case SOLVER_RULE_UPDATE: 00963 s = mapSolvable (source); 00964 ret = str::form (_("problem with installed package %s"), s.asString().c_str()); 00965 break; 00966 case SOLVER_RULE_JOB: 00967 ret = _("conflicting requests"); 00968 break; 00969 case SOLVER_RULE_RPM: 00970 ret = _("some dependency problem"); 00971 break; 00972 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP: 00973 ret = str::form (_("nothing provides requested %s"), dep2str(pool, dep)); 00974 detail += _("Have you enabled all requested repositories?"); 00975 break; 00976 case SOLVER_RULE_RPM_NOT_INSTALLABLE: 00977 s = mapSolvable (source); 00978 ret = str::form (_("%s is not installable"), s.asString().c_str()); 00979 break; 00980 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP: 00981 ignoreId = source; // for setting weak dependencies 00982 s = mapSolvable (source); 00983 ret = str::form (_("nothing provides %s needed by %s"), dep2str(pool, dep), s.asString().c_str()); 00984 break; 00985 case SOLVER_RULE_RPM_SAME_NAME: 00986 s = mapSolvable (source); 00987 s2 = mapSolvable (target); 00988 ret = str::form (_("cannot install both %s and %s"), s.asString().c_str(), s2.asString().c_str()); 00989 break; 00990 case SOLVER_RULE_RPM_PACKAGE_CONFLICT: 00991 s = mapSolvable (source); 00992 s2 = mapSolvable (target); 00993 ret = str::form (_("%s conflicts with %s provided by %s"), s.asString().c_str(), dep2str(pool, dep), s2.asString().c_str()); 00994 break; 00995 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES: 00996 s = mapSolvable (source); 00997 s2 = mapSolvable (target); 00998 ret = str::form (_("%s obsoletes %s provided by %s"), s.asString().c_str(), dep2str(pool, dep), s2.asString().c_str()); 00999 break; 01000 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES: 01001 s = mapSolvable (source); 01002 s2 = mapSolvable (target); 01003 ret = str::form (_("installed %s obsoletes %s provided by %s"), s.asString().c_str(), dep2str(pool, dep), s2.asString().c_str()); 01004 break; 01005 case SOLVER_RULE_RPM_SELF_CONFLICT: 01006 s = mapSolvable (source); 01007 ret = str::form (_("solvable %s conflicts with %s provided by itself"), s.asString().c_str(), dep2str(pool, dep)); 01008 break; 01009 case SOLVER_RULE_RPM_PACKAGE_REQUIRES: 01010 ignoreId = source; // for setting weak dependencies 01011 s = mapSolvable (source); 01012 Capability cap(dep); 01013 sat::WhatProvides possibleProviders(cap); 01014 01015 // check, if a provider will be deleted 01016 typedef list<PoolItem> ProviderList; 01017 ProviderList providerlistInstalled, providerlistUninstalled; 01018 for_( iter1, possibleProviders.begin(), possibleProviders.end() ) { 01019 PoolItem provider1 = ResPool::instance().find( *iter1 ); 01020 // find pair of an installed/uninstalled item with the same NVR 01021 bool found = false; 01022 for_( iter2, possibleProviders.begin(), possibleProviders.end() ) { 01023 PoolItem provider2 = ResPool::instance().find( *iter2 ); 01024 if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0 01025 && ( (provider1.status().isInstalled() && provider2.status().isUninstalled()) 01026 || (provider2.status().isInstalled() && provider1.status().isUninstalled()) )) { 01027 found = true; 01028 break; 01029 } 01030 } 01031 if (!found) { 01032 if (provider1.status().isInstalled()) 01033 providerlistInstalled.push_back(provider1); 01034 else 01035 providerlistUninstalled.push_back(provider1); 01036 } 01037 } 01038 01039 ret = str::form (_("%s requires %s, but this requirement cannot be provided"), s.asString().c_str(), dep2str(pool, dep)); 01040 if (providerlistInstalled.size() > 0) { 01041 detail += _("deleted providers: "); 01042 for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) { 01043 if (iter == providerlistInstalled.begin()) 01044 detail += itemToString( *iter ); 01045 else 01046 detail += "\n " + itemToString( mapItem(*iter) ); 01047 } 01048 } 01049 if (providerlistUninstalled.size() > 0) { 01050 if (detail.size() > 0) 01051 detail += _("\nuninstallable providers: "); 01052 else 01053 detail = _("uninstallable providers: "); 01054 for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) { 01055 if (iter == providerlistUninstalled.begin()) 01056 detail += itemToString( *iter ); 01057 else 01058 detail += "\n " + itemToString( mapItem(*iter) ); 01059 } 01060 } 01061 break; 01062 } 01063 01064 return ret; 01065 } 01066 01067 ResolverProblemList 01068 SATResolver::problems () 01069 { 01070 ResolverProblemList resolverProblems; 01071 if (_solv && _solv->problems.count) { 01072 Pool *pool = _solv->pool; 01073 int pcnt; 01074 Id p, rp, what; 01075 Id problem, solution, element; 01076 sat::Solvable s, sd; 01077 01078 CapabilitySet system_requires = SystemCheck::instance().requiredSystemCap(); 01079 CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap(); 01080 01081 MIL << "Encountered problems! Here are the solutions:\n" << endl; 01082 pcnt = 1; 01083 problem = 0; 01084 while ((problem = solver_next_problem(_solv, problem)) != 0) { 01085 MIL << "Problem " << pcnt++ << ":" << endl; 01086 MIL << "====================================" << endl; 01087 string detail; 01088 Id ignoreId; 01089 string whatString = SATprobleminfoString (problem,detail,ignoreId); 01090 MIL << whatString << endl; 01091 MIL << "------------------------------------" << endl; 01092 ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail); 01093 01094 solution = 0; 01095 while ((solution = solver_next_solution(_solv, problem, solution)) != 0) { 01096 element = 0; 01097 ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem); 01098 while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) { 01099 if (p == SOLVER_SOLUTION_JOB) { 01100 /* job, rp is index into job queue */ 01101 what = _jobQueue.elements[rp]; 01102 switch (_jobQueue.elements[rp-1]&(SOLVER_SELECTMASK|SOLVER_JOBMASK)) 01103 { 01104 case SOLVER_INSTALL | SOLVER_SOLVABLE: { 01105 s = mapSolvable (what); 01106 PoolItem poolItem = _pool.find (s); 01107 if (poolItem) { 01108 if (_solv->installed && s.get()->repo == _solv->installed) { 01109 problemSolution->addSingleAction (poolItem, REMOVE); 01110 string description = str::form (_("remove lock to allow removal of %s"), s.asString().c_str() ); 01111 MIL << description << endl; 01112 problemSolution->addDescription (description); 01113 } else { 01114 problemSolution->addSingleAction (poolItem, KEEP); 01115 string description = str::form (_("do not install %s"), s.asString().c_str()); 01116 MIL << description << endl; 01117 problemSolution->addDescription (description); 01118 } 01119 } else { 01120 ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << s.asString() << endl; 01121 } 01122 } 01123 break; 01124 case SOLVER_ERASE | SOLVER_SOLVABLE: { 01125 s = mapSolvable (what); 01126 PoolItem poolItem = _pool.find (s); 01127 if (poolItem) { 01128 if (_solv->installed && s.get()->repo == _solv->installed) { 01129 problemSolution->addSingleAction (poolItem, KEEP); 01130 string description = str::form (_("keep %s"), s.asString().c_str()); 01131 MIL << description << endl; 01132 problemSolution->addDescription (description); 01133 } else { 01134 problemSolution->addSingleAction (poolItem, UNLOCK); 01135 string description = str::form (_("remove lock to allow installation of %s"), itemToString( poolItem ).c_str()); 01136 MIL << description << endl; 01137 problemSolution->addDescription (description); 01138 } 01139 } else { 01140 ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << s.asString() << endl; 01141 } 01142 } 01143 break; 01144 case SOLVER_INSTALL | SOLVER_SOLVABLE_NAME: 01145 { 01146 IdString ident( what ); 01147 SolverQueueItemInstall_Ptr install = 01148 new SolverQueueItemInstall(_pool, ident.asString(), false ); 01149 problemSolution->addSingleAction (install, REMOVE_SOLVE_QUEUE_ITEM); 01150 01151 string description = str::form (_("do not install %s"), ident.c_str() ); 01152 MIL << description << endl; 01153 problemSolution->addDescription (description); 01154 } 01155 break; 01156 case SOLVER_ERASE | SOLVER_SOLVABLE_NAME: 01157 { 01158 // As we do not know, if this request has come from resolvePool or 01159 // resolveQueue we will have to take care for both cases. 01160 IdString ident( what ); 01161 FindPackage info (problemSolution, KEEP); 01162 invokeOnEach( _pool.byIdentBegin( ident ), 01163 _pool.byIdentEnd( ident ), 01164 functor::chain (resfilter::ByInstalled (), // ByInstalled 01165 resfilter::ByTransact ()), // will be deinstalled 01166 functor::functorRef<bool,PoolItem> (info) ); 01167 01168 SolverQueueItemDelete_Ptr del = 01169 new SolverQueueItemDelete(_pool, ident.asString(), false ); 01170 problemSolution->addSingleAction (del, REMOVE_SOLVE_QUEUE_ITEM); 01171 01172 string description = str::form (_("keep %s"), ident.c_str()); 01173 MIL << description << endl; 01174 problemSolution->addDescription (description); 01175 } 01176 break; 01177 case SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES: 01178 { 01179 problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_REQUIRE); 01180 string description = ""; 01181 01182 // Checking if this problem solution would break your system 01183 if (system_requires.find(Capability(what)) != system_requires.end()) { 01184 // Show a better warning 01185 resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() ); 01186 resolverProblem->setDescription(_("This request will break your system!")); 01187 description = _("ignore the warning of a broken system"); 01188 description += string(" (requires:")+dep2str(pool, what)+")"; 01189 MIL << description << endl; 01190 problemSolution->addFrontDescription (description); 01191 } else { 01192 description = str::form (_("do not ask to install a solvable providing %s"), dep2str(pool, what)); 01193 MIL << description << endl; 01194 problemSolution->addDescription (description); 01195 } 01196 } 01197 break; 01198 case SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES: 01199 { 01200 problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_CONFLICT); 01201 string description = ""; 01202 01203 // Checking if this problem solution would break your system 01204 if (system_conflicts.find(Capability(what)) != system_conflicts.end()) { 01205 // Show a better warning 01206 resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() ); 01207 resolverProblem->setDescription(_("This request will break your system!")); 01208 description = _("ignore the warning of a broken system"); 01209 description += string(" (conflicts:")+dep2str(pool, what)+")"; 01210 MIL << description << endl; 01211 problemSolution->addFrontDescription (description); 01212 01213 } else { 01214 description = str::form (_("do not ask to delete all solvables providing %s"), dep2str(pool, what)); 01215 MIL << description << endl; 01216 problemSolution->addDescription (description); 01217 } 01218 } 01219 break; 01220 case SOLVER_UPDATE | SOLVER_SOLVABLE: 01221 { 01222 s = mapSolvable (what); 01223 PoolItem poolItem = _pool.find (s); 01224 if (poolItem) { 01225 if (_solv->installed && s.get()->repo == _solv->installed) { 01226 problemSolution->addSingleAction (poolItem, KEEP); 01227 string description = str::form (_("do not install most recent version of %s"), s.asString().c_str()); 01228 MIL << description << endl; 01229 problemSolution->addDescription (description); 01230 } else { 01231 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl; 01232 } 01233 } else { 01234 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << s.asString() << endl; 01235 } 01236 } 01237 break; 01238 default: 01239 MIL << "- do something different" << endl; 01240 ERR << "No valid solution available" << endl; 01241 break; 01242 } 01243 } else if (p == SOLVER_SOLUTION_INFARCH) { 01244 s = mapSolvable (rp); 01245 PoolItem poolItem = _pool.find (s); 01246 if (_solv->installed && s.get()->repo == _solv->installed) { 01247 problemSolution->addSingleAction (poolItem, LOCK); 01248 string description = str::form (_("keep %s despite the inferior architecture"), s.asString().c_str()); 01249 MIL << description << endl; 01250 problemSolution->addDescription (description); 01251 } else { 01252 problemSolution->addSingleAction (poolItem, INSTALL); 01253 string description = str::form (_("install %s despite the inferior architecture"), s.asString().c_str()); 01254 MIL << description << endl; 01255 problemSolution->addDescription (description); 01256 } 01257 } else if (p == SOLVER_SOLUTION_DISTUPGRADE) { 01258 s = mapSolvable (rp); 01259 PoolItem poolItem = _pool.find (s); 01260 if (_solv->installed && s.get()->repo == _solv->installed) { 01261 problemSolution->addSingleAction (poolItem, LOCK); 01262 string description = str::form (_("keep obsolete %s"), s.asString().c_str()); 01263 MIL << description << endl; 01264 problemSolution->addDescription (description); 01265 } else { 01266 problemSolution->addSingleAction (poolItem, INSTALL); 01267 string description = str::form (_("install %s from excluded repository"), s.asString().c_str()); 01268 MIL << description << endl; 01269 problemSolution->addDescription (description); 01270 } 01271 } else { 01272 /* policy, replace p with rp */ 01273 s = mapSolvable (p); 01274 if (rp) 01275 sd = mapSolvable (rp); 01276 01277 PoolItem itemFrom = _pool.find (s); 01278 if (s == sd && _solv->distupgrade) 01279 { 01280 PoolItem poolItem = _pool.find (s); 01281 if (poolItem) { 01282 problemSolution->addSingleAction (poolItem, LOCK); // for solver reason: NOT weak lock. 01283 string description = str::form (_("keep obsolete %s"), s.asString().c_str()); 01284 MIL << description << endl; 01285 problemSolution->addDescription (description); 01286 } else { 01287 ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << s.asString() << endl; 01288 } 01289 } 01290 else if (rp) 01291 { 01292 int gotone = 0; 01293 01294 PoolItem itemTo = _pool.find (sd); 01295 if (itemFrom && itemTo) { 01296 problemSolution->addSingleAction (itemTo, INSTALL); 01297 01298 if (evrcmp(pool, s.get()->evr, sd.get()->evr, EVRCMP_COMPARE ) > 0) 01299 { 01300 string description = str::form (_("downgrade of %s to %s"), s.asString().c_str(), sd.asString().c_str()); 01301 MIL << description << endl; 01302 problemSolution->addDescription (description); 01303 gotone = 1; 01304 } 01305 if (!_solv->allowarchchange && s.get()->name == sd.get()->name && s.get()->arch != sd.get()->arch 01306 && policy_illegal_archchange(_solv, s.get(), sd.get())) 01307 { 01308 string description = str::form (_("architecture change of %s to %s"), s.asString().c_str(), sd.asString().c_str()); 01309 MIL << description << endl; 01310 problemSolution->addDescription (description); 01311 gotone = 1; 01312 } 01313 if (!_solv->allowvendorchange && s.get()->name == sd.get()->name && s.get()->vendor != sd.get()->vendor 01314 && policy_illegal_vendorchange(_solv, s.get(), sd.get())) 01315 { 01316 IdString s_vendor( s.vendor() ); 01317 IdString sd_vendor( sd.vendor() ); 01318 string description = str::form (_("install %s (with vendor change)\n %s --> %s") , 01319 sd.asString().c_str(), 01320 ( s_vendor ? s_vendor.c_str() : " (no vendor) " ), 01321 ( sd_vendor ? sd_vendor.c_str() : " (no vendor) " ) ); 01322 MIL << description << endl; 01323 problemSolution->addDescription (description); 01324 gotone = 1; 01325 } 01326 if (!gotone) { 01327 string description = str::form (_("replacement of %s with %s"), s.asString().c_str(), sd.asString().c_str()); 01328 MIL << description << endl; 01329 problemSolution->addDescription (description); 01330 } 01331 } else { 01332 ERR << s.asString() << " or " << sd.asString() << " not found" << endl; 01333 } 01334 } 01335 else 01336 { 01337 if (itemFrom) { 01338 string description = str::form (_("deinstallation of %s"), s.asString().c_str()); 01339 MIL << description << endl; 01340 problemSolution->addDescription (description); 01341 problemSolution->addSingleAction (itemFrom, REMOVE); 01342 } 01343 } 01344 } 01345 } 01346 resolverProblem->addSolution (problemSolution, 01347 problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first. 01348 MIL << "------------------------------------" << endl; 01349 } 01350 01351 if (ignoreId > 0) { 01352 // There is a possibility to ignore this error by setting weak dependencies 01353 PoolItem item = _pool.find (sat::Solvable(ignoreId)); 01354 ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(resolverProblem, item); 01355 resolverProblem->addSolution (problemSolution, 01356 false); // Solutions will be shown at the end 01357 MIL << "ignore some dependencies of " << item << endl; 01358 MIL << "------------------------------------" << endl; 01359 } 01360 01361 // save problem 01362 resolverProblems.push_back (resolverProblem); 01363 } 01364 } 01365 return resolverProblems; 01366 } 01367 01368 void 01369 SATResolver::applySolutions (const ProblemSolutionList & solutions) 01370 { 01371 for (ProblemSolutionList::const_iterator iter = solutions.begin(); 01372 iter != solutions.end(); ++iter) { 01373 ProblemSolution_Ptr solution = *iter; 01374 Resolver dummyResolver(_pool); 01375 if (!solution->apply (dummyResolver)) 01376 break; 01377 } 01378 } 01379 01380 void SATResolver::setLocks() 01381 { 01382 for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); ++iter) { 01383 sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() ); 01384 if (iter->status().isInstalled()) { 01385 MIL << "Lock installed item " << *iter << endl; 01386 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE ); 01387 queue_push( &(_jobQueue), ident ); 01388 } else { 01389 MIL << "Lock NOT installed item " << *iter << endl; 01390 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | MAYBE_CLEANDEPS ); 01391 queue_push( &(_jobQueue), ident ); 01392 } 01393 } 01394 01396 // Weak locks: Ignore if an item with this name is already installed. 01397 // If it's not installed try to keep it this way using a weak delete 01399 std::set<IdString> unifiedByName; 01400 for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); ++iter) { 01401 IdString ident( (*iter)->satSolvable().ident() ); 01402 if ( unifiedByName.insert( ident ).second ) 01403 { 01404 if ( ! ui::Selectable::get( *iter )->hasInstalledObj() ) 01405 { 01406 MIL << "Keep NOT installed name " << ident << " (" << *iter << ")" << endl; 01407 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS ); 01408 queue_push( &(_jobQueue), ident.id() ); 01409 } 01410 } 01411 } 01412 } 01413 01414 void SATResolver::setSystemRequirements() 01415 { 01416 CapabilitySet system_requires = SystemCheck::instance().requiredSystemCap(); 01417 CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap(); 01418 01419 for (CapabilitySet::const_iterator iter = system_requires.begin(); iter != system_requires.end(); ++iter) { 01420 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES ); 01421 queue_push( &(_jobQueue), iter->id() ); 01422 MIL << "SYSTEM Requires " << *iter << endl; 01423 } 01424 01425 for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); ++iter) { 01426 queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS ); 01427 queue_push( &(_jobQueue), iter->id() ); 01428 MIL << "SYSTEM Conflicts " << *iter << endl; 01429 } 01430 01431 // Lock the architecture of the running systems rpm 01432 // package on distupgrade. 01433 if ( _distupgrade && ZConfig::instance().systemRoot() == "/" ) 01434 { 01435 ResPool pool( ResPool::instance() ); 01436 IdString rpm( "rpm" ); 01437 for_( it, pool.byIdentBegin(rpm), pool.byIdentEnd(rpm) ) 01438 { 01439 if ( (*it)->isSystem() ) 01440 { 01441 Capability archrule( (*it)->arch(), rpm.c_str(), Capability::PARSED ); 01442 queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_NAME | SOLVER_ESSENTIAL ); 01443 queue_push( &(_jobQueue), archrule.id() ); 01444 01445 } 01446 } 01447 } 01448 } 01449 01450 01452 };// namespace detail 01455 };// namespace solver 01458 };// namespace zypp 01460