libzypp 17.31.23
TargetImpl.commitFindFileConflicts.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
11extern "C"
12{
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>
20}
21#include <iostream>
22#include <unordered_set>
23#include <string>
24
25#include <zypp/base/LogTools.h>
26#include <zypp/base/Gettext.h>
27#include <zypp/base/Exception.h>
28#include <zypp-core/base/UserRequestException>
29
30#include <zypp/sat/Queue.h>
32#include <zypp/sat/Pool.h>
33
36
37#include <zypp/ZYppCallbacks.h>
38
39using std::endl;
40
42namespace zypp
43{
45 namespace target
46 {
48 namespace
49 {
51 struct FileConflictsCB
52 {
53 FileConflictsCB( sat::detail::CPool * pool_r, ProgressData & progress_r )
54 : _progress( progress_r )
55 , _state( ::rpm_state_create( pool_r, ::pool_get_rootdir(pool_r) ), ::rpm_state_free )
56 {}
57
58 void * operator()( sat::detail::CPool * pool_r, sat::detail::IdType id_r )
59 {
60 void * ret = lookup( id_r );
61
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() )
65 {
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 );
70 _progress.incr();
71 }
72 else
73 {
74 _progress.tick();
75 }
76 return ret;
77 }
78
79 const sat::Queue & noFilelist() const
80 { return _noFilelist; }
81
82 static void * invoke( sat::detail::CPool * pool_r, sat::detail::IdType id_r, void * cbdata_r )
83 { return (*reinterpret_cast<FileConflictsCB*>(cbdata_r))( pool_r, id_r ); }
84
85 private:
86 void * lookup( sat::detail::IdType id_r )
87 {
88 sat::Solvable solv( id_r );
89 if ( solv.isSystem() )
90 {
91 Solvable * s = solv.get();
92 if ( ! s->repo->rpmdbid )
93 return nullptr;
94 sat::detail::IdType rpmdbid = s->repo->rpmdbid[id_r - s->repo->start];
95 if ( ! rpmdbid )
96 return nullptr;
97 return ::rpm_byrpmdbid( _state, rpmdbid );
98 }
99 else
100 {
101 Package::Ptr pkg( make<Package>( solv ) );
102 if ( ! pkg )
103 return nullptr;
104 Pathname localfile( pkg->cachedLocation() );
105 if ( localfile.empty() )
106 return nullptr;
107 AutoDispose<FILE*> fp( ::fopen( localfile.c_str(), "re" ), ::fclose );
108 return ::rpm_byfp( _state, fp, localfile.c_str() );
109 }
110 }
111
112 private:
113 ProgressData & _progress;
114 AutoDispose<void*> _state;
115 std::unordered_set<sat::detail::IdType> _visited;
116 sat::Queue _noFilelist;
117 };
118
119 } // namespace
121
123 {
124 sat::Queue todo;
125 sat::FileConflicts conflicts;
126 int newpkgs = result_r.transaction().installedResult( todo );
127 MIL << "Checking for file conflicts in " << newpkgs << " new packages..." << endl;
128 if ( ! newpkgs )
129 return;
130
131 try {
133 ProgressData progress( todo.size() );
134 if ( ! report->start( progress ) )
135 ZYPP_THROW( AbortRequestException() );
136
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 {
142 progress.noSend(); // take care progress DTOR does not trigger a final report (2nd exeption)
143 ZYPP_THROW( AbortRequestException() );
144 }
145 return true;
146 };
147 progress.sendTo( sendProgress );
148
149 unsigned count =
150 ::pool_findfileconflicts( sat::Pool::instance().get(),
151 todo,
152 newpkgs,
153 conflicts,
154 FINDFILECONFLICTS_USE_SOLVABLEFILELIST | FINDFILECONFLICTS_CHECK_DIRALIASING | FINDFILECONFLICTS_USE_ROOTDIR,
155 &FileConflictsCB::invoke,
156 &cb );
157 progress.toMax();
158 progress.noSend();
159
160 (count?WAR:MIL) << "Found " << count << " file conflicts." << endl;
161 if ( ! report->result( progress, cb.noFilelist(), conflicts ) )
162 ZYPP_THROW( AbortRequestException() );
163 }
164 catch ( const AbortRequestException & e )
165 {
167 excpt.remember( e );
168 ZYPP_THROW( excpt );
169 }
170 }
171
172 } // namespace target
174} // namespace zypp
std::unordered_set< sat::detail::IdType > _visited
ProgressData & _progress
AutoDispose< void * > _state
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:105
TraitsType::PtrType Ptr
Definition: Package.h:37
Maintain [min,max] and counter (value) for progress counting.
Definition: progressdata.h:132
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
Definition: progressdata.h:229
bool toMax()
Set counter value to current max value (unless no range).
Definition: progressdata.h:276
void noSend()
Set no ReceiverFnc.
Definition: progressdata.h:233
Options and policies for ZYpp::commit.
Result returned from ZYpp::commit.
const sat::Transaction & transaction() const
The full transaction list.
Libsolv queue representing file conflicts.
Definition: FileConflicts.h:31
static Pool instance()
Singleton ctor.
Definition: Pool.h:55
Libsolv Id queue wrapper.
Definition: Queue.h:35
size_type size() const
Definition: Queue.cc:49
int installedResult(Queue &result_r) const
Return all packages that would be installed after the transaction is run.
Definition: Transaction.cc:355
void commitFindFileConflicts(const ZYppCommitPolicy &policy_r, ZYppCommitResult &result_r)
Commit helper checking for file conflicts after download.
int IdType
Generic Id type.
Definition: PoolMember.h:104
::s_Pool CPool
Wrapped libsolv C data type exposed as backdoor.
Definition: PoolMember.h:61
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428
#define MIL
Definition: Logger.h:96
#define WAR
Definition: Logger.h:97