libzypp 17.38.15
PoolImpl.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <algorithm>
13#include <iostream>
14#include <fstream>
15#include <boost/mpl/int.hpp>
16#include <boost/mpl/assert.hpp>
17
18#include <zypp-core/base/Easy.h>
22#include <zypp/base/Measure.h>
23#include <zypp-core/fs/WatchFile>
24#include <zypp-core/parser/Sysconfig>
26
27#include <zypp/ZConfig.h>
28
30extern "C"
31{
32#include <solv/pool_snapshot.h>
33}
37#include <zypp/sat/Pool.h>
38#include <zypp/Capability.h>
39#include <zypp/Locale.h>
40#include <zypp/PoolItem.h>
41
44
45extern "C"
46{
47// Workaround libsolv project not providing a common include
48// directory. (the -devel package does, but the git repo doesn't).
49// #include <solv/repo_helix.h>
50// #include <solv/testcase.h>
51int repo_add_helix( ::Repo *repo, FILE *fp, int flags );
52int testcase_add_testtags(Repo *repo, FILE *fp, int flags);
53}
54
55using std::endl;
56
57#undef ZYPP_BASE_LOGGER_LOGGROUP
58#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::satpool"
59
60// ///////////////////////////////////////////////////////////////////
61namespace zypp
62{
64 namespace env
65 {
67 inline int LIBSOLV_DEBUGMASK()
68 {
69 const char * envp = getenv("LIBSOLV_DEBUGMASK");
70 return envp ? str::strtonum<int>( envp ) : 0;
71 }
72 } // namespace env
74 namespace sat
75 {
76
78 namespace detail
79 {
80
81 // MPL checks for satlib constants we redefine to avoid
82 // includes and defines.
83 BOOST_MPL_ASSERT_RELATION( noId, ==, STRID_NULL );
84 BOOST_MPL_ASSERT_RELATION( emptyId, ==, STRID_EMPTY );
85
86 BOOST_MPL_ASSERT_RELATION( noSolvableId, ==, ID_NULL );
87 BOOST_MPL_ASSERT_RELATION( systemSolvableId, ==, SYSTEMSOLVABLE );
88
89 BOOST_MPL_ASSERT_RELATION( solvablePrereqMarker, ==, SOLVABLE_PREREQMARKER );
90 BOOST_MPL_ASSERT_RELATION( solvableFileMarker, ==, SOLVABLE_FILEMARKER );
91
101
102 BOOST_MPL_ASSERT_RELATION( namespaceModalias, ==, NAMESPACE_MODALIAS );
103 BOOST_MPL_ASSERT_RELATION( namespaceLanguage, ==, NAMESPACE_LANGUAGE );
104 BOOST_MPL_ASSERT_RELATION( namespaceFilesystem, ==, NAMESPACE_FILESYSTEM );
105
107
108 const std::string & PoolImpl::systemRepoAlias()
109 {
110 static const std::string _val( "@System" );
111 return _val;
112 }
113
115 {
116 static const Pathname _val( "/etc/sysconfig/storage" );
117 return _val;
118 }
119
121
122 static void logSat( CPool *, void *data, int type, const char *logString )
123 {
124 // "1234567890123456789012345678901234567890
125 if ( 0 == strncmp( logString, "job: drop orphaned", 18 ) )
126 return;
127 if ( 0 == strncmp( logString, "job: user installed", 19 ) )
128 return;
129 if ( 0 == strncmp( logString, "job: multiversion", 17 ) )
130 return;
131 if ( 0 == strncmp( logString, " - no rule created", 19 ) )
132 return;
133 if ( 0 == strncmp( logString, " next rules: 0 0", 19 ) )
134 return;
135
136 if ( type & (SOLV_FATAL|SOLV_ERROR) ) {
137 L_ERR("libsolv") << logString;
138 } else if ( type & SOLV_DEBUG_STATS ) {
139 L_DBG("libsolv") << logString;
140 } else {
141 L_MIL("libsolv") << logString;
142 }
143 }
144
146 {
147 // lhs: the namespace identifier, e.g. NAMESPACE:MODALIAS
148 // rhs: the value, e.g. pci:v0000104Cd0000840[01]sv*sd*bc*sc*i*
149 // return: 0 if not supportded
150 // 1 if supported by the system
151 // -1 AFAIK it's also possible to return a list of solvables that support it, but don't know how.
152
153 static const detail::IdType RET_unsupported = 0;
154 static const detail::IdType RET_systemProperty = 1;
155 switch ( lhs )
156 {
157 case NAMESPACE_LANGUAGE:
158 {
159 const TrackedLocaleIds & localeIds( reinterpret_cast<PoolImpl*>(data)->trackedLocaleIds() );
160 return localeIds.contains( IdString(rhs) ) ? RET_systemProperty : RET_unsupported;
161 }
162 break;
163
164 case NAMESPACE_MODALIAS:
165 {
166 // modalias strings in capability may be hexencoded because rpm does not allow
167 // ',', ' ' or other special chars.
168 return target::Modalias::instance().query( str::hexdecode( IdString(rhs).c_str() ) )
169 ? RET_systemProperty
170 : RET_unsupported;
171 }
172 break;
173
174 case NAMESPACE_FILESYSTEM:
175 {
176 const std::set<std::string> & requiredFilesystems( reinterpret_cast<PoolImpl*>(data)->requiredFilesystems() );
177 return requiredFilesystems.find( IdString(rhs).asString() ) != requiredFilesystems.end() ? RET_systemProperty : RET_unsupported;
178 }
179 break;
180
181 }
182
183 WAR << "Unhandled " << Capability( lhs ) << " vs. " << Capability( rhs ) << endl;
184 return RET_unsupported;
185 }
186
188 //
189 // METHOD NAME : PoolImpl::PoolImpl
190 // METHOD TYPE : Ctor
191 //
193 : _pool( zyppng::sat::StringPool::instance().getPool() )
194 {
195 // libzypp#726: ::pool_setdisttype(_pool, DISTTYPE_RPM )
196 // is already set by the StringPool::instance because the
197 // disttype affects the version string comparison.
198
199 // initialialize logging
201 {
202 ::pool_setdebugmask(_pool, env::LIBSOLV_DEBUGMASK() );
203 }
204 else
205 {
206 if ( getenv("ZYPP_LIBSOLV_FULLLOG") || getenv("ZYPP_LIBSAT_FULLLOG") )
207 ::pool_setdebuglevel( _pool, 3 );
208 else if ( getenv("ZYPP_FULLLOG") )
209 ::pool_setdebuglevel( _pool, 2 );
210 else
211 ::pool_setdebugmask(_pool, SOLV_DEBUG_JOB|SOLV_DEBUG_STATS );
212 }
213
214 ::pool_setdebugcallback( _pool, logSat, NULL );
215
216 // We keep interning ids after the pool is built (locales, queries,
217 // PoolItems), and pool_createwhatprovides would drop the hashes just
218 // before that, making the next lookup rebuild them for every string.
219 // The price is that the hashes stay allocated for the lifetime of the
220 // pool (a few MB on a Factory sized pool), which a long running
221 // consumer pays without ever interning anything again.
222 ::pool_set_flag( _pool, POOL_FLAG_KEEPIDHASHES, 1 );
223
224 // set namespace callback
225 _pool->nscallback = &nsCallback;
226 _pool->nscallbackdata = (void*)this;
227
228 // CAVEAT: We'd like to do it here, but in side the Pool ctor we can not
229 // yet use IdString types. We do in setDirty, when the 1st
230 // _retractedSpec.addProvides( Capability( Solvable::retractedToken.id() ) );
231 // _ptfMasterSpec.addProvides( Capability( Solvable::ptfMasterToken.id() ) );
232 // _ptfPackageSpec.addProvides( Capability( Solvable::ptfPackageToken.id() ) );
233 _retractedSpec.addIdenticalInstalledToo( true ); // retracted indicator is not part of the package!
234 }
235
237 //
238 // METHOD NAME : PoolImpl::~PoolImpl
239 // METHOD TYPE : Dtor
240 //
242 {
243 }
244
246
247 void PoolImpl::setDirty( const char * a1, const char * a2, const char * a3 )
248 {
249 if ( _retractedSpec.empty() ) {
250 // lazy init IdString types we can not use inside the ctor
254 }
255
256 if ( a1 )
257 {
258 if ( a3 ) MIL << a1 << " " << a2 << " " << a3 << endl;
259 else if ( a2 ) MIL << a1 << " " << a2 << endl;
260 else MIL << a1 << endl;
261 }
262 _serial.setDirty(); // pool content change
263 _availableLocalesPtr.reset(); // available locales may change
264 _multiversionListPtr.reset(); // re-evaluate ZConfig::multiversionSpec.
265 _needrebootSpec.setDirty(); // re-evaluate needrebootSpec
266
267 _retractedSpec.setDirty(); // re-evaluate blacklisted spec
268 _ptfMasterSpec.setDirty(); // --"--
269 _ptfPackageSpec.setDirty(); // --"--
270
271 depSetDirty(); // invaldate dependency/namespace related indices
272 }
273
274 void PoolImpl::localeSetDirty( const char * a1, const char * a2, const char * a3 )
275 {
276 if ( a1 )
277 {
278 if ( a3 ) MIL << a1 << " " << a2 << " " << a3 << endl;
279 else if ( a2 ) MIL << a1 << " " << a2 << endl;
280 else MIL << a1 << endl;
281 }
282 _trackedLocaleIdsPtr.reset(); // requested locales changed
283 depSetDirty(); // invaldate dependency/namespace related indices
284 }
285
286 void PoolImpl::depSetDirty( const char * a1, const char * a2, const char * a3 )
287 {
288 if ( a1 )
289 {
290 if ( a3 ) MIL << a1 << " " << a2 << " " << a3 << endl;
291 else if ( a2 ) MIL << a1 << " " << a2 << endl;
292 else MIL << a1 << endl;
293 }
294 ::pool_freewhatprovides( _pool );
295 }
296
297 bool PoolImpl::mapSnapshot( const Pathname & path_r, const std::string & cookie_r )
298 {
299 AutoFILE fp { ::fopen( path_r.c_str(), "re" ) };
300 if ( !fp )
301 return false;
302 unsigned char buf[4096];
303 unsigned int len = sizeof(buf);
304 if ( ::pool_snapshot_read_cookie( fp, buf, &len ) != 0
305 || cookie_r != std::string( reinterpret_cast<char*>(buf), len ) )
306 {
307 MIL << "Pool snapshot " << path_r << " is stale" << endl;
308 return false;
309 }
310 // Invalidate before mapping: afterwards it would free the
311 // whatprovides index restored from the snapshot.
312 setDirty( "mapSnapshot", path_r.c_str() );
313 // The stored whatprovides index only lists the providers the
314 // writer's arch policy accepted, so libsolv checks ours against
315 // it and recomputes the index if it differs. prepare() installs
316 // the policy far too late for that, and all the arch names are
317 // in fixedPoolIds already, so interning them here adds no ids.
318 ::pool_setarch( _pool, ZConfig::instance().systemArchitecture().asString().c_str() );
319 int res = ::pool_snapshot_map( _pool, fp );
320 if ( res == -2 )
321 {
322 // Nothing wrong with the file, it just cannot be used here:
323 // the pool is no longer empty (something was loaded before
324 // the first RepoManager::loadFromCache), or another client's
325 // pre-load interned ids differ from ours. Fall back, but do
326 // not rewrite it - we would only do so again on every run.
327 MIL << "Pool snapshot " << path_r << " not usable by this run, not replacing it" << endl;
328 _snapshotCookie.clear();
329 return false;
330 }
331 if ( res != 0 )
332 {
333 WAR << "Pool snapshot " << path_r << " failed to map" << endl;
334 return false;
335 }
336 MIL << "Mapped pool snapshot " << path_r << endl;
337 _snapshotFileProvides = true; // ...and they cover the mapped content
338 {
339 // wire up the system repo like _createRepo would; a no-op
340 // where the snapshot already restored pool->installed
341 CPool * pool = _pool;
342 ::Repo * repo;
343 int i;
344 FOR_REPOS( i, repo )
345 if ( repo->name && systemRepoAlias() == repo->name )
346 {
347 ::pool_set_installed( _pool, repo );
348 // autoprovide the dummy RepoInfo Pool::reposInsert would
349 // have attached when creating the system repo; assigned
350 // directly as setRepoInfo's priority sync might setDirty,
351 // freeing the whatprovides index just restored
353 info.setAlias( systemRepoAlias() );
354 info.setName( systemRepoAlias() );
355 info.setAutorefresh( true );
356 info.setEnabled( true );
358 }
359 // The application claims the repos it wants via setRepoInfo;
360 // whatever stays unclaimed is erased in prepare(). Otherwise
361 // e.g. 'zypper --repo foo' would silently operate on the
362 // whole snapshot instead of just foo.
363 _snapshotUnclaimed.clear();
364 FOR_REPOS( i, repo )
365 if ( repo != pool->installed )
366 _snapshotUnclaimed.insert( repo );
367 }
368 return true;
369 }
370
372 {
373 if ( _snapshotCookie.empty() || Pool::snapshotMapped() )
374 return;
375 // the pool must contain exactly the repo set the cookie was
376 // computed for, e.g. no temporary cli repos
377 std::vector<std::string> aliases;
378 CPool * pool = _pool;
379 ::Repo * repo;
380 int i;
381 FOR_REPOS( i, repo )
382 aliases.push_back( repo->name ? repo->name : "" );
383 std::sort( aliases.begin(), aliases.end() );
384 if ( aliases != _snapshotAliases )
385 {
386 MIL << "Not writing pool snapshot: pool does not match the known repos" << endl;
387 _snapshotCookie.clear();
388 return;
389 }
390 // no staleness check: reaching this point means the snapshot
391 // was not mapped although the repo set qualifies, e.g. it is
392 // missing, stale, or a referenced solv file changed
393 if ( ! Pool::instance().writeSnapshot( _snapshotPath, _snapshotCookie ) )
394 WAR << "Could not write pool snapshot " << _snapshotPath << endl;
395 _snapshotCookie.clear(); // once per process
396 }
397
398 void PoolImpl::prepare() const
399 {
400 if ( ! _snapshotUnclaimed.empty() && ! _snapshotClaiming )
401 {
402 // Snapshot repos the application never claimed in this run
403 // (e.g. zypper --repo limits the repo set): erase them so the
404 // pool matches what was actually requested.
405 //
406 // Only outside a repo load: prepare() is reached from
407 // pool::PoolImpl::checkSerial(), i.e. from virtually every
408 // ResPool access, and a progress callback querying the pool
409 // while repos are still being claimed would erase the ones
410 // that come later. Erasing early stays correct - the repo is
411 // then simply loaded from its solv file again - but it throws
412 // away the restored whatprovides index, which is the whole
413 // point of the snapshot.
414 std::set<RepoIdType> unclaimed;
415 unclaimed.swap( _snapshotUnclaimed );
416 for ( CRepo * repo : unclaimed )
417 {
418 MIL << "Erase unclaimed snapshot repo " << ( repo->name ? repo->name : "" ) << endl;
419 const_cast<PoolImpl*>(this)->_deleteRepo( repo );
420 }
421 }
422 // additional /etc/sysconfig/storage check:
423 static WatchFile sysconfigFile( sysconfigStoragePath(), WatchFile::NO_INIT );
424 if ( sysconfigFile.hasChanged() )
425 {
426 _requiredFilesystemsPtr.reset(); // recreated on demand
427 const_cast<PoolImpl*>(this)->depSetDirty( "/etc/sysconfig/storage change" );
428 }
429 if ( _watcher.remember( _serial ) )
430 {
431 // After repo/solvable add/remove:
432 // set pool architecture
433 ::pool_setarch( _pool, ZConfig::instance().systemArchitecture().asString().c_str() );
434 }
435 if ( ! _pool->whatprovides )
436 {
437 MIL << "pool_createwhatprovides..." << endl;
438
439 // Unifying the whatprovides data sorts every id that has
440 // providers, which costs more than the few MB of data it
441 // saves. Only a run which goes on to store the index in a
442 // snapshot gets that back: it pays the sort once, and a run
443 // which maps the file then copies an eightfold smaller index.
444 //
445 // That last part only pays off while the index survives the
446 // map. On an installed system it usually does not: reading
447 // /var/lib/zypp/RequestedLocales marks the dependencies dirty,
448 // which frees the restored index and has it recomputed here.
449 // The mapping itself is still by far the larger win.
450 // This has to be decided here, not at pool construction: only
451 // now is it known whether a snapshot will be written.
452 // ...which is exactly when snapshotWriteIfNeeded() below writes
453 // one: a run which mapped a snapshot keeps its cookie, but will
454 // not write, so it must not pay the sort either.
455 const bool willWriteSnapshot = ( ! _snapshotCookie.empty() && ! Pool::snapshotMapped() );
456 ::pool_set_flag( _pool, POOL_FLAG_NOWHATPROVIDESSHRINK, willWriteSnapshot ? 0 : 1 );
457
458 // A mapped snapshot already contains the file provides, but only
459 // for the content it restored. Anything added afterwards (a
460 // commandline repo, a repo the snapshot did not have) brings
461 // file dependencies libsolv has not seen, and it would not just
462 // miss them: grow_whatprovides() marks an unknown file id as
463 // 'no providers, do not look further' once addedfileprovides is
464 // set. So this may only be skipped while the pool still holds
465 // exactly what the snapshot restored.
466 if ( ! _snapshotFileProvides )
467 ::pool_addfileprovides( _pool );
468 ::pool_createwhatprovides( _pool );
470 }
471 if ( ! _pool->languages )
472 {
473 // initial seting
474 const_cast<PoolImpl*>(this)->setTextLocale( ZConfig::instance().textLocale() );
475 }
476 }
477
479
480 CRepo * PoolImpl::_createRepo( const std::string & name_r )
481 {
482 setDirty(__FUNCTION__, name_r.c_str() );
483 CRepo * ret = ::repo_create( _pool, name_r.c_str() );
484 if ( ret && name_r == systemRepoAlias() )
485 ::pool_set_installed( _pool, ret );
486 return ret;
487 }
488
490 {
491 setDirty(__FUNCTION__, repo_r->name );
492 _snapshotUnclaimed.erase( repo_r ); // pointer must not dangle
493 if ( isSystemRepo( repo_r ) )
495 eraseRepoInfo( repo_r );
496 ::repo_free( repo_r, /*resusePoolIDs*/false );
497 // If the last repo is removed clear the pool to actually reuse all IDs.
498 // NOTE: the explicit ::repo_free above asserts all solvables are memset(0)!
499 if ( !_pool->urepos )
500 {
501 _serialIDs.setDirty(); // Indicate resusePoolIDs - ResPool must also invalidate its PoolItems
502 ::pool_freeallrepos( _pool, /*resusePoolIDs*/true );
503 }
504 }
505
506 int PoolImpl::_addSolv( CRepo * repo_r, FILE * file_r )
507 {
508 setDirty(__FUNCTION__, repo_r->name );
509 int ret = ::repo_add_solv( repo_r, file_r, 0 );
510 if ( ret == 0 )
511 _postRepoAdd( repo_r );
512 return ret;
513 }
514
515 int PoolImpl::_addHelix( CRepo * repo_r, FILE * file_r )
516 {
517 setDirty(__FUNCTION__, repo_r->name );
518 int ret = ::repo_add_helix( repo_r, file_r, 0 );
519 if ( ret == 0 )
520 _postRepoAdd( repo_r );
521 return 0;
522 }
523
524 int PoolImpl::_addTesttags(CRepo *repo_r, FILE *file_r)
525 {
526 setDirty(__FUNCTION__, repo_r->name );
527 int ret = ::testcase_add_testtags( repo_r, file_r, 0 );
528 if ( ret == 0 )
529 _postRepoAdd( repo_r );
530 return 0;
531 }
532
534 {
535 _snapshotFileProvides = false; // new content, new file dependencies
536
537 if ( ! isSystemRepo( repo_r ) )
538 {
539 // Filter out unwanted archs
540 std::set<detail::IdType> sysids;
541 {
542 Arch::CompatSet sysarchs( Arch::compatSet( ZConfig::instance().systemArchitecture() ) );
543 for_( it, sysarchs.begin(), sysarchs.end() )
544 sysids.insert( it->id() );
545
546 // unfortunately libsolv treats src/nosrc as architecture:
547 sysids.insert( ARCH_SRC );
548 sysids.insert( ARCH_NOSRC );
549 }
550
551 detail::IdType blockBegin = 0;
552 unsigned blockSize = 0;
553 for ( detail::IdType i = repo_r->start; i < repo_r->end; ++i )
554 {
555 CSolvable * s( _pool->solvables + i );
556 if ( s->repo == repo_r && sysids.find( s->arch ) == sysids.end() )
557 {
558 // Remember an unwanted arch entry:
559 if ( ! blockBegin )
560 blockBegin = i;
561 ++blockSize;
562 }
563 else if ( blockSize )
564 {
565 // Free remembered entries
566 ::repo_free_solvable_block( repo_r, blockBegin, blockSize, /*resusePoolIDs*/false );
567 blockBegin = blockSize = 0;
568 }
569 }
570 if ( blockSize )
571 {
572 // Free remembered entries
573 ::repo_free_solvable_block( repo_r, blockBegin, blockSize, /*resusePoolIDs*/false );
574 blockBegin = blockSize = 0;
575 }
576 }
577 }
578
580 {
581 setDirty(__FUNCTION__, repo_r->name );
582 _snapshotFileProvides = false; // new content, new file dependencies
583 return ::repo_add_solvable_block( repo_r, count_r );
584 }
585
586 void PoolImpl::setRepoInfo( RepoIdType id_r, const RepoInfo & info_r )
587 {
588 _snapshotUnclaimed.erase( id_r ); // this run wants the repo
589 CRepo * repo( getRepo( id_r ) );
590 if ( repo )
591 {
592 bool dirty = false;
593
594 // libsolv priority is based on '<', while yum's repoinfo
595 // uses 1(highest)->99(lowest). Thus we use -info_r.priority.
596 if ( repo->priority != int(-info_r.priority()) )
597 {
598 repo->priority = -info_r.priority();
599 dirty = true;
600 }
601
602 // subpriority is used to e.g. prefer http over dvd iff
603 // both have same priority.
604 int mediaPriority( media::MediaPriority( info_r.url() ) );
605 if ( repo->subpriority != mediaPriority )
606 {
607 repo->subpriority = mediaPriority;
608 dirty = true;
609 }
610
611 if ( dirty )
612 setDirty(__FUNCTION__, info_r.alias().c_str() );
613 }
614 _repoinfos[id_r] = info_r;
615 }
616
618
619 void PoolImpl::setTextLocale( const Locale & locale_r )
620 {
621 if ( ! locale_r )
622 {
623 // We need one, so "en" is the last resort
624 const char *needone[] { "en" };
625 ::pool_set_languages( _pool, needone, 1 );
626 return;
627 }
628
629 std::vector<std::string> fallbacklist;
630 for ( Locale l( locale_r ); l; l = l.fallback() )
631 {
632 fallbacklist.push_back( l.code() );
633 }
634 dumpRangeLine( MIL << "pool_set_languages: ", fallbacklist.begin(), fallbacklist.end() ) << endl;
635
636 std::vector<const char *> fallbacklist_cstr;
637 for_( it, fallbacklist.begin(), fallbacklist.end() )
638 {
639 fallbacklist_cstr.push_back( it->c_str() );
640 }
641 ::pool_set_languages( _pool, &fallbacklist_cstr.front(), fallbacklist_cstr.size() );
642 }
643
645 {
646 if ( _requestedLocalesTracker.setInitial( locales_r ) )
647 {
648 localeSetDirty( "initRequestedLocales" );
649 MIL << "Init RequestedLocales: " << _requestedLocalesTracker << " =" << locales_r << endl;
650 }
651 }
652
653 void PoolImpl::setRequestedLocales( const LocaleSet & locales_r )
654 {
655 if ( _requestedLocalesTracker.set( locales_r ) )
656 {
657 localeSetDirty( "setRequestedLocales" );
658 MIL << "New RequestedLocales: " << _requestedLocalesTracker << " =" << locales_r << endl;
659 }
660 }
661
662 bool PoolImpl::addRequestedLocale( const Locale & locale_r )
663 {
664 bool done = _requestedLocalesTracker.add( locale_r );
665 if ( done )
666 {
667 localeSetDirty( "addRequestedLocale", locale_r.code().c_str() );
668 MIL << "New RequestedLocales: " << _requestedLocalesTracker << " +" << locale_r << endl;
669 }
670 return done;
671 }
672
673 bool PoolImpl::eraseRequestedLocale( const Locale & locale_r )
674 {
675 bool done = _requestedLocalesTracker.remove( locale_r );
676 if ( done )
677 {
678 localeSetDirty( "eraseRequestedLocale", locale_r.code().c_str() );
679 MIL << "New RequestedLocales: " << _requestedLocalesTracker << " -" << locale_r << endl;
680 }
681 return done;
682 }
683
684
686 {
687 if ( ! _trackedLocaleIdsPtr )
688 {
690
693
694 // Add current locales+fallback except for added ones
695 for ( Locale lang: localesTracker.current() )
696 {
697 if ( localesTracker.wasAdded( lang ) )
698 continue;
699 for ( ; lang; lang = lang.fallback() )
700 { localeIds.current().insert( IdString(lang) ); }
701 }
702
703 // Add added locales+fallback except they are already in current
704 for ( Locale lang: localesTracker.added() )
705 {
706 for ( ; lang && localeIds.current().insert( IdString(lang) ).second; lang = lang.fallback() )
707 { localeIds.added().insert( IdString(lang) ); }
708 }
709
710 // Add removed locales+fallback except they are still in current
711 for ( Locale lang: localesTracker.removed() )
712 {
713 for ( ; lang && ! localeIds.current().count( IdString(lang) ); lang = lang.fallback() )
714 { localeIds.removed().insert( IdString(lang) ); }
715 }
716
717 // bsc#1155678: We try to differ between an empty RequestedLocales
718 // and one containing 'en' (explicit or as fallback). An empty RequestedLocales
719 // should not even drag in recommended 'en' packages. So we no longer enforce
720 // 'en' being in the set.
721 }
722 return *_trackedLocaleIdsPtr;
723 }
724
725
726 static void _getLocaleDeps( const Capability & cap_r, LocaleSet & store_r )
727 {
728 // Collect locales from any 'namespace:language(lang)' dependency
729 CapDetail detail( cap_r );
730 if ( detail.kind() == CapDetail::EXPRESSION )
731 {
732 switch ( detail.capRel() )
733 {
736 // expand
737 _getLocaleDeps( detail.lhs(), store_r );
738 _getLocaleDeps( detail.rhs(), store_r );
739 break;
740
742 if ( detail.lhs().id() == NAMESPACE_LANGUAGE )
743 {
744 store_r.insert( Locale( IdString(detail.rhs().id()) ) );
745 }
746 break;
747
748 default:
749 break; // unwanted
750 }
751 }
752 }
753
755 {
757 {
758 _availableLocalesPtr.reset( new LocaleSet );
759 LocaleSet & localeSet( *_availableLocalesPtr );
760
761 for ( const Solvable & pi : Pool::instance().solvables() )
762 {
763 for ( const Capability & cap : pi.dep_supplements() )
764 {
765 _getLocaleDeps( cap, localeSet );
766 }
767 }
768 }
769 return *_availableLocalesPtr;
770 }
771
773
775 {
778
780 for ( const std::string & spec : ZConfig::instance().multiversionSpec() )
781 {
782 static const std::string prefix( "provides:" );
783 bool provides = str::hasPrefix( spec, prefix );
784
785 for ( Solvable solv : WhatProvides( Capability( provides ? spec.c_str() + prefix.size() : spec.c_str() ) ) )
786 {
787 if ( provides || solv.ident() == spec )
788 multiversionList.insert( solv );
789 }
790
792 MIL << "Multiversion install " << spec << ": " << (nsize-size) << " matches" << endl;
793 size = nsize;
794 }
795 }
796
799
806
807 bool PoolImpl::isMultiversion( const Solvable & solv_r ) const
808 { return multiversionList().contains( solv_r ); }
809
811
812 const std::set<std::string> & PoolImpl::requiredFilesystems() const
813 {
815 {
816 _requiredFilesystemsPtr.reset( new std::set<std::string> );
817 std::set<std::string> & requiredFilesystems( *_requiredFilesystemsPtr );
819 std::inserter( requiredFilesystems, requiredFilesystems.end() ) );
820 }
822 }
823
825 } // namespace detail
826
828 } // namespace sat
831} // namespace zypp
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition Easy.h:27
#define L_ERR(GROUP)
Definition Logger.h:141
#define MIL
Definition Logger.h:130
#define WAR
Definition Logger.h:131
#define L_MIL(GROUP)
Definition Logger.h:139
#define L_DBG(GROUP)
Definition Logger.h:138
static CompatSet compatSet(const Arch &targetArch_r)
Return a set of all Arch's compatibleWith a targetArch_r.
Definition Arch.cc:793
std::set< Arch, CompareByGT< Arch > > CompatSet
Reversed arch order, best Arch first.
Definition Arch.h:122
Helper providing more detailed information about a Capability.
Definition Capability.h:366
A sat capability.
Definition Capability.h:63
Capability()
Default ctor, Empty capability.
Definition Capability.h:69
@ CAP_WITHOUT
without
Definition Capability.h:161
@ CAP_ARCH
Used internally.
Definition Capability.h:164
constexpr IdString()
Default ctor, empty string.
Definition IdString.h:61
'Language[_Country]' codes.
Definition Locale.h:51
Locale fallback() const
Return the fallback locale for this locale, if no fallback exists the empty Locale::noCode.
Definition Locale.cc:211
std::string code() const
Return the locale code asString.
Definition Locale.h:89
Locale()
Default Ctor: noCode.
Definition Locale.cc:180
What is known about a repository.
Definition RepoInfo.h:72
Url url() const
Pars pro toto: The first repository url, this is either baseUrls().front() or if no baseUrl is define...
Definition RepoInfo.cc:894
unsigned priority() const
Repository priority for solver.
Definition RepoInfo.cc:600
bool remember(unsigned serial_r) const
Return isDirty, storing serial_r as new value.
Remember a files attributes to detect content changes.
Definition watchfile.h:50
bool hasChanged()
Definition watchfile.h:80
static ZConfig & instance()
Singleton ctor.
Definition ZConfig.cc:794
const char * c_str() const
String representation.
Definition Pathname.h:113
Derive a numeric priority from Url scheme according to zypp.conf(download.media_preference).
std::string alias() const
unique identifier for this source.
static Pool instance()
Singleton ctor.
Definition Pool.h:56
static bool snapshotMapped()
Whether mapSnapshot succeeded in this process.
Definition Pool.cc:195
void clear()
Clear the queue.
Definition Queue.cc:94
Container::size_type size_type
Definition SolvableSet.h:42
size_type size() const
Size of the set.
Definition SolvableSet.h:63
bool insert(const TSolv &solv_r)
Insert a Solvable.
Definition SolvableSet.h:88
bool contains(const TSolv &solv_r) const
Definition SolvableSet.h:68
A Solvable object within the sat Pool.
Definition Solvable.h:54
static const IdString ptfMasterToken
Indicator provides ptf().
Definition Solvable.h:62
static const IdString ptfPackageToken
Indicator provides ptf-package().
Definition Solvable.h:63
static const IdString retractedToken
Indicator provides retracted-patch-package().
Definition Solvable.h:61
WhatProvides()
Default ctor.
sat::SolvableSpec _needrebootSpec
Solvables which should trigger the reboot-needed hint if installed/updated.
Definition PoolImpl.h:412
scoped_ptr< TrackedLocaleIds > _trackedLocaleIdsPtr
Definition PoolImpl.h:400
bool _snapshotFileProvides
Whether the pool still holds exactly what the snapshot restored, i.e.
Definition PoolImpl.h:385
std::string _snapshotCookie
Experimental pool snapshot (see Pool::mapSnapshot).
Definition PoolImpl.h:378
base::SetTracker< IdStringSet > TrackedLocaleIds
Definition PoolImpl.h:306
CPool * getPool() const
Definition PoolImpl.h:188
sat::SolvableSpec _retractedSpec
Blacklisted specs:
Definition PoolImpl.h:415
scoped_ptr< LocaleSet > _availableLocalesPtr
Definition PoolImpl.h:402
scoped_ptr< MultiversionList > _multiversionListPtr
Definition PoolImpl.h:406
bool isSystemRepo(CRepo *repo_r) const
Definition PoolImpl.h:117
static detail::IdType nsCallback(CPool *, void *data, detail::IdType lhs, detail::IdType rhs)
Callback to resolve namespace dependencies (language, modalias, filesystem, etc.).
Definition PoolImpl.cc:145
CRepo * getRepo(RepoIdType id_r) const
Definition PoolImpl.h:192
void setTextLocale(const Locale &locale_r)
Definition PoolImpl.cc:619
void initRequestedLocales(const LocaleSet &locales_r)
Start tracking changes based on this locales_r.
Definition PoolImpl.cc:644
sat::StringQueue _autoinstalled
Definition PoolImpl.h:409
int _addTesttags(CRepo *repo_r, FILE *file_r)
Adding testtags file to a repo.
Definition PoolImpl.cc:524
void multiversionListInit() const
Definition PoolImpl.cc:774
unsigned _snapshotClaiming
>0 while a repo load may still claim snapshot repos, see prepare.
Definition PoolImpl.h:387
const LocaleSet & getAvailableLocales() const
All Locales occurring in any repo.
Definition PoolImpl.cc:754
std::map< RepoIdType, RepoInfo > _repoinfos
Additional RepoInfo.
Definition PoolImpl.h:395
void _deleteRepo(CRepo *repo_r)
Delete repo repo_r from pool.
Definition PoolImpl.cc:489
bool eraseRequestedLocale(const Locale &locale_r)
User change (tracked).
Definition PoolImpl.cc:673
sat::SolvableSpec _ptfMasterSpec
Definition PoolImpl.h:416
void eraseRepoInfo(RepoIdType id_r)
Definition PoolImpl.h:240
const TrackedLocaleIds & trackedLocaleIds() const
Expanded _requestedLocalesTracker for solver.
Definition PoolImpl.cc:685
void localeSetDirty(const char *a1=0, const char *a2=0, const char *a3=0)
Invalidate locale related housekeeping data.
Definition PoolImpl.cc:274
scoped_ptr< std::set< std::string > > _requiredFilesystemsPtr
filesystems mentioned in /etc/sysconfig/storage
Definition PoolImpl.h:420
base::SetTracker< LocaleSet > _requestedLocalesTracker
Definition PoolImpl.h:399
void setRequestedLocales(const LocaleSet &locales_r)
User change (tracked).
Definition PoolImpl.cc:653
std::vector< std::string > _snapshotAliases
Definition PoolImpl.h:380
const MultiversionList & multiversionList() const
Definition PoolImpl.cc:800
void snapshotWriteIfNeeded() const
Definition PoolImpl.cc:371
CRepo * _createRepo(const std::string &name_r)
Creating a new repo named name_r.
Definition PoolImpl.cc:480
SerialNumberWatcher _watcher
Watch serial number.
Definition PoolImpl.h:391
SerialNumber _serial
Serial number - changes with each Pool content change.
Definition PoolImpl.h:376
const std::set< std::string > & requiredFilesystems() const
accessor for etc/sysconfig/storage reading file on demand
Definition PoolImpl.cc:812
void _postRepoAdd(CRepo *repo_r)
Helper postprocessing the repo after adding solv or helix files.
Definition PoolImpl.cc:533
bool mapSnapshot(const Pathname &path_r, const std::string &cookie_r)
Experimental pool snapshot (see Pool::mapSnapshot).
Definition PoolImpl.cc:297
bool addRequestedLocale(const Locale &locale_r)
User change (tracked).
Definition PoolImpl.cc:662
int _addSolv(CRepo *repo_r, FILE *file_r)
Adding solv file to a repo.
Definition PoolImpl.cc:506
int _addHelix(CRepo *repo_r, FILE *file_r)
Adding helix file to a repo.
Definition PoolImpl.cc:515
sat::SolvableSpec _ptfPackageSpec
Definition PoolImpl.h:417
detail::SolvableIdType _addSolvables(CRepo *repo_r, unsigned count_r)
Adding Solvables to a repo.
Definition PoolImpl.cc:579
std::set< RepoIdType > _snapshotUnclaimed
Snapshot repos not (yet) requested via setRepoInfo; erased in prepare.
Definition PoolImpl.h:382
SerialNumber _serialIDs
Serial number of IDs - changes whenever resusePoolIDs==true - ResPool must also invalidate its PoolIt...
Definition PoolImpl.h:389
bool isMultiversion(const Solvable &solv_r) const
Definition PoolImpl.cc:807
void prepare() const
Update housekeeping data (e.g.
Definition PoolImpl.cc:398
static const std::string & systemRepoAlias()
Reserved system repository alias @System .
Definition PoolImpl.cc:108
CPool * _pool
sat-pool.
Definition PoolImpl.h:374
void setRepoInfo(RepoIdType id_r, const RepoInfo &info_r)
Also adjust repo priority and subpriority accordingly.
Definition PoolImpl.cc:586
void setDirty(const char *a1=0, const char *a2=0, const char *a3=0)
Invalidate housekeeping data (e.g.
Definition PoolImpl.cc:247
void depSetDirty(const char *a1=0, const char *a2=0, const char *a3=0)
Invalidate housekeeping data (e.g.
Definition PoolImpl.cc:286
bool query(IdString cap_r) const
Checks if a device on the system matches a modalias pattern.
Definition Modalias.h:70
static Modalias & instance()
Singleton access.
Definition Modalias.cc:223
Singleton manager for the underlying libsolv string pool.
Definition stringpool.h:46
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int running_handles CURLINFO info
Definition curl_dl.cc:160
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t s
Definition curl_dl.cc:154
std::map< std::string, std::string > read(const Pathname &_path)
Read sysconfig file path_r and return (key,valye) pairs.
Definition sysconfig.cc:34
int LIBSOLV_DEBUGMASK()
Definition PoolImpl.cc:67
static void _getLocaleDeps(const Capability &cap_r, LocaleSet &store_r)
Definition PoolImpl.cc:726
unsigned int SolvableIdType
Id type to connect Solvable and sat-solvable.
Definition PoolDefines.h:65
::s_Repo CRepo
Wrapped libsolv C data type exposed as backdoor.
Definition PoolDefines.h:38
const Pathname & sysconfigStoragePath()
Definition PoolImpl.cc:114
int IdType
Generic Id type.
Definition PoolDefines.h:44
::s_Solvable CSolvable
Wrapped libsolv C data type exposed as backdoor.
Definition PoolDefines.h:39
::s_Pool CPool
Wrapped libsolv C data type exposed as backdoor.
Definition PoolDefines.h:36
BOOST_MPL_ASSERT_RELATION(noId,==, STRID_NULL)
CRepo * RepoIdType
Id to denote Solvable::noSolvable.
Definition PoolDefines.h:73
static void logSat(CPool *, void *data, int type, const char *logString)
Definition PoolImpl.cc:122
Libsolv interface
bool dirty() const
Whether the cache is needed and dirty.
std::string hexdecode(const C_Str &str_r)
Decode hexencoded XX sequences.
Definition String.cc:148
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition String.h:1097
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition String.h:602
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Easy-to use interface to the ZYPP dependency resolver.
std::ostream & dumpRangeLine(std::ostream &str, TIterator begin, TIterator end)
Print range defined by iterators (single line style).
Definition LogTools.h:442
std::unordered_set< Locale > LocaleSet
Definition Locale.h:29
std::string asString(const Patch::Category &obj)
relates: Patch::Category string representation.
Definition Patch.cc:122
int repo_add_helix(::Repo *repo, FILE *fp, int flags)
int testcase_add_testtags(Repo *repo, FILE *fp, int flags)
AutoDispose<FILE*> calling fclose
Track added/removed set items based on an initial set.
Definition SetTracker.h:39
const set_type & current() const
Return the current set.
Definition SetTracker.h:140
bool set(set_type new_r)
Set a new_r set and track changes.
Definition SetTracker.h:79
bool add(const value_type &val_r)
Add an element to the set and track changes.
Definition SetTracker.h:101
bool wasAdded(const key_type &key_r) const
Whether val_r is tracked as added.
Definition SetTracker.h:133
const set_type & added() const
Return the set of added items.
Definition SetTracker.h:143
bool remove(const value_type &val_r)
Remove an element from the set and track changes.
Definition SetTracker.h:115
const set_type & removed() const
Return the set of removed items.
Definition SetTracker.h:146
bool setInitial()
(Re-)Start tracking the current set (discards previously tracked changes).
Definition SetTracker.h:58
bool contains(const key_type &key_r) const
Whether val_r is in the set.
Definition SetTracker.h:130