SATResolver.cc

Go to the documentation of this file.
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 (_("do not keep %s installed"),  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 (_("do not forbid 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 

Generated on Tue May 5 14:43:19 2015 for libzypp by  doxygen 1.5.6