{"id":187,"date":"2013-05-27T20:00:16","date_gmt":"2013-05-27T18:00:16","guid":{"rendered":"https:\/\/blogs.gentoo.org\/mgorny\/?p=187"},"modified":"2013-07-23T11:02:39","modified_gmt":"2013-07-23T09:02:39","slug":"the-pointless-art-of-subslots","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/mgorny\/2013\/05\/27\/the-pointless-art-of-subslots\/","title":{"rendered":"The pointless art of subslots"},"content":{"rendered":"<p>The&nbsp;sub-slots feature of&nbsp;EAPI&nbsp;5 was announced as&nbsp;if&nbsp;it was the&nbsp;ultimate solution to&nbsp;the&nbsp;problem of&nbsp;SONAME changes on&nbsp;library upgrades. However, the&nbsp;longer I see it, the&nbsp;more I believe that it is not&nbsp;really a&nbsp;good solution, and&nbsp;that it misses the&nbsp;actual issue targeting somewhere nearby.<\/p>\n<p>The&nbsp;issue is likely well-known by&nbsp;most of&nbsp;the&nbsp;Gentoo users. Every time a&nbsp;library changes its ABI, it changes the&nbsp;SONAME (the&nbsp;filename programs link&nbsp;to) to&nbsp;avoid breaking existing programs. When the&nbsp;package is upgraded, the&nbsp;new version is installed under the&nbsp;new name, and&nbsp;the&nbsp;old one is removed. As a&nbsp;direct result, <em>all<\/em> applications linking to the&nbsp;old version become broken and&nbsp;need to be&nbsp;rebuilt.<\/p>\n<p>The&nbsp;classic way of&nbsp;handling this is to&nbsp;run the&nbsp;<em>revdep-rebuild<\/em> tool. It takes a&nbsp;while to&nbsp;scan the&nbsp;system with it but it supposedly finds all broken executables and&nbsp;initiates a&nbsp;rebuild of&nbsp;them. Of&nbsp;course, the&nbsp;system is in&nbsp;broken state until all relevant packages are&nbsp;rebuilt, and&nbsp;sometimes they just fail to&nbsp;build\u2026<\/p>\n<p>As you can guess, this is far from being perfect. That&#8217;s why people tried to&nbsp;find a&nbsp;better solution, and&nbsp;a&nbsp;few solutions were actually implemented. I&#8217;d like to describe them in a&nbsp;quasi-chronological order.<\/p>\n<p><!--more--><\/p>\n<h3>Using slots with slot-operator deps<\/h3>\n<p>A&nbsp;perfect solution that has been long advocated by&nbsp;Exherbo developers. I&#8217;m not aware, though, if&nbsp;they ever used it themselves. I&nbsp;didn&#8217;t see an&nbsp;exact explanation of&nbsp;how they expect it to be&nbsp;done, therefore I&nbsp;am mostly explaining here how I&nbsp;think it could be&nbsp;done.<\/p>\n<p>The&nbsp;idea is&nbsp;that every SONAME-version of&nbsp;the&nbsp;library uses a&nbsp;different slot. That is, every time the&nbsp;SONAME changes, you change slot as well. Using different slots for&nbsp;each SONAME means that the&nbsp;incompatible versions of&nbsp;the&nbsp;library can be&nbsp;installed in&nbsp;parallel until all applications are&nbsp;rebuilt. This has a&nbsp;few requirements though.<\/p>\n<p>First of&nbsp;all, only the&nbsp;newest slot may install development files such as&nbsp;headers. This requires that every version bump is&nbsp;accompanied by&nbsp;a&nbsp;revision bump of&nbsp;the&nbsp;older version, dropping the&nbsp;development files. On&nbsp;each upgrade, user builds not only the&nbsp;new version but&nbsp;also rebuilds the&nbsp;older version.<\/p>\n<p>To handle the&nbsp;upgrades without a&nbsp;small moment of&nbsp;breakage (and&nbsp;risk of&nbsp;longer breakage if&nbsp;a&nbsp;build fails), the&nbsp;package manager would need to&nbsp;build both packages before starting the&nbsp;merge process. I&nbsp;doubt that enforcing this is&nbsp;really possible right now.<\/p>\n<p>Secondly, the&nbsp;ebuilds installing development files would need to&nbsp;block the&nbsp;older versions (in&nbsp;other slots) doing the&nbsp;same <em>while<\/em> keeping the&nbsp;versions lacking development files non-blocked.<\/p>\n<p>To explain this better: let&#8217;s assume that we have: foo-1, foo-1-r1, foo-2, foo-2-r1, foo-3, \u2026 The&nbsp;-r0 versions have development files and&nbsp;-r1 versions don&#8217;t have them (they are just the&nbsp;upgrade compatibility ebuilds). Now, the&nbsp;blocker in&nbsp;foo-3 would need to&nbsp;block all the&nbsp;older -r0 versions and&nbsp;<em>not<\/em> -r1 ones.<\/p>\n<p>In&nbsp;a&nbsp;real-life situation, there will likely be differing revision numbers as&nbsp;well. And&nbsp;I&nbsp;don&#8217;t know any way of&nbsp;handling this other than explicitly listing <em>all<\/em> blocked versions, one by&nbsp;one.<\/p>\n<p>And&nbsp;in&nbsp;the&nbsp;end, reverse dependencies need to&nbsp;use a&nbsp;special slot-dependency operator which binds the&nbsp;dependency to the&nbsp;slot that was used during the&nbsp;package build. But it&#8217;s least of&nbsp;the&nbsp;problems, I believe.<\/p>\n<h3>The&nbsp;solution of&nbsp;preserved-libs<\/h3>\n<p>An&nbsp;another attempt of&nbsp;solving the&nbsp;issue was developed in&nbsp;portage-2.2. Although it is available in&nbsp;mainstream portage nowadays, it is still disabled by&nbsp;default due to a&nbsp;few bugs and&nbsp;the&nbsp;fact that some people believe it&#8217;s a&nbsp;hack.<\/p>\n<p>The&nbsp;idea of&nbsp;<em>preserved-libs<\/em> is&nbsp;for&nbsp;the&nbsp;package manager to&nbsp;actually trace library linkage within installed programs and&nbsp;automatically preserve old versions of&nbsp;libraries as&nbsp;long as&nbsp;the&nbsp;relevant programs are&nbsp;not&nbsp;rebuilt to use the&nbsp;newer versions. As&nbsp;complex and&nbsp;as&nbsp;simple as&nbsp;that.<\/p>\n<p>Preserving libraries this way doesn&#8217;t require any&nbsp;specific action from the&nbsp;package maintainer. Portage detects itself that a&nbsp;library with a&nbsp;new SONAME has been installed during an&nbsp;upgrade and&nbsp;preserves the&nbsp;old one. It&nbsp;also keeps track of&nbsp;all the&nbsp;consumers that link against the&nbsp;old version and&nbsp;remove it after the&nbsp;last one is&nbsp;rebuilt.<\/p>\n<p>Of course it is not&nbsp;perfect. It can&#8217;t handle all kinds of&nbsp;incompatibilities, it won&#8217;t work outside the&nbsp;traditional executable-library linkage and&nbsp;the&nbsp;SONAME tracking is&nbsp;not perfect. But I&nbsp;believe this is&nbsp;the&nbsp;best <em>solution<\/em> we can have.<\/p>\n<h3>The&nbsp;nothing-new in&nbsp;sub-slots<\/h3>\n<p>Lately, a&nbsp;few developers who believed that preserved-libs is not&nbsp;supposed to go&nbsp;mainstream decided to&nbsp;implemented a&nbsp;different solution. After some discussion, the&nbsp;feature was quickly put into EAPI&nbsp;5 and&nbsp;then started to be&nbsp;tested on&nbsp;the&nbsp;tree.<\/p>\n<p>The&nbsp;problem is that it&#8217;s somehow a&nbsp;solution to&nbsp;the&nbsp;wrong problem. As far as I&nbsp;am concerned, the&nbsp;major issue with SONAMEs changing is that the&nbsp;system is <em>broken<\/em> between package rebuilds. Tangentially to&nbsp;this, sub-slots mostly address having to call tools like <em>revdep-rebuild<\/em> which is not a&nbsp;solution to&nbsp;the&nbsp;problem.<\/p>\n<p>Basically all sub-slots do is&nbsp;forcing rebuild on a&nbsp;given set of&nbsp;reverse dependencies when the&nbsp;sub-slot of&nbsp;package changes. The&nbsp;rebuilds are pulled into the&nbsp;same dependency graph as&nbsp;the&nbsp;upgrade to be&nbsp;forced immediately after it.<\/p>\n<p>I can agree that sub-slots have their uses. For&nbsp;example, xorg-server modules definitely benefit from them, and&nbsp;so may other cases which weren&#8217;t handled by&nbsp;preserved-libs already. For&nbsp;other cases the&nbsp;sub-slots are either not good enough (virtuals), redundant (regular libraries) or&nbsp;even broken (packages installing multiple libraries).<\/p>\n<p>Aside from the&nbsp;xorg module benefit, I don&#8217;t see much use of&nbsp;sub-slots. On&nbsp;systems not&nbsp;having preserved-libs enabled, they <em>may eventually<\/em> remove the&nbsp;need for&nbsp;revdep-rebuild. On&nbsp;systems having preserved-libs, it can only result in&nbsp;<em>needless<\/em> or&nbsp;<em>needlessly hurried<\/em> rebuilds.<\/p>\n<h3>A&nbsp;short summary<\/h3>\n<p>So, we&#8217;re having two live solutions right now: one in&nbsp;preserved-libs, and&nbsp;other in&nbsp;sub-slots. The&nbsp;former addresses the&nbsp;issue of&nbsp;system being broken mid-upgrade, the&nbsp;latter removes (partially?) the&nbsp;need for&nbsp;calling an&nbsp;external tool. The&nbsp;former allows you to&nbsp;rebuild the&nbsp;affected packages at any&nbsp;convenient time, the&nbsp;latter forces you to do it right away.<\/p>\n<p>What really worries me is&nbsp;that people are so&nbsp;opposed to&nbsp;preserved-libs, and&nbsp;at&nbsp;the&nbsp;same time accept a&nbsp;partial, mis-designed work called&nbsp;sub-slots that easily. Then advertise it without thoroughly explaining how and&nbsp;when to use it, and&nbsp;what are the&nbsp;problems with it. And, for&nbsp;example, unnecessarily rebuilding webkit-gtk regularly would be an&nbsp;<em>important<\/em> issue.<\/p>\n<p>A&nbsp;particular result of&nbsp;that was visible when sub-slot support was introduced into&nbsp;<em>app-text\/poppler<\/em>. That package installs a&nbsp;core library with quite an&nbsp;unstable ABI and&nbsp;a&nbsp;set of&nbsp;interface libraries with stable ABIs. External packages usually link with the&nbsp;latter.<\/p>\n<p>When sub-slot support was enabled on&nbsp;poppler, <em>all<\/em> reverse dependencies were desired to use sub-slot matching. As&nbsp;a&nbsp;result, every poppler upgrade required <em>needlessly<\/em> rebuilding half of&nbsp;the&nbsp;system. The&nbsp;rev-deps were reverted but&nbsp;this only made people try to&nbsp;extend the&nbsp;sub-slots into a&nbsp;more complex and&nbsp;even less maintainable idea.<\/p>\n<p>Is this really what we all want? Does it benefit us? And&nbsp;why the&nbsp;heck people reinvented library preservation in&nbsp;eclasses?!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The&nbsp;sub-slots feature of&nbsp;EAPI&nbsp;5 was announced as&nbsp;if&nbsp;it was the&nbsp;ultimate solution to&nbsp;the&nbsp;problem of&nbsp;SONAME changes on&nbsp;library upgrades. However, the&nbsp;longer I see it, the&nbsp;more I believe that it is not&nbsp;really a&nbsp;good solution, and&nbsp;that it misses the&nbsp;actual issue targeting somewhere nearby. The&nbsp;issue is likely well-known by&nbsp;most of&nbsp;the&nbsp;Gentoo users. Every time a&nbsp;library changes its ABI, it changes the&nbsp;SONAME (the&nbsp;filename programs link&nbsp;to) &hellip; <a href=\"https:\/\/blogs.gentoo.org\/mgorny\/2013\/05\/27\/the-pointless-art-of-subslots\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;The pointless art of subslots&#8221;<\/span><\/a><\/p>\n","protected":false},"author":137,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[3],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/187"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/users\/137"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/comments?post=187"}],"version-history":[{"count":6,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/187\/revisions"}],"predecessor-version":[{"id":204,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/187\/revisions\/204"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/media?parent=187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/categories?post=187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/tags?post=187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}