1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/TargetImpl.commitFindFileConflicts.cc
13 #include <solv/pool.h>
14 #include <solv/repo.h>
15 #include <solv/solvable.h>
16 #include <solv/poolarch.h>
17 #include <solv/repo_solv.h>
18 #include <solv/repo_rpmdb.h>
19 #include <solv/pool_fileconflicts.h>
22 #include <unordered_set>
25 #include "zypp/base/LogTools.h"
26 #include "zypp/base/Gettext.h"
27 #include "zypp/base/Exception.h"
28 #include "zypp/base/UserRequestException.h"
30 #include "zypp/sat/Queue.h"
31 #include "zypp/sat/FileConflicts.h"
32 #include "zypp/sat/Pool.h"
34 #include "zypp/target/TargetImpl.h"
35 #include "zypp/target/CommitPackageCache.h"
37 #include "zypp/ZYppCallbacks.h"
41 ///////////////////////////////////////////////////////////////////
44 ///////////////////////////////////////////////////////////////////
47 ///////////////////////////////////////////////////////////////////
50 /** libsolv::pool_findfileconflicts callback providing package header. */
51 struct FileConflictsCB
53 FileConflictsCB( ::_Pool * pool_r, ProgressData & progress_r )
54 : _progress( progress_r )
55 , _state( ::rpm_state_create( pool_r, ::pool_get_rootdir(pool_r) ), ::rpm_state_free )
58 void * operator()( ::_Pool * pool_r, sat::detail::IdType id_r )
60 void * ret = lookup( id_r );
62 // report progress on 1st visit only, ticks later
63 // (there may be up to 3 visits)
64 if ( _visited.find( id_r ) == _visited.end() )
66 //DBG << "FCCB: " << sat::Solvable( id_r ) << " " << ret << endl;
67 _visited.insert( id_r );
68 if ( ! ret && sat::Solvable( id_r ).isKind<Package>() ) // only packages have filelists
69 _noFilelist.push( id_r );
79 const sat::Queue & noFilelist() const
80 { return _noFilelist; }
82 static void * invoke( ::_Pool * pool_r, sat::detail::IdType id_r, void * cbdata_r )
83 { return (*reinterpret_cast<FileConflictsCB*>(cbdata_r))( pool_r, id_r ); }
86 void * lookup( sat::detail::IdType id_r )
88 sat::Solvable solv( id_r );
89 if ( solv.isSystem() )
91 Solvable * s = solv.get();
92 if ( ! s->repo->rpmdbid )
94 sat::detail::IdType rpmdbid = s->repo->rpmdbid[id_r - s->repo->start];
97 return ::rpm_byrpmdbid( _state, rpmdbid );
101 Package::Ptr pkg( make<Package>( solv ) );
104 Pathname localfile( pkg->cachedLocation() );
105 if ( localfile.empty() )
107 AutoDispose<FILE*> fp( ::fopen( localfile.c_str(), "re" ), ::fclose );
108 return ::rpm_byfp( _state, fp, localfile.c_str() );
113 ProgressData & _progress;
114 AutoDispose<void*> _state;
115 std::unordered_set<sat::detail::IdType> _visited;
116 sat::Queue _noFilelist;
120 ///////////////////////////////////////////////////////////////////
122 void TargetImpl::commitFindFileConflicts( const ZYppCommitPolicy & policy_r, ZYppCommitResult & result_r )
125 sat::FileConflicts conflicts;
126 int newpkgs = result_r.transaction().installedResult( todo );
127 MIL << "Checking for file conflicts in " << newpkgs << " new packages..." << endl;
132 callback::SendReport<FindFileConflictstReport> report;
133 ProgressData progress( todo.size() );
134 if ( ! report->start( progress ) )
135 ZYPP_THROW( AbortRequestException() );
137 FileConflictsCB cb( sat::Pool::instance().get(), progress );
138 // lambda receives progress trigger and translates into report
139 auto sendProgress = [&]( const ProgressData & progress_r )->bool {
140 if ( ! report->progress( progress_r, cb.noFilelist() ) )
141 ZYPP_THROW( AbortRequestException() );
144 progress.sendTo( sendProgress );
147 ::pool_findfileconflicts( sat::Pool::instance().get(),
151 FINDFILECONFLICTS_USE_SOLVABLEFILELIST | FINDFILECONFLICTS_CHECK_DIRALIASING | FINDFILECONFLICTS_USE_ROOTDIR,
152 &FileConflictsCB::invoke,
157 (count?WAR:MIL) << "Found " << count << " file conflicts." << endl;
158 if ( ! report->result( progress, cb.noFilelist(), conflicts ) )
159 ZYPP_THROW( AbortRequestException() );
161 catch ( const AbortRequestException & e )
163 TargetAbortedException excpt( N_("Installation has been aborted as directed.") );
169 } // namespace target
170 ///////////////////////////////////////////////////////////////////
172 ///////////////////////////////////////////////////////////////////