libzypp 17.31.0
Transaction.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
11extern "C"
12{
13#include <solv/transaction.h>
14#include <solv/solver.h>
15}
16#include <iostream>
17#include <zypp/base/LogTools.h>
19#include <zypp-core/base/DefaultIntegral>
20#include <zypp/base/NonCopyable.h>
21#include <zypp/base/Hash.h>
22
23#include <zypp/sat/detail/PoolImpl.h>
25#include <zypp/sat/Solvable.h>
26#include <zypp/sat/Queue.h>
27#include <zypp/sat/Map.h>
28#include <zypp/ResPool.h>
29
30using std::endl;
31
33namespace zypp
34{
36 namespace sat
37 {
38
39 constexpr Transaction::LoadFromPoolType Transaction::loadFromPool;
40
50 , private base::NonCopyable
51 {
52 friend std::ostream & operator<<( std::ostream & str, const Impl & obj );
53
54 public:
55 typedef std::unordered_set<detail::IdType> set_type;
56 typedef std::unordered_map<detail::IdType,detail::IdType> map_type;
57
59 {
61 {}
62 PostMortem( const sat::Solvable & solv_r )
63 : _ident( solv_r.ident() )
64 , _edition( solv_r.edition() )
65 , _arch( solv_r.arch() )
66 {}
67
71 };
72 typedef std::unordered_map<detail::IdType,PostMortem> pmmap_type;
73
74 public:
76 : _trans( ::transaction_create( nullptr ) )
77 { memset( _trans, 0, sizeof(*_trans) ); }
78
80 : _watcher( myPool().serial() )
81 , _trans( nullptr )
82 {
83 Queue decisionq;
84 for ( const PoolItem & pi : ResPool::instance() )
85 {
86 if ( ! pi.status().transacts() )
87 continue;
88 decisionq.push( pi.isSystem() ? -pi.id() : pi.id() );
89 }
90 Queue noobsq;
91 for ( const Solvable & solv : myPool().multiversionList() )
92 {
93 noobsq.push( SOLVER_NOOBSOLETES | SOLVER_SOLVABLE );
94 noobsq.push( solv.id() );
95 }
96 Map noobsmap;
97 ::solver_calculate_noobsmap( myPool().getPool(), noobsq, noobsmap );
98 _trans = ::transaction_create_decisionq( myPool().getPool(), decisionq, noobsmap );
99
100 // NOTE: package/product buddies share the same ResStatus
101 // so we also link the buddies stepStages. This assumes
102 // only one buddy is acting during commit (package is installed,
103 // but no extra operation for the product).
104 for_( it, _trans->steps.elements, _trans->steps.elements + _trans->steps.count )
105 {
106 sat::Solvable solv( *it );
107 // buddy list:
108 if ( ! solv.isKind<Package>() )
109 {
110 PoolItem pi( solv );
111 if ( pi.buddy() )
112 {
113 _linkMap[*it] = pi.buddy().id();
114 }
115 }
116 if ( solv.isSystem() )
117 {
118 // to delete list:
119 if ( stepType( solv ) == TRANSACTION_ERASE )
120 {
121 _systemErase.insert( *it );
122 }
123 // post mortem data
124 _pmMap[*it] = solv;
125 }
126 }
127 }
128
130 { ::transaction_free( _trans ); }
131
132 public:
133 bool valid() const
134 { return _watcher.isClean( myPool().serial() ); }
135
136 bool order()
137 {
138 if ( ! valid() )
139 return false;
140 if ( empty() )
141 return true;
142#if 0
143 // This is hwo we could implement out own order method.
144 // As ::transaction already groups by MediaNr, we don't
145 // need it for ORDER_BY_MEDIANR.
146 ::transaction_order( _trans, SOLVER_TRANSACTION_KEEP_ORDERDATA );
147 detail::IdType chosen = 0;
148 Queue choices;
149
150 while ( true )
151 {
152 int ret = transaction_order_add_choices( _trans, chosen, choices );
153 MIL << ret << ": " << chosen << ": " << choices << endl;
154 chosen = choices.pop_front(); // pick one out of choices
155 if ( ! chosen )
156 break;
157 }
158 return true;
159#endif
160 if ( !_ordered )
161 {
162 ::transaction_order( _trans, 0 );
163 _ordered = true;
164 }
165 return true;
166 }
167
168 bool empty() const
169 { return( _trans->steps.count == 0 ); }
170
171 size_t size() const
172 { return _trans->steps.count; }
173
175 { return const_iterator( self_r, _trans->steps.elements ); }
177 { return iterator( self_r, _trans->steps.elements ); }
178
180 { return const_iterator( self_r, _trans->steps.elements + _trans->steps.count ); }
182 { return iterator( self_r, _trans->steps.elements + _trans->steps.count ); }
183
184 const_iterator find(const RW_pointer<Transaction::Impl> & self_r, const sat::Solvable & solv_r ) const
185 { detail::IdType * it( _find( solv_r ) ); return it ? const_iterator( self_r, it ) : end( self_r ); }
187 { detail::IdType * it( _find( solv_r ) ); return it ? iterator( self_r, it ) : end( self_r ); }
188
189 public:
190 int installedResult( Queue & result_r ) const
191 { return ::transaction_installedresult( _trans, result_r ); }
192
194 { return _autoInstalled; }
195
196 void autoInstalled( const StringQueue & queue_r )
197 { _autoInstalled = queue_r; }
198
199 public:
200 StepType stepType( Solvable solv_r ) const
201 {
202 if ( ! solv_r )
203 {
204 // post mortem @System solvable
206 }
207
208 switch( ::transaction_type( _trans, solv_r.id(), SOLVER_TRANSACTION_RPM_ONLY ) )
209 {
210 case SOLVER_TRANSACTION_ERASE: return TRANSACTION_ERASE; break;
211 case SOLVER_TRANSACTION_INSTALL: return TRANSACTION_INSTALL; break;
212 case SOLVER_TRANSACTION_MULTIINSTALL: return TRANSACTION_MULTIINSTALL; break;
213 }
214 return TRANSACTION_IGNORE;
215 }
216
218 { return stepStage( resolve( solv_r ) ); }
219
220 void stepStage( Solvable solv_r, StepStage newval_r )
221 { stepStage( resolve( solv_r ), newval_r ); }
222
223 const PostMortem & pmdata( Solvable solv_r ) const
224 {
225 static PostMortem _none;
226 pmmap_type::const_iterator it( _pmMap.find( solv_r.id() ) );
227 return( it == _pmMap.end() ? _none : it->second );
228 }
229
230 private:
231 detail::IdType resolve( const Solvable & solv_r ) const
232 {
233 map_type::const_iterator res( _linkMap.find( solv_r.id() ) );
234 return( res == _linkMap.end() ? solv_r.id() : res->second );
235 }
236
237 bool isIn( const set_type & set_r, detail::IdType sid_r ) const
238 { return( set_r.find( sid_r ) != set_r.end() ); }
239
241 {
242 if ( isIn( _doneSet, sid_r ) )
243 return STEP_DONE;
244 if ( isIn( _errSet, sid_r ) )
245 return STEP_ERROR;
246 return STEP_TODO;
247 }
248
249 void stepStage( detail::IdType sid_r, StepStage newval_r )
250 {
251 StepStage stage( stepStage( sid_r ) );
252 if ( stage != newval_r )
253 {
254 // reset old stage
255 if ( stage != STEP_TODO )
256 {
257 (stage == STEP_DONE ? _doneSet : _errSet).erase( sid_r );
258 }
259 if ( newval_r != STEP_TODO )
260 {
261 (newval_r == STEP_DONE ? _doneSet : _errSet).insert( sid_r );
262 }
263 }
264 }
265
266 private:
267 detail::IdType * _find( const sat::Solvable & solv_r ) const
268 {
269 if ( solv_r && _trans->steps.elements )
270 {
271 for_( it, _trans->steps.elements, _trans->steps.elements + _trans->steps.count )
272 {
273 if ( *it == detail::IdType(solv_r.id()) )
274 return it;
275 }
276 }
277 return 0;
278 }
279
280 private:
282 mutable ::Transaction * _trans;
284 //
287 map_type _linkMap; // buddy map to adopt buddies StepResult
288 set_type _systemErase; // @System packages to be eased (otherse are TRANSACTION_IGNORE)
289 pmmap_type _pmMap; // Post mortem data of deleted @System solvables
290
291 StringQueue _autoInstalled; // ident strings of all packages that would be auto-installed after the transaction is run.
292
293 public:
295 static shared_ptr<Impl> nullimpl()
296 {
297 static shared_ptr<Impl> _nullimpl( new Impl );
298 return _nullimpl;
299 }
300 };
301
303 inline std::ostream & operator<<( std::ostream & str, const Transaction::Impl & obj )
304 {
305 return str << "Transaction: " << obj.size() << " (" << (obj.valid()?"valid":"INVALID") << ")";
306 }
307
309 //
310 // CLASS NAME : Transaction
311 //
313
315 : _pimpl( Impl::nullimpl() )
316 {}
317
319 : _pimpl( new Impl( loadFromPool ) )
320 {}
321
323 {}
324
326 { return _pimpl->valid(); }
327
329 { return _pimpl->order(); }
330
332 { return _pimpl->empty(); }
333
334 size_t Transaction::size() const
335 { return _pimpl->size(); }
336
338 { return _pimpl->begin( _pimpl ); }
339
341 { return _pimpl->begin( _pimpl ); }
342
344 { return _pimpl->end( _pimpl ); }
345
347 { return _pimpl->end( _pimpl ); }
348
350 { return _pimpl->find( _pimpl, solv_r ); }
351
353 { return _pimpl->find( _pimpl, solv_r ); }
354
355 int Transaction::installedResult( Queue & result_r ) const
356 { return _pimpl->installedResult( result_r ); }
357
359 { return _pimpl->autoInstalled(); }
360
362 { _pimpl->autoInstalled( queue_r ); }
363
364 std::ostream & operator<<( std::ostream & str, const Transaction & obj )
365 { return str << *obj._pimpl; }
366
367 std::ostream & dumpOn( std::ostream & str, const Transaction & obj )
368 {
369 for_( it, obj.begin(), obj.end() )
370 {
371 str << *it << endl;
372 }
373 return str;
374 }
375
376 bool operator==( const Transaction & lhs, const Transaction & rhs )
377 { return lhs._pimpl == rhs._pimpl; }
378
380 //
381 // CLASS NAME : Transaction::Step
382 //
384
386 {}
387
389 { return _pimpl->stepType( _solv ); }
390
392 { return _pimpl->stepStage( _solv ); }
393
395 { _pimpl->stepStage( _solv, val_r ); }
396
398 { return _solv ? _solv.ident() : _pimpl->pmdata(_solv )._ident; }
399
401 { return _solv ? _solv.edition() : _pimpl->pmdata(_solv )._edition; }
402
404 { return _solv ? _solv.arch() : _pimpl->pmdata(_solv )._arch; }
405
406 std::ostream & operator<<( std::ostream & str, const Transaction::Step & obj )
407 {
408 str << obj.stepType() << obj.stepStage() << " ";
409 if ( obj.satSolvable() )
410 str << PoolItem( obj.satSolvable() );
411 else
412 str << '[' << obj.ident() << '-' << obj.edition() << '.' << obj.arch() << ']';
413 return str;
414 }
415
416 std::ostream & operator<<( std::ostream & str, Transaction::StepType obj )
417 {
418 switch ( obj )
419 {
420 #define OUTS(E,S) case Transaction::E: return str << #S; break
421 OUTS( TRANSACTION_IGNORE, [ ] );
422 OUTS( TRANSACTION_ERASE, [-] );
425 #undef OUTS
426 }
427 return str << "[?]";
428 }
429
430 std::ostream & operator<<( std::ostream & str, Transaction::StepStage obj )
431 {
432 switch ( obj )
433 {
434 #define OUTS(E,S) case Transaction::E: return str << #S; break
435 OUTS( STEP_TODO, [__] );
436 OUTS( STEP_DONE, [OK] );
437 OUTS( STEP_ERROR, [**] );
438 #undef OUTS
439 }
440 return str << "[??]";
441 }
443 namespace detail
444 {
446 //
447 // CLASS NAME : Transaction::const_iterator/iterator
448 //
450
451 Transaction_const_iterator::Transaction_const_iterator()
452 : Transaction_const_iterator::iterator_adaptor_( 0 )
453 {}
454
456 : Transaction_const_iterator::iterator_adaptor_( iter_r.base() )
457 , _pimpl( iter_r._pimpl )
458 {}
459
461 : Transaction_iterator::iterator_adaptor_( 0 )
462 {}
463
465 } // namespace detail
468 } // namespace sat
471} // namespace zypp
#define OUTS(E, S)
Architecture.
Definition: Arch.h:37
Edition represents [epoch:]version[-release]
Definition: Edition.h:61
Access to the sat-pools string space.
Definition: IdString.h:43
Package interface.
Definition: Package.h:33
Combining sat::Solvable and ResStatus.
Definition: PoolItem.h:51
sat::Solvable buddy() const
Return the buddy we share our status object with.
Definition: PoolItem.cc:214
static ResPool instance()
Singleton ctor.
Definition: ResPool.cc:37
Simple serial number watcher.
Definition: SerialNumber.h:123
bool isClean(unsigned serial_r) const
Return whether serial_r is still unchanged.
Definition: SerialNumber.h:152
Libsolv (bit)Map wrapper.
Definition: Map.h:34
Libsolv Id queue wrapper.
Definition: Queue.h:35
value_type pop_front()
Pop and return the 1st Id from the queue or 0 if empty.
Definition: Queue.cc:115
void push(value_type val_r)
Push a value to the end off the Queue.
Definition: Queue.cc:103
A Solvable object within the sat Pool.
Definition: Solvable.h:54
IdType id() const
Expert backdoor.
Definition: Solvable.h:428
bool isSystem() const
Return whether this Solvable belongs to the system repo.
Definition: Solvable.cc:373
bool isKind(const ResKind &kind_r) const
Test whether a Solvable is of a certain ResKind.
Definition: Solvable.cc:302
A single step within a Transaction.
Definition: Transaction.h:219
StepType stepType() const
Type of action to perform in this step.
Definition: Transaction.cc:388
StepStage stepStage() const
Step action result.
Definition: Transaction.cc:391
Solvable satSolvable() const
Return the corresponding Solvable.
Definition: Transaction.h:243
Libsolv transaction wrapper.
Definition: Transaction.h:52
const_iterator end() const
Iterator behind the last TransactionStep.
Definition: Transaction.cc:343
RW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: Transaction.h:186
int installedResult(Queue &result_r) const
Return all packages that would be installed after the transaction is run.
Definition: Transaction.cc:355
StringQueue autoInstalled() const
Return the ident strings of all packages that would be auto-installed after the transaction is run.
Definition: Transaction.cc:358
const_iterator begin() const
Iterator to the first TransactionStep.
Definition: Transaction.cc:337
bool valid() const
Whether transaction actually contains data and also fits the current pools content.
Definition: Transaction.cc:325
Transaction()
Default ctor: empty transaction.
Definition: Transaction.cc:314
bool order()
Order transaction steps for commit.
Definition: Transaction.cc:328
friend std::ostream & operator<<(std::ostream &str, const Transaction &obj)
Definition: Transaction.cc:364
static constexpr LoadFromPoolType loadFromPool
Definition: Transaction.h:82
detail::Transaction_const_iterator const_iterator
Definition: Transaction.h:116
const_iterator find(const sat::Solvable &solv_r) const
Return iterator pointing to solv_r or end.
Definition: Transaction.cc:349
StepType
Type of (rpm) action to perform in a Step.
Definition: Transaction.h:63
@ TRANSACTION_MULTIINSTALL
[M] Install(multiversion) item (
Definition: Transaction.h:67
@ TRANSACTION_INSTALL
[+] Install(update) item
Definition: Transaction.h:66
@ TRANSACTION_IGNORE
[ ] Nothing (includes implicit deletes due to obsoletes and non-package actions)
Definition: Transaction.h:64
@ TRANSACTION_ERASE
[-] Delete item
Definition: Transaction.h:65
detail::Transaction_iterator iterator
Definition: Transaction.h:115
size_t size() const
Number of steps in transaction steps.
Definition: Transaction.cc:334
StepStage
Step action result.
Definition: Transaction.h:72
@ STEP_DONE
[OK] success
Definition: Transaction.h:74
@ STEP_TODO
[__] unprocessed
Definition: Transaction.h:73
@ STEP_ERROR
[**] error
Definition: Transaction.h:75
bool empty() const
Whether the transaction contains any steps.
Definition: Transaction.cc:331
String related utilities and Regular expression matching.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
int erase(const Pathname &path)
Erase whatever happens to be located at path (file or directory).
Definition: PathInfo.cc:1073
int IdType
Generic Id type.
Definition: PoolMember.h:104
std::ostream & operator<<(std::ostream &str, const FileConflicts &obj)
std::ostream & dumpOn(std::ostream &str, const LocaleSupport &obj)
bool operator==(const Map &lhs, const Map &rhs)
Definition: Map.cc:125
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
Wrapper for const correct access via Smart pointer types.
Definition: PtrTypes.h:286
PostMortem(const sat::Solvable &solv_r)
Definition: Transaction.cc:62
Transaction implementation.
Definition: Transaction.cc:51
void stepStage(Solvable solv_r, StepStage newval_r)
Definition: Transaction.cc:220
const_iterator find(const RW_pointer< Transaction::Impl > &self_r, const sat::Solvable &solv_r) const
Definition: Transaction.cc:184
void autoInstalled(const StringQueue &queue_r)
Definition: Transaction.cc:196
int installedResult(Queue &result_r) const
Definition: Transaction.cc:190
iterator end(const RW_pointer< Transaction::Impl > &self_r)
Definition: Transaction.cc:181
SerialNumberWatcher _watcher
Definition: Transaction.cc:281
static shared_ptr< Impl > nullimpl()
Offer default Impl.
Definition: Transaction.cc:295
iterator find(const RW_pointer< Transaction::Impl > &self_r, const sat::Solvable &solv_r)
Definition: Transaction.cc:186
detail::IdType resolve(const Solvable &solv_r) const
Definition: Transaction.cc:231
std::unordered_map< detail::IdType, PostMortem > pmmap_type
Definition: Transaction.cc:72
friend std::ostream & operator<<(std::ostream &str, const Impl &obj)
DefaultIntegral< bool, false > _ordered
Definition: Transaction.cc:283
StepStage stepStage(Solvable solv_r) const
Definition: Transaction.cc:217
mutable::Transaction * _trans
Definition: Transaction.cc:282
bool isIn(const set_type &set_r, detail::IdType sid_r) const
Definition: Transaction.cc:237
detail::IdType * _find(const sat::Solvable &solv_r) const
Definition: Transaction.cc:267
std::unordered_map< detail::IdType, detail::IdType > map_type
Definition: Transaction.cc:56
std::unordered_set< detail::IdType > set_type
Definition: Transaction.cc:55
const_iterator end(const RW_pointer< Transaction::Impl > &self_r) const
Definition: Transaction.cc:179
StepType stepType(Solvable solv_r) const
Definition: Transaction.cc:200
const PostMortem & pmdata(Solvable solv_r) const
Definition: Transaction.cc:223
iterator begin(const RW_pointer< Transaction::Impl > &self_r)
Definition: Transaction.cc:176
const_iterator begin(const RW_pointer< Transaction::Impl > &self_r) const
Definition: Transaction.cc:174
StringQueue autoInstalled() const
Definition: Transaction.cc:193
std::ostream & operator<<(std::ostream &str, const Transaction::Impl &obj)
Stream output.
Definition: Transaction.cc:303
StepStage stepStage(detail::IdType sid_r) const
Definition: Transaction.cc:240
Impl(LoadFromPoolType)
Definition: Transaction.cc:79
void stepStage(detail::IdType sid_r, StepStage newval_r)
Definition: Transaction.cc:249
Backlink to the associated PoolImpl.
Definition: PoolMember.h:89
static PoolImpl & myPool()
Definition: PoolImpl.cc:184
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
#define nullptr
Definition: Easy.h:55
#define MIL
Definition: Logger.h:96