[systemd-devel] providing backwards compatibility
Zbigniew Jędrzejewski-Szmek
zbyszek at in.waw.pl
Fri Jan 17 08:41:26 PST 2014
On Fri, Jan 17, 2014 at 03:45:03PM +0100, Lennart Poettering wrote:
> On Fri, 17.01.14 04:06, Zbigniew Jędrzejewski-Szmek (zbyszek at in.waw.pl) wrote:
>
> > So there's "binary" compatibility, and "source" compatibility.
> > It would be nice if we could do those changes without
> >
> > a) requiring recompilation ("binary")
> > b) requiring editing build scripts in dependent packages ("source").
> >
> > For b, keeping around a .pc file which points to the *new* library
> > name should be enough:
> >
> > - Libs: -L${libdir} -lsystemd-login
> > + Libs: -L${libdir} -lsystemd
> >
> > On our side it's a tiny effort, and avoid a major PITA for distributions.
> >
> > For a, a compatibility symlink (e.g. libsystemd-login.so.0 -> libsystemd.so.0)
> > can be provided. I'm attaching a POC patch which moves the symbol exports
> > so that programs compiled against libsystemd-login will continue working.
> > The symlink is not created, this part must be done by hand.
> >
> > I think that if we ever decide to futher merge libraries, those
> > would be the steps to take.
>
> So here's my opinion on all of this:
>
> First let me say that I am pretty strongly of the belief that API+ABI
> breaks are something that distros have to deal with, it's one of the
> primary reasons distros exist, so that they can deal with things like
> this across the whole system. For example, recently glibc reorganized
> "-lrt", and if they can do that, we certainly can do this too.
>
> That said, while I believe that distros must be prepared to deal with
> this, I think we can certainly help to make this easy for them, and make
> the transition gradual rather than abrupt. However, for us upstream a
> couple of things matter:
>
> a) I don't want legacy/dead code in our upstream repo that we don't use
> and hence test regularly. Thus I don't think it is an option to
> simply keep two copies of everything in our repo, once for the old
> and once for the new library.
>
> b) The symbols after they have moved must carry a new, correct symbol
> version, it's not an option to just move the library they are defined
> in.
>
> c) Manual symblinks between libraries are not an option I think, this
> will break too easily, and will likely confuse tools like ldconfig...
>
> d) Compatibility for the old library names and versions must be
> isolated in the source tree, and it must be clear that we can remove this
> easily within a year or so.
OK.
> So, here's what I'd propose to maintain compatibility in both API and
> ABI for a year or so:
>
> 1) Merge the libraries now. Give everything new symbol versions.
>
> 2) Expose the sd-bus/sd-event/sd-memfd/ symbols only if --enable-kdbus
> is specified. People who enable this will hence get a different API
> for this library than others! This is OK I think, by specifying
> --enable-kdbus users basically declare that they know that there are
> no API/ABI guarantees.
>
> 3) The new library will ship one .pc file only.
>
> 4) In a new subdirectory src/compat-libs/ (or something like that) we
> will provide compat stubs that will build libraries (for ABI compat)
> and pc files (for API compat) that redirect to
> the new versions. This stuff should be optional though, and only be
> enabled if --enable-compat-libs is specified, and the README should
> name a date when this will be removed.
OK.
> Now, the way I'd propose the stub libs of item #4 to be implemented is
> via a combination of ".symver" asm magic, and the "ifunc" function
> attribute. With a script we'd first generate for every old symbol code
> like the following:
>
> void new_sd_id128_from_string(void);
> __asm__(".symver new_sd_id128_from_string,sd_id128_from_string at LIBSYSTEMD_209");
>
> This would define a new symbol new_sd_id128_from_string which refers to
> the specific version of the function from thew new library. Note that we
> don't care for the right function signature, we only care for the naked
> symbol name, that's all.
>
> Then, we'd use ifunc to define a local function with the right name,
> that just maps to the new implementation:
>
> static void (*resolve_sd_id128_from_string (void)) (void) {
> return new_sd_id128_from_string;
> }
> void sd_id128_from_string(void) __attribute__((ifunc("resolve_sd_id128_from_string")));
>
> This newly defined function would then be assigned the right old version
> with the ".sym" file, as before.
This sounds like a good plan.
Zbyszek
More information about the systemd-devel
mailing list