libzypp  15.28.6
TargetImpl.commitFindFileConflicts.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
11 extern "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"
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"
36 
37 #include "zypp/ZYppCallbacks.h"
38 
39 using std::endl;
40 
42 namespace 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  {
166  TargetAbortedException excpt( N_("Installation has been aborted as directed.") );
167  excpt.remember( e );
168  ZYPP_THROW( excpt );
169  }
170  }
171 
172  } // namespace target
174 } // namespace zypp
std::unordered_set< sat::detail::IdType > _visited
Interface to gettext.
#define MIL
Definition: Logger.h:64
int IdType
Generic Id type.
Definition: PoolMember.h:130
ProgressData & _progress
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:321
Result returned from ZYpp::commit.
::_Pool CPool
Wrapped libsolv C data type exposed as backdoor.
Definition: PoolMember.h:86
#define N_(MSG)
Just tag text for translation.
Definition: Gettext.h:18
void commitFindFileConflicts(const ZYppCommitPolicy &policy_r, ZYppCommitResult &result_r)
Commit helper checking for file conflicts after download.
Libsolv queue representing file conflicts.
Definition: FileConflicts.h:30
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:89
int installedResult(Queue &result_r) const
Return all packages that would be installed after the transaction is run.
Definition: Transaction.cc:353
static Pool instance()
Singleton ctor.
Definition: Pool.h:53
Options and policies for ZYpp::commit.
#define WAR
Definition: Logger.h:65
Maintain [min,max] and counter (value) for progress counting.
Definition: ProgressData.h:130
Libsolv Id queue wrapper.
Definition: Queue.h:34
TraitsType::PtrType Ptr
Definition: Package.h:37
const sat::Transaction & transaction() const
The full transaction list.
callback::SendReport< DownloadProgressReport > * report
Definition: MediaCurl.cc:184
AutoDispose< void * > _state
size_type size() const
Definition: Queue.cc:49