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