libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 #include <set> 00014 00015 #include "zypp/base/LogTools.h" 00016 #include "zypp/base/LogControl.h" 00017 #include "zypp/sat/Solvable.h" 00018 #include "zypp/sat/WhatObsoletes.h" 00019 #include "zypp/pool/GetResolvablesToInsDel.h" 00020 #include "zypp/pool/PoolStats.h" 00021 #include "zypp/solver/detail/InstallOrder.h" 00022 00023 #include "zypp/Resolver.h" 00024 #include "zypp/sat/Transaction.h" 00025 00026 using std::endl; 00027 using zypp::solver::detail::InstallOrder; 00028 00029 #undef ZYPP_BASE_LOGGER_LOGGROUP 00030 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::GetResolvablesToInsDel" 00031 00033 namespace zypp 00034 { 00035 00036 namespace pool 00037 { 00038 00039 /****************************************************************** 00040 ** 00041 ** FUNCTION NAME : strip_obsoleted_to_delete 00042 ** FUNCTION TYPE : void 00043 ** 00044 ** strip packages to_delete which get obsoleted by 00045 ** to_install (i.e. delay deletion in case the 00046 ** obsoleting package likes to save whatever... 00047 */ 00048 00049 static void 00050 strip_obsoleted_to_delete( GetResolvablesToInsDel::PoolItemList & deleteList_r, 00051 const GetResolvablesToInsDel::PoolItemList & instlist_r ) 00052 { 00053 if ( deleteList_r.size() == 0 || instlist_r.size() == 0 ) 00054 return; // ---> nothing to do 00055 00056 // These are all installed packages obsoleted by any package to be installed. 00057 // Actually we expect all of them to appear in the deleteList_r, and we want 00058 // to kick them out. Rpm will delete them when the obsoleter gets installed. 00059 sat::WhatObsoletes obsoleted( instlist_r.begin(), instlist_r.end() ); 00060 for_( it, obsoleted.poolItemBegin(), obsoleted.poolItemEnd() ) 00061 { 00062 DBG << "Ignore appl_delete (should be obsoleted): " << *it << endl; 00063 deleteList_r.remove( *it ); 00064 } 00065 00066 MIL << "Undelayed deletes: " << deleteList_r << endl; 00067 } 00068 00070 // 00071 // METHOD NAME : GetResolvablesToInsDel::GetResolvablesToInsDel 00072 // METHOD TYPE : Ctor 00073 // 00074 GetResolvablesToInsDel::GetResolvablesToInsDel( ResPool pool_r, Order order_r ) 00075 { 00076 zypp::base::LogControl::TmpLineWriter shutUp; 00077 typedef std::set<PoolItem> PoolItemSet; 00078 00079 PoolItemList & dellist_r( _toDelete ); 00080 PoolItemList & instlist_r( _toInstall ); 00081 PoolItemList & srclist_r( _toSrcinstall ); 00082 00083 for ( ResPool::const_iterator it = pool_r.begin(); it != pool_r.end(); ++it ) 00084 { 00085 if (it->status().isToBeInstalled()) 00086 { 00087 if ((*it)->kind() == ResKind::srcpackage) { 00088 srclist_r.push_back( *it ); 00089 } 00090 else 00091 instlist_r.push_back( *it ); 00092 } 00093 else if (it->status().isToBeUninstalled()) 00094 { 00095 if ( it->status().isToBeUninstalledDueToObsolete() ) 00096 { 00097 DBG << "Ignore auto_delete (should be obsoleted): " << *it << endl; 00098 } 00099 else if ( it->status().isToBeUninstalledDueToUpgrade() ) 00100 { 00101 DBG << "Ignore auto_delete (should be upgraded): " << *it << endl; 00102 } 00103 else { 00104 dellist_r.push_back( *it ); 00105 } 00106 } 00107 } 00108 00109 MIL << "ResolvablesToInsDel: delete " << dellist_r.size() 00110 << ", install " << instlist_r.size() 00111 << ", srcinstall " << srclist_r.size() << endl; 00112 00114 // 00115 // strip packages to_delete which get obsoleted by 00116 // to_install (i.e. delay deletion in case the 00117 // obsoleting package likes to save whatever... 00118 // 00120 strip_obsoleted_to_delete( dellist_r, instlist_r ); 00121 00122 if ( dellist_r.size() ) { 00124 // 00125 // sort delete list... 00126 // 00128 PoolItemSet delset( dellist_r.begin(), dellist_r.end() ); // for delete order 00129 PoolItemSet dummy; // dummy, empty, should contain already installed 00130 00131 InstallOrder order( pool_r, delset, dummy ); // sort according top prereq 00132 order.init(); 00133 const PoolItemList dsorted( order.getTopSorted() ); 00134 00135 dellist_r.clear(); 00136 for ( PoolItemList::const_reverse_iterator cit = dsorted.rbegin(); 00137 cit != dsorted.rend(); ++cit ) 00138 { 00139 dellist_r.push_back( *cit ); 00140 } 00141 } 00142 00144 // 00145 // sort installed list... 00146 // 00148 if ( instlist_r.empty() ) 00149 return; 00150 00152 // Compute install order according to packages prereq. 00153 // Try to group packages with respect to the desired install order 00155 // backup list for debug purpose. 00156 // You can as well build the set, clear the list and rebuild it in install order. 00157 PoolItemList instbackup_r; 00158 instbackup_r.swap( instlist_r ); 00159 00160 PoolItemSet insset( instbackup_r.begin(), instbackup_r.end() ); // for install order 00161 PoolItemSet installed; // dummy, empty, should contain already installed 00162 00163 InstallOrder order( pool_r, insset, installed ); 00164 // start recursive depth-first-search 00165 order.init(); 00166 MIL << "order.init() done" << endl; 00167 order.printAdj( XXX, false ); 00169 // build install list in install order 00171 PoolItemList best_list; 00172 sat::detail::RepoIdType best_prio = 0; 00173 unsigned best_medianum = 0; 00174 00175 PoolItemList last_list; 00176 sat::detail::RepoIdType last_prio = 0; 00177 unsigned last_medianum = 0; 00178 00179 PoolItemList other_list; 00180 00181 for ( PoolItemList items = order.computeNextSet(); ! items.empty(); items = order.computeNextSet() ) 00182 { 00183 XXX << "order.computeNextSet: " << items.size() << " resolvables" << endl; 00185 // items contains all objects we could install now. Pick all objects 00186 // from current media, or best media if none for current. Alwayys pick 00187 // objects that do not require media access. 00189 00190 best_list.clear(); 00191 last_list.clear(); 00192 other_list.clear(); 00193 00194 for ( PoolItemList::iterator cit = items.begin(); cit != items.end(); ++cit ) 00195 { 00196 ResObject::constPtr cobj( cit->resolvable() ); 00197 if (!cobj) 00198 continue; 00199 00200 if ( ! cobj->mediaNr() ) { 00201 XXX << "No media access required for " << *cit << endl; 00202 order.setInstalled( *cit ); 00203 other_list.push_back( *cit ); 00204 continue; 00205 } 00206 00207 if ( cobj->satSolvable().repository().id() == last_prio && 00208 cobj->mediaNr() == last_medianum ) { 00209 // prefer packages on current media. 00210 XXX << "Stay with current media " << *cit << endl; 00211 last_list.push_back( *cit ); 00212 continue; 00213 } 00214 00215 if ( last_list.empty() ) { 00216 // check for best media as long as there are no packages for current media. 00217 00218 if ( ! best_list.empty() ) { 00219 00220 if ( order_r == ORDER_BY_MEDIANR ) 00221 { 00222 if ( cobj->mediaNr() < best_medianum ) { 00223 best_list.clear(); // new best 00224 } else if ( cobj->mediaNr() == best_medianum ) { 00225 if ( cobj->satSolvable().repository().id() < best_prio ) { 00226 best_list.clear(); // new best 00227 } else if ( cobj->satSolvable().repository().id() == best_prio ) { 00228 XXX << "Add to best list " << *cit << endl; 00229 best_list.push_back( *cit ); // same as best -> add 00230 continue; 00231 } else { 00232 continue; // worse 00233 } 00234 } else { 00235 continue; // worse 00236 } 00237 } 00238 else // default: ORDER_BY_SOURCE 00239 { 00240 if ( cobj->satSolvable().repository().id() < best_prio ) { 00241 best_list.clear(); // new best 00242 } else if ( cobj->satSolvable().repository().id() == best_prio ) { 00243 if ( cobj->mediaNr() < best_medianum ) { 00244 best_list.clear(); // new best 00245 } else if ( cobj->mediaNr() == best_medianum ) { 00246 XXX << "Add to best list " << *cit << endl; 00247 best_list.push_back( *cit ); // same as best -> add 00248 continue; 00249 } else { 00250 continue; // worse 00251 } 00252 } else { 00253 continue; // worse 00254 } 00255 } 00256 } 00257 00258 if ( best_list.empty() ) 00259 { 00260 XXX << "NEW BEST LIST [S" << cobj->satSolvable().repository().id() << ":" << cobj->mediaNr() 00261 << "] (last [S" << best_prio << ":" << best_medianum << "])" << endl; 00262 best_prio = cobj->satSolvable().repository().id(); 00263 best_medianum = cobj->mediaNr(); 00264 // first package or new best 00265 XXX << "Add to best list " << *cit << endl; 00266 best_list.push_back( *cit ); 00267 continue; 00268 } 00269 } 00270 00271 } // for all objects in current set 00272 00274 // remove objects picked from install order and append them to 00275 // install list. 00277 PoolItemList & take_list( last_list.empty() ? best_list : last_list ); 00278 if ( last_list.empty() ) 00279 { 00280 MIL << "SET NEW media [S" << best_prio << ":" << best_medianum << "]" << endl; 00281 last_prio = best_prio; 00282 last_medianum = best_medianum; 00283 } 00284 else 00285 { 00286 XXX << "SET CONTINUE [S" << best_prio << ":" << best_medianum << "]" << endl; 00287 } 00288 00289 for ( PoolItemList::iterator it = take_list.begin(); it != take_list.end(); ++it ) 00290 { 00291 order.setInstalled( *it ); 00292 XXX << "SET collect " << (*it) << endl; 00293 } 00294 // move everthing from take_list to the end of instlist_r, clean take_list 00295 instlist_r.splice( instlist_r.end(), take_list ); 00296 // same for other_list 00297 instlist_r.splice( instlist_r.end(), other_list ); 00298 00299 } // for all sets computed 00300 00301 00302 MIL << "order done" << endl; 00303 if ( instbackup_r.size() != instlist_r.size() ) 00304 { 00305 ERR << "***************** Lost packages in InstallOrder sort." << endl; 00306 } 00307 00308 } 00309 00310 void GetResolvablesToInsDel::debugDiffTransaction() const 00311 { 00312 SEC << "START debugDiffTransaction" << endl; 00313 sat::Transaction trans( ResPool::instance().resolver().getTransaction() ); 00314 00315 { 00316 const PoolItemList & clist( _toDelete ); 00317 for_( it, clist.begin(), clist.end() ) 00318 { 00319 sat::Transaction::const_iterator ci( trans.find( *it ) ); 00320 if ( ci == trans.end() ) 00321 ERR << "Missing to del in NEW trans: " << *it << endl; 00322 } 00323 } 00324 { 00325 const PoolItemList & clist( _toInstall ); 00326 for_( it, clist.begin(), clist.end() ) 00327 { 00328 sat::Transaction::const_iterator ci( trans.find( *it ) ); 00329 if ( ci == trans.end() ) 00330 ERR << "Missing to ins in NEW trans: " << *it << endl; 00331 } 00332 } 00333 { 00334 const PoolItemList & clist( _toSrcinstall ); 00335 for_( it, clist.begin(), clist.end() ) 00336 { 00337 sat::Transaction::const_iterator ci( trans.find( *it ) ); 00338 if ( ci == trans.end() ) 00339 ERR << "Missing srcins in NEW trans: " << *it << endl; 00340 } 00341 } 00342 00343 SEC << "END debugDiffTransaction" << endl; 00344 } 00345 00346 /****************************************************************** 00347 ** 00348 ** FUNCTION NAME : operator<< 00349 ** FUNCTION TYPE : std::ostream & 00350 */ 00351 std::ostream & operator<<( std::ostream & str, const GetResolvablesToInsDel & obj ) 00352 { 00353 dumpPoolStats( str << "toInstall: " << endl, 00354 obj._toInstall.begin(), obj._toInstall.end() ) << endl; 00355 dumpPoolStats( str << "toDelete: " << endl, 00356 obj._toDelete.begin(), obj._toDelete.end() ) << endl; 00357 return str; 00358 } 00359 00361 } // namespace pool 00364 } // namespace zypp 00366