libzypp: zypp/target/TargetImpl.commitFindFileConflicts.cc Source File

libzypp 17.38.9

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-core/base/LogTools.h>
26#include <zypp-core/base/Gettext.h>
27#include <zypp-core/base/Exception.h>
28#include <zypp-core/base/UserRequestException>
29
30#include <zypp/sat/Queue.h>
31#include <zypp/sat/FileConflicts.h>
32#include <zypp/sat/Pool.h>
33
34#include <zypp/target/TargetImpl.h>
35#include <zypp/target/CommitPackageCache.h>
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
122 void TargetImpl::commitFindFileConflicts( const ZYppCommitPolicy & policy_r, ZYppCommitResult & result_r )
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 {
132 callback::SendReport<FindFileConflictstReport> report;
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 {
166 TargetAbortedException excpt;
167 excpt.remember( e );
168 ZYPP_THROW( excpt );
169 }
170 }
171
172 } // namespace target
174} // namespace zypp
CommitPackageCache.h
Exception.h
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
FileConflicts.h
Gettext.h
LogTools.h
MIL
#define MIL
Definition Logger.h:103
WAR
#define WAR
Definition Logger.h:104
Pool.h
Queue.h
TargetImpl.h
ZYppCallbacks.h
zypp::Exception::remember
void remember(const Exception &old_r)
Store an other Exception as history.
Definition Exception.cc:154
zypp::Package::Ptr
TraitsType::PtrType Ptr
Definition Package.h:38
zypp::ProgressData
Maintain [min,max] and counter (value) for progress counting.
Definition progressdata.h:132
zypp::ProgressData::sendTo
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
Definition progressdata.h:229
zypp::ProgressData::toMax
bool toMax()
Set counter value to current max value (unless no range).
Definition progressdata.h:276
zypp::ProgressData::noSend
void noSend()
Set no ReceiverFnc.
Definition progressdata.h:233
zypp::ZYppCommitPolicy
Options and policies for ZYpp::commit.
Definition ZYppCommitPolicy.h:34
zypp::ZYppCommitResult
Result returned from ZYpp::commit.
Definition ZYppCommitResult.h:64
zypp::ZYppCommitResult::transaction
const sat::Transaction & transaction() const
The full transaction list.
Definition ZYppCommitResult.cc:84
zypp::sat::FileConflicts
Libsolv queue representing file conflicts.
Definition FileConflicts.h:31
zypp::sat::Pool::instance
static Pool instance()
Singleton ctor.
Definition Pool.h:55
zypp::sat::Queue
Libsolv Id queue wrapper.
Definition Queue.h:36
zypp::sat::Queue::size
size_type size() const
Definition Queue.cc:49
zypp::sat::Transaction::installedResult
int installedResult(Queue &result_r) const
Return all packages that would be installed after the transaction is run.
Definition Transaction.cc:357
zypp::target::TargetAbortedException
Definition TargetException.h:52
zypp::target::TargetImpl::commitFindFileConflicts
void commitFindFileConflicts(const ZYppCommitPolicy &policy_r, ZYppCommitResult &result_r)
Commit helper checking for file conflicts after download.
Definition TargetImpl.commitFindFileConflicts.cc:122
std::invoke
std::enable_if< std::is_member_pointer< typenamestd::decay< Functor >::type >::value, typenamestd::result_of< Functor &&(Args &&...)>::type >::type invoke(Functor &&f, Args &&... args)
Definition functional.h:32
zypp::sat::detail::IdType
int IdType
Generic Id type.
Definition PoolDefines.h:42
zypp::sat::detail::CPool
::s_Pool CPool
Wrapped libsolv C data type exposed as backdoor.
Definition PoolDefines.h:34
zypp::target
Definition KeyRing.h:325
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition CodePitfalls.doc:2
zypp::make
ResTraits< TRes >::PtrType make(const sat::Solvable &solvable_r)
Directly create a certain kind of ResObject from sat::Solvable.
Definition ResObject.h:118
zypp::isKind
bool isKind(const Resolvable::constPtr &p)
Test whether a Resolvable::Ptr is of a certain Kind.
Definition Resolvable.h:99
zypp::callback::SendReport
Definition Callback.h:237