libzypp  11.13.5
SATResolver.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* SATResolver.cc
3  *
4  * Copyright (C) 2000-2002 Ximian, Inc.
5  * Copyright (C) 2005 SUSE Linux Products GmbH
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License,
9  * version 2, as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19  * 02111-1307, USA.
20  */
21 extern "C"
22 {
23 #include <solv/repo_solv.h>
24 #include <solv/poolarch.h>
25 #include <solv/evr.h>
26 #include <solv/poolvendor.h>
27 #include <solv/policy.h>
28 #include <solv/bitmap.h>
29 #include <solv/queue.h>
30 }
31 
33 #include "zypp/base/String.h"
34 #include "zypp/Product.h"
35 #include "zypp/Capability.h"
36 #include "zypp/ResStatus.h"
37 #include "zypp/VendorAttr.h"
38 #include "zypp/base/LogTools.h"
39 #include "zypp/base/String.h"
40 #include "zypp/base/Gettext.h"
41 #include "zypp/base/Algorithm.h"
42 #include "zypp/ResPool.h"
43 #include "zypp/ResFilters.h"
44 #include "zypp/ZConfig.h"
45 #include "zypp/sat/Pool.h"
46 #include "zypp/sat/WhatProvides.h"
47 #include "zypp/sat/WhatObsoletes.h"
54 #include "zypp/sat/Transaction.h"
55 #include "zypp/sat/Queue.h"
56 
58 namespace zypp
59 {
60 
61  namespace solver
62  {
63 
64  namespace detail
65  {
66 
67 using namespace std;
68 
69 IMPL_PTR_TYPE(SATResolver);
70 
71 #define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0)
72 
73 //---------------------------------------------------------------------------
74 // Callbacks for SAT policies
75 //---------------------------------------------------------------------------
76 
77 int vendorCheck( Pool *pool, Solvable *solvable1, Solvable *solvable2 )
78 {
79  return VendorAttr::instance().equivalent( IdString(solvable1->vendor),
80  IdString(solvable2->vendor) ) ? 0 : 1;
81 }
82 
83 
84 inline std::string itemToString( const PoolItem & item )
85 {
86  if ( !item )
87  return std::string();
88 
89  sat::Solvable slv( item.satSolvable() );
90  std::string ret( slv.asString() ); // n-v-r.a
91  if ( ! slv.isSystem() )
92  {
93  ret += "[";
94  ret += slv.repository().alias();
95  ret += "]";
96  }
97  return ret;
98 }
99 
100 inline PoolItem getPoolItem( Id id_r )
101 {
102  PoolItem ret( (sat::Solvable( id_r )) );
103  if ( !ret && id_r )
104  INT << "id " << id_r << " not found in ZYPP pool." << endl;
105  return ret;
106 }
107 
108 //---------------------------------------------------------------------------
109 
110 std::ostream &
111 SATResolver::dumpOn( std::ostream & os ) const
112 {
113  os << "<resolver>" << endl;
114  if (_solv) {
115  // os << " fixsystem = " << _solv->fixsystem << endl;
116  // os << " updatesystem = " << _solv->updatesystem << endl;
117  os << " allowdowngrade = " << solver_get_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE) << endl;
118  os << " allowarchchange = " << solver_get_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE) << endl;
119  os << " allowvendorchange = " << solver_get_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE) << endl;
120  os << " allowuninstall = " << solver_get_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL) << endl;
121  os << " noupdateprovide = " << solver_get_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE) << endl;
122  os << " dosplitprovides = " << solver_get_flag(_solv, SOLVER_FLAG_SPLITPROVIDES) << endl;
123  os << " onlyRequires = " << solver_get_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED) << endl;
124  os << " ignorealreadyrecommended = " << !solver_get_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED) << endl;
125  os << " distupgrade = " << _distupgrade << endl;
126  os << " distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl;
127  os << " solveSrcPackages = " << _solveSrcPackages << endl;
128  os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl;
129  } else {
130  os << "<NULL>";
131  }
132  return os << "<resolver/>" << endl;
133 }
134 
135 //---------------------------------------------------------------------------
136 
137 SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
138  : _pool (pool)
139  , _SATPool (SATPool)
140  , _solv(NULL)
141  , _fixsystem(false)
142  , _allowdowngrade(false)
143  , _allowarchchange(false)
144  , _allowvendorchange(ZConfig::instance().solver_allowVendorChange())
145  , _allowuninstall(false)
146  , _updatesystem(false)
147  , _noupdateprovide(false)
148  , _dosplitprovides(false)
149  , _onlyRequires(ZConfig::instance().solver_onlyRequires())
150  , _ignorealreadyrecommended(false)
151  , _distupgrade(false)
152  , _distupgrade_removeunsupported(false)
153  , _solveSrcPackages(false)
154  , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove())
155 {
156 }
157 
158 
160 {
161  solverEnd();
162 }
163 
164 //---------------------------------------------------------------------------
165 
166 ResPool
167 SATResolver::pool (void) const
168 {
169  return _pool;
170 }
171 
172 void
174 {
175  bool found = false;
176  for (PoolItemList::const_iterator iter = _items_to_remove.begin();
177  iter != _items_to_remove.end(); ++iter) {
178  if (*iter == item) {
179  _items_to_remove.remove(*iter);
180  found = true;
181  break;
182  }
183  }
184  if (!found) {
185  for (PoolItemList::const_iterator iter = _items_to_install.begin();
186  iter != _items_to_install.end(); ++iter) {
187  if (*iter == item) {
188  _items_to_install.remove(*iter);
189  found = true;
190  break;
191  }
192  }
193  }
194  if (!found) {
195  for (PoolItemList::const_iterator iter = _items_to_keep.begin();
196  iter != _items_to_keep.end(); ++iter) {
197  if (*iter == item) {
198  _items_to_keep.remove(*iter);
199  found = true;
200  break;
201  }
202  }
203  }
204  if (!found) {
205  for (PoolItemList::const_iterator iter = _items_to_lock.begin();
206  iter != _items_to_lock.end(); ++iter) {
207  if (*iter == item) {
208  _items_to_lock.remove(*iter);
209  found = true;
210  break;
211  }
212  }
213  }
214 }
215 
216 
217 void
219 {
220  resetItemTransaction (item);
221  _items_to_install.push_back (item);
222  _items_to_install.unique ();
223 }
224 
225 
226 void
228 {
229  for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
230  addPoolItemToInstall (*iter);
231  }
232 }
233 
234 
235 void
237 {
238  resetItemTransaction (item);
239  _items_to_remove.push_back (item);
240  _items_to_remove.unique ();
241 }
242 
243 
244 void
246 {
247  for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
248  addPoolItemToRemove (*iter);
249  }
250 }
251 
252 void
254 {
255  resetItemTransaction (item);
256  _items_to_lock.push_back (item);
257  _items_to_lock.unique ();
258 }
259 
260 void
262 {
263  resetItemTransaction (item);
264  _items_to_keep.push_back (item);
265  _items_to_keep.unique ();
266 }
267 
268 //---------------------------------------------------------------------------
269 
270 // copy marked item from solution back to pool
271 // if data != NULL, set as APPL_LOW (from establishPool())
272 
273 static void
275 {
276  // resetting
277  item.status().resetTransact (causer);
278  item.status().resetWeak ();
279 
280  bool r;
281 
282  // installation/deletion
283  if (status.isToBeInstalled()) {
284  r = item.status().setToBeInstalled (causer);
285  _XDEBUG("SATSolutionToPool install returns " << item << ", " << r);
286  }
287  else if (status.isToBeUninstalledDueToUpgrade()) {
288  r = item.status().setToBeUninstalledDueToUpgrade (causer);
289  _XDEBUG("SATSolutionToPool upgrade returns " << item << ", " << r);
290  }
291  else if (status.isToBeUninstalled()) {
292  r = item.status().setToBeUninstalled (causer);
293  _XDEBUG("SATSolutionToPool remove returns " << item << ", " << r);
294  }
295 
296  return;
297 }
298 
299 //----------------------------------------------------------------------------
300 //----------------------------------------------------------------------------
301 // resolvePool
302 //----------------------------------------------------------------------------
303 //----------------------------------------------------------------------------
304 
305 //----------------------------------------------------------------------------
306 // Helper functions for the ZYPP-Pool
307 //----------------------------------------------------------------------------
308 
309 
310 //------------------------------------------------------------------------------------------------------------
311 // This function loops over the pool and grabs all items
312 // It clears all previous bySolver() states also
313 //
314 // Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall()
315 // Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove()
316 //
317 // Solver results must be written back to the pool.
318 //------------------------------------------------------------------------------------------------------------
319 
320 
322 {
324 
326  : resolver (r)
327  { }
328 
329  bool operator()( PoolItem item ) // only transacts() items go here
330  {
331  ResStatus status = item.status();
332  bool by_solver = (status.isBySolver() || status.isByApplLow());
333 
334  if (by_solver) {
335  item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions
336  return true; // back out here, dont re-queue former solver result
337  }
338 
339  if ( item.satSolvable().isKind<SrcPackage>() && ! resolver.solveSrcPackages() )
340  {
341  // Later we may continue on a per source package base.
342  return true; // dont process this source package.
343  }
344 
345  if (status.isToBeInstalled()) {
346  resolver.addPoolItemToInstall(item); // -> install!
347  }
348  else if (status.isToBeUninstalled()) {
349  resolver.addPoolItemToRemove(item); // -> remove !
350  }
351  else if (status.isLocked()
352  && !by_solver) {
354  }
355  else if (status.isKept()
356  && !by_solver) {
358  }
359 
360  return true;
361  }
362 };
363 
364 
365 //----------------------------------------------------------------------------
366 //----------------------------------------------------------------------------
367 // solving.....
368 //----------------------------------------------------------------------------
369 //----------------------------------------------------------------------------
370 
371 
373 {
374  public:
378 
380  : is_updated( false )
381  , multiversion( installed_r.multiversionInstall() )
382  , _installed( installed_r )
383  {}
384 
385  // check this item will be updated
386 
387  bool operator()( PoolItem item )
388  {
389  if ( item.status().isToBeInstalled() )
390  {
391  if ( ! multiversion || sameNVRA( _installed, item ) )
392  {
393  is_updated = true;
394  return false;
395  }
396  }
397  return true;
398  }
399 };
400 
401 
403 {
404  public:
406 
407  CollectPseudoInstalled( Queue *queue )
408  :solvableQueue (queue)
409  {}
410 
411  // collecting PseudoInstalled items
412  bool operator()( PoolItem item )
413  {
414  if ( traits::isPseudoInstalled( item.satSolvable().kind() ) )
415  queue_push( solvableQueue, item.satSolvable().id() );
416  return true;
417  }
418 };
419 
420 bool
421 SATResolver::solving(const CapabilitySet & requires_caps,
422  const CapabilitySet & conflict_caps)
423 {
424  _solv = solver_create( _SATPool );
425  _solv->vendorCheckCb = &vendorCheck;
426  if (_fixsystem) {
427  queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
428  queue_push( &(_jobQueue), 0 );
429  }
430  if (_updatesystem) {
431  queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL);
432  queue_push( &(_jobQueue), 0 );
433  }
434  if (_distupgrade) {
435  queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL);
436  queue_push( &(_jobQueue), 0 );
437  }
439  queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
440  queue_push( &(_jobQueue), 0 );
441  }
442  solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
443  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
444  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
445  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
446  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
447  solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
448  solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
449  solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
450 
452 
453  // Solve !
454  MIL << "Starting solving...." << endl;
455  MIL << *this;
456  solver_solve( _solv, &(_jobQueue) );
457  MIL << "....Solver end" << endl;
458 
459  // copying solution back to zypp pool
460  //-----------------------------------------
461  _result_items_to_install.clear();
462  _result_items_to_remove.clear();
463 
464  /* solvables to be installed */
465  Queue decisionq;
466  queue_init(&decisionq);
467  solver_get_decisionqueue(_solv, &decisionq);
468  for ( int i = 0; i < decisionq.count; ++i )
469  {
470  sat::Solvable slv( decisionq.elements[i] );
471  if ( !slv || slv.isSystem() )
472  continue;
473 
474  PoolItem poolItem( slv );
476  _result_items_to_install.push_back (poolItem);
477  }
478  queue_free(&decisionq);
479 
480  /* solvables to be erased */
481  Repository systemRepo( sat::Pool::instance().findSystemRepo() ); // don't create if it does not exist
482  if ( systemRepo && ! systemRepo.solvablesEmpty() )
483  {
484  bool mustCheckObsoletes = false;
485  for_( it, systemRepo.solvablesBegin(), systemRepo.solvablesEnd() )
486  {
487  if (solver_get_decisionlevel(_solv, it->id()) > 0)
488  continue;
489 
490  // Check if this is an update
491  CheckIfUpdate info( *it );
492  PoolItem poolItem( *it );
493  invokeOnEach( _pool.byIdentBegin( poolItem ),
494  _pool.byIdentEnd( poolItem ),
495  resfilter::ByUninstalled(), // ByUninstalled
496  functor::functorRef<bool,PoolItem> (info) );
497 
498  if (info.is_updated) {
500  } else {
502  if ( ! mustCheckObsoletes )
503  mustCheckObsoletes = true; // lazy check for UninstalledDueToObsolete
504  }
505  _result_items_to_remove.push_back (poolItem);
506  }
507  if ( mustCheckObsoletes )
508  {
510  for_( it, obsoleted.poolItemBegin(), obsoleted.poolItemEnd() )
511  {
512  ResStatus & status( it->status() );
513  // WhatObsoletes contains installed items only!
514  if ( status.transacts() && ! status.isToBeUninstalledDueToUpgrade() )
516  }
517  }
518  }
519 
520  Queue recommendations;
521  Queue suggestions;
522  Queue orphaned;
523  Queue unneeded;
524  queue_init(&recommendations);
525  queue_init(&suggestions);
526  queue_init(&orphaned);
527  queue_init(&unneeded);
528  solver_get_recommendations(_solv, &recommendations, &suggestions, 0);
529  solver_get_orphaned(_solv, &orphaned);
530  solver_get_unneeded(_solv, &unneeded, 1);
531  /* solvables which are recommended */
532  for ( int i = 0; i < recommendations.count; ++i )
533  {
534  PoolItem poolItem( getPoolItem( recommendations.elements[i] ) );
535  poolItem.status().setRecommended( true );
536  }
537 
538  /* solvables which are suggested */
539  for ( int i = 0; i < suggestions.count; ++i )
540  {
541  PoolItem poolItem( getPoolItem( suggestions.elements[i] ) );
542  poolItem.status().setSuggested( true );
543  }
544 
545  _problem_items.clear();
546  /* solvables which are orphaned */
547  for ( int i = 0; i < orphaned.count; ++i )
548  {
549  PoolItem poolItem( getPoolItem( orphaned.elements[i] ) );
550  poolItem.status().setOrphaned( true );
551  _problem_items.push_back( poolItem );
552  }
553 
554  /* solvables which are unneeded */
555  for ( int i = 0; i < unneeded.count; ++i )
556  {
557  PoolItem poolItem( getPoolItem( unneeded.elements[i] ) );
558  poolItem.status().setUnneeded( true );
559  }
560 
561  queue_free(&recommendations);
562  queue_free(&suggestions);
563  queue_free(&orphaned);
564  queue_free(&unneeded);
565 
566  /* Write validation state back to pool */
567  Queue flags, solvableQueue;
568 
569  queue_init(&flags);
570  queue_init(&solvableQueue);
571 
572  CollectPseudoInstalled collectPseudoInstalled(&solvableQueue);
574  _pool.end(),
575  functor::functorRef<bool,PoolItem> (collectPseudoInstalled) );
576  solver_trivial_installable(_solv, &solvableQueue, &flags );
577  for (int i = 0; i < solvableQueue.count; i++) {
578  PoolItem item = _pool.find (sat::Solvable(solvableQueue.elements[i]));
579  item.status().setUndetermined();
580 
581  if (flags.elements[i] == -1) {
582  item.status().setNonRelevant();
583  _XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
584  } else if (flags.elements[i] == 1) {
585  item.status().setSatisfied();
586  _XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
587  } else if (flags.elements[i] == 0) {
588  item.status().setBroken();
589  _XDEBUG("SATSolutionToPool(" << item << " ) broken !");
590  }
591  }
592  queue_free(&(solvableQueue));
593  queue_free(&flags);
594 
595 
596  // Solvables which were selected due requirements which have been made by the user will
597  // be selected by APPL_LOW. We can't use any higher level, because this setting must
598  // not serve as a request for the next solver run. APPL_LOW is reset before solving.
599  for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
600  sat::WhatProvides rpmProviders(*iter);
601  for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
602  PoolItem poolItem(*iter2);
603  if (poolItem.status().isToBeInstalled()) {
604  MIL << "User requirement " << *iter << " sets " << poolItem << endl;
606  }
607  }
608  }
609  for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
610  sat::WhatProvides rpmProviders(*iter);
611  for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
612  PoolItem poolItem(*iter2);
613  if (poolItem.status().isToBeUninstalled()) {
614  MIL << "User conflict " << *iter << " sets " << poolItem << endl;
616  }
617  }
618  }
619 
620  if (solver_problem_count(_solv) > 0 )
621  {
622  ERR << "Solverrun finished with an ERROR" << endl;
623  return false;
624  }
625 
626  return true;
627 }
628 
629 
630 void
632 {
633  SATCollectTransact info (*this);
634 
635  MIL << "SATResolver::solverInit()" << endl;
636 
637  // remove old stuff
638  solverEnd();
639 
640  queue_init( &_jobQueue );
641  _items_to_install.clear();
642  _items_to_remove.clear();
643  _items_to_lock.clear();
644  _items_to_keep.clear();
645 
647  functor::functorRef<bool,PoolItem>(info) );
648 
649  for (PoolItemList::const_iterator iter = weakItems.begin(); iter != weakItems.end(); iter++) {
650  Id id = (*iter)->satSolvable().id();
651  if (id == ID_NULL) {
652  ERR << "Weaken: " << *iter << " not found" << endl;
653  }
654  MIL << "Weaken dependencies of " << *iter << endl;
655  queue_push( &(_jobQueue), SOLVER_WEAKENDEPS | SOLVER_SOLVABLE );
656  queue_push( &(_jobQueue), id );
657  }
658 
659  // Add rules for parallel installable resolvables with different versions
660  for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() )
661  {
662  queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE_NAME );
663  queue_push( &(_jobQueue), it->id() );
664  }
665 
666  if ( cleandepsOnRemove() )
667  {
668  // Add all items known to be installed by user request (not solver selected).
669  for_( it, sat::Pool::instance().onSystemByUserBegin(), sat::Pool::instance().onSystemByUserEnd() )
670  {
671  queue_push( &(_jobQueue), SOLVER_USERINSTALLED | SOLVER_SOLVABLE_NAME );
672  queue_push( &(_jobQueue), it->id() );
673  }
674  }
675 
676  if ( _distupgrade )
677  {
679  {
680  MIL << "Checking droplists ..." << endl;
681  // Dropped packages: look for 'weakremover()' provides
682  // in dup candidates of installed products.
683  ResPoolProxy proxy( ResPool::instance().proxy() );
684  for_( it, proxy.byKindBegin<Product>(), proxy.byKindEnd<Product>() )
685  {
686  if ( (*it)->onSystem() ) // (to install) or (not to delete)
687  {
688  Product::constPtr prodCand( (*it)->candidateAsKind<Product>() );
689  if ( ! prodCand || (*it)->identicalInstalledCandidate() )
690  continue; // product no longer available or unchanged
691 
692  CapabilitySet droplist( prodCand->droplist() );
693  dumpRangeLine( MIL << "Droplist for " << (*it)->candidateObj() << ": " << droplist.size() << " ", droplist.begin(), droplist.end() ) << endl;
694  for_( cap, droplist.begin(), droplist.end() )
695  {
696  queue_push( &_jobQueue, SOLVER_DROP_ORPHANED | SOLVER_SOLVABLE_NAME );
697  queue_push( &_jobQueue, cap->id() );
698  }
699  }
700  }
701  }
702  else
703  {
704  MIL << "Droplist processing is disabled." << endl;
705  }
706  }
707 }
708 
709 void
711 {
712  // cleanup
713  if ( _solv )
714  {
715  solver_free(_solv);
716  _solv = NULL;
717  queue_free( &(_jobQueue) );
718  }
719 }
720 
721 
722 bool
724  const CapabilitySet & conflict_caps,
725  const PoolItemList & weakItems,
726  const std::set<Repository> & upgradeRepos)
727 {
728  MIL << "SATResolver::resolvePool()" << endl;
729 
730  // initialize
731  solverInit(weakItems);
732 
733  for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
734  Id id = (*iter)->satSolvable().id();
735  if (id == ID_NULL) {
736  ERR << "Install: " << *iter << " not found" << endl;
737  } else {
738  MIL << "Install " << *iter << endl;
739  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
740  queue_push( &(_jobQueue), id );
741  }
742  }
743 
744  for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
745  Id id = (*iter)->satSolvable().id();
746  if (id == ID_NULL) {
747  ERR << "Delete: " << *iter << " not found" << endl;
748  } else {
749  MIL << "Delete " << *iter << endl;
750  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
751  queue_push( &(_jobQueue), id);
752  }
753  }
754 
755  for_( iter, upgradeRepos.begin(), upgradeRepos.end() )
756  {
757  queue_push( &(_jobQueue), SOLVER_DISTUPGRADE | SOLVER_SOLVABLE_REPO );
758  queue_push( &(_jobQueue), iter->get()->repoid );
759  MIL << "Upgrade repo " << *iter << endl;
760  }
761 
762  for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
763  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
764  queue_push( &(_jobQueue), iter->id() );
765  MIL << "Requires " << *iter << endl;
766  }
767 
768  for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
769  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
770  queue_push( &(_jobQueue), iter->id() );
771  MIL << "Conflicts " << *iter << endl;
772  }
773 
774  // set requirements for a running system
776 
777  // set locks for the solver
778  setLocks();
779 
780  // solving
781  bool ret = solving(requires_caps, conflict_caps);
782 
783  (ret?MIL:WAR) << "SATResolver::resolvePool() done. Ret:" << ret << endl;
784  return ret;
785 }
786 
787 
788 bool
790  const PoolItemList & weakItems)
791 {
792  MIL << "SATResolver::resolvQueue()" << endl;
793 
794  // initialize
795  solverInit(weakItems);
796 
797  // generate solver queue
798  for (SolverQueueItemList::const_iterator iter = requestQueue.begin(); iter != requestQueue.end(); iter++) {
799  (*iter)->addRule(_jobQueue);
800  }
801 
802  // Add addition item status to the resolve-queue cause these can be set by problem resolutions
803  for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
804  Id id = (*iter)->satSolvable().id();
805  if (id == ID_NULL) {
806  ERR << "Install: " << *iter << " not found" << endl;
807  } else {
808  MIL << "Install " << *iter << endl;
809  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
810  queue_push( &(_jobQueue), id );
811  }
812  }
813  for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
814  sat::detail::IdType ident( (*iter)->satSolvable().ident().id() );
815  MIL << "Delete " << *iter << ident << endl;
816  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | MAYBE_CLEANDEPS );
817  queue_push( &(_jobQueue), ident);
818  }
819 
820  // set requirements for a running system
822 
823  // set locks for the solver
824  setLocks();
825 
826  // solving
827  bool ret = solving();
828 
829  MIL << "SATResolver::resolveQueue() done. Ret:" << ret << endl;
830  return ret;
831 }
832 
835 {
836  MIL << "SATResolver::doUpdate()" << endl;
837 
838  // initialize
840 
841  // set requirements for a running system
843 
844  // set locks for the solver
845  setLocks();
846 
847  _solv = solver_create( _SATPool );
848  _solv->vendorCheckCb = &vendorCheck;
849  if (_fixsystem) {
850  queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
851  queue_push( &(_jobQueue), 0 );
852  }
853  if (1) {
854  queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL);
855  queue_push( &(_jobQueue), 0 );
856  }
857  if (_distupgrade) {
858  queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL);
859  queue_push( &(_jobQueue), 0 );
860  }
862  queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
863  queue_push( &(_jobQueue), 0 );
864  }
865  solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
866  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
867  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
868  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
869  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
870  solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
871  solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
872  solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
873 
875 
876  // Solve !
877  MIL << "Starting solving for update...." << endl;
878  MIL << *this;
879  solver_solve( _solv, &(_jobQueue) );
880  MIL << "....Solver end" << endl;
881 
882  // copying solution back to zypp pool
883  //-----------------------------------------
884 
885  /* solvables to be installed */
886  Queue decisionq;
887  queue_init(&decisionq);
888  solver_get_decisionqueue(_solv, &decisionq);
889  for (int i = 0; i < decisionq.count; i++)
890  {
891  Id p;
892  p = decisionq.elements[i];
893  if (p < 0 || !sat::Solvable(p))
894  continue;
895  if (sat::Solvable(p).repository().get() == _solv->pool->installed)
896  continue;
897 
898  PoolItem poolItem = _pool.find (sat::Solvable(p));
899  if (poolItem) {
901  } else {
902  ERR << "id " << p << " not found in ZYPP pool." << endl;
903  }
904  }
905  queue_free(&decisionq);
906 
907  /* solvables to be erased */
908  for (int i = _solv->pool->installed->start; i < _solv->pool->installed->start + _solv->pool->installed->nsolvables; i++)
909  {
910  if (solver_get_decisionlevel(_solv, i) > 0)
911  continue;
912 
913  PoolItem poolItem( _pool.find( sat::Solvable(i) ) );
914  if (poolItem) {
915  // Check if this is an update
916  CheckIfUpdate info( (sat::Solvable(i)) );
917  invokeOnEach( _pool.byIdentBegin( poolItem ),
918  _pool.byIdentEnd( poolItem ),
919  resfilter::ByUninstalled(), // ByUninstalled
920  functor::functorRef<bool,PoolItem> (info) );
921 
922  if (info.is_updated) {
924  } else {
926  }
927  } else {
928  ERR << "id " << i << " not found in ZYPP pool." << endl;
929  }
930  }
931  MIL << "SATResolver::doUpdate() done" << endl;
932 }
933 
934 
935 
936 //----------------------------------------------------------------------------
937 //----------------------------------------------------------------------------
938 // error handling
939 //----------------------------------------------------------------------------
940 //----------------------------------------------------------------------------
941 
942 //----------------------------------------------------------------------------
943 // helper function
944 //----------------------------------------------------------------------------
945 
947 {
951  : problemSolution (p)
952  , action (act)
953  {
954  }
955 
957  {
959  return true;
960  }
961 };
962 
963 
964 //----------------------------------------------------------------------------
965 // Checking if this solvable/item has a buddy which reflect the real
966 // user visible description of an item
967 // e.g. The release package has a buddy to the concerning product item.
968 // This user want's the message "Product foo conflicts with product bar" and
969 // NOT "package release-foo conflicts with package release-bar"
970 // (ma: that's why we should map just packages to buddies, not vice versa)
971 //----------------------------------------------------------------------------
972 inline sat::Solvable mapBuddy( const PoolItem & item_r )
973 {
974  if ( item_r.satSolvable().isKind<Package>() )
975  {
976  sat::Solvable buddy = item_r.buddy();
977  if ( buddy )
978  return buddy;
979  }
980  return item_r.satSolvable();
981 }
983 { return mapBuddy( PoolItem( item_r ) ); }
984 
986 { return PoolItem( mapBuddy( item ) ); }
987 
989 { return mapBuddy( sat::Solvable(id) ); }
990 
991 string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreId)
992 {
993  string ret;
994  Pool *pool = _solv->pool;
995  Id probr;
996  Id dep, source, target;
997  sat::Solvable s, s2;
998 
999  ignoreId = 0;
1000  probr = solver_findproblemrule(_solv, problem);
1001  switch (solver_ruleinfo(_solv, probr, &source, &target, &dep))
1002  {
1003  case SOLVER_RULE_DISTUPGRADE:
1004  s = mapSolvable (source);
1005  ret = str::form (_("%s does not belong to a distupgrade repository"), s.asString().c_str());
1006  break;
1007  case SOLVER_RULE_INFARCH:
1008  s = mapSolvable (source);
1009  ret = str::form (_("%s has inferior architecture"), s.asString().c_str());
1010  break;
1011  case SOLVER_RULE_UPDATE:
1012  s = mapSolvable (source);
1013  ret = str::form (_("problem with installed package %s"), s.asString().c_str());
1014  break;
1015  case SOLVER_RULE_JOB:
1016  ret = _("conflicting requests");
1017  break;
1018  case SOLVER_RULE_RPM:
1019  ret = _("some dependency problem");
1020  break;
1021  case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP:
1022  ret = str::form (_("nothing provides requested %s"), pool_dep2str(pool, dep));
1023  detail += _("Have you enabled all requested repositories?");
1024  break;
1025  case SOLVER_RULE_RPM_NOT_INSTALLABLE:
1026  s = mapSolvable (source);
1027  ret = str::form (_("%s is not installable"), s.asString().c_str());
1028  break;
1029  case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP:
1030  ignoreId = source; // for setting weak dependencies
1031  s = mapSolvable (source);
1032  ret = str::form (_("nothing provides %s needed by %s"), pool_dep2str(pool, dep), s.asString().c_str());
1033  break;
1034  case SOLVER_RULE_RPM_SAME_NAME:
1035  s = mapSolvable (source);
1036  s2 = mapSolvable (target);
1037  ret = str::form (_("cannot install both %s and %s"), s.asString().c_str(), s2.asString().c_str());
1038  break;
1039  case SOLVER_RULE_RPM_PACKAGE_CONFLICT:
1040  s = mapSolvable (source);
1041  s2 = mapSolvable (target);
1042  ret = str::form (_("%s conflicts with %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1043  break;
1044  case SOLVER_RULE_RPM_PACKAGE_OBSOLETES:
1045  s = mapSolvable (source);
1046  s2 = mapSolvable (target);
1047  ret = str::form (_("%s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1048  break;
1049  case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES:
1050  s = mapSolvable (source);
1051  s2 = mapSolvable (target);
1052  ret = str::form (_("installed %s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1053  break;
1054  case SOLVER_RULE_RPM_SELF_CONFLICT:
1055  s = mapSolvable (source);
1056  ret = str::form (_("solvable %s conflicts with %s provided by itself"), s.asString().c_str(), pool_dep2str(pool, dep));
1057  break;
1058  case SOLVER_RULE_RPM_PACKAGE_REQUIRES:
1059  ignoreId = source; // for setting weak dependencies
1060  s = mapSolvable (source);
1061  Capability cap(dep);
1062  sat::WhatProvides possibleProviders(cap);
1063 
1064  // check, if a provider will be deleted
1065  typedef list<PoolItem> ProviderList;
1066  ProviderList providerlistInstalled, providerlistUninstalled;
1067  for_( iter1, possibleProviders.begin(), possibleProviders.end() ) {
1068  PoolItem provider1 = ResPool::instance().find( *iter1 );
1069  // find pair of an installed/uninstalled item with the same NVR
1070  bool found = false;
1071  for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
1072  PoolItem provider2 = ResPool::instance().find( *iter2 );
1073  if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
1074  && ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
1075  || (provider2.status().isInstalled() && provider1.status().isUninstalled()) )) {
1076  found = true;
1077  break;
1078  }
1079  }
1080  if (!found) {
1081  if (provider1.status().isInstalled())
1082  providerlistInstalled.push_back(provider1);
1083  else
1084  providerlistUninstalled.push_back(provider1);
1085  }
1086  }
1087 
1088  ret = str::form (_("%s requires %s, but this requirement cannot be provided"), s.asString().c_str(), pool_dep2str(pool, dep));
1089  if (providerlistInstalled.size() > 0) {
1090  detail += _("deleted providers: ");
1091  for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) {
1092  if (iter == providerlistInstalled.begin())
1093  detail += itemToString( *iter );
1094  else
1095  detail += "\n " + itemToString( mapItem(*iter) );
1096  }
1097  }
1098  if (providerlistUninstalled.size() > 0) {
1099  if (detail.size() > 0)
1100  detail += _("\nuninstallable providers: ");
1101  else
1102  detail = _("uninstallable providers: ");
1103  for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
1104  if (iter == providerlistUninstalled.begin())
1105  detail += itemToString( *iter );
1106  else
1107  detail += "\n " + itemToString( mapItem(*iter) );
1108  }
1109  }
1110  break;
1111  }
1112 
1113  return ret;
1114 }
1115 
1118 {
1119  ResolverProblemList resolverProblems;
1120  if (_solv && solver_problem_count(_solv)) {
1121  Pool *pool = _solv->pool;
1122  int pcnt;
1123  Id p, rp, what;
1124  Id problem, solution, element;
1125  sat::Solvable s, sd;
1126 
1128  CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
1129 
1130  MIL << "Encountered problems! Here are the solutions:\n" << endl;
1131  pcnt = 1;
1132  problem = 0;
1133  while ((problem = solver_next_problem(_solv, problem)) != 0) {
1134  MIL << "Problem " << pcnt++ << ":" << endl;
1135  MIL << "====================================" << endl;
1136  string detail;
1137  Id ignoreId;
1138  string whatString = SATprobleminfoString (problem,detail,ignoreId);
1139  MIL << whatString << endl;
1140  MIL << "------------------------------------" << endl;
1141  ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail);
1142 
1143  solution = 0;
1144  while ((solution = solver_next_solution(_solv, problem, solution)) != 0) {
1145  element = 0;
1146  ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
1147  while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) {
1148  if (p == SOLVER_SOLUTION_JOB) {
1149  /* job, rp is index into job queue */
1150  what = _jobQueue.elements[rp];
1151  switch (_jobQueue.elements[rp-1]&(SOLVER_SELECTMASK|SOLVER_JOBMASK))
1152  {
1153  case SOLVER_INSTALL | SOLVER_SOLVABLE: {
1154  s = mapSolvable (what);
1155  PoolItem poolItem = _pool.find (s);
1156  if (poolItem) {
1157  if (pool->installed && s.get()->repo == pool->installed) {
1158  problemSolution->addSingleAction (poolItem, REMOVE);
1159  string description = str::form (_("do not keep %s installed"), s.asString().c_str() );
1160  MIL << description << endl;
1161  problemSolution->addDescription (description);
1162  } else {
1163  problemSolution->addSingleAction (poolItem, KEEP);
1164  string description = str::form (_("do not install %s"), s.asString().c_str());
1165  MIL << description << endl;
1166  problemSolution->addDescription (description);
1167  }
1168  } else {
1169  ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << s.asString() << endl;
1170  }
1171  }
1172  break;
1173  case SOLVER_ERASE | SOLVER_SOLVABLE: {
1174  s = mapSolvable (what);
1175  PoolItem poolItem = _pool.find (s);
1176  if (poolItem) {
1177  if (pool->installed && s.get()->repo == pool->installed) {
1178  problemSolution->addSingleAction (poolItem, KEEP);
1179  string description = str::form (_("keep %s"), s.asString().c_str());
1180  MIL << description << endl;
1181  problemSolution->addDescription (description);
1182  } else {
1183  problemSolution->addSingleAction (poolItem, UNLOCK);
1184  string description = str::form (_("do not forbid installation of %s"), itemToString( poolItem ).c_str());
1185  MIL << description << endl;
1186  problemSolution->addDescription (description);
1187  }
1188  } else {
1189  ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << s.asString() << endl;
1190  }
1191  }
1192  break;
1193  case SOLVER_INSTALL | SOLVER_SOLVABLE_NAME:
1194  {
1195  IdString ident( what );
1196  SolverQueueItemInstall_Ptr install =
1197  new SolverQueueItemInstall(_pool, ident.asString(), false );
1198  problemSolution->addSingleAction (install, REMOVE_SOLVE_QUEUE_ITEM);
1199 
1200  string description = str::form (_("do not install %s"), ident.c_str() );
1201  MIL << description << endl;
1202  problemSolution->addDescription (description);
1203  }
1204  break;
1205  case SOLVER_ERASE | SOLVER_SOLVABLE_NAME:
1206  {
1207  // As we do not know, if this request has come from resolvePool or
1208  // resolveQueue we will have to take care for both cases.
1209  IdString ident( what );
1210  FindPackage info (problemSolution, KEEP);
1211  invokeOnEach( _pool.byIdentBegin( ident ),
1212  _pool.byIdentEnd( ident ),
1213  functor::chain (resfilter::ByInstalled (), // ByInstalled
1214  resfilter::ByTransact ()), // will be deinstalled
1215  functor::functorRef<bool,PoolItem> (info) );
1216 
1217  SolverQueueItemDelete_Ptr del =
1218  new SolverQueueItemDelete(_pool, ident.asString(), false );
1219  problemSolution->addSingleAction (del, REMOVE_SOLVE_QUEUE_ITEM);
1220 
1221  string description = str::form (_("keep %s"), ident.c_str());
1222  MIL << description << endl;
1223  problemSolution->addDescription (description);
1224  }
1225  break;
1226  case SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES:
1227  {
1228  problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_REQUIRE);
1229  string description = "";
1230 
1231  // Checking if this problem solution would break your system
1232  if (system_requires.find(Capability(what)) != system_requires.end()) {
1233  // Show a better warning
1234  resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1235  resolverProblem->setDescription(_("This request will break your system!"));
1236  description = _("ignore the warning of a broken system");
1237  description += string(" (requires:")+pool_dep2str(pool, what)+")";
1238  MIL << description << endl;
1239  problemSolution->addFrontDescription (description);
1240  } else {
1241  description = str::form (_("do not ask to install a solvable providing %s"), pool_dep2str(pool, what));
1242  MIL << description << endl;
1243  problemSolution->addDescription (description);
1244  }
1245  }
1246  break;
1247  case SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES:
1248  {
1249  problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_CONFLICT);
1250  string description = "";
1251 
1252  // Checking if this problem solution would break your system
1253  if (system_conflicts.find(Capability(what)) != system_conflicts.end()) {
1254  // Show a better warning
1255  resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1256  resolverProblem->setDescription(_("This request will break your system!"));
1257  description = _("ignore the warning of a broken system");
1258  description += string(" (conflicts:")+pool_dep2str(pool, what)+")";
1259  MIL << description << endl;
1260  problemSolution->addFrontDescription (description);
1261 
1262  } else {
1263  description = str::form (_("do not ask to delete all solvables providing %s"), pool_dep2str(pool, what));
1264  MIL << description << endl;
1265  problemSolution->addDescription (description);
1266  }
1267  }
1268  break;
1269  case SOLVER_UPDATE | SOLVER_SOLVABLE:
1270  {
1271  s = mapSolvable (what);
1272  PoolItem poolItem = _pool.find (s);
1273  if (poolItem) {
1274  if (pool->installed && s.get()->repo == pool->installed) {
1275  problemSolution->addSingleAction (poolItem, KEEP);
1276  string description = str::form (_("do not install most recent version of %s"), s.asString().c_str());
1277  MIL << description << endl;
1278  problemSolution->addDescription (description);
1279  } else {
1280  ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl;
1281  }
1282  } else {
1283  ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << s.asString() << endl;
1284  }
1285  }
1286  break;
1287  default:
1288  MIL << "- do something different" << endl;
1289  ERR << "No valid solution available" << endl;
1290  break;
1291  }
1292  } else if (p == SOLVER_SOLUTION_INFARCH) {
1293  s = mapSolvable (rp);
1294  PoolItem poolItem = _pool.find (s);
1295  if (pool->installed && s.get()->repo == pool->installed) {
1296  problemSolution->addSingleAction (poolItem, LOCK);
1297  string description = str::form (_("keep %s despite the inferior architecture"), s.asString().c_str());
1298  MIL << description << endl;
1299  problemSolution->addDescription (description);
1300  } else {
1301  problemSolution->addSingleAction (poolItem, INSTALL);
1302  string description = str::form (_("install %s despite the inferior architecture"), s.asString().c_str());
1303  MIL << description << endl;
1304  problemSolution->addDescription (description);
1305  }
1306  } else if (p == SOLVER_SOLUTION_DISTUPGRADE) {
1307  s = mapSolvable (rp);
1308  PoolItem poolItem = _pool.find (s);
1309  if (pool->installed && s.get()->repo == pool->installed) {
1310  problemSolution->addSingleAction (poolItem, LOCK);
1311  string description = str::form (_("keep obsolete %s"), s.asString().c_str());
1312  MIL << description << endl;
1313  problemSolution->addDescription (description);
1314  } else {
1315  problemSolution->addSingleAction (poolItem, INSTALL);
1316  string description = str::form (_("install %s from excluded repository"), s.asString().c_str());
1317  MIL << description << endl;
1318  problemSolution->addDescription (description);
1319  }
1320  } else {
1321  /* policy, replace p with rp */
1322  s = mapSolvable (p);
1323  PoolItem itemFrom = _pool.find (s);
1324  if (rp)
1325  {
1326  int gotone = 0;
1327 
1328  sd = mapSolvable (rp);
1329  PoolItem itemTo = _pool.find (sd);
1330  if (itemFrom && itemTo) {
1331  problemSolution->addSingleAction (itemTo, INSTALL);
1332  int illegal = policy_is_illegal(_solv, s.get(), sd.get(), 0);
1333 
1334  if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
1335  {
1336  string description = str::form (_("downgrade of %s to %s"), s.asString().c_str(), sd.asString().c_str());
1337  MIL << description << endl;
1338  problemSolution->addDescription (description);
1339  gotone = 1;
1340  }
1341  if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0)
1342  {
1343  string description = str::form (_("architecture change of %s to %s"), s.asString().c_str(), sd.asString().c_str());
1344  MIL << description << endl;
1345  problemSolution->addDescription (description);
1346  gotone = 1;
1347  }
1348  if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
1349  {
1350  IdString s_vendor( s.vendor() );
1351  IdString sd_vendor( sd.vendor() );
1352  string description = str::form (_("install %s (with vendor change)\n %s --> %s") ,
1353  sd.asString().c_str(),
1354  ( s_vendor ? s_vendor.c_str() : " (no vendor) " ),
1355  ( sd_vendor ? sd_vendor.c_str() : " (no vendor) " ) );
1356  MIL << description << endl;
1357  problemSolution->addDescription (description);
1358  gotone = 1;
1359  }
1360  if (!gotone) {
1361  string description = str::form (_("replacement of %s with %s"), s.asString().c_str(), sd.asString().c_str());
1362  MIL << description << endl;
1363  problemSolution->addDescription (description);
1364  }
1365  } else {
1366  ERR << s.asString() << " or " << sd.asString() << " not found" << endl;
1367  }
1368  }
1369  else
1370  {
1371  if (itemFrom) {
1372  string description = str::form (_("deinstallation of %s"), s.asString().c_str());
1373  MIL << description << endl;
1374  problemSolution->addDescription (description);
1375  problemSolution->addSingleAction (itemFrom, REMOVE);
1376  }
1377  }
1378  }
1379  }
1380  resolverProblem->addSolution (problemSolution,
1381  problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first.
1382  MIL << "------------------------------------" << endl;
1383  }
1384 
1385  if (ignoreId > 0) {
1386  // There is a possibility to ignore this error by setting weak dependencies
1387  PoolItem item = _pool.find (sat::Solvable(ignoreId));
1388  ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(resolverProblem, item);
1389  resolverProblem->addSolution (problemSolution,
1390  false); // Solutions will be shown at the end
1391  MIL << "ignore some dependencies of " << item << endl;
1392  MIL << "------------------------------------" << endl;
1393  }
1394 
1395  // save problem
1396  resolverProblems.push_back (resolverProblem);
1397  }
1398  }
1399  return resolverProblems;
1400 }
1401 
1402 void
1404 {
1405  for (ProblemSolutionList::const_iterator iter = solutions.begin();
1406  iter != solutions.end(); ++iter) {
1407  ProblemSolution_Ptr solution = *iter;
1408  Resolver dummyResolver(_pool);
1409  if (!solution->apply (dummyResolver))
1410  break;
1411  }
1412 }
1413 
1415 {
1416  for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); ++iter) {
1417  sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
1418  if (iter->status().isInstalled()) {
1419  MIL << "Lock installed item " << *iter << endl;
1420  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
1421  queue_push( &(_jobQueue), ident );
1422  } else {
1423  MIL << "Lock NOT installed item " << *iter << endl;
1424  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
1425  queue_push( &(_jobQueue), ident );
1426  }
1427  }
1428 
1430  // Weak locks: Ignore if an item with this name is already installed.
1431  // If it's not installed try to keep it this way using a weak delete
1433  std::set<IdString> unifiedByName;
1434  for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); ++iter) {
1435  IdString ident( (*iter)->satSolvable().ident() );
1436  if ( unifiedByName.insert( ident ).second )
1437  {
1438  if ( ! ui::Selectable::get( *iter )->hasInstalledObj() )
1439  {
1440  MIL << "Keep NOT installed name " << ident << " (" << *iter << ")" << endl;
1441  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS );
1442  queue_push( &(_jobQueue), ident.id() );
1443  }
1444  }
1445  }
1446 }
1447 
1449 {
1451  CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
1452 
1453  for (CapabilitySet::const_iterator iter = system_requires.begin(); iter != system_requires.end(); ++iter) {
1454  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
1455  queue_push( &(_jobQueue), iter->id() );
1456  MIL << "SYSTEM Requires " << *iter << endl;
1457  }
1458 
1459  for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); ++iter) {
1460  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
1461  queue_push( &(_jobQueue), iter->id() );
1462  MIL << "SYSTEM Conflicts " << *iter << endl;
1463  }
1464 
1465  // Lock the architecture of the running systems rpm
1466  // package on distupgrade.
1467  if ( _distupgrade && ZConfig::instance().systemRoot() == "/" )
1468  {
1470  IdString rpm( "rpm" );
1471  for_( it, pool.byIdentBegin(rpm), pool.byIdentEnd(rpm) )
1472  {
1473  if ( (*it)->isSystem() )
1474  {
1475  Capability archrule( (*it)->arch(), rpm.c_str(), Capability::PARSED );
1476  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_NAME | SOLVER_ESSENTIAL );
1477  queue_push( &(_jobQueue), archrule.id() );
1478 
1479  }
1480  }
1481  }
1482 }
1483 
1484 
1486 };// namespace detail
1489  };// namespace solver
1492 };// namespace zypp
1494